Merge branch 'master' into careminster
commit
d5e5c13f3b
|
@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
if (!DisableInterRegionTeleportCancellation)
|
||||
client.OnTeleportCancel += OnClientCancelTeleport;
|
||||
|
||||
client.OnConnectionClosed += OnConnectionClosed;
|
||||
}
|
||||
|
||||
public virtual void Close() {}
|
||||
|
@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
#region Agent Teleports
|
||||
|
||||
private void OnConnectionClosed(IClientAPI client)
|
||||
{
|
||||
if (client.IsLoggingOut)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
|
||||
client.Name, Scene.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientCancelTeleport(IClientAPI client)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
|
||||
|
@ -603,6 +617,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
return;
|
||||
}
|
||||
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Past this point we have to attempt clean up if the teleport fails, so update transfer state.
|
||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
|
||||
|
@ -662,12 +684,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
|
||||
|
||||
// We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
|
||||
// establish th econnection to the destination which makes it return true.
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// A common teleport failure occurs when we can send CreateAgent to the
|
||||
// destination region but the viewer cannot establish the connection (e.g. due to network issues between
|
||||
// the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
|
||||
// there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
|
||||
if (!UpdateAgent(reg, finalDestination, agent, sp))
|
||||
{
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
|
@ -682,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
CleanupAbortedInterRegionTeleport(sp, finalDestination);
|
||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -711,6 +753,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// that the client contacted the destination before we close things here.
|
||||
if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
|
||||
{
|
||||
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
|
||||
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
|
||||
|
@ -777,7 +828,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// <remarks>
|
||||
/// <param name='sp'> </param>
|
||||
/// <param name='finalDestination'></param>
|
||||
protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
|
||||
protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
|
||||
{
|
||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||
|
||||
|
@ -799,7 +850,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
|
||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
|
||||
{
|
||||
CleanupAbortedInterRegionTeleport(sp, finalDestination);
|
||||
CleanupFailedInterRegionTeleport(sp, finalDestination);
|
||||
|
||||
sp.ControllingClient.SendTeleportFailed(
|
||||
string.Format(
|
||||
|
|
|
@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// This is a state machine.
|
||||
///
|
||||
/// [Entry] => Preparing
|
||||
/// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] }
|
||||
/// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp }
|
||||
/// Cancelling => CleaningUp
|
||||
/// ReceivedAtDestination => CleaningUp
|
||||
/// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
|
||||
/// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
|
||||
/// Cancelling => CleaningUp || Aborting
|
||||
/// ReceivedAtDestination => CleaningUp || Aborting
|
||||
/// CleaningUp => [Exit]
|
||||
/// Aborting => [Exit]
|
||||
///
|
||||
/// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
|
||||
/// However, any state can transition to CleaningUp if the teleport has failed.
|
||||
|
@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
Transferring, // The agent is in the process of being transferred to a destination
|
||||
ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
|
||||
CleaningUp, // The agent is being changed to child/removed after a transfer
|
||||
Cancelling // The user has cancelled the teleport but we have yet to act upon this.
|
||||
Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
|
||||
Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// Illegal to try and update an agent that's not actually in transit.
|
||||
if (!m_agentsInTransit.ContainsKey(id))
|
||||
{
|
||||
if (newState != AgentTransferState.Cancelling)
|
||||
if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
|
||||
failureMessage = string.Format(
|
||||
"Agent with ID {0} is not registered as in transit in {1}",
|
||||
id, m_mod.Scene.RegionInfo.RegionName);
|
||||
|
@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
{
|
||||
oldState = m_agentsInTransit[id];
|
||||
|
||||
if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||
if (newState == AgentTransferState.Aborting)
|
||||
{
|
||||
transitionOkay = true;
|
||||
}
|
||||
else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||
{
|
||||
transitionOkay = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue