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