Properly restore position on crossing failure for mega-regions.

Fix odd "cannot cross into banned parcel" viewer error message when crossing
into non-existant region. Proper permission failure messages are now returned.
0.8.0.3
Robert Adams 2014-02-15 17:02:53 -08:00
parent 877bdcdce1
commit 7fc289c039
4 changed files with 51 additions and 22 deletions

View File

@ -1443,10 +1443,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// see that it is actually outside the current region), find the new region that the // see that it is actually outside the current region), find the new region that the
// point is actually in. // point is actually in.
// Returns the coordinates and information of the new region or 'null' of it doesn't exist. // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
out string version, out Vector3 newpos, out string failureReason)
{ {
version = String.Empty; version = String.Empty;
newpos = pos; newpos = pos;
failureReason = string.Empty;
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
@ -1463,12 +1465,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (neighbourRegion != null) if (neighbourRegion != null)
{ {
// Compute the entity's position relative to the new region // Compute the entity's position relative to the new region
newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
(float)(presenceWorldY - (double)neighbourRegion.RegionLocY), (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
pos.Z); pos.Z);
if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
{ {
failureReason = "Cannot region cross into banned parcel";
neighbourRegion = null; neighbourRegion = null;
} }
else else
@ -1478,15 +1481,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
// Check to see if we have access to the target region. // Check to see if we have access to the target region.
string reason;
if (neighbourRegion != null if (neighbourRegion != null
&& !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out failureReason))
{ {
// remember banned // remember banned
m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
neighbourRegion = null; neighbourRegion = null;
} }
} }
else
{
// The destination region just doesn't exist
failureReason = "Cannot cross into non-existant region";
}
if (neighbourRegion == null) if (neighbourRegion == null)
m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
@ -1509,11 +1516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint y; uint y;
Vector3 newpos; Vector3 newpos;
string version; string version;
string failureReason;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos); GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition,
out version, out newpos, out failureReason);
if (neighbourRegion == null) if (neighbourRegion == null)
{ {
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); agent.ControllingClient.SendAlertMessage(failureReason);
return false; return false;
} }

View File

@ -92,7 +92,8 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region); void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos); GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version,
out Vector3 newpos, out string reason);
void Cross(SceneObjectGroup sog, Vector3 position, bool silent); void Cross(SceneObjectGroup sog, Vector3 position, bool silent);

View File

@ -459,6 +459,7 @@ namespace OpenSim.Region.Framework.Scenes
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
string version = String.Empty; string version = String.Empty;
Vector3 newpos = Vector3.Zero; Vector3 newpos = Vector3.Zero;
string failureReason = String.Empty;
OpenSim.Services.Interfaces.GridRegion destination = null; OpenSim.Services.Interfaces.GridRegion destination = null;
if (m_rootPart.KeyframeMotion != null) if (m_rootPart.KeyframeMotion != null)
@ -476,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
// We set the avatar position as being the object // We set the avatar position as being the object
// position to get the region to send to // position to get the region to send to
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null) if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null)
{ {
canCross = false; canCross = false;
break; break;

View File

@ -3473,8 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos2 = AbsolutePosition; Vector3 pos2 = AbsolutePosition;
Vector3 origPosition = pos2; Vector3 origPosition = pos2;
Vector3 vel = Velocity; Vector3 vel = Velocity;
int neighbor = 0;
int[] fix = new int[2];
// Compute the avatar position in the next physics tick. // Compute the avatar position in the next physics tick.
// If the avatar will be crossing, we force the crossing to happen now // If the avatar will be crossing, we force the crossing to happen now
@ -3507,23 +3505,13 @@ namespace OpenSim.Region.Framework.Scenes
if (m_requestedSitTargetUUID == UUID.Zero) if (m_requestedSitTargetUUID == UUID.Zero)
{ {
m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
const float borderFudge = 0.1f;
if (origPosition.X < 0)
origPosition.X = borderFudge;
else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX)
origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge;
if (origPosition.Y < 0)
origPosition.Y = borderFudge;
else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY)
origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge;
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
AbsolutePosition = origPosition; AbsolutePosition = EnforceSanityOnPosition(origPosition);
AddToPhysicalScene(isFlying); AddToPhysicalScene(isFlying);
} }
} }
} }
} }
else else
@ -3541,6 +3529,36 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// 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.
private Vector3 EnforceSanityOnPosition(Vector3 origPosition)
{
const float borderFudge = 0.1f;
Vector3 ret = origPosition;
// Sanity checking on the position to make sure it is in the region we couldn't cross from
float extentX = (float)m_scene.RegionInfo.RegionSizeX;
float extentY = (float)m_scene.RegionInfo.RegionSizeY;
IRegionCombinerModule combiner = m_scene.RequestModuleInterface<IRegionCombinerModule>();
if (combiner != null)
{
// If a mega-region, the size could be much bigger
Vector2 megaExtent = combiner.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
extentX = megaExtent.X;
extentY = megaExtent.Y;
}
if (ret.X < 0)
ret.X = borderFudge;
else if (ret.X >= extentX)
ret.X = extentX - borderFudge;
if (ret.Y < 0)
ret.Y = borderFudge;
else if (ret.Y >= extentY)
ret.Y = extentY - borderFudge;
return ret;
}
/// <summary> /// <summary>
/// Moves the agent outside the region bounds /// Moves the agent outside the region bounds
/// Tells neighbor region that we're crossing to it /// Tells neighbor region that we're crossing to it