From 5c9086ade688b457e9aa9cd0d2099985b7336b71 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 24 May 2012 22:26:02 +0100 Subject: [PATCH 1/4] Fix issue where a dns resolution failure on the final destination might leave the user unable to teleport since the transit flag was not being reset. This moves the 'already in transit' check further up and resets the flag if dns resolution fails and in the new required places. --- .../EntityTransfer/EntityTransferModule.cs | 454 +++++++++--------- 1 file changed, 231 insertions(+), 223 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 408d63da10..4988e93269 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -358,6 +358,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { + // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection + // of whether the destination region completes the teleport. + if (!SetInTransit(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", + sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); + + return; + } + + if (reg == null || finalDestination == null) + { + sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); + ResetFromTransit(sp.UUID); + + return; + } + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Teleporting {0} {1} from {2} to {3} ({4}) {5}/{6}", + sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, + reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); + RegionInfo sourceRegion = sp.Scene.RegionInfo; if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) @@ -369,31 +393,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, MaxTransferDistance)); + ResetFromTransit(sp.UUID); + return; } IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (reg == null || finalDestination == null) - { - sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); - return; - } - - if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", - sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); - - return; - } - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Teleporting {0} {1} from {2} to {3} ({4}) {5}/{6}", - sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, - reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); - uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -405,17 +411,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = finalDestination.ExternalEndPoint; - if (endPoint.Address != null) - { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); - if (!sp.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); + if (endPoint.Address == null) + { + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + ResetFromTransit(sp.UUID); + + return; + } + + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); + + if (!sp.ValidateAttachments()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); // if (!sp.ValidateAttachments()) // { @@ -423,211 +436,206 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // return; // } - string reason; - string version; - if (!m_scene.SimulationService.QueryAccess( - finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) - { - sp.ControllingClient.SendTeleportFailed(reason); - ResetFromTransit(sp.UUID); - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - - return; - } - - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); - - sp.ControllingClient.SendTeleportStart(teleportFlags); - - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = avatar.KnownRegionHandles; - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - - string capsPath = String.Empty; - - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); - AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.startpos = position; - agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; - if (currentAgentCircuit != null) - { - agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; - agentCircuit.IPAddress = currentAgentCircuit.IPAddress; - agentCircuit.Viewer = currentAgentCircuit.Viewer; - agentCircuit.Channel = currentAgentCircuit.Channel; - agentCircuit.Mac = currentAgentCircuit.Mac; - agentCircuit.Id0 = currentAgentCircuit.Id0; - } - - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); - } - - // Let's create an agent there if one doesn't exist yet. - bool logout = false; - if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) - { - sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); - ResetFromTransit(sp.UUID); - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - - return; - } - - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); - - IClientIPEndpoint ipepClient; - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT - // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - - if (eq != null) - { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); - - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait - Thread.Sleep(200); - - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - - } - else - { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); - } - } - else - { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - } - - // Let's send a full update of the agent. This is a synchronous call. - AgentData agent = new AgentData(); - sp.CopyTo(agent); - agent.Position = position; - SetCallbackURL(agent, sp.Scene.RegionInfo); - - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); - - if (!UpdateAgent(reg, finalDestination, agent)) - { - // Region doesn't take it - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } - - sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); + string reason; + string version; + if (!m_scene.SimulationService.QueryAccess( + finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) + { + sp.ControllingClient.SendTeleportFailed(reason); + ResetFromTransit(sp.UUID); m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", - capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); + "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + + return; + } + + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + + sp.ControllingClient.SendTeleportStart(teleportFlags); + + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = avatar.KnownRegionHandles; + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); + + string capsPath = String.Empty; + + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + if (currentAgentCircuit != null) + { + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; + agentCircuit.IPAddress = currentAgentCircuit.IPAddress; + agentCircuit.Viewer = currentAgentCircuit.Viewer; + agentCircuit.Channel = currentAgentCircuit.Channel; + agentCircuit.Mac = currentAgentCircuit.Mac; + agentCircuit.Id0 = currentAgentCircuit.Id0; + } + + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + } + + // Let's create an agent there if one doesn't exist yet. + bool logout = false; + if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) + { + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); + ResetFromTransit(sp.UUID); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + + return; + } + + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); + + IClientIPEndpoint ipepClient; + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); if (eq != null) { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(200); + + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + } else { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } - - // Let's set this to true tentatively. This does not trigger OnChildAgent - sp.IsChildAgent = true; - - // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which - // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation - // that the client contacted the destination before we close things here. - if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) - { - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } - - // For backwards compatibility - if (version == "Unknown" || version == string.Empty) - { - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); - CrossAttachmentsIntoNewRegion(finalDestination, sp, true); - } - - // May need to logout or other cleanup - AgentHasMovedAway(sp, logout); - - // Well, this is it. The agent is over there. - KillEntity(sp.Scene, sp.LocalId); - - // Now let's make it officially a child agent - sp.MakeChildAgent(); - -// sp.Scene.CleanDroppedAttachments(); - - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - - if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before - // they regard the new region as the current region after receiving the AgentMovementComplete - // response. If close is sent before then, it will cause the viewer to quit instead. - // However, if this delay is longer, then a viewer can teleport back to this region and experience - // a failure because the old ScenePresence has not yet been cleaned up. - Thread.Sleep(2000); - - sp.Close(); - sp.Scene.IncomingCloseAgent(sp.UUID); - } - else - { - // now we have a child agent in this region. - sp.Reset(); - } - - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (sp.Scene.NeedSceneCacheClear(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", - sp.UUID); + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); } } else { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + SetCallbackURL(agent, sp.Scene.RegionInfo); + + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); + + if (!UpdateAgent(reg, finalDestination, agent)) + { + // Region doesn't take it + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } + + sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", + capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); + + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } + + // Let's set this to true tentatively. This does not trigger OnChildAgent + sp.IsChildAgent = true; + + // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which + // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation + // that the client contacted the destination before we close things here. + if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } + + // For backwards compatibility + if (version == "Unknown" || version == string.Empty) + { + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + } + + // May need to logout or other cleanup + AgentHasMovedAway(sp, logout); + + // Well, this is it. The agent is over there. + KillEntity(sp.Scene, sp.LocalId); + + // Now let's make it officially a child agent + sp.MakeChildAgent(); + +// sp.Scene.CleanDroppedAttachments(); + + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone + + if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before + // they regard the new region as the current region after receiving the AgentMovementComplete + // response. If close is sent before then, it will cause the viewer to quit instead. + // However, if this delay is longer, then a viewer can teleport back to this region and experience + // a failure because the old ScenePresence has not yet been cleaned up. + Thread.Sleep(2000); + + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); + } + else + { + // now we have a child agent in this region. + sp.Reset(); + } + + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); } } From cd225215b1284b4a50e5ebb928c1aecc3f005e05 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 24 May 2012 22:40:24 +0100 Subject: [PATCH 2/4] Now that the EntityTransferModule is per-region, fetch the event queue module once rather than repeatedly via scene presences --- .../EntityTransfer/EntityTransferModule.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4988e93269..361e4535ce 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -73,6 +73,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private ExpiringCache> m_bannedRegions = new ExpiringCache>(); + private IEventQueue m_eqModule; + #region ISharedRegionModule public Type ReplaceableInterface @@ -147,7 +149,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void RemoveRegion(Scene scene) {} - public virtual void RegionLoaded(Scene scene) {} + public virtual void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_eqModule = m_scene.RequestModuleInterface(); + } #endregion @@ -398,8 +406,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); - uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -416,7 +422,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); ResetFromTransit(sp.UUID); - + return; } @@ -516,16 +522,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - if (eq != null) + if (m_eqModule != null) { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep(200); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else @@ -564,10 +570,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); - if (eq != null) + if (m_eqModule != null) { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); + m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); } else { @@ -1122,11 +1127,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - IEventQueue eq = agent.Scene.RequestModuleInterface(); - if (eq != null) + if (m_eqModule != null) { - eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); } else { @@ -1474,8 +1479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (regionAccepted && newAgent) { - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (eq != null) + if (m_eqModule != null) { #region IP Translation for NAT IClientIPEndpoint ipepClient; @@ -1489,8 +1493,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "and EstablishAgentCommunication with seed cap {4}", scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); - eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else { From cc53d91d2f53adf952703f7fb91a7ab33c7a5d8a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 24 May 2012 22:46:45 +0100 Subject: [PATCH 3/4] On inter-region teleport, only stand the avatar up if the QueryAccess call to the destination scene actually succeeds. --- .../EntityTransfer/EntityTransferModule.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 361e4535ce..5afe553545 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (!m_Enabled) return; - + m_eqModule = m_scene.RequestModuleInterface(); } @@ -426,11 +426,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); - if (!sp.ValidateAttachments()) m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", @@ -457,7 +452,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); sp.ControllingClient.SendTeleportStart(teleportFlags); From 93ff27053a2d46a934bb6a1780ccfecd505ab44f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 24 May 2012 22:59:52 +0100 Subject: [PATCH 4/4] Don't actually proceed on a within-region teleport if another is already taking place, rather than just (falsely) logging that we're not going to proceed. An oversight from recent commit 9ab0c81 --- .../Framework/EntityTransfer/EntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5afe553545..b5717cdccd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -227,6 +227,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", sp.Name, sp.UUID, position); + + return; } // Teleport within the same region