From b1c26a56b3d615f3709363e3a2f91b5423f5891f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 8 Aug 2013 23:29:30 +0100 Subject: Fix an issue where under teleport v2 protocol, teleporting from regions in an line from A->B->C would not close region A when reaching C The root cause was that v2 was only closing neighbour agents if the root connection also needed a close. However, fixing this requires the neighbour regions also detect when they should not close due to re-teleports re-establishing the child connection. This involves restructuring the code to introduce a scene presence state machine that can serialize the different add and remove client calls that are now possible with the late close of the This commit appears to fix these issues and improve teleport, but still has holes on at least quick reteleporting (and possibly occasionally on ordinary teleports). Also, has not been completely tested yet in scenarios where regions are running on different simulators --- .../EntityTransfer/EntityTransferModule.cs | 48 +++++++++++----------- .../World/Estate/EstateManagementModule.cs | 6 +-- 2 files changed, 28 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 01ef710..2f74253 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1064,8 +1064,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone + // May still need to signal neighbours whether child agents may need closing irrespective of whether this + // one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or + // teleport re-established the child connection. + sp.CloseChildAgents(newRegionX, newRegionY); + // 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)) { sp.DoNotCloseAfterTeleport = false; @@ -1081,14 +1085,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!sp.DoNotCloseAfterTeleport) { // OK, it got this agent. Let's close everything - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name); - sp.CloseChildAgents(newRegionX, newRegionY); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name); sp.Scene.IncomingCloseAgent(sp.UUID, false); - } else { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name); sp.DoNotCloseAfterTeleport = false; } } @@ -1863,10 +1865,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer List newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); List oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); - //Dump("Current Neighbors", neighbourHandles); - //Dump("Previous Neighbours", previousRegionNeighbourHandles); - //Dump("New Neighbours", newRegions); - //Dump("Old Neighbours", oldRegions); + Dump("Current Neighbors", neighbourHandles); + Dump("Previous Neighbours", previousRegionNeighbourHandles); + Dump("New Neighbours", newRegions); + Dump("Old Neighbours", oldRegions); /// Update the scene presence's known regions here on this region sp.DropOldNeighbours(oldRegions); @@ -1874,8 +1876,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// Collect as many seeds as possible Dictionary seeds; if (sp.Scene.CapsModule != null) - seeds - = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); + seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); else seeds = new Dictionary(); @@ -1945,6 +1946,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer newAgent = true; else newAgent = false; +// continue; if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) { @@ -2178,18 +2180,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return handles; } -// private void Dump(string msg, List handles) -// { -// m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); -// foreach (ulong handle in handles) -// { -// uint x, y; -// Utils.LongToUInts(handle, out x, out y); -// x = x / Constants.RegionSize; -// y = y / Constants.RegionSize; -// m_log.InfoFormat("({0}, {1})", x, y); -// } -// } + private void Dump(string msg, List handles) + { + m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); + foreach (ulong handle in handles) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.InfoFormat("({0}, {1})", x, y); + } + } #endregion diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 121b2aa..31547a6 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -562,7 +562,7 @@ namespace OpenSim.Region.CoreModules.World.Estate if (!Scene.TeleportClientHome(user, s.ControllingClient)) { s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); - s.ControllingClient.Close(); + Scene.IncomingCloseAgent(s.UUID, false); } } } @@ -797,7 +797,7 @@ namespace OpenSim.Region.CoreModules.World.Estate if (!Scene.TeleportClientHome(prey, s.ControllingClient)) { s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); - s.ControllingClient.Close(); + Scene.IncomingCloseAgent(s.UUID, false); } } } @@ -820,7 +820,7 @@ namespace OpenSim.Region.CoreModules.World.Estate if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) { p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); - p.ControllingClient.Close(); + Scene.IncomingCloseAgent(p.UUID, false); } } } -- cgit v1.1 From 6fcbf219da1d5095d6f37e8e44031db9ef108c39 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 9 Aug 2013 17:48:35 +0100 Subject: Comment back out seed dump code enabled in b1c26a56. Also adds a few teleport comments. --- .../EntityTransfer/EntityTransferModule.cs | 38 +++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 2f74253..87f0264 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1067,6 +1067,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // May still need to signal neighbours whether child agents may need closing irrespective of whether this // one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or // teleport re-established the child connection. + // + // It may be possible to also close child agents after a pause but one needs to be very careful about + // race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back + // to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible + // with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's + // easier to close immediately and greatly reduce the scope of race conditions if possible. sp.CloseChildAgents(newRegionX, newRegionY); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone @@ -1865,10 +1871,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer List newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); List oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); - Dump("Current Neighbors", neighbourHandles); - Dump("Previous Neighbours", previousRegionNeighbourHandles); - Dump("New Neighbours", newRegions); - Dump("Old Neighbours", oldRegions); +// Dump("Current Neighbors", neighbourHandles); +// Dump("Previous Neighbours", previousRegionNeighbourHandles); +// Dump("New Neighbours", newRegions); +// Dump("Old Neighbours", oldRegions); /// Update the scene presence's known regions here on this region sp.DropOldNeighbours(oldRegions); @@ -2180,18 +2186,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return handles; } - private void Dump(string msg, List handles) - { - m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); - foreach (ulong handle in handles) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.InfoFormat("({0}, {1})", x, y); - } - } +// private void Dump(string msg, List handles) +// { +// m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); +// foreach (ulong handle in handles) +// { +// uint x, y; +// Utils.LongToUInts(handle, out x, out y); +// x = x / Constants.RegionSize; +// y = y / Constants.RegionSize; +// m_log.InfoFormat("({0}, {1})", x, y); +// } +// } #endregion -- cgit v1.1