diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 9a7ea80e26..567aae188a 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -451,7 +451,7 @@ namespace OpenSim.Framework RegionHandleToWorldLoc(handle, out uint uhX, out uint uhY); double px = uhX - region.WorldLocX + (double)handleOffset.X; double py = uhY - region.WorldLocY + (double)handleOffset.Y; - if (px >= 0 && px < region.RegionSizeX && py >= 0 && py < region.RegionSizeY) + if (px >= 0 && px < region.RegionSizeX && py >= 0 && py < region.RegionSizeY) { regionOffset = new Vector3((float)px, (float)py, handleOffset.Z); return true; @@ -460,7 +460,7 @@ namespace OpenSim.Framework return false; } - public static bool CompareRegionHandler(ulong handle, Vector3 handleOffset, ulong regionhandle, int regionSizeX, int regionSizeY, out Vector3 regionOffset) + public static bool CompareRegionHandles(ulong handle, Vector3 handleOffset, ulong regionhandle, int regionSizeX, int regionSizeY, out Vector3 regionOffset) { RegionHandleToWorldLoc(handle, out uint uhX, out uint uhY); RegionHandleToWorldLoc(regionhandle, out uint urX, out uint urY); @@ -475,7 +475,7 @@ namespace OpenSim.Framework return false; } - public static bool CompareRegionHandlers(ulong handle, Vector3 handleOffset, int regionX, int regionY, int regionSizeX, int regionSizeY, out Vector3 regionOffset) + public static bool CompareRegionHandles(ulong handle, Vector3 handleOffset, int regionX, int regionY, int regionSizeX, int regionSizeY, out Vector3 regionOffset) { RegionHandleToWorldLoc(handle, out uint uhX, out uint uhY); double px = uhX - regionX + (double)handleOffset.X; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 74ac00e0f5..616fd11cc1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Nothing to validate here protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) { - reason = String.Empty; + reason = string.Empty; return true; } @@ -1412,16 +1412,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm, Vector3 lookAt) { - GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId); + if (sp == null || sp.IsDeleted || sp.IsInTransit || sp.IsNPC) + return; + GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); if (info == null) { // can't find the region: Tell viewer and abort - remoteClient.SendTeleportFailed("The teleport destination could not be found."); + remoteClient.SendTeleportFailed("Landmark region not found"); return; } - ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, - lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + //check if region on same position and fix local offset + if (Util.CompareRegionHandles(lm.RegionHandle, lm.Position, info.RegionLocX, info.RegionLocY, info.RegionSizeX, info.RegionSizeY, out Vector3 offset)) + { + Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, offset, + lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + } + else //region may had move to other grid slot. assume the lm position is good + Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, + lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); } #endregion diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 92d9f2f6a5..f94fbfb4c4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -546,64 +546,63 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); - if (lm.Gatekeeper == string.Empty) - { - base.RequestTeleportLandmark(remoteClient, lm, lookAt); + ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId); + if (sp == null || sp.IsDeleted || sp.IsInTransit || sp.IsNPC) return; - } GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); - // Local region? if (info != null) { - Scene.RequestTeleportLocation( - remoteClient, info.RegionHandle, lm.Position, - Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + //check if region on same position and fix local offset + if (Util.CompareRegionHandles(lm.RegionHandle, lm.Position, info.RegionLocX, info.RegionLocY, info.RegionSizeX, info.RegionSizeY, out Vector3 offset)) + { + Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, offset, + lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + } + else //region may had move to other grid slot. assume the lm position is good + Scene.RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, + lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; } - else + + if (lm.Gatekeeper == string.Empty) { - // Foreign region - GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); - GridRegion gatekeeper = MakeGateKeeperRegion(lm.Gatekeeper); - if (gatekeeper == null) - { - remoteClient.SendTeleportFailed("Could not parse landmark destiny URI"); - return; - } - - string homeURI = Scene.GetAgentHomeURI(remoteClient.AgentId); - - GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID), remoteClient.AgentId, homeURI, out string message); - - if (finalDestination != null) - { - ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId); - - if (sp != null) - { - if (message != null) - sp.ControllingClient.SendAgentAlertMessage(message, true); - - // Validate assorted conditions - string reason = string.Empty; - if (!ValidateGenericConditions(sp, gatekeeper, finalDestination, 0, out reason)) - { - sp.ControllingClient.SendTeleportFailed(reason); - return; - } - - DoTeleport( - sp, gatekeeper, finalDestination, lm.Position, lookAt, - (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); - } - } - else - { - remoteClient.SendTeleportFailed(message); - } - + remoteClient.SendTeleportFailed("Landmark region not found"); + return; } + + // Foreign region + GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); + GridRegion gatekeeper = MakeGateKeeperRegion(lm.Gatekeeper); + if (gatekeeper == null) + { + remoteClient.SendTeleportFailed("Could not parse landmark destiny URI"); + return; + } + + string homeURI = Scene.GetAgentHomeURI(remoteClient.AgentId); + + GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, lm.RegionID, remoteClient.AgentId, homeURI, out string message); + if(finalDestination == null) + remoteClient.SendTeleportFailed(message); + + // Validate assorted conditions + string reason = string.Empty; + if (!ValidateGenericConditions(sp, gatekeeper, finalDestination, 0, out reason)) + { + remoteClient.SendTeleportFailed(reason); + return; + } + + if (Util.CompareRegionHandles(lm.RegionHandle, lm.Position, finalDestination.RegionLocX, finalDestination.RegionLocY, + finalDestination.RegionSizeX, finalDestination.RegionSizeY, out Vector3 roffset)) + { + DoTeleport(sp, gatekeeper, finalDestination, roffset, lookAt, + (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; + } + remoteClient.SendTeleportFailed("landmark region not found"); } private void RemoveIncomingSceneObjectJobs(string commonIdToRemove)