From 7fc289c039ca3cdbad0f050e17c1b1d13e684c73 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 15 Feb 2014 17:02:53 -0800 Subject: 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. --- .../EntityTransfer/EntityTransferModule.cs | 21 +++++++--- .../Framework/Interfaces/IEntityTransferModule.cs | 5 ++- .../Region/Framework/Scenes/SceneObjectGroup.cs | 3 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 46 +++++++++++++++------- 4 files changed, 52 insertions(+), 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 3eff96e..f1d69b0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -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 // point is actually in. // 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; newpos = pos; + failureReason = string.Empty; // m_log.DebugFormat( // "[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) { // 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), pos.Z); if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) { + failureReason = "Cannot region cross into banned parcel"; neighbourRegion = null; } else @@ -1478,15 +1481,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Check to see if we have access to the target region. - string reason; 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 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); neighbourRegion = null; } } + else + { + // The destination region just doesn't exist + failureReason = "Cannot cross into non-existant region"; + } 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}", @@ -1509,11 +1516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer uint y; Vector3 newpos; 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) { - agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); + agent.ControllingClient.SendAlertMessage(failureReason); return false; } diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 709d8fc..5d07a5f 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -92,11 +92,12 @@ namespace OpenSim.Region.Framework.Interfaces 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); - ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); + ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); } public interface IUserAgentVerificationModule diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0657cbb..73a30f3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -459,6 +459,7 @@ namespace OpenSim.Region.Framework.Scenes IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface(); string version = String.Empty; Vector3 newpos = Vector3.Zero; + string failureReason = String.Empty; OpenSim.Services.Interfaces.GridRegion destination = null; if (m_rootPart.KeyframeMotion != null) @@ -476,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes // We set the avatar position as being the object // 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; break; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 576b8c2..d4af9fc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3473,8 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos2 = AbsolutePosition; Vector3 origPosition = pos2; Vector3 vel = Velocity; - int neighbor = 0; - int[] fix = new int[2]; // Compute the avatar position in the next physics tick. // 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) { 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; - AbsolutePosition = origPosition; + AbsolutePosition = EnforceSanityOnPosition(origPosition); AddToPhysicalScene(isFlying); } } - } } 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(); + 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; + } + /// /// Moves the agent outside the region bounds /// Tells neighbor region that we're crossing to it -- cgit v1.1