diff options
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 123 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 |
2 files changed, 87 insertions, 42 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 3cb1901..07c3666 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -179,13 +179,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
179 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) | 179 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) |
180 | return; | 180 | return; |
181 | 181 | ||
182 | // Reset animations; the viewer does that in teleports. | ||
183 | sp.Animator.ResetAnimations(); | ||
184 | |||
185 | string destinationRegionName = "(not found)"; | 182 | string destinationRegionName = "(not found)"; |
186 | 183 | ||
184 | // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection | ||
185 | // of whether the destination region completes the teleport. | ||
186 | if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) | ||
187 | { | ||
188 | m_log.DebugFormat( | ||
189 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", | ||
190 | sp.Name, sp.UUID, position, regionHandle); | ||
191 | |||
192 | return; | ||
193 | } | ||
194 | |||
187 | try | 195 | try |
188 | { | 196 | { |
197 | // Reset animations; the viewer does that in teleports. | ||
198 | sp.Animator.ResetAnimations(); | ||
199 | |||
189 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) | 200 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) |
190 | { | 201 | { |
191 | destinationRegionName = sp.Scene.RegionInfo.RegionName; | 202 | destinationRegionName = sp.Scene.RegionInfo.RegionName; |
@@ -194,12 +205,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
194 | } | 205 | } |
195 | else // Another region possibly in another simulator | 206 | else // Another region possibly in another simulator |
196 | { | 207 | { |
197 | GridRegion finalDestination; | 208 | GridRegion finalDestination = null; |
198 | TeleportAgentToDifferentRegion( | 209 | try |
199 | sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); | 210 | { |
200 | 211 | TeleportAgentToDifferentRegion( | |
201 | if (finalDestination != null) | 212 | sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); |
202 | destinationRegionName = finalDestination.RegionName; | 213 | } |
214 | finally | ||
215 | { | ||
216 | if (finalDestination != null) | ||
217 | destinationRegionName = finalDestination.RegionName; | ||
218 | } | ||
203 | } | 219 | } |
204 | } | 220 | } |
205 | catch (Exception e) | 221 | catch (Exception e) |
@@ -209,11 +225,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
209 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, | 225 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, |
210 | e.Message, e.StackTrace); | 226 | e.Message, e.StackTrace); |
211 | 227 | ||
212 | // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. | ||
213 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
214 | |||
215 | sp.ControllingClient.SendTeleportFailed("Internal error"); | 228 | sp.ControllingClient.SendTeleportFailed("Internal error"); |
216 | } | 229 | } |
230 | finally | ||
231 | { | ||
232 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
233 | } | ||
217 | } | 234 | } |
218 | 235 | ||
219 | /// <summary> | 236 | /// <summary> |
@@ -229,15 +246,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
229 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", | 246 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", |
230 | sp.Name, position, sp.Scene.RegionInfo.RegionName); | 247 | sp.Name, position, sp.Scene.RegionInfo.RegionName); |
231 | 248 | ||
232 | if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) | ||
233 | { | ||
234 | m_log.DebugFormat( | ||
235 | "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", | ||
236 | sp.Name, sp.UUID, position); | ||
237 | |||
238 | return; | ||
239 | } | ||
240 | |||
241 | // Teleport within the same region | 249 | // Teleport within the same region |
242 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | 250 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) |
243 | { | 251 | { |
@@ -282,7 +290,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
282 | } | 290 | } |
283 | 291 | ||
284 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | 292 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
285 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
286 | } | 293 | } |
287 | 294 | ||
288 | /// <summary> | 295 | /// <summary> |
@@ -336,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
336 | // | 343 | // |
337 | // This is it | 344 | // This is it |
338 | // | 345 | // |
339 | DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); | 346 | DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags); |
340 | // | 347 | // |
341 | // | 348 | // |
342 | // | 349 | // |
@@ -391,6 +398,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
391 | && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; | 398 | && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; |
392 | } | 399 | } |
393 | 400 | ||
401 | /// <summary> | ||
402 | /// Wraps DoTeleportInternal() and manages the transfer state. | ||
403 | /// </summary> | ||
394 | public void DoTeleport( | 404 | public void DoTeleport( |
395 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, | 405 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, |
396 | Vector3 position, Vector3 lookAt, uint teleportFlags) | 406 | Vector3 position, Vector3 lookAt, uint teleportFlags) |
@@ -405,12 +415,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
405 | 415 | ||
406 | return; | 416 | return; |
407 | } | 417 | } |
418 | |||
419 | try | ||
420 | { | ||
421 | DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags); | ||
422 | } | ||
423 | catch (Exception e) | ||
424 | { | ||
425 | m_log.ErrorFormat( | ||
426 | "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", | ||
427 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName, | ||
428 | e.Message, e.StackTrace); | ||
408 | 429 | ||
409 | if (reg == null || finalDestination == null) | 430 | sp.ControllingClient.SendTeleportFailed("Internal error"); |
431 | } | ||
432 | finally | ||
410 | { | 433 | { |
411 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); | ||
412 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | 434 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
435 | } | ||
436 | } | ||
413 | 437 | ||
438 | /// <summary> | ||
439 | /// Teleports the agent to another region. | ||
440 | /// This method doesn't manage the transfer state; the caller must do that. | ||
441 | /// </summary> | ||
442 | private void DoTeleportInternal( | ||
443 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, | ||
444 | Vector3 position, Vector3 lookAt, uint teleportFlags) | ||
445 | { | ||
446 | if (reg == null || finalDestination == null) | ||
447 | { | ||
448 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); | ||
414 | return; | 449 | return; |
415 | } | 450 | } |
416 | 451 | ||
@@ -430,8 +465,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
430 | sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, | 465 | sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, |
431 | MaxTransferDistance)); | 466 | MaxTransferDistance)); |
432 | 467 | ||
433 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
434 | |||
435 | return; | 468 | return; |
436 | } | 469 | } |
437 | 470 | ||
@@ -450,7 +483,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
450 | if (endPoint.Address == null) | 483 | if (endPoint.Address == null) |
451 | { | 484 | { |
452 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 485 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
453 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
454 | 486 | ||
455 | return; | 487 | return; |
456 | } | 488 | } |
@@ -472,7 +504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
472 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) | 504 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) |
473 | { | 505 | { |
474 | sp.ControllingClient.SendTeleportFailed(reason); | 506 | sp.ControllingClient.SendTeleportFailed(reason); |
475 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
476 | 507 | ||
477 | m_log.DebugFormat( | 508 | m_log.DebugFormat( |
478 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", | 509 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", |
@@ -528,7 +559,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
528 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 559 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) |
529 | { | 560 | { |
530 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | 561 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); |
531 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
532 | 562 | ||
533 | m_log.DebugFormat( | 563 | m_log.DebugFormat( |
534 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", | 564 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", |
@@ -629,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
629 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | 659 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", |
630 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 660 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
631 | 661 | ||
632 | Fail(sp, finalDestination, logout); | 662 | Fail(sp, finalDestination, logout); |
633 | return; | 663 | return; |
634 | } | 664 | } |
635 | 665 | ||
@@ -682,8 +712,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
682 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | 712 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", |
683 | // sp.UUID); | 713 | // sp.UUID); |
684 | // } | 714 | // } |
685 | |||
686 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
687 | } | 715 | } |
688 | 716 | ||
689 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) | 717 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) |
@@ -703,8 +731,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
703 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); | 731 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); |
704 | 732 | ||
705 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); | 733 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); |
706 | |||
707 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
708 | } | 734 | } |
709 | 735 | ||
710 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 736 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) |
@@ -1133,16 +1159,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1133 | if (neighbourRegion == null) | 1159 | if (neighbourRegion == null) |
1134 | return agent; | 1160 | return agent; |
1135 | 1161 | ||
1136 | try | 1162 | if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) |
1137 | { | 1163 | { |
1138 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | 1164 | m_log.ErrorFormat( |
1165 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit", | ||
1166 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName); | ||
1167 | return agent; | ||
1168 | } | ||
1139 | 1169 | ||
1170 | bool transitWasReset = false; | ||
1171 | |||
1172 | try | ||
1173 | { | ||
1140 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 1174 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
1141 | 1175 | ||
1142 | m_log.DebugFormat( | 1176 | m_log.DebugFormat( |
1143 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | 1177 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", |
1144 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | 1178 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); |
1145 | 1179 | ||
1146 | Scene m_scene = agent.Scene; | 1180 | Scene m_scene = agent.Scene; |
1147 | 1181 | ||
1148 | if (!agent.ValidateAttachments()) | 1182 | if (!agent.ValidateAttachments()) |
@@ -1155,7 +1189,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1155 | 1189 | ||
1156 | agent.RemoveFromPhysicalScene(); | 1190 | agent.RemoveFromPhysicalScene(); |
1157 | 1191 | ||
1158 | AgentData cAgent = new AgentData(); | 1192 | AgentData cAgent = new AgentData(); |
1159 | agent.CopyTo(cAgent); | 1193 | agent.CopyTo(cAgent); |
1160 | cAgent.Position = pos; | 1194 | cAgent.Position = pos; |
1161 | if (isFlying) | 1195 | if (isFlying) |
@@ -1174,7 +1208,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1174 | 1208 | ||
1175 | ReInstantiateScripts(agent); | 1209 | ReInstantiateScripts(agent); |
1176 | agent.AddToPhysicalScene(isFlying); | 1210 | agent.AddToPhysicalScene(isFlying); |
1177 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1178 | 1211 | ||
1179 | return agent; | 1212 | return agent; |
1180 | } | 1213 | } |
@@ -1222,6 +1255,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1222 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1255 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1223 | // but not sure yet what the side effects would be. | 1256 | // but not sure yet what the side effects would be. |
1224 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1257 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1258 | transitWasReset = true; | ||
1225 | 1259 | ||
1226 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1260 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1227 | agent.SendOtherAgentsAvatarDataToMe(); | 1261 | agent.SendOtherAgentsAvatarDataToMe(); |
@@ -1261,6 +1295,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1261 | 1295 | ||
1262 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | 1296 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. |
1263 | } | 1297 | } |
1298 | finally | ||
1299 | { | ||
1300 | if (!transitWasReset) | ||
1301 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1302 | } | ||
1264 | 1303 | ||
1265 | return agent; | 1304 | return agent; |
1266 | } | 1305 | } |
@@ -2083,4 +2122,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2083 | #endregion | 2122 | #endregion |
2084 | 2123 | ||
2085 | } | 2124 | } |
2086 | } \ No newline at end of file | 2125 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9c1d2b6..39a885c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -657,6 +657,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
657 | 657 | ||
658 | private bool m_inTransit; | 658 | private bool m_inTransit; |
659 | 659 | ||
660 | /// <summary> | ||
661 | /// This signals whether the presence is in transit between neighbouring regions. | ||
662 | /// </summary> | ||
663 | /// <remarks> | ||
664 | /// It is not set when the presence is teleporting or logging in/out directly to a region. | ||
665 | /// </remarks> | ||
660 | public bool IsInTransit | 666 | public bool IsInTransit |
661 | { | 667 | { |
662 | get { return m_inTransit; } | 668 | get { return m_inTransit; } |