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.user_profiles
parent
0d08f81421
commit
ccb7cce819
|
@ -179,13 +179,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
|
||||
return;
|
||||
|
||||
// Reset animations; the viewer does that in teleports.
|
||||
sp.Animator.ResetAnimations();
|
||||
|
||||
string destinationRegionName = "(not found)";
|
||||
|
||||
// Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
|
||||
// of whether the destination region completes the teleport.
|
||||
if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
|
||||
sp.Name, sp.UUID, position, regionHandle);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Reset animations; the viewer does that in teleports.
|
||||
sp.Animator.ResetAnimations();
|
||||
|
||||
if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
|
||||
{
|
||||
destinationRegionName = sp.Scene.RegionInfo.RegionName;
|
||||
|
@ -194,12 +205,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
else // Another region possibly in another simulator
|
||||
{
|
||||
GridRegion finalDestination;
|
||||
TeleportAgentToDifferentRegion(
|
||||
sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
|
||||
|
||||
if (finalDestination != null)
|
||||
destinationRegionName = finalDestination.RegionName;
|
||||
GridRegion finalDestination = null;
|
||||
try
|
||||
{
|
||||
TeleportAgentToDifferentRegion(
|
||||
sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (finalDestination != null)
|
||||
destinationRegionName = finalDestination.RegionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -209,11 +225,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
|
||||
e.Message, e.StackTrace);
|
||||
|
||||
// Make sure that we clear the in-transit flag so that future teleport attempts don't always fail.
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
sp.ControllingClient.SendTeleportFailed("Internal error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -229,15 +246,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
|
||||
sp.Name, position, sp.Scene.RegionInfo.RegionName);
|
||||
|
||||
if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.",
|
||||
sp.Name, sp.UUID, position);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Teleport within the same region
|
||||
if (IsOutsideRegion(sp.Scene, position) || position.Z < 0)
|
||||
{
|
||||
|
@ -282,7 +290,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
|
||||
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -336,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
//
|
||||
// This is it
|
||||
//
|
||||
DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags);
|
||||
DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -391,6 +398,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
&& Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps DoTeleportInternal() and manages the transfer state.
|
||||
/// </summary>
|
||||
public void DoTeleport(
|
||||
ScenePresence sp, GridRegion reg, GridRegion finalDestination,
|
||||
Vector3 position, Vector3 lookAt, uint teleportFlags)
|
||||
|
@ -405,12 +415,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
|
||||
sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName,
|
||||
e.Message, e.StackTrace);
|
||||
|
||||
sp.ControllingClient.SendTeleportFailed("Internal error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Teleports the agent to another region.
|
||||
/// This method doesn't manage the transfer state; the caller must do that.
|
||||
/// </summary>
|
||||
private void DoTeleportInternal(
|
||||
ScenePresence sp, GridRegion reg, GridRegion finalDestination,
|
||||
Vector3 position, Vector3 lookAt, uint teleportFlags)
|
||||
{
|
||||
if (reg == null || finalDestination == null)
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -430,8 +465,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
|
||||
MaxTransferDistance));
|
||||
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -450,7 +483,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
if (endPoint.Address == null)
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -472,7 +504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed(reason);
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
|
||||
|
@ -528,7 +559,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
|
||||
|
@ -629,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
"[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);
|
||||
|
||||
Fail(sp, finalDestination, logout);
|
||||
Fail(sp, finalDestination, logout);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -682,8 +712,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
|
||||
// sp.UUID);
|
||||
// }
|
||||
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
}
|
||||
|
||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
|
||||
|
@ -703,8 +731,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
|
||||
|
||||
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
|
||||
|
||||
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
|
||||
}
|
||||
|
||||
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
|
|||
if (neighbourRegion == null)
|
||||
return agent;
|
||||
|
||||
if (!m_entityTransferStateMachine.SetInTransit(agent.UUID))
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
|
||||
agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
|
||||
return agent;
|
||||
}
|
||||
|
||||
bool transitWasReset = false;
|
||||
|
||||
try
|
||||
{
|
||||
m_entityTransferStateMachine.SetInTransit(agent.UUID);
|
||||
|
||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
||||
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
|
||||
agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
|
||||
|
||||
|
||||
Scene m_scene = agent.Scene;
|
||||
|
||||
if (!agent.ValidateAttachments())
|
||||
|
@ -1155,7 +1189,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
agent.RemoveFromPhysicalScene();
|
||||
|
||||
AgentData cAgent = new AgentData();
|
||||
AgentData cAgent = new AgentData();
|
||||
agent.CopyTo(cAgent);
|
||||
cAgent.Position = pos;
|
||||
if (isFlying)
|
||||
|
@ -1174,7 +1208,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
ReInstantiateScripts(agent);
|
||||
agent.AddToPhysicalScene(isFlying);
|
||||
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
@ -1222,6 +1255,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// FIXME: Possibly this should occur lower down after other commands to close other agents,
|
||||
// but not sure yet what the side effects would be.
|
||||
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
||||
transitWasReset = true;
|
||||
|
||||
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
||||
agent.SendOtherAgentsAvatarDataToMe();
|
||||
|
@ -1261,6 +1295,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
// TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!transitWasReset)
|
||||
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
||||
}
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
@ -2083,4 +2122,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue