diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 426 |
1 files changed, 210 insertions, 216 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7498cfe..31e6ce9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
146 | 146 | ||
147 | protected virtual void OnNewClient(IClientAPI client) | 147 | protected virtual void OnNewClient(IClientAPI client) |
148 | { | 148 | { |
149 | client.OnTeleportHomeRequest += TeleportHome; | 149 | client.OnTeleportHomeRequest += TriggerTeleportHome; |
150 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 150 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
151 | } | 151 | } |
152 | 152 | ||
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
220 | /// <param name="sp"></param> | 220 | /// <param name="sp"></param> |
221 | /// <param name="position"></param> | 221 | /// <param name="position"></param> |
222 | /// <param name="lookAt"></param> | 222 | /// <param name="lookAt"></param> |
223 | /// <param name="teleportFlags"></param | 223 | /// <param name="teleportFlags"></param> |
224 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | 224 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) |
225 | { | 225 | { |
226 | m_log.DebugFormat( | 226 | m_log.DebugFormat( |
@@ -264,11 +264,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
264 | position.Z = newPosZ; | 264 | position.Z = newPosZ; |
265 | } | 265 | } |
266 | 266 | ||
267 | if (sp.Flying) | ||
268 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
269 | |||
267 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 270 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
268 | 271 | ||
269 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 272 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
270 | 273 | ||
271 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 274 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
275 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | ||
272 | sp.Velocity = Vector3.Zero; | 276 | sp.Velocity = Vector3.Zero; |
273 | sp.Teleport(position); | 277 | sp.Teleport(position); |
274 | 278 | ||
@@ -444,8 +448,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
444 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 448 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
445 | // it's actually doing a lot of work. | 449 | // it's actually doing a lot of work. |
446 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 450 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
447 | 451 | if (endPoint == null || endPoint.Address == null) | |
448 | if (endPoint.Address == null) | ||
449 | { | 452 | { |
450 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 453 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
451 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | 454 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
@@ -485,6 +488,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
485 | // both regions | 488 | // both regions |
486 | if (sp.ParentID != (uint)0) | 489 | if (sp.ParentID != (uint)0) |
487 | sp.StandUp(); | 490 | sp.StandUp(); |
491 | else if (sp.Flying) | ||
492 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
488 | 493 | ||
489 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to | 494 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to |
490 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). | 495 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). |
@@ -662,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
662 | // | 667 | // |
663 | // This sleep can be increased if necessary. However, whilst it's active, | 668 | // This sleep can be increased if necessary. However, whilst it's active, |
664 | // an agent cannot teleport back to this region if it has teleported away. | 669 | // an agent cannot teleport back to this region if it has teleported away. |
665 | Thread.Sleep(2000); | 670 | Thread.Sleep(3000); |
666 | 671 | ||
667 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 672 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
668 | } | 673 | } |
@@ -802,7 +807,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
802 | 807 | ||
803 | #region Teleport Home | 808 | #region Teleport Home |
804 | 809 | ||
805 | public virtual void TeleportHome(UUID id, IClientAPI client) | 810 | public virtual void TriggerTeleportHome(UUID id, IClientAPI client) |
811 | { | ||
812 | TeleportHome(id, client); | ||
813 | } | ||
814 | |||
815 | public virtual bool TeleportHome(UUID id, IClientAPI client) | ||
806 | { | 816 | { |
807 | m_log.DebugFormat( | 817 | m_log.DebugFormat( |
808 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 818 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
@@ -812,12 +822,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
812 | 822 | ||
813 | if (uinfo != null) | 823 | if (uinfo != null) |
814 | { | 824 | { |
825 | if (uinfo.HomeRegionID == UUID.Zero) | ||
826 | { | ||
827 | // can't find the Home region: Tell viewer and abort | ||
828 | client.SendTeleportFailed("You don't have a home position set."); | ||
829 | return false; | ||
830 | } | ||
815 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 831 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
816 | if (regionInfo == null) | 832 | if (regionInfo == null) |
817 | { | 833 | { |
818 | // can't find the Home region: Tell viewer and abort | 834 | // can't find the Home region: Tell viewer and abort |
819 | client.SendTeleportFailed("Your home region could not be found."); | 835 | client.SendTeleportFailed("Your home region could not be found."); |
820 | return; | 836 | return false; |
821 | } | 837 | } |
822 | 838 | ||
823 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", | 839 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", |
@@ -830,10 +846,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
830 | } | 846 | } |
831 | else | 847 | else |
832 | { | 848 | { |
833 | m_log.ErrorFormat( | 849 | // can't find the Home region: Tell viewer and abort |
834 | "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", | 850 | client.SendTeleportFailed("Your home region could not be found."); |
835 | client.Name, client.AgentId); | 851 | return false; |
836 | } | 852 | } |
853 | return true; | ||
837 | } | 854 | } |
838 | 855 | ||
839 | #endregion | 856 | #endregion |
@@ -841,11 +858,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
841 | 858 | ||
842 | #region Agent Crossings | 859 | #region Agent Crossings |
843 | 860 | ||
844 | public bool Cross(ScenePresence agent, bool isFlying) | 861 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) |
845 | { | 862 | { |
846 | Scene scene = agent.Scene; | 863 | version = String.Empty; |
847 | Vector3 pos = agent.AbsolutePosition; | 864 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
848 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
849 | uint neighbourx = scene.RegionInfo.RegionLocX; | 865 | uint neighbourx = scene.RegionInfo.RegionLocX; |
850 | uint neighboury = scene.RegionInfo.RegionLocY; | 866 | uint neighboury = scene.RegionInfo.RegionLocY; |
851 | const float boundaryDistance = 1.7f; | 867 | const float boundaryDistance = 1.7f; |
@@ -866,52 +882,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
866 | } | 882 | } |
867 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 883 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
868 | { | 884 | { |
869 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 885 | neighboury--; |
870 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 886 | newpos.Y = Constants.RegionSize - enterDistance; |
871 | { | ||
872 | neighboury--; | ||
873 | newpos.Y = Constants.RegionSize - enterDistance; | ||
874 | } | ||
875 | else | ||
876 | { | ||
877 | agent.IsInTransit = true; | ||
878 | |||
879 | neighboury = b.TriggerRegionY; | ||
880 | neighbourx = b.TriggerRegionX; | ||
881 | |||
882 | Vector3 newposition = pos; | ||
883 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
884 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
885 | agent.ControllingClient.SendAgentAlertMessage( | ||
886 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
887 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
888 | return true; | ||
889 | } | ||
890 | } | ||
891 | |||
892 | Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); | ||
893 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
894 | { | ||
895 | neighbourx--; | ||
896 | newpos.X = Constants.RegionSize - enterDistance; | ||
897 | } | ||
898 | else | ||
899 | { | ||
900 | agent.IsInTransit = true; | ||
901 | |||
902 | neighboury = ba.TriggerRegionY; | ||
903 | neighbourx = ba.TriggerRegionX; | ||
904 | |||
905 | Vector3 newposition = pos; | ||
906 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
907 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
908 | agent.ControllingClient.SendAgentAlertMessage( | ||
909 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
910 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
911 | |||
912 | return true; | ||
913 | } | 887 | } |
914 | 888 | ||
889 | neighbourx--; | ||
890 | newpos.X = Constants.RegionSize - enterDistance; | ||
915 | } | 891 | } |
916 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | 892 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) |
917 | { | 893 | { |
@@ -921,26 +897,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
921 | 897 | ||
922 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 898 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
923 | { | 899 | { |
924 | Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 900 | neighboury--; |
925 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | 901 | newpos.Y = Constants.RegionSize - enterDistance; |
926 | { | ||
927 | neighboury--; | ||
928 | newpos.Y = Constants.RegionSize - enterDistance; | ||
929 | } | ||
930 | else | ||
931 | { | ||
932 | agent.IsInTransit = true; | ||
933 | |||
934 | neighboury = ba.TriggerRegionY; | ||
935 | neighbourx = ba.TriggerRegionX; | ||
936 | Vector3 newposition = pos; | ||
937 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
938 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
939 | agent.ControllingClient.SendAgentAlertMessage( | ||
940 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
941 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
942 | return true; | ||
943 | } | ||
944 | } | 902 | } |
945 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 903 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
946 | { | 904 | { |
@@ -952,25 +910,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
952 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 910 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
953 | { | 911 | { |
954 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 912 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); |
955 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 913 | neighboury--; |
956 | { | 914 | newpos.Y = Constants.RegionSize - enterDistance; |
957 | neighboury--; | ||
958 | newpos.Y = Constants.RegionSize - enterDistance; | ||
959 | } | ||
960 | else | ||
961 | { | ||
962 | agent.IsInTransit = true; | ||
963 | |||
964 | neighboury = b.TriggerRegionY; | ||
965 | neighbourx = b.TriggerRegionX; | ||
966 | Vector3 newposition = pos; | ||
967 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
968 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
969 | agent.ControllingClient.SendAgentAlertMessage( | ||
970 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
971 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
972 | return true; | ||
973 | } | ||
974 | } | 915 | } |
975 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 916 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
976 | { | 917 | { |
@@ -1004,19 +945,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1004 | } | 945 | } |
1005 | */ | 946 | */ |
1006 | 947 | ||
1007 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 948 | xDest = neighbourx; |
949 | yDest = neighboury; | ||
1008 | 950 | ||
1009 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); | 951 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); |
1010 | 952 | ||
953 | ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); | ||
954 | |||
1011 | ExpiringCache<ulong, DateTime> r; | 955 | ExpiringCache<ulong, DateTime> r; |
1012 | DateTime banUntil; | 956 | DateTime banUntil; |
1013 | 957 | ||
1014 | if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) | 958 | if (m_bannedRegions.TryGetValue(agentID, out r)) |
1015 | { | 959 | { |
1016 | if (r.TryGetValue(neighbourHandle, out banUntil)) | 960 | if (r.TryGetValue(neighbourHandle, out banUntil)) |
1017 | { | 961 | { |
1018 | if (DateTime.Now < banUntil) | 962 | if (DateTime.Now < banUntil) |
1019 | return false; | 963 | return null; |
1020 | r.Remove(neighbourHandle); | 964 | r.Remove(neighbourHandle); |
1021 | } | 965 | } |
1022 | } | 966 | } |
@@ -1028,28 +972,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1028 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 972 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1029 | 973 | ||
1030 | string reason; | 974 | string reason; |
1031 | string version; | 975 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
1032 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) | ||
1033 | { | 976 | { |
1034 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1035 | if (r == null) | 977 | if (r == null) |
1036 | { | 978 | { |
1037 | r = new ExpiringCache<ulong, DateTime>(); | 979 | r = new ExpiringCache<ulong, DateTime>(); |
1038 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 980 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1039 | 981 | ||
1040 | m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); | 982 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); |
1041 | } | 983 | } |
1042 | else | 984 | else |
1043 | { | 985 | { |
1044 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 986 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1045 | } | 987 | } |
988 | return null; | ||
989 | } | ||
990 | |||
991 | return neighbourRegion; | ||
992 | } | ||
993 | |||
994 | public bool Cross(ScenePresence agent, bool isFlying) | ||
995 | { | ||
996 | uint x; | ||
997 | uint y; | ||
998 | Vector3 newpos; | ||
999 | string version; | ||
1000 | |||
1001 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); | ||
1002 | if (neighbourRegion == null) | ||
1003 | { | ||
1004 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1046 | return false; | 1005 | return false; |
1047 | } | 1006 | } |
1048 | 1007 | ||
1049 | agent.IsInTransit = true; | 1008 | agent.IsInTransit = true; |
1050 | 1009 | ||
1051 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 1010 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; |
1052 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | 1011 | d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); |
1053 | 1012 | ||
1054 | return true; | 1013 | return true; |
1055 | } | 1014 | } |
@@ -1118,44 +1077,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1118 | icon.EndInvoke(iar); | 1077 | icon.EndInvoke(iar); |
1119 | } | 1078 | } |
1120 | 1079 | ||
1121 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | 1080 | public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) |
1081 | { | ||
1082 | if (neighbourRegion == null) | ||
1083 | return false; | ||
1084 | |||
1085 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1086 | |||
1087 | agent.RemoveFromPhysicalScene(); | ||
1088 | |||
1089 | return true; | ||
1090 | } | ||
1122 | 1091 | ||
1123 | /// <summary> | 1092 | /// <summary> |
1124 | /// This Closes child agents on neighbouring regions | 1093 | /// This Closes child agents on neighbouring regions |
1125 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1094 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1126 | /// </summary> | 1095 | /// </summary> |
1127 | protected ScenePresence CrossAgentToNewRegionAsync( | 1096 | public ScenePresence CrossAgentToNewRegionAsync( |
1128 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1097 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1129 | bool isFlying, string version) | 1098 | bool isFlying, string version) |
1130 | { | 1099 | { |
1131 | if (neighbourRegion == null) | 1100 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) |
1132 | return agent; | 1101 | return agent; |
1133 | 1102 | ||
1134 | try | 1103 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) |
1135 | { | 1104 | return agent; |
1136 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1137 | |||
1138 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | ||
1139 | |||
1140 | m_log.DebugFormat( | ||
1141 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1142 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
1143 | |||
1144 | Scene m_scene = agent.Scene; | ||
1145 | |||
1146 | if (!agent.ValidateAttachments()) | ||
1147 | m_log.DebugFormat( | ||
1148 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1149 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1150 | |||
1151 | pos = pos + agent.Velocity; | ||
1152 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1153 | 1105 | ||
1154 | agent.RemoveFromPhysicalScene(); | 1106 | CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); |
1107 | return agent; | ||
1108 | } | ||
1155 | 1109 | ||
1110 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) | ||
1111 | { | ||
1112 | try | ||
1113 | { | ||
1156 | AgentData cAgent = new AgentData(); | 1114 | AgentData cAgent = new AgentData(); |
1157 | agent.CopyTo(cAgent); | 1115 | agent.CopyTo(cAgent); |
1158 | cAgent.Position = pos; | 1116 | cAgent.Position = pos + agent.Velocity; |
1159 | if (isFlying) | 1117 | if (isFlying) |
1160 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 1118 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
1161 | 1119 | ||
@@ -1165,7 +1123,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1165 | // Beyond this point, extra cleanup is needed beyond removing transit state | 1123 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1166 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | 1124 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); |
1167 | 1125 | ||
1168 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1126 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) |
1169 | { | 1127 | { |
1170 | // region doesn't take it | 1128 | // region doesn't take it |
1171 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1129 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
@@ -1174,93 +1132,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1174 | agent.AddToPhysicalScene(isFlying); | 1132 | agent.AddToPhysicalScene(isFlying); |
1175 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1133 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1176 | 1134 | ||
1177 | return agent; | 1135 | return false; |
1178 | } | 1136 | } |
1179 | 1137 | ||
1180 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | 1138 | } |
1181 | agent.ControllingClient.RequestClientInfo(); | 1139 | catch (Exception e) |
1140 | { | ||
1141 | m_log.ErrorFormat( | ||
1142 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | ||
1143 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | ||
1182 | 1144 | ||
1183 | //m_log.Debug("BEFORE CROSS"); | 1145 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. |
1184 | //Scene.DumpChildrenSeeds(UUID); | 1146 | return false; |
1185 | //DumpKnownRegions(); | 1147 | } |
1186 | string agentcaps; | ||
1187 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1188 | { | ||
1189 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1190 | neighbourRegion.RegionHandle); | ||
1191 | return agent; | ||
1192 | } | ||
1193 | // No turning back | ||
1194 | agent.IsChildAgent = true; | ||
1195 | 1148 | ||
1196 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1149 | return true; |
1150 | } | ||
1197 | 1151 | ||
1198 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | 1152 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1153 | bool isFlying, string version) | ||
1154 | { | ||
1155 | agent.ControllingClient.RequestClientInfo(); | ||
1199 | 1156 | ||
1200 | if (m_eqModule != null) | 1157 | string agentcaps; |
1201 | { | 1158 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) |
1202 | m_eqModule.CrossRegion( | 1159 | { |
1203 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1160 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", |
1204 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | 1161 | neighbourRegion.RegionHandle); |
1205 | } | 1162 | return; |
1206 | else | 1163 | } |
1207 | { | ||
1208 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1209 | capsPath); | ||
1210 | } | ||
1211 | 1164 | ||
1212 | // SUCCESS! | 1165 | // No turning back |
1213 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | 1166 | agent.IsChildAgent = true; |
1214 | 1167 | ||
1215 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | 1168 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
1216 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | ||
1217 | 1169 | ||
1218 | agent.MakeChildAgent(); | 1170 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); |
1171 | |||
1172 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1173 | |||
1174 | if (m_eqModule != null) | ||
1175 | { | ||
1176 | m_eqModule.CrossRegion( | ||
1177 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | ||
1178 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1179 | } | ||
1180 | else | ||
1181 | { | ||
1182 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1183 | capsPath); | ||
1184 | } | ||
1219 | 1185 | ||
1220 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1186 | // SUCCESS! |
1221 | // but not sure yet what the side effects would be. | 1187 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
1222 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1223 | 1188 | ||
1224 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1189 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1225 | agent.SendOtherAgentsAvatarDataToMe(); | 1190 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1226 | agent.SendOtherAgentsAppearanceToMe(); | ||
1227 | 1191 | ||
1228 | // Backwards compatibility. Best effort | 1192 | agent.MakeChildAgent(); |
1229 | if (version == "Unknown" || version == string.Empty) | ||
1230 | { | ||
1231 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1232 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1233 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1234 | } | ||
1235 | 1193 | ||
1236 | // Next, let's close the child agent connections that are too far away. | 1194 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1237 | agent.CloseChildAgents(neighbourx, neighboury); | 1195 | // but not sure yet what the side effects would be. |
1196 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1238 | 1197 | ||
1239 | AgentHasMovedAway(agent, false); | 1198 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1199 | agent.SendOtherAgentsAvatarDataToMe(); | ||
1200 | agent.SendOtherAgentsAppearanceToMe(); | ||
1240 | 1201 | ||
1241 | // // the user may change their profile information in other region, | 1202 | // Backwards compatibility. Best effort |
1242 | // // so the userinfo in UserProfileCache is not reliable any more, delete it | 1203 | if (version == "Unknown" || version == string.Empty) |
1243 | // // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1244 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1245 | // { | ||
1246 | // m_log.DebugFormat( | ||
1247 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1248 | // } | ||
1249 | |||
1250 | //m_log.Debug("AFTER CROSS"); | ||
1251 | //Scene.DumpChildrenSeeds(UUID); | ||
1252 | //DumpKnownRegions(); | ||
1253 | } | ||
1254 | catch (Exception e) | ||
1255 | { | 1204 | { |
1256 | m_log.ErrorFormat( | 1205 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); |
1257 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | 1206 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback |
1258 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | 1207 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
1259 | |||
1260 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | ||
1261 | } | 1208 | } |
1262 | 1209 | ||
1263 | return agent; | 1210 | // Next, let's close the child agent connections that are too far away. |
1211 | uint neighbourx; | ||
1212 | uint neighboury; | ||
1213 | |||
1214 | Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1215 | |||
1216 | neighbourx /= Constants.RegionSize; | ||
1217 | neighboury /= Constants.RegionSize; | ||
1218 | |||
1219 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1220 | |||
1221 | AgentHasMovedAway(agent, false); | ||
1222 | |||
1223 | // the user may change their profile information in other region, | ||
1224 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1225 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1226 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1227 | // { | ||
1228 | // m_log.DebugFormat( | ||
1229 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1230 | // } | ||
1231 | |||
1232 | //m_log.Debug("AFTER CROSS"); | ||
1233 | //Scene.DumpChildrenSeeds(UUID); | ||
1234 | //DumpKnownRegions(); | ||
1235 | |||
1236 | return; | ||
1264 | } | 1237 | } |
1265 | 1238 | ||
1266 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1239 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
@@ -1331,10 +1304,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1331 | agent.Id0 = currentAgentCircuit.Id0; | 1304 | agent.Id0 = currentAgentCircuit.Id0; |
1332 | } | 1305 | } |
1333 | 1306 | ||
1334 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 1307 | IPEndPoint external = region.ExternalEndPoint; |
1335 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | 1308 | if (external != null) |
1309 | { | ||
1310 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
1311 | d.BeginInvoke(sp, agent, region, external, true, | ||
1336 | InformClientOfNeighbourCompleted, | 1312 | InformClientOfNeighbourCompleted, |
1337 | d); | 1313 | d); |
1314 | } | ||
1338 | } | 1315 | } |
1339 | #endregion | 1316 | #endregion |
1340 | 1317 | ||
@@ -1915,27 +1892,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1915 | Utils.LongToUInts(newRegionHandle, out x, out y); | 1892 | Utils.LongToUInts(newRegionHandle, out x, out y); |
1916 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 1893 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1917 | 1894 | ||
1918 | if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) | 1895 | if (destination != null) |
1919 | { | 1896 | { |
1920 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); | 1897 | if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) |
1898 | return; // we did it | ||
1899 | } | ||
1921 | 1900 | ||
1922 | // We are going to move the object back to the old position so long as the old position | 1901 | // no one or failed lets go back and tell physics to go on |
1923 | // is in the region | 1902 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f); |
1924 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); | 1903 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f); |
1925 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); | 1904 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f); |
1926 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); | ||
1927 | 1905 | ||
1928 | grp.RootPart.GroupPosition = oldGroupPosition; | 1906 | grp.AbsolutePosition = oldGroupPosition; |
1907 | grp.Velocity = Vector3.Zero; | ||
1929 | 1908 | ||
1930 | // Need to turn off the physics flags, otherwise the object will continue to attempt to | 1909 | if (grp.RootPart.PhysActor != null) |
1931 | // move out of the region creating an infinite loop of failed attempts to cross | 1910 | grp.RootPart.PhysActor.CrossingFailure(); |
1932 | grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); | ||
1933 | 1911 | ||
1934 | grp.ScheduleGroupForFullUpdate(); | 1912 | if (grp.RootPart.KeyframeMotion != null) |
1935 | } | 1913 | grp.RootPart.KeyframeMotion.CrossingFailure(); |
1914 | |||
1915 | grp.ScheduleGroupForFullUpdate(); | ||
1936 | } | 1916 | } |
1937 | 1917 | ||
1938 | 1918 | ||
1919 | |||
1939 | /// <summary> | 1920 | /// <summary> |
1940 | /// Move the given scene object into a new region | 1921 | /// Move the given scene object into a new region |
1941 | /// </summary> | 1922 | /// </summary> |
@@ -1986,17 +1967,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1986 | grp, e); | 1967 | grp, e); |
1987 | } | 1968 | } |
1988 | } | 1969 | } |
1970 | /* | ||
1971 | * done on caller ( not in attachments crossing for now) | ||
1989 | else | 1972 | else |
1990 | { | 1973 | { |
1974 | |||
1991 | if (!grp.IsDeleted) | 1975 | if (!grp.IsDeleted) |
1992 | { | 1976 | { |
1993 | PhysicsActor pa = grp.RootPart.PhysActor; | 1977 | PhysicsActor pa = grp.RootPart.PhysActor; |
1994 | if (pa != null) | 1978 | if (pa != null) |
1979 | { | ||
1995 | pa.CrossingFailure(); | 1980 | pa.CrossingFailure(); |
1981 | if (grp.RootPart.KeyframeMotion != null) | ||
1982 | { | ||
1983 | // moved to KeyframeMotion.CrossingFailure | ||
1984 | // grp.RootPart.Velocity = Vector3.Zero; | ||
1985 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
1986 | // grp.SendGroupRootTerseUpdate(); | ||
1987 | } | ||
1988 | } | ||
1996 | } | 1989 | } |
1997 | 1990 | ||
1998 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | 1991 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); |
1999 | } | 1992 | } |
1993 | */ | ||
2000 | } | 1994 | } |
2001 | else | 1995 | else |
2002 | { | 1996 | { |
@@ -2081,4 +2075,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2081 | #endregion | 2075 | #endregion |
2082 | 2076 | ||
2083 | } | 2077 | } |
2084 | } \ No newline at end of file | 2078 | } |