From 459c7635afdbc4002cacbf5780185645a4296f6a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 00:31:14 +0100 Subject: If an agent is still registered as 'in transit' by the source region, don't allow an immediate teleport back. This is to help relieve a race condition when an agent teleports then immediately attempts to teleport back before the source region has properly cleaned up/demoted the old ScenePresence. This is rare in viewers but much more possible via scripting or region module. However, more needs to be done since virtually all clean up happens after the transit flag is cleared . Possibly need to add a 'cleaning up' state to in transit. This change required making the EntityTransferModule and HGEntityTransferModule per-region rather than shared, in order to allow separate transit lists. Changes were also required in LocalSimulationConnector. Tested in standalone, grid and with local and remote region crossings with attachments. --- OpenSim/Region/Framework/Scenes/Scene.cs | 67 ++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fbe56f6..755b1e6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -166,7 +166,6 @@ namespace OpenSim.Region.Framework.Scenes protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; - protected IEntityTransferModule m_teleportModule; protected ICapabilitiesModule m_capsModule; protected IGroupsModule m_groupsModule; @@ -498,6 +497,7 @@ namespace OpenSim.Region.Framework.Scenes } public IAttachmentsModule AttachmentsModule { get; set; } + public IEntityTransferModule EntityTransferModule { get; private set; } public IAvatarFactoryModule AvatarFactory { @@ -924,8 +924,8 @@ namespace OpenSim.Region.Framework.Scenes List old = new List(); old.Add(otherRegion.RegionHandle); agent.DropOldNeighbours(old); - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, otherRegion); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, otherRegion); }); } catch (NullReferenceException) @@ -1062,8 +1062,8 @@ namespace OpenSim.Region.Framework.Scenes { ForEachRootScenePresence(delegate(ScenePresence agent) { - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, r); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, r); }); } catch (NullReferenceException) @@ -1238,7 +1238,7 @@ namespace OpenSim.Region.Framework.Scenes m_serialiser = RequestModuleInterface(); m_dialogModule = RequestModuleInterface(); m_capsModule = RequestModuleInterface(); - m_teleportModule = RequestModuleInterface(); + EntityTransferModule = RequestModuleInterface(); m_groupsModule = RequestModuleInterface(); } @@ -2275,8 +2275,8 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (m_teleportModule != null) - m_teleportModule.Cross(grp, attemptedPosition, silent); + if (EntityTransferModule != null) + EntityTransferModule.Cross(grp, attemptedPosition, silent); } public Border GetCrossedBorder(Vector3 position, Cardinals gridline) @@ -3078,8 +3078,10 @@ namespace OpenSim.Region.Framework.Scenes /// The IClientAPI for the client public virtual void TeleportClientHome(UUID agentId, IClientAPI client) { - if (m_teleportModule != null) - m_teleportModule.TeleportHome(agentId, client); + if (EntityTransferModule != null) + { + EntityTransferModule.TeleportHome(agentId, client); + } else { m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); @@ -3638,7 +3640,6 @@ namespace OpenSim.Region.Framework.Scenes private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) { - bool banned = land.IsBannedFromLand(agent.AgentID); bool restricted = land.IsRestrictedFromLand(agent.AgentID); @@ -4131,8 +4132,10 @@ namespace OpenSim.Region.Framework.Scenes position.Y -= shifty; } - if (m_teleportModule != null) - m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + if (EntityTransferModule != null) + { + EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + } else { m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); @@ -4143,8 +4146,10 @@ namespace OpenSim.Region.Framework.Scenes public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) { - if (m_teleportModule != null) - return m_teleportModule.Cross(agent, isFlying); + if (EntityTransferModule != null) + { + return EntityTransferModule.Cross(agent, isFlying); + } else { m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); @@ -5188,14 +5193,34 @@ namespace OpenSim.Region.Framework.Scenes throw new Exception(error); } - // This method is called across the simulation connector to - // determine if a given agent is allowed in this region - // AS A ROOT AGENT. Returning false here will prevent them - // from logging into the region, teleporting into the region - // or corssing the broder walking, but will NOT prevent - // child agent creation, thereby emulating the SL behavior. + /// + /// This method is called across the simulation connector to + /// determine if a given agent is allowed in this region + /// AS A ROOT AGENT + /// + /// + /// Returning false here will prevent them + /// from logging into the region, teleporting into the region + /// or corssing the broder walking, but will NOT prevent + /// child agent creation, thereby emulating the SL behavior. + /// + /// + /// + /// + /// public bool QueryAccess(UUID agentID, Vector3 position, out string reason) { + if (EntityTransferModule.IsInTransit(agentID)) + { + reason = "Agent is already in transit on this region"; + + m_log.DebugFormat( + "[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit", + agentID, RegionInfo.RegionName); + + return false; + } + // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. // However, the long term fix is to make sure root agent count is always accurate. m_sceneGraph.RecalculateStats(); -- cgit v1.1