aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2012-09-04 03:14:39 +0200
committerMelanie2012-09-04 03:14:39 +0200
commit056e66b3dec555613bd96b153ba03a124863dbf2 (patch)
tree83a095370983d9e5d295a5dc539acc2989d3b94b /OpenSim/Region
parentPrevent a nullref if SimStatsReporter tries to report on a sim where psysics are (diff)
downloadopensim-SC-056e66b3dec555613bd96b153ba03a124863dbf2.zip
opensim-SC-056e66b3dec555613bd96b153ba03a124863dbf2.tar.gz
opensim-SC-056e66b3dec555613bd96b153ba03a124863dbf2.tar.bz2
opensim-SC-056e66b3dec555613bd96b153ba03a124863dbf2.tar.xz
Refactor avatar transfer so that the heavy (UpdateAgent) part is separated into
it's own sub-method
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs204
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs2
3 files changed, 113 insertions, 97 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 9ffb851..1f884c8 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(
@@ -982,7 +982,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
982 agent.IsInTransit = true; 982 agent.IsInTransit = true;
983 983
984 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 984 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
985 d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 985 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
986 986
987 return true; 987 return true;
988 } 988 }
@@ -1039,42 +1039,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1039 icon.EndInvoke(iar); 1039 icon.EndInvoke(iar);
1040 } 1040 }
1041 1041
1042 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1043 {
1044 if (neighbourRegion == null)
1045 return false;
1046
1047 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1048
1049 agent.RemoveFromPhysicalScene();
1050
1051 return true;
1052 }
1053
1042 /// <summary> 1054 /// <summary>
1043 /// This Closes child agents on neighbouring regions 1055 /// This Closes child agents on neighbouring regions
1044 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1056 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1045 /// </summary> 1057 /// </summary>
1046 public ScenePresence CrossAgentToNewRegionAsync( 1058 public ScenePresence CrossAgentToNewRegionAsync(
1047 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1059 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1048 bool isFlying, string version) 1060 bool isFlying, string version)
1049 { 1061 {
1050 if (neighbourRegion == null) 1062 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1051 return agent; 1063 return agent;
1052 1064
1053 try 1065 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1054 { 1066 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 1067
1073 agent.RemoveFromPhysicalScene(); 1068 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1069 return agent;
1070 }
1074 1071
1072 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1073 {
1074 try
1075 {
1075 AgentData cAgent = new AgentData(); 1076 AgentData cAgent = new AgentData();
1076 agent.CopyTo(cAgent); 1077 agent.CopyTo(cAgent);
1077 cAgent.Position = pos; 1078 cAgent.Position = pos + agent.Velocity;
1078 if (isFlying) 1079 if (isFlying)
1079 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1080 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1080 1081
@@ -1084,7 +1085,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1084 // Beyond this point, extra cleanup is needed beyond removing transit state 1085 // Beyond this point, extra cleanup is needed beyond removing transit state
1085 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1086 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1086 1087
1087 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1088 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1088 { 1089 {
1089 // region doesn't take it 1090 // region doesn't take it
1090 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1091 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1093,93 +1094,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1093 agent.AddToPhysicalScene(isFlying); 1094 agent.AddToPhysicalScene(isFlying);
1094 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1095 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1095 1096
1096 return agent; 1097 return false;
1097 } 1098 }
1098 1099
1099 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1100 }
1100 agent.ControllingClient.RequestClientInfo(); 1101 catch (Exception e)
1102 {
1103 m_log.ErrorFormat(
1104 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1105 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1101 1106
1102 //m_log.Debug("BEFORE CROSS"); 1107 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1103 //Scene.DumpChildrenSeeds(UUID); 1108 return false;
1104 //DumpKnownRegions(); 1109 }
1105 string agentcaps;
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 1110
1115 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1111 return true;
1112 }
1116 1113
1117 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1114 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1115 bool isFlying, string version)
1116 {
1117 agent.ControllingClient.RequestClientInfo();
1118 1118
1119 if (m_eqModule != null) 1119 string agentcaps;
1120 { 1120 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1121 m_eqModule.CrossRegion( 1121 {
1122 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1122 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1123 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1123 neighbourRegion.RegionHandle);
1124 } 1124 return;
1125 else 1125 }
1126 {
1127 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1128 capsPath);
1129 }
1130 1126
1131 // SUCCESS! 1127 // No turning back
1132 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1128 agent.IsChildAgent = true;
1133 1129
1134 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1130 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1135 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1136 1131
1137 agent.MakeChildAgent(); 1132 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1138 1133
1139 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1134 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1140 // but not sure yet what the side effects would be.
1141 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1142 1135
1143 // now we have a child agent in this region. Request all interesting data about other (root) agents 1136 if (m_eqModule != null)
1144 agent.SendOtherAgentsAvatarDataToMe(); 1137 {
1145 agent.SendOtherAgentsAppearanceToMe(); 1138 m_eqModule.CrossRegion(
1139 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1140 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1141 }
1142 else
1143 {
1144 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1145 capsPath);
1146 }
1146 1147
1147 // Backwards compatibility. Best effort 1148 // SUCCESS!
1148 if (version == "Unknown" || version == string.Empty) 1149 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
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 1150
1155 // Next, let's close the child agent connections that are too far away. 1151 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1156 agent.CloseChildAgents(neighbourx, neighboury); 1152 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1157 1153
1158 AgentHasMovedAway(agent, false); 1154 agent.MakeChildAgent();
1159 1155
1160 // the user may change their profile information in other region, 1156 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1161 // so the userinfo in UserProfileCache is not reliable any more, delete it 1157 // but not sure yet what the side effects would be.
1162 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1158 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1163 if (agent.Scene.NeedSceneCacheClear(agent.UUID)) 1159
1164 { 1160 // now we have a child agent in this region. Request all interesting data about other (root) agents
1165 m_log.DebugFormat( 1161 agent.SendOtherAgentsAvatarDataToMe();
1166 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); 1162 agent.SendOtherAgentsAppearanceToMe();
1167 } 1163
1168 1164 // Backwards compatibility. Best effort
1169 //m_log.Debug("AFTER CROSS"); 1165 if (version == "Unknown" || version == string.Empty)
1170 //Scene.DumpChildrenSeeds(UUID);
1171 //DumpKnownRegions();
1172 }
1173 catch (Exception e)
1174 { 1166 {
1175 m_log.ErrorFormat( 1167 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}", 1168 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); 1169 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1170 }
1178 1171
1179 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1172 // Next, let's close the child agent connections that are too far away.
1173 uint neighbourx;
1174 uint neighboury;
1175
1176 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1177
1178 neighbourx /= Constants.RegionSize;
1179 neighboury /= Constants.RegionSize;
1180
1181 agent.CloseChildAgents(neighbourx, neighboury);
1182
1183 AgentHasMovedAway(agent, false);
1184
1185 // the user may change their profile information in other region,
1186 // so the userinfo in UserProfileCache is not reliable any more, delete it
1187 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1188 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1189 {
1190 m_log.DebugFormat(
1191 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1180 } 1192 }
1181 1193
1182 return agent; 1194 //m_log.Debug("AFTER CROSS");
1195 //Scene.DumpChildrenSeeds(UUID);
1196 //DumpKnownRegions();
1197
1198 return;
1183 } 1199 }
1184 1200
1185 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1201 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 5bc8e51..1949a90 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -35,7 +35,7 @@ using OpenSim.Region.Framework.Scenes;
35 35
36namespace OpenSim.Region.Framework.Interfaces 36namespace OpenSim.Region.Framework.Interfaces
37{ 37{
38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
39 39
40 public interface IEntityTransferModule 40 public interface IEntityTransferModule
41 { 41 {
@@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Interfaces
76 76
77 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 77 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
78 78
79 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 79 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
80 80
81 } 81 }
82 82
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index bc0f5b6..4798481 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -581,7 +581,7 @@ namespace OpenSim.Region.Framework.Scenes
581 av.IsInTransit = true; 581 av.IsInTransit = true;
582 582
583 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; 583 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
584 d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); 584 d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
585 } 585 }
586 else 586 else
587 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); 587 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);