aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs210
1 files changed, 116 insertions, 94 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 538dd5f..486f9d2 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -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,6 +264,9 @@ 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);
@@ -471,6 +474,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
471 if (sp.ParentID != (uint)0) 474 if (sp.ParentID != (uint)0)
472 sp.StandUp(); 475 sp.StandUp();
473 476
477 else if (sp.Flying)
478 teleportFlags |= (uint)TeleportFlags.IsFlying;
479
474 sp.ControllingClient.SendTeleportStart(teleportFlags); 480 sp.ControllingClient.SendTeleportStart(teleportFlags);
475 481
476 // the avatar.Close below will clear the child region list. We need this below for (possibly) 482 // the avatar.Close below will clear the child region list. We need this below for (possibly)
@@ -982,7 +988,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
982 agent.IsInTransit = true; 988 agent.IsInTransit = true;
983 989
984 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 990 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
985 d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 991 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
986 992
987 return true; 993 return true;
988 } 994 }
@@ -1039,42 +1045,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1039 icon.EndInvoke(iar); 1045 icon.EndInvoke(iar);
1040 } 1046 }
1041 1047
1048 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1049 {
1050 if (neighbourRegion == null)
1051 return false;
1052
1053 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1054
1055 agent.RemoveFromPhysicalScene();
1056
1057 return true;
1058 }
1059
1042 /// <summary> 1060 /// <summary>
1043 /// This Closes child agents on neighbouring regions 1061 /// This Closes child agents on neighbouring regions
1044 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1062 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1045 /// </summary> 1063 /// </summary>
1046 public ScenePresence CrossAgentToNewRegionAsync( 1064 public ScenePresence CrossAgentToNewRegionAsync(
1047 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1065 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1048 bool isFlying, string version) 1066 bool isFlying, string version)
1049 { 1067 {
1050 if (neighbourRegion == null) 1068 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1051 return agent; 1069 return agent;
1052 1070
1053 try 1071 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1054 { 1072 return agent;
1055 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1056
1057 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
1058
1059 m_log.DebugFormat(
1060 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1061 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1062
1063 Scene m_scene = agent.Scene;
1064
1065 if (!agent.ValidateAttachments())
1066 m_log.DebugFormat(
1067 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1068 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1069
1070 pos = pos + agent.Velocity;
1071 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1072 1073
1073 agent.RemoveFromPhysicalScene(); 1074 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1075 return agent;
1076 }
1074 1077
1078 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1079 {
1080 try
1081 {
1075 AgentData cAgent = new AgentData(); 1082 AgentData cAgent = new AgentData();
1076 agent.CopyTo(cAgent); 1083 agent.CopyTo(cAgent);
1077 cAgent.Position = pos; 1084 cAgent.Position = pos + agent.Velocity;
1078 if (isFlying) 1085 if (isFlying)
1079 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1086 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1080 1087
@@ -1084,7 +1091,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1084 // Beyond this point, extra cleanup is needed beyond removing transit state 1091 // Beyond this point, extra cleanup is needed beyond removing transit state
1085 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1092 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1086 1093
1087 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1094 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1088 { 1095 {
1089 // region doesn't take it 1096 // region doesn't take it
1090 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1097 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1093,93 +1100,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1093 agent.AddToPhysicalScene(isFlying); 1100 agent.AddToPhysicalScene(isFlying);
1094 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1101 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1095 1102
1096 return agent; 1103 return false;
1097 } 1104 }
1098 1105
1099 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1106 }
1100 agent.ControllingClient.RequestClientInfo(); 1107 catch (Exception e)
1108 {
1109 m_log.ErrorFormat(
1110 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1111 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1112
1113 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1114 return false;
1115 }
1116
1117 return true;
1118 }
1101 1119
1102 //m_log.Debug("BEFORE CROSS"); 1120 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1103 //Scene.DumpChildrenSeeds(UUID); 1121 bool isFlying, string version)
1104 //DumpKnownRegions(); 1122 {
1105 string agentcaps; 1123 agent.ControllingClient.RequestClientInfo();
1106 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1107 {
1108 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1109 neighbourRegion.RegionHandle);
1110 return agent;
1111 }
1112 // No turning back
1113 agent.IsChildAgent = true;
1114 1124
1115 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1125 string agentcaps;
1126 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1127 {
1128 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1129 neighbourRegion.RegionHandle);
1130 return;
1131 }
1116 1132
1117 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1133 // No turning back
1134 agent.IsChildAgent = true;
1118 1135
1119 if (m_eqModule != null) 1136 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1120 {
1121 m_eqModule.CrossRegion(
1122 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1123 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1124 }
1125 else
1126 {
1127 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1128 capsPath);
1129 }
1130 1137
1131 // SUCCESS! 1138 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1132 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1133 1139
1134 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1140 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1135 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1136 1141
1137 agent.MakeChildAgent(); 1142 if (m_eqModule != null)
1143 {
1144 m_eqModule.CrossRegion(
1145 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1146 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1147 }
1148 else
1149 {
1150 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1151 capsPath);
1152 }
1138 1153
1139 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1154 // SUCCESS!
1140 // but not sure yet what the side effects would be. 1155 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1141 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1142 1156
1143 // now we have a child agent in this region. Request all interesting data about other (root) agents 1157 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1144 agent.SendOtherAgentsAvatarDataToMe(); 1158 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1145 agent.SendOtherAgentsAppearanceToMe();
1146 1159
1147 // Backwards compatibility. Best effort 1160 agent.MakeChildAgent();
1148 if (version == "Unknown" || version == string.Empty)
1149 {
1150 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1151 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1152 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1153 }
1154 1161
1155 // Next, let's close the child agent connections that are too far away. 1162 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1156 agent.CloseChildAgents(neighbourx, neighboury); 1163 // but not sure yet what the side effects would be.
1164 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1157 1165
1158 AgentHasMovedAway(agent, false); 1166 // now we have a child agent in this region. Request all interesting data about other (root) agents
1167 agent.SendOtherAgentsAvatarDataToMe();
1168 agent.SendOtherAgentsAppearanceToMe();
1159 1169
1160 // the user may change their profile information in other region, 1170 // Backwards compatibility. Best effort
1161 // so the userinfo in UserProfileCache is not reliable any more, delete it 1171 if (version == "Unknown" || version == string.Empty)
1162 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1163 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1164 {
1165 m_log.DebugFormat(
1166 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1167 }
1168
1169 //m_log.Debug("AFTER CROSS");
1170 //Scene.DumpChildrenSeeds(UUID);
1171 //DumpKnownRegions();
1172 }
1173 catch (Exception e)
1174 { 1172 {
1175 m_log.ErrorFormat( 1173 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1176 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", 1174 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1177 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); 1175 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1176 }
1178 1177
1179 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1178 // Next, let's close the child agent connections that are too far away.
1179 uint neighbourx;
1180 uint neighboury;
1181
1182 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1183
1184 neighbourx /= Constants.RegionSize;
1185 neighboury /= Constants.RegionSize;
1186
1187 agent.CloseChildAgents(neighbourx, neighboury);
1188
1189 AgentHasMovedAway(agent, false);
1190
1191 // the user may change their profile information in other region,
1192 // so the userinfo in UserProfileCache is not reliable any more, delete it
1193 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1194 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1195 {
1196 m_log.DebugFormat(
1197 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1180 } 1198 }
1181 1199
1182 return agent; 1200 //m_log.Debug("AFTER CROSS");
1201 //Scene.DumpChildrenSeeds(UUID);
1202 //DumpKnownRegions();
1203
1204 return;
1183 } 1205 }
1184 1206
1185 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1207 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)