Try to resolve some problems with viewers crashing after hitting parcel banlines or freezing on the banline.

This involves
1) On forcible teleport, call m_scene.RequestTeleportLocation() rather than ScenePresence.Teleport() - only EntityTransferModule now should call SP.Teleport()
2) When avatar is being forcibly moved due to banlines, use a 'stop movement' tolerance of 0.2 to requested position rather than 1
This prevents the avatar sometimes being stuck to banlines until they teleport somewhere else.
This aims to fix some problems in http://opensimulator.org/mantis/view.php?id=5822
xassetservice
Justin Clark-Casey (justincc) 2012-02-23 22:56:42 +00:00
parent 9ed4245d9e
commit 90ea00a109
3 changed files with 41 additions and 16 deletions

View File

@ -94,8 +94,11 @@ namespace OpenSim.Region.CoreModules.World.Land
// caches ExtendedLandData // caches ExtendedLandData
private Cache parcelInfoCache; private Cache parcelInfoCache;
private Dictionary<UUID, Vector3> forcedPosition =
new Dictionary<UUID, Vector3>(); /// <summary>
/// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
/// </summary>
private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
#region INonSharedRegionModule Members #region INonSharedRegionModule Members
@ -224,22 +227,34 @@ namespace OpenSim.Region.CoreModules.World.Land
//When the avatar walks into a ban line on the ground, it prevents getting stuck //When the avatar walks into a ban line on the ground, it prevents getting stuck
agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
//Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2) if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
{ {
Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition[remoteClient.AgentId], clientAvatar.AbsolutePosition)); // m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
forcedPosition.Remove(remoteClient.AgentId); forcedPosition.Remove(remoteClient.AgentId);
} }
//if we are far away, teleport //if we are far away, teleport
else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3) else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
{ {
Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition[remoteClient.AgentId], clientAvatar.AbsolutePosition)); Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
clientAvatar.Teleport(forcedPosition[remoteClient.AgentId]); // m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
forcedPosition.Remove(remoteClient.AgentId); forcedPosition.Remove(remoteClient.AgentId);
} }
else else
{ {
// m_log.DebugFormat(
// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
//Forces them toward the forced position we want if they aren't there yet //Forces them toward the forced position we want if they aren't there yet
agentData.UseClientAgentPosition = true; agentData.UseClientAgentPosition = true;
agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId]; agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];

View File

@ -4699,7 +4699,10 @@ namespace OpenSim.Region.Framework.Scenes
Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
if (nearestPoint != null) if (nearestPoint != null)
{ {
Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString()); // m_log.DebugFormat(
// "[SCENE]: Found a sane previous position based on velocity for {0}, sending them to {1} in {2}",
// avatar.Name, nearestPoint, nearestParcel.LandData.Name);
return nearestPoint.Value; return nearestPoint.Value;
} }
@ -4709,12 +4712,16 @@ namespace OpenSim.Region.Framework.Scenes
nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
if (nearestPoint != null) if (nearestPoint != null)
{ {
Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString()); // m_log.DebugFormat(
// "[SCENE]: {0} had a zero velocity, sending them to {1}", avatar.Name, nearestPoint);
return nearestPoint.Value; return nearestPoint.Value;
} }
//Ultimate backup if we have no idea where they are //Ultimate backup if we have no idea where they are
Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString()); // m_log.DebugFormat(
// "[SCENE]: No idea where {0} is, sending them to {1}", avatar.Name, avatar.lastKnownAllowedPosition);
return avatar.lastKnownAllowedPosition; return avatar.lastKnownAllowedPosition;
} }
@ -5120,7 +5127,7 @@ namespace OpenSim.Region.Framework.Scenes
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
Vector3 agent_control_v3 = new Vector3(); Vector3 agent_control_v3 = new Vector3();
presence.HandleMoveToTargetUpdate(ref agent_control_v3); presence.HandleMoveToTargetUpdate(1, ref agent_control_v3);
presence.AddNewMovement(agent_control_v3); presence.AddNewMovement(agent_control_v3);
} }
} }

View File

@ -1048,7 +1048,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// /// Do not call this directly. Call Scene.RequestTeleportLocation() instead.
/// </summary> /// </summary>
/// <param name="pos"></param> /// <param name="pos"></param>
public void Teleport(Vector3 pos) public void Teleport(Vector3 pos)
@ -1522,7 +1522,10 @@ namespace OpenSim.Region.Framework.Scenes
} }
else if (bAllowUpdateMoveToPosition) else if (bAllowUpdateMoveToPosition)
{ {
if (HandleMoveToTargetUpdate(ref agent_control_v3)) // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
// certain position. It's only check for tolerance on returning to that position is 0.2
// rather than 1, at which point it removes its force target.
if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
update_movementflag = true; update_movementflag = true;
} }
} }
@ -1584,7 +1587,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
/// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param> /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
/// <returns>True if movement has been updated in some way. False otherwise.</returns> /// <returns>True if movement has been updated in some way. False otherwise.</returns>
public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) public bool HandleMoveToTargetUpdate(double tolerance, ref Vector3 agent_control_v3)
{ {
// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
@ -1601,7 +1604,7 @@ namespace OpenSim.Region.Framework.Scenes
// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
// Check the error term of the current position in relation to the target position // Check the error term of the current position in relation to the target position
if (distanceToTarget <= 1) if (distanceToTarget <= tolerance)
{ {
// We are close enough to the target // We are close enough to the target
AbsolutePosition = MoveToPositionTarget; AbsolutePosition = MoveToPositionTarget;
@ -1777,7 +1780,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation);
Vector3 agent_control_v3 = new Vector3(); Vector3 agent_control_v3 = new Vector3();
HandleMoveToTargetUpdate(ref agent_control_v3); HandleMoveToTargetUpdate(1, ref agent_control_v3);
AddNewMovement(agent_control_v3); AddNewMovement(agent_control_v3);
} }