aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs426
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}