diff options
author | Justin Clark-Casey (justincc) | 2013-02-22 21:59:00 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-02-22 21:59:00 +0000 |
commit | ccb7cce8190f50024ebf25369d95e7267376f28b (patch) | |
tree | 37f9855cc945b09cca6a7e8197ba0e194157634b /OpenSim | |
parent | Err.. wrong dll name for groups in Robust.HG.ini.example (diff) | |
download | opensim-SC_OLD-ccb7cce8190f50024ebf25369d95e7267376f28b.zip opensim-SC_OLD-ccb7cce8190f50024ebf25369d95e7267376f28b.tar.gz opensim-SC_OLD-ccb7cce8190f50024ebf25369d95e7267376f28b.tar.bz2 opensim-SC_OLD-ccb7cce8190f50024ebf25369d95e7267376f28b.tar.xz |
Make reset of EntityTransferStateMachine for an avatar transfer always happen despite unexpected exceptions.
This means that if such an exception does occur, the region does not need to be reset before that user can teleport from it again.
This is all Oren's code from his patch in http://opensimulator.org/mantis/view.php?id=6374 but I've chosen to split it in two.
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 123 |
1 files changed, 81 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 | } |