Fixed problems if an avatar tries to cross regions when the previous cross hasn't completed yet

This caused the client to stop responding, and even the simulators to have problems. The solution is to disallow crossing before the previous cross has completed.
0.8.0.3
Oren Hurvitz 2014-07-10 16:02:38 +03:00 committed by Justin Clark-Casey
parent 5229a3c51c
commit 37fcc827e2
2 changed files with 151 additions and 153 deletions

View File

@ -568,7 +568,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); m_log.DebugFormat("[SCENE OBJECT]: Not crossing avatar {0} to {1} because it's already in transit", av.Name, val);
} }
} }

View File

@ -1691,6 +1691,11 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
client.Name, Scene.Name, AbsolutePosition); client.Name, Scene.Name, AbsolutePosition);
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); // Get this ahead of time because IsInTransit modifies 'm_AgentControlFlags'
IsInTransit = true;
try
{
// Make sure it's not a login agent. We don't want to wait for updates during login // Make sure it's not a login agent. We don't want to wait for updates during login
if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
{ {
@ -1719,7 +1724,6 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
} }
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (!MakeRootAgent(AbsolutePosition, flying)) if (!MakeRootAgent(AbsolutePosition, flying))
{ {
m_log.DebugFormat( m_log.DebugFormat(
@ -1736,7 +1740,7 @@ namespace OpenSim.Region.Framework.Scenes
if (m_teleportFlags > 0) if (m_teleportFlags > 0)
SendInitialDataToMe(); SendInitialDataToMe();
// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); // m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
if (!string.IsNullOrEmpty(m_callbackURI)) if (!string.IsNullOrEmpty(m_callbackURI))
{ {
@ -1745,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes
// here until we know for sure that the agent is active in this region. Sending AgentMovementComplete // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
// is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
// region as the current region, meaning that a close sent before then will fail the teleport. // region as the current region, meaning that a close sent before then will fail the teleport.
// System.Threading.Thread.Sleep(2000); // System.Threading.Thread.Sleep(2000);
m_log.DebugFormat( m_log.DebugFormat(
"[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
@ -1759,12 +1763,12 @@ namespace OpenSim.Region.Framework.Scenes
Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
m_callbackURI = null; m_callbackURI = null;
} }
// else // else
// { // {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); // client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
// } // }
ValidateAndSendAppearanceAndAgentData(); ValidateAndSendAppearanceAndAgentData();
@ -1773,7 +1777,12 @@ namespace OpenSim.Region.Framework.Scenes
{ {
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
if (m_agentTransfer != null) if (m_agentTransfer != null)
{
// Note: this call can take a while, because it notifies each of the simulator's neighbours.
// It's important that we don't allow the avatar to cross regions meanwhile, as that will
// cause serious errors. We've prevented that from happening by setting IsInTransit=true.
m_agentTransfer.EnableChildAgents(this); m_agentTransfer.EnableChildAgents(this);
}
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null) if (friendsModule != null)
@ -1790,10 +1799,14 @@ namespace OpenSim.Region.Framework.Scenes
sog.ScheduleGroupForFullUpdate(); sog.ScheduleGroupForFullUpdate();
} }
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
}
finally
{
IsInTransit = false;
}
} }
/// <summary> /// <summary>
@ -3587,8 +3600,9 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
return; return;
if (!IsInTransit) if (IsInTransit)
{ return;
Vector3 pos2 = AbsolutePosition; Vector3 pos2 = AbsolutePosition;
Vector3 origPosition = pos2; Vector3 origPosition = pos2;
Vector3 vel = Velocity; Vector3 vel = Velocity;
@ -3601,10 +3615,9 @@ namespace OpenSim.Region.Framework.Scenes
pos2.Y = pos2.Y + (vel.Y * timeStep); pos2.Y = pos2.Y + (vel.Y * timeStep);
pos2.Z = pos2.Z + (vel.Z * timeStep); pos2.Z = pos2.Z + (vel.Z * timeStep);
if (!IsInTransit) if (m_scene.PositionIsInCurrentRegion(pos2))
{ return;
if (!m_scene.PositionIsInCurrentRegion(pos2))
{
m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}", m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
LogHeader, Name, Scene.Name, pos2); LogHeader, Name, Scene.Name, pos2);
@ -3632,21 +3645,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
}
else
{
// This constant has been inferred from experimentation
// I'm not sure what this value should be, so I tried a few values.
timeStep = 0.04f;
pos2 = AbsolutePosition;
pos2.X = pos2.X + (vel.X * timeStep);
pos2.Y = pos2.Y + (vel.Y * timeStep);
// Don't touch the Z
m_pos = pos2;
m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos);
}
}
}
// Given a position, make sure it is within the current region. // Given a position, make sure it is within the current region.
// If just outside some border, the returned position will be just inside the border on that side. // If just outside some border, the returned position will be just inside the border on that side.