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))
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,14 +205,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
else // Another region possibly in another simulator
{
GridRegion finalDestination;
GridRegion finalDestination = null;
try
{
TeleportAgentToDifferentRegion(
sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
}
finally
{
if (finalDestination != null)
destinationRegionName = finalDestination.RegionName;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
@ -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)
@ -406,11 +416,36 @@ 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}",
@ -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,10 +1159,18 @@ 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(
@ -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;
}

View File

@ -657,6 +657,12 @@ namespace OpenSim.Region.Framework.Scenes
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
{
get { return m_inTransit; }