From 888210ea4af0f9d41263193d450d73eba5d866fc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 25 May 2012 03:06:26 +0100 Subject: [PATCH 1/2] refactor: make ETM.CrossAgentToNewRegionAsync neighbourRegion == null check return earlier to simplify method --- .../EntityTransfer/EntityTransferModule.cs | 204 +++++++++--------- 1 file changed, 103 insertions(+), 101 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ddb621d81d..7295383cd0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1106,119 +1106,121 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { + if (neighbourRegion == null) + return agent; + try { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", + agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; - - if (neighbourRegion != null) + + if (!agent.ValidateAttachments()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", + agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); + + pos = pos + agent.Velocity; + Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + + agent.RemoveFromPhysicalScene(); + + SetInTransit(agent.UUID); + + AgentData cAgent = new AgentData(); + agent.CopyTo(cAgent); + cAgent.Position = pos; + if (isFlying) + cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + + // We don't need the callback anymnore + cAgent.CallbackURI = String.Empty; + + // Beyond this point, extra cleanup is needed beyond removing transit state + UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + + if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { - if (!agent.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", - agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - - pos = pos + agent.Velocity; - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); - - agent.RemoveFromPhysicalScene(); - - SetInTransit(agent.UUID); - - AgentData cAgent = new AgentData(); - agent.CopyTo(cAgent); - cAgent.Position = pos; - if (isFlying) - cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; - - // We don't need the callback anymnore - cAgent.CallbackURI = String.Empty; - - // Beyond this point, extra cleanup is needed beyond removing transit state - UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - - if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) - { - // region doesn't take it - ReInstantiateScripts(agent); - agent.AddToPhysicalScene(isFlying); - ResetFromTransit(agent.UUID); - return agent; - } - - //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); - agent.ControllingClient.RequestClientInfo(); - - //m_log.Debug("BEFORE CROSS"); - //Scene.DumpChildrenSeeds(UUID); - //DumpKnownRegions(); - string agentcaps; - if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) - { - m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", - neighbourRegion.RegionHandle); - return agent; - } - // No turning back - agent.IsChildAgent = true; - - string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - - if (m_eqModule != null) - { - m_eqModule.CrossRegion( - neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); - } - else - { - agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); - } - - // SUCCESS! - UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); - - // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. - UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); - - agent.MakeChildAgent(); - - // FIXME: Possibly this should occur lower down after other commands to close other agents, - // but not sure yet what the side effects would be. + // region doesn't take it + ReInstantiateScripts(agent); + agent.AddToPhysicalScene(isFlying); ResetFromTransit(agent.UUID); + return agent; + } - // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendOtherAgentsAvatarDataToMe(); - agent.SendOtherAgentsAppearanceToMe(); + //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); + agent.ControllingClient.RequestClientInfo(); - // Backwards compatibility. Best effort - if (version == "Unknown" || version == string.Empty) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } + //m_log.Debug("BEFORE CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + string agentcaps; + if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) + { + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + neighbourRegion.RegionHandle); + return agent; + } + // No turning back + agent.IsChildAgent = true; + + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); + + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); + + if (m_eqModule != null) + { + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath); + } + + // SUCCESS! + UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + + // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + + agent.MakeChildAgent(); + + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. + ResetFromTransit(agent.UUID); + + // now we have a child agent in this region. Request all interesting data about other (root) agents + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); + + // Backwards compatibility. Best effort + if (version == "Unknown" || version == string.Empty) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); + Thread.Sleep(3000); // wait a little now that we're not waiting for the callback + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + } - // Next, let's close the child agent connections that are too far away. - agent.CloseChildAgents(neighbourx, neighboury); - - AgentHasMovedAway(agent, false); - - // the user may change their profile information in other region, - // so the userinfo in UserProfileCache is not reliable any more, delete it - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (agent.Scene.NeedSceneCacheClear(agent.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); - } + // Next, let's close the child agent connections that are too far away. + agent.CloseChildAgents(neighbourx, neighboury); + + AgentHasMovedAway(agent, false); + + // the user may change their profile information in other region, + // so the userinfo in UserProfileCache is not reliable any more, delete it + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (agent.Scene.NeedSceneCacheClear(agent.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); } //m_log.Debug("AFTER CROSS"); From ab59c0a658c25f129255198f27704cdbbcb13d6b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 25 May 2012 03:39:10 +0100 Subject: [PATCH 2/2] on agent cross, remove from physics scene after its been placed in transit, not before. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7295383cd0..a5fb0c2fb5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1111,6 +1111,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { + SetInTransit(agent.UUID); + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); m_log.DebugFormat( @@ -1129,8 +1131,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.RemoveFromPhysicalScene(); - SetInTransit(agent.UUID); - AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; @@ -1146,9 +1146,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); ResetFromTransit(agent.UUID); + return agent; } @@ -1208,7 +1211,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); } - // Next, let's close the child agent connections that are too far away. agent.CloseChildAgents(neighbourx, neighboury); @@ -1232,6 +1234,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); + + // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. } return agent;