Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

user_profiles
Diva Canto 2013-02-22 15:58:06 -08:00
commit d7115cfd46
2 changed files with 87 additions and 42 deletions

View File

@ -179,13 +179,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
return; return;
// Reset animations; the viewer does that in teleports.
sp.Animator.ResetAnimations();
string destinationRegionName = "(not found)"; 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 try
{ {
// Reset animations; the viewer does that in teleports.
sp.Animator.ResetAnimations();
if (regionHandle == sp.Scene.RegionInfo.RegionHandle) if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
{ {
destinationRegionName = sp.Scene.RegionInfo.RegionName; destinationRegionName = sp.Scene.RegionInfo.RegionName;
@ -194,12 +205,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else // Another region possibly in another simulator else // Another region possibly in another simulator
{ {
GridRegion finalDestination; GridRegion finalDestination = null;
TeleportAgentToDifferentRegion( try
sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); {
TeleportAgentToDifferentRegion(
if (finalDestination != null) sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
destinationRegionName = finalDestination.RegionName; }
finally
{
if (finalDestination != null)
destinationRegionName = finalDestination.RegionName;
}
} }
} }
catch (Exception e) catch (Exception e)
@ -209,11 +225,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
e.Message, e.StackTrace); 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"); sp.ControllingClient.SendTeleportFailed("Internal error");
} }
finally
{
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
}
} }
/// <summary> /// <summary>
@ -229,15 +246,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
sp.Name, position, sp.Scene.RegionInfo.RegionName); 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 // Teleport within the same region
if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 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.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
} }
/// <summary> /// <summary>
@ -336,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// //
// This is it // 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; && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
} }
/// <summary>
/// Wraps DoTeleportInternal() and manages the transfer state.
/// </summary>
public void DoTeleport( public void DoTeleport(
ScenePresence sp, GridRegion reg, GridRegion finalDestination, ScenePresence sp, GridRegion reg, GridRegion finalDestination,
Vector3 position, Vector3 lookAt, uint teleportFlags) Vector3 position, Vector3 lookAt, uint teleportFlags)
@ -406,11 +416,36 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; 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) if (reg == null || finalDestination == null)
{ {
sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
return; return;
} }
@ -430,8 +465,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
MaxTransferDistance)); MaxTransferDistance));
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
return; return;
} }
@ -450,7 +483,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (endPoint.Address == null) if (endPoint.Address == null)
{ {
sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
return; return;
} }
@ -472,7 +504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
{ {
sp.ControllingClient.SendTeleportFailed(reason); sp.ControllingClient.SendTeleportFailed(reason);
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", "[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)) if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
{ {
sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
@ -682,8 +712,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
// sp.UUID); // sp.UUID);
// } // }
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
} }
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 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); Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 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) protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
@ -1133,10 +1159,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (neighbourRegion == null) if (neighbourRegion == null)
return agent; 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 try
{ {
m_entityTransferStateMachine.SetInTransit(agent.UUID);
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
m_log.DebugFormat( m_log.DebugFormat(
@ -1174,7 +1208,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
ReInstantiateScripts(agent); ReInstantiateScripts(agent);
agent.AddToPhysicalScene(isFlying); agent.AddToPhysicalScene(isFlying);
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
return agent; 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, // FIXME: Possibly this should occur lower down after other commands to close other agents,
// but not sure yet what the side effects would be. // but not sure yet what the side effects would be.
m_entityTransferStateMachine.ResetFromTransit(agent.UUID); m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
transitWasReset = true;
// now we have a child agent in this region. Request all interesting data about other (root) agents // now we have a child agent in this region. Request all interesting data about other (root) agents
agent.SendOtherAgentsAvatarDataToMe(); 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. // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
} }
finally
{
if (!transitWasReset)
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
}
return agent; return agent;
} }

View File

@ -657,6 +657,12 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_inTransit; private bool m_inTransit;
/// <summary>
/// This signals whether the presence is in transit between neighbouring regions.
/// </summary>
/// <remarks>
/// It is not set when the presence is teleporting or logging in/out directly to a region.
/// </remarks>
public bool IsInTransit public bool IsInTransit
{ {
get { return m_inTransit; } get { return m_inTransit; }