diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 36e9da62d1..408d63da10 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,7 +46,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -65,9 +65,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool EnableWaitForCallbackFromTeleportDest { get; set; } protected bool m_Enabled = false; - protected Scene m_aScene; - protected List m_Scenes = new List(); + + protected Scene m_scene; + protected List m_agentsInTransit; + private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -129,10 +131,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_Enabled) return; - if (m_aScene == null) - m_aScene = scene; + m_scene = scene; - m_Scenes.Add(scene); scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; } @@ -143,27 +143,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } - public virtual void Close() - { - if (!m_Enabled) - return; - } + public virtual void Close() {} - public virtual void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - if (scene == m_aScene) - m_aScene = null; + public virtual void RemoveRegion(Scene scene) {} - m_Scenes.Remove(scene); - } - - public virtual void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - } + public virtual void RegionLoaded(Scene scene) {} #endregion @@ -294,7 +278,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { @@ -441,7 +425,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason; string version; - if (!m_aScene.SimulationService.QueryAccess( + if (!m_scene.SimulationService.QueryAccess( finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); @@ -660,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer EnableChildAgents(sp); // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); + m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } @@ -668,7 +652,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) { logout = false; - bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); if (success) sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); @@ -678,7 +662,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) { - return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); + return m_scene.SimulationService.UpdateAgent(finalDestination, agent); } protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) @@ -730,7 +714,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - #endregion #region Landmark Teleport @@ -742,7 +725,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) { - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); if (info == null) { @@ -763,12 +746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); - //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); - GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); + //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId); + GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); if (uinfo != null) { - GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); + GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { // can't find the Home region: Tell viewer and abort @@ -1625,7 +1608,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Arrived public void AgentArrivedAtDestination(UUID id) { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); ResetFromTransit(id); } @@ -1896,8 +1878,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //// And the new channel... //if (m_interregionCommsOut != null) // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); - if (m_aScene.SimulationService != null) - successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true); + if (m_scene.SimulationService != null) + successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true); if (successYN) { @@ -2004,7 +1986,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// true if the agent is in the process of being teleported, false otherwise. /// The agent ID - protected bool IsInTransit(UUID id) + public bool IsInTransit(UUID id) { lock (m_agentsInTransit) return m_agentsInTransit.Contains(id); @@ -2024,10 +2006,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_agentsInTransit.Contains(id)) { m_agentsInTransit.Remove(id); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}", + id, m_scene.RegionInfo.RegionName); + return true; } } + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.", + id, m_scene.RegionInfo.RegionName); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index b578bcb788..412466714c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -45,11 +45,11 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule + public class HGEntityTransferModule + : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Initialized = false; private int m_levelHGTeleport = 0; private GatekeeperServiceConnector m_GatekeeperConnector; @@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void Initialise(IConfigSource source) { IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) { string name = moduleConfig.GetString("EntityTransferModule", ""); @@ -82,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void AddRegion(Scene scene) { base.AddRegion(scene); + if (m_Enabled) - { scene.RegisterModuleInterface(this); - } } protected override void OnNewClient(IClientAPI client) @@ -98,24 +98,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); + if (m_Enabled) - if (!m_Initialized) - { - m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); - m_Initialized = true; - - } - + m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); } + public override void RemoveRegion(Scene scene) { base.AddRegion(scene); - if (m_Enabled) - { - scene.UnregisterModuleInterface(this); - } - } + if (m_Enabled) + scene.UnregisterModuleInterface(this); + } #endregion @@ -123,8 +117,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, region.RegionID); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); + if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); @@ -135,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); return real_destination; } + return region; } @@ -143,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) return true; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) return true; @@ -156,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (logout) { // Log them out of this grid - m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); + m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } } @@ -165,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); reason = string.Empty; logout = false; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid @@ -205,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); + IUserManagement uMan = m_scene.RequestModuleInterface(); if (uMan != null && uMan.IsLocalGridUser(id)) { // local grid user @@ -262,19 +258,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); + if (lm.Gatekeeper == string.Empty) { base.RequestTeleportLandmark(remoteClient, lm); return; } - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); // Local region? if (info != null) { ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; } else @@ -285,6 +283,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion gatekeeper = new GridRegion(); gatekeeper.ServerURI = lm.Gatekeeper; GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); + if (finalDestination != null) { ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); @@ -314,8 +313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IUserAgentService security = new UserAgentServiceConnector(url); return security.VerifyClient(aCircuit.SessionID, token); } - else - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); + else + { + m_log.DebugFormat( + "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", + aCircuit.firstname, aCircuit.lastname); + } return false; } @@ -332,8 +335,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); - UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); + IUserManagement uMan = m_scene.RequestModuleInterface(); + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user @@ -356,7 +359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - private GridRegion MakeRegion(AgentCircuitData aCircuit) { GridRegion region = new GridRegion(); @@ -373,6 +375,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); return region; } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 90f27c4806..026c6c884c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using log4net; using Nini.Config; @@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // Version of this service + + /// + /// Version of this service + /// private const string m_Version = "SIMULATION/0.1"; - private List m_sceneList = new List(); - - private IEntityTransferModule m_AgentTransferModule; - protected IEntityTransferModule AgentTransferModule - { - get - { - if (m_AgentTransferModule == null) - m_AgentTransferModule = m_sceneList[0].RequestModuleInterface(); - return m_AgentTransferModule; - } - } + /// + /// Map region ID to scene. + /// + private Dictionary m_scenes = new Dictionary(); + /// + /// Is this module enabled? + /// private bool m_ModuleEnabled = false; #region IRegionModule @@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void RemoveScene(Scene scene) { - lock (m_sceneList) + lock (m_scenes) { - if (m_sceneList.Contains(scene)) - { - m_sceneList.Remove(scene); - } + if (m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes.Remove(scene.RegionInfo.RegionID); + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present", + scene.RegionInfo.RegionName); } } @@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void Init(Scene scene) { - if (!m_sceneList.Contains(scene)) + lock (m_scenes) { - lock (m_sceneList) - { - m_sceneList.Add(scene); - } - + if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes[scene.RegionInfo.RegionID] = scene; + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present", + scene.RegionInfo.RegionName); } } @@ -158,15 +160,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region ISimulation - public IScene GetScene(ulong regionhandle) + public IScene GetScene(UUID regionId) { - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(regionId)) { - if (s.RegionInfo.RegionHandle == regionhandle) - return s; + return m_scenes[regionId]; + } + else + { + // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather + // than making it obvious and fixable. Need to see if the error message comes up in practice. + Scene s = m_scenes.Values.ToArray()[0]; + + m_log.ErrorFormat( + "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead", + regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID); + + return s; } - // ? weird. should not happen - return m_sceneList[0]; } public ISimulationService GetInnerService() @@ -187,13 +198,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); - return s.NewUserConnection(aCircuit, teleportFlags, out reason); - } + return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason); } reason = "Did not find region " + destination.RegionName; @@ -205,17 +213,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat( // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - s.IncomingChildAgentDataUpdate(cAgentData); - return true; - } + return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); } // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); @@ -231,11 +235,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // simulator so when we receive the update we need to hand it to each of the // scenes; scenes each check to see if the is a scene presence for the avatar // note that we really don't need the GridRegion for this call - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return true; } @@ -247,14 +252,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); - return s.IncomingRetrieveRootAgent(id, out agent); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return false; } @@ -266,27 +272,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - return s.QueryAccess(id, position, out reason); +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].QueryAccess(id, position, out reason); } + //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); return false; } - public bool ReleaseAgent(UUID origin, UUID id, string uri) + public bool ReleaseAgent(UUID originId, UUID agentId, string uri) { - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(originId)) { - if (s.RegionInfo.RegionID == origin) - { -// m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); - AgentTransferModule.AgentArrivedAtDestination(id); - return true; -// return s.IncomingReleaseAgent(id); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); return false; } @@ -296,17 +306,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); - // Let's spawn a threadlet right here, because this may take - // a while - Util.FireAndForget(delegate { s.IncomingCloseAgent(id); }); - return true; - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); return false; } @@ -320,25 +329,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Scene s = m_scenes[destination.RegionID]; + + if (isLocalCall) { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); - if (isLocalCall) - { - // We need to make a local copy of the object - ISceneObject sogClone = sog.CloneForNewScene(); - sogClone.SetState(sog.GetStateSnapshot(), s); - return s.IncomingCreateObject(newPosition, sogClone); - } - else - { - // Use the object as it came through the wire - return s.IncomingCreateObject(newPosition, sog); - } + // We need to make a local copy of the object + ISceneObject sogClone = sog.CloneForNewScene(); + sogClone.SetState(sog.GetStateSnapshot(), s); + return s.IncomingCreateObject(newPosition, sogClone); + } + else + { + // Use the object as it came through the wire + return s.IncomingCreateObject(newPosition, sog); } } + return false; } @@ -347,13 +359,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - return s.IncomingCreateObject(userID, itemID); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID); } + return false; } @@ -364,20 +378,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public bool IsLocalRegion(ulong regionhandle) { - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) if (s.RegionInfo.RegionHandle == regionhandle) return true; + return false; } public bool IsLocalRegion(UUID id) { - foreach (Scene s in m_sceneList) - if (s.RegionInfo.RegionID == id) - return true; - return false; + return m_scenes.ContainsKey(id); } #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index eaf9506332..3d2851806f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -151,9 +151,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region IInterregionComms - public IScene GetScene(ulong handle) + public IScene GetScene(UUID regionId) { - return m_localBackend.GetScene(handle); + return m_localBackend.GetScene(regionId); } public ISimulationService GetInnerService() diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 504f09ba5b..4edaaca594 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -428,9 +428,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver s = sw.ToString(); } - if (m_scene != null) - Console.WriteLine( - "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); +// if (m_scene != null) +// Console.WriteLine( +// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 18e9e3c021..75c44d5823 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -74,6 +74,13 @@ namespace OpenSim.Region.Framework.Interfaces /// void TeleportHome(UUID id, IClientAPI client); + /// + /// Show whether the given agent is being teleported. + /// + /// true if the agent is in the process of being teleported, false otherwise. + /// The agent ID + bool IsInTransit(UUID id); + bool Cross(ScenePresence agent, bool isFlying); void AgentArrivedAtDestination(UUID agent); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fbe56f6b36..755b1e6c1c 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(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 41bff7f92e..ccfe4ff218 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -110,12 +110,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -127,7 +128,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -174,12 +177,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -195,13 +200,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA ); + // We need to set up the permisions module on scene B so that our later use of agent limit to deny // QueryAccess won't succeed anyway because administrators are always allowed in and the default // IsAdministrator if no permissions module is present is true. - SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule() }); + SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB }); // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -249,12 +256,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -267,8 +275,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -312,12 +323,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -329,9 +341,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); - SceneHelpers.SetupSceneModules(sceneA, new CapabilitiesModule()); - SceneHelpers.SetupSceneModules(sceneB, new CapabilitiesModule()); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 5c9be8f0de..99ae7f0405 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -546,7 +546,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentData agent = new AgentData(); try { - agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionID)); } catch (Exception ex) { @@ -566,7 +566,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentPosition agent = new AgentPosition(); try { - agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionID)); } catch (Exception ex) { diff --git a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs index f0d8f69827..a4d03ba891 100644 --- a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs @@ -161,7 +161,7 @@ namespace OpenSim.Server.Handlers.Simulation if (args.ContainsKey("extra") && args["extra"] != null) extraStr = args["extra"].AsString(); - IScene s = m_SimulationService.GetScene(destination.RegionHandle); + IScene s = m_SimulationService.GetScene(destination.RegionID); ISceneObject sog = null; try { diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index cb003d1dd2..cc46ba88c1 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -62,7 +62,7 @@ namespace OpenSim.Services.Connectors.Simulation //m_Region = region; } - public IScene GetScene(ulong regionHandle) + public IScene GetScene(UUID regionId) { return null; } diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index 36fd6fcaa9..4e52532415 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -35,7 +35,17 @@ namespace OpenSim.Services.Interfaces { public interface ISimulationService { - IScene GetScene(ulong regionHandle); + /// + /// Retrieve the scene with the given region ID. + /// + /// + /// Region identifier. + /// + /// + /// The scene. + /// + IScene GetScene(UUID regionId); + ISimulationService GetInnerService(); #region Agents