aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs20
2 files changed, 67 insertions, 10 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 195d7a9..25334b9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
167 167
168 if (!DisableInterRegionTeleportCancellation) 168 if (!DisableInterRegionTeleportCancellation)
169 client.OnTeleportCancel += OnClientCancelTeleport; 169 client.OnTeleportCancel += OnClientCancelTeleport;
170
171 client.OnConnectionClosed += OnConnectionClosed;
170 } 172 }
171 173
172 public virtual void Close() {} 174 public virtual void Close() {}
@@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
185 187
186 #region Agent Teleports 188 #region Agent Teleports
187 189
190 private void OnConnectionClosed(IClientAPI client)
191 {
192 if (client.IsLoggingOut)
193 {
194 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
195
196 m_log.DebugFormat(
197 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
198 client.Name, Scene.Name);
199 }
200 }
201
188 private void OnClientCancelTeleport(IClientAPI client) 202 private void OnClientCancelTeleport(IClientAPI client)
189 { 203 {
190 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); 204 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
@@ -603,6 +617,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
603 617
604 return; 618 return;
605 } 619 }
620 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
621 {
622 m_log.DebugFormat(
623 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
624 sp.Name, finalDestination.RegionName, sp.Scene.Name);
625
626 return;
627 }
606 628
607 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 629 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
608 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 630 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
@@ -662,12 +684,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
662 684
663 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 685 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
664 686
687 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
688 // establish th econnection to the destination which makes it return true.
689 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
690 {
691 m_log.DebugFormat(
692 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
693 sp.Name, finalDestination.RegionName, sp.Scene.Name);
694
695 return;
696 }
697
665 // A common teleport failure occurs when we can send CreateAgent to the 698 // A common teleport failure occurs when we can send CreateAgent to the
666 // destination region but the viewer cannot establish the connection (e.g. due to network issues between 699 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
667 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then 700 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
668 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). 701 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
669 if (!UpdateAgent(reg, finalDestination, agent, sp)) 702 if (!UpdateAgent(reg, finalDestination, agent, sp))
670 { 703 {
704 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
705 {
706 m_log.DebugFormat(
707 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
708 sp.Name, finalDestination.RegionName, sp.Scene.Name);
709
710 return;
711 }
712
671 m_log.WarnFormat( 713 m_log.WarnFormat(
672 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", 714 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
673 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 715 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
@@ -682,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
682 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", 724 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
683 sp.Name, finalDestination.RegionName, sp.Scene.Name); 725 sp.Name, finalDestination.RegionName, sp.Scene.Name);
684 726
685 CleanupAbortedInterRegionTeleport(sp, finalDestination); 727 CleanupFailedInterRegionTeleport(sp, finalDestination);
686 728
687 return; 729 return;
688 } 730 }
@@ -711,6 +753,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
711 // that the client contacted the destination before we close things here. 753 // that the client contacted the destination before we close things here.
712 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) 754 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
713 { 755 {
756 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
757 {
758 m_log.DebugFormat(
759 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
760 sp.Name, finalDestination.RegionName, sp.Scene.Name);
761
762 return;
763 }
764
714 m_log.WarnFormat( 765 m_log.WarnFormat(
715 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 766 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
716 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 767 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
@@ -777,7 +828,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
777 /// <remarks> 828 /// <remarks>
778 /// <param name='sp'> </param> 829 /// <param name='sp'> </param>
779 /// <param name='finalDestination'></param> 830 /// <param name='finalDestination'></param>
780 protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) 831 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
781 { 832 {
782 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 833 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
783 834
@@ -799,7 +850,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
799 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> 850 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
800 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) 851 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
801 { 852 {
802 CleanupAbortedInterRegionTeleport(sp, finalDestination); 853 CleanupFailedInterRegionTeleport(sp, finalDestination);
803 854
804 sp.ControllingClient.SendTeleportFailed( 855 sp.ControllingClient.SendTeleportFailed(
805 string.Format( 856 string.Format(
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index b4f09ac..e903383 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 /// This is a state machine. 51 /// This is a state machine.
52 /// 52 ///
53 /// [Entry] => Preparing 53 /// [Entry] => Preparing
54 /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
56 /// Cancelling => CleaningUp 56 /// Cancelling => CleaningUp || Aborting
57 /// ReceivedAtDestination => CleaningUp 57 /// ReceivedAtDestination => CleaningUp || Aborting
58 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
59 /// Aborting => [Exit]
59 /// 60 ///
60 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp 61 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
61 /// However, any state can transition to CleaningUp if the teleport has failed. 62 /// However, any state can transition to CleaningUp if the teleport has failed.
@@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 Transferring, // The agent is in the process of being transferred to a destination 67 Transferring, // The agent is in the process of being transferred to a destination
67 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 68 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
68 CleaningUp, // The agent is being changed to child/removed after a transfer 69 CleaningUp, // The agent is being changed to child/removed after a transfer
69 Cancelling // The user has cancelled the teleport but we have yet to act upon this. 70 Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
71 Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
70 } 72 }
71 73
72 /// <summary> 74 /// <summary>
@@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
134 // Illegal to try and update an agent that's not actually in transit. 136 // Illegal to try and update an agent that's not actually in transit.
135 if (!m_agentsInTransit.ContainsKey(id)) 137 if (!m_agentsInTransit.ContainsKey(id))
136 { 138 {
137 if (newState != AgentTransferState.Cancelling) 139 if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
138 failureMessage = string.Format( 140 failureMessage = string.Format(
139 "Agent with ID {0} is not registered as in transit in {1}", 141 "Agent with ID {0} is not registered as in transit in {1}",
140 id, m_mod.Scene.RegionInfo.RegionName); 142 id, m_mod.Scene.RegionInfo.RegionName);
@@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
145 { 147 {
146 oldState = m_agentsInTransit[id]; 148 oldState = m_agentsInTransit[id];
147 149
148 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 150 if (newState == AgentTransferState.Aborting)
151 {
152 transitionOkay = true;
153 }
154 else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
149 { 155 {
150 transitionOkay = true; 156 transitionOkay = true;
151 } 157 }