diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index ee5007abf8..2d00296460 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -398,7 +398,8 @@ namespace OpenSim.Framework // Scripted public ControllerData[] Controllers; - public string CallbackURI; + public string CallbackURI; // to remove + public string NewCallbackURI; // These two must have the same Count public List AttachmentObjects; @@ -528,6 +529,9 @@ namespace OpenSim.Framework if ((CallbackURI != null) && (!CallbackURI.Equals(""))) args["callback_uri"] = OSD.FromString(CallbackURI); + if ((NewCallbackURI != null) && (!NewCallbackURI.Equals(""))) + args["cb_uri"] = OSD.FromString(NewCallbackURI); + // Attachment objects for fatpack messages if (AttachmentObjects != null) { @@ -811,12 +815,7 @@ namespace OpenSim.Framework } // end of code to remove } -/* moved above - if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) - Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); - else - m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); -*/ + if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { OSDArray controls = (OSDArray)(args["controllers"]); @@ -834,6 +833,9 @@ namespace OpenSim.Framework if (args["callback_uri"] != null) CallbackURI = args["callback_uri"].AsString(); + if (args["cb_uri"] != null) + NewCallbackURI = args["cb_uri"].AsString(); + // Attachment objects if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 9471c908cb..09b0dd6027 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -54,14 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]"; - public const int DefaultMaxTransferDistance = 4095; public const bool WaitForAgentArrivedAtDestinationDefault = true; - /// - /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. - /// - public int MaxTransferDistance { get; set; } - /// /// If true then on a teleport, the source region waits for a callback from the destination region. If /// a callback fails to arrive within a set time then the user is pulled back into the source region. @@ -227,11 +221,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer WaitForAgentArrivedAtDestination = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); - MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); - } - else - { - MaxTransferDistance = DefaultMaxTransferDistance; } m_entityTransferStateMachine = new EntityTransferStateMachine(this); @@ -639,29 +628,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } - /// - /// Determines whether this instance is within the max transfer distance. - /// - /// - /// - /// - /// true if this instance is within max transfer distance; otherwise, false. - /// - private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) - { - if(MaxTransferDistance == 0) - return true; - -// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); -// -// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", -// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); - - // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position. - return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance - && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; - } - /// /// Wraps DoTeleportInternal() and manages the transfer state. /// @@ -722,18 +688,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer RegionInfo sourceRegion = sp.Scene.RegionInfo; - if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) - { - sp.ControllingClient.SendTeleportFailed( - string.Format( - "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", - finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, - sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, - MaxTransferDistance)); - - return; - } - ulong destinationHandle = finalDestination.RegionHandle; // Let's do DNS resolution only once in this process, please! @@ -1175,7 +1129,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.SenderWantsToWaitForRoot = true; - //SetCallbackURL(agent, sp.Scene.RegionInfo); + if(!sp.IsInLocalTransit) + SetNewCallbackURL(agent, sp.Scene.RegionInfo); // Reset the do not close flag. This must be done before the destination opens child connections (here // triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible @@ -1224,25 +1179,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.closeAllChildAgents(); else sp.CloseChildAgents(childRegionsToClose); + } - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - // goes by HG hook - if (NeedsClosing(reg, OutSideViewRange)) + // if far jump we do need to close anyways + if (NeedsClosing(reg, OutSideViewRange)) + { + int count = 60; + do { - if (!sp.Scene.IncomingPreCloseClient(sp)) - { - sp.IsInTransit = false; + Thread.Sleep(250); + if(sp.IsDeleted) return; - } + } while (--count > 0); - // viewers and target region take extra time to process the tp - Thread.Sleep(15000); + if (!sp.IsDeleted) + { m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); + "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport timeout", sp.Name, Scene.Name); sp.Scene.CloseAgent(sp.UUID, false); } - sp.IsInTransit = false; + return; } + // otherwise keep child + sp.IsInTransit = false; } /// @@ -1313,6 +1272,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; + //m_log.DebugFormat( + // "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", + // agent.CallbackURI, region.RegionName); + } + + protected virtual void SetNewCallbackURL(AgentData agent, RegionInfo region) + { + agent.NewCallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", agent.CallbackURI, region.RegionName); @@ -2488,7 +2456,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public void AgentArrivedAtDestination(UUID id) { - m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); + ScenePresence sp = Scene.GetScenePresence(id); + if(sp == null || sp.IsDeleted || !sp.IsInTransit) + return; + + Scene.CloseAgent(sp.UUID, false); + m_entityTransferStateMachine.ResetFromTransit(id); // this needs cleanup + //m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2145fcdbac..a95036c198 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -457,9 +457,10 @@ namespace OpenSim.Region.Framework.Scenes #region For teleports and crossings callbacks /// - /// In the V1 teleport protocol, the destination simulator sends ReleaseAgent to this address. + /// the destination simulator sends ReleaseAgent to this address, for very long range tps, HG. /// - private string m_callbackURI; + private string m_callbackURI; // to remove with v1 support + private string m_newCallbackURI; /// /// Records the region from which this presence originated, if not from login. @@ -2155,28 +2156,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF); } - if (!string.IsNullOrEmpty(m_callbackURI)) - { - // We cannot sleep here since this would hold up the inbound packet processing thread, as - // CompleteMovement() is executed synchronously. However, it might be better to delay the release - // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete - // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this - // region as the current region, meaning that a close sent before then will fail the teleport. - // System.Threading.Thread.Sleep(2000); - - m_log.DebugFormat( - "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", - client.Name, client.AgentId, m_callbackURI); - - UUID originID; - - lock (m_originRegionIDAccessLock) - originID = m_originRegionID; - - Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); - m_callbackURI = null; - //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - } } // Tell the client that we're totally ready ControllingClient.SendRegionHandshake(); @@ -2381,6 +2360,37 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + if (!string.IsNullOrEmpty(m_callbackURI)) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Releasing {0} {1} with old callback to {2}", + client.Name, client.AgentId, m_callbackURI); + + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); + m_callbackURI = null; + //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + } + else if (!string.IsNullOrEmpty(m_newCallbackURI)) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", + client.Name, client.AgentId, m_newCallbackURI); + + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI); + m_newCallbackURI = null; + //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + } + if (openChildAgents) { IFriendsModule friendsModule = m_scene.RequestModuleInterface(); @@ -4589,12 +4599,15 @@ namespace OpenSim.Region.Framework.Scenes byebyeRegions.Add(handle); else if(handle == curRegionHandle) { + continue; + /* RegionInfo curreg = m_scene.RegionInfo; if (Util.IsOutsideView(255, curreg.RegionLocX, newRegionX, curreg.RegionLocY, newRegionY, (int)curreg.RegionSizeX, (int)curreg.RegionSizeX, newRegionSizeX, newRegionSizeY)) { byebyeRegions.Add(handle); } + */ } else { @@ -4774,6 +4787,7 @@ namespace OpenSim.Region.Framework.Scenes public void CopyTo(AgentData cAgent, bool isCrossUpdate) { cAgent.CallbackURI = m_callbackURI; + cAgent.NewCallbackURI = m_newCallbackURI; cAgent.AgentID = UUID; cAgent.RegionID = Scene.RegionInfo.RegionID; @@ -4860,9 +4874,10 @@ namespace OpenSim.Region.Framework.Scenes private void CopyFrom(AgentData cAgent) { m_callbackURI = cAgent.CallbackURI; -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", -// Name, m_scene.RegionInfo.RegionName, m_callbackURI); + m_newCallbackURI = cAgent.NewCallbackURI; + // m_log.DebugFormat( + // "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", + // Name, m_scene.RegionInfo.RegionName, m_callbackURI); GodController.SetState(cAgent.GodData);