diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index baf24f00dd..dd7c16874d 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -175,6 +175,7 @@ namespace OpenSim.Framework.Communications public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz) { m_userService.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); + } /// diff --git a/OpenSim/Framework/Communications/IInterRegionCommunications.cs b/OpenSim/Framework/Communications/IInterRegionCommunications.cs index 13ae21fbd6..e93719ed09 100644 --- a/OpenSim/Framework/Communications/IInterRegionCommunications.cs +++ b/OpenSim/Framework/Communications/IInterRegionCommunications.cs @@ -45,6 +45,6 @@ namespace OpenSim.Framework.Communications bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId); bool AcknowledgePrimCrossed(ulong regionHandle, LLUUID primID); - void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID); + bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID); } } \ No newline at end of file diff --git a/OpenSim/Framework/IRegionCommsListener.cs b/OpenSim/Framework/IRegionCommsListener.cs index 19608c8c05..c8fc9c555f 100644 --- a/OpenSim/Framework/IRegionCommsListener.cs +++ b/OpenSim/Framework/IRegionCommsListener.cs @@ -44,12 +44,14 @@ namespace OpenSim.Framework public delegate void AcknowledgePrimCross(ulong regionHandle, LLUUID PrimID); - public delegate void CloseAgentConnection(ulong regionHandle, LLUUID agentID); + public delegate bool CloseAgentConnection(ulong regionHandle, LLUUID agentID); public delegate bool RegionUp(RegionInfo region); public delegate bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData); + + public interface IRegionCommsListener { @@ -64,5 +66,6 @@ namespace OpenSim.Framework event CloseAgentConnection OnCloseAgentConnection; event RegionUp OnRegionUp; event ChildAgentUpdate OnChildAgentUpdate; + } } \ No newline at end of file diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs index 1db5aaebd6..c12c3dfd9c 100644 --- a/OpenSim/Framework/RegionCommsListener.cs +++ b/OpenSim/Framework/RegionCommsListener.cs @@ -45,6 +45,7 @@ namespace OpenSim.Framework public event CloseAgentConnection OnCloseAgentConnection; public event RegionUp OnRegionUp; public event ChildAgentUpdate OnChildAgentUpdate; + public string debugRegionName = String.Empty; @@ -139,12 +140,15 @@ namespace OpenSim.Framework return false; } - public virtual void TriggerCloseAgentConnection(ulong regionHandle, LLUUID agentID) + public virtual bool TriggerCloseAgentConnection(ulong regionHandle, LLUUID agentID) { if (OnCloseAgentConnection != null) { OnCloseAgentConnection(regionHandle, agentID); + return true; + } + return false; } /// @@ -179,5 +183,13 @@ namespace OpenSim.Framework return false; } + + public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + if (OnCloseAgentConnection != null) + return OnCloseAgentConnection(regionHandle, agentID); + + return false; + } } } \ No newline at end of file diff --git a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs index 5b16e5afe8..25452c13ac 100644 --- a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs +++ b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs @@ -203,7 +203,14 @@ namespace OpenSim.Region.Communications.Local } return mapBlocks; } - + public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + if (m_regionListeners.ContainsKey(regionHandle)) + { + return m_regionListeners[regionHandle].TriggerTellRegionToCloseChildConnection(regionHandle, agentID); + } + return false; + } public virtual bool RegionUp(SearializableRegionInfo sregion, ulong regionhandle) { @@ -267,6 +274,14 @@ namespace OpenSim.Region.Communications.Local return false; } + public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + if (m_regionListeners.ContainsKey(regionHandle)) + { + return m_regionListeners[regionHandle].TriggerTellRegionToCloseChildConnection(regionHandle, agentID); + } + return false; + } /// /// /// @@ -328,13 +343,7 @@ namespace OpenSim.Region.Communications.Local return false; } - public void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) - { - if (m_regionListeners.ContainsKey(regionHandle)) - { - m_regionListeners[regionHandle].TriggerCloseAgentConnection(regionHandle, agentID); - } - } + public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId) { diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs index 2ca9022c7b..683fbfb8c8 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -491,7 +491,8 @@ namespace OpenSim.Region.Communications.OGS1 InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing; InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp; InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate; - //InterRegionSingleton.Instance.OnRegionUp += RegionUp; + InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection; + } #region Methods called by regions in this instance @@ -959,8 +960,53 @@ namespace OpenSim.Region.Communications.OGS1 } } - public void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) { + RegionInfo regInfo = null; + try + { + if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID)) + { + return true; + } + + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + bool retValue = false; + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + if (remObject != null) + { + retValue = + remObject.TellRegionToCloseChildConnection(regionHandle, agentID.UUID); + } + else + { + Console.WriteLine("remoting object not found"); + } + remObject = null; + + return true; + } + //TODO need to see if we know about where this region is and use .net remoting + // to inform it. + return false; + } + catch (RemotingException e) + { + MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName + + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + //MainLog.Instance.Debug(e.ToString()); + return false; + } + catch + { + return false; + } } public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId) @@ -1086,6 +1132,20 @@ namespace OpenSim.Region.Communications.OGS1 } } + public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + try + { + return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID); + } + catch (RemotingException) + { + MainLog.Instance.Verbose("INTERREGION", "Remoting Error: Unable to connect to neighbour to tell it to close a child connection"); + return false; + } + + } + #endregion #endregion diff --git a/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs index a0da07e71c..b39e0b7f30 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs @@ -45,6 +45,8 @@ namespace OpenSim.Region.Communications.OGS1 public delegate bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate childUpdate); + public delegate bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID); + public sealed class InterRegionSingleton { private static readonly InterRegionSingleton instance = new InterRegionSingleton(); @@ -55,6 +57,8 @@ namespace OpenSim.Region.Communications.OGS1 public event PrimGroupArrival OnPrimGroupArrival; public event RegionUp OnRegionUp; public event ChildAgentUpdate OnChildAgentUpdate; + public event TellRegionToCloseChildConnection OnTellRegionToCloseChildConnection; + static InterRegionSingleton() @@ -123,6 +127,16 @@ namespace OpenSim.Region.Communications.OGS1 } return false; } + + public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + if (OnTellRegionToCloseChildConnection != null) + { + + return OnTellRegionToCloseChildConnection(regionHandle, agentID); + } + return false; + } } public class OGS1InterRegionRemoting : MarshalByRefObject @@ -171,6 +185,7 @@ namespace OpenSim.Region.Communications.OGS1 } } + public bool ExpectAvatarCrossing(ulong regionHandle, Guid agentID, sLLVector3 position, bool isFlying) { try @@ -215,5 +230,18 @@ namespace OpenSim.Region.Communications.OGS1 return false; } } + public bool TellRegionToCloseChildConnection(ulong regionHandle, Guid agentID) + { + try + { + return InterRegionSingleton.Instance.TellRegionToCloseChildConnection(regionHandle, new LLUUID(agentID)); + + } + catch (RemotingException) + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("INTERREGION", "Remoting Error: Unable to connect to remote region: " + regionHandle.ToString()); + return false; + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 2f961c1488..7175d838b7 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1288,6 +1288,7 @@ namespace OpenSim.Region.Environment.Scenes CommsManager.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); + m_sceneGridService.SendCloseChildAgentConnections(avatar); } } catch (NullReferenceException) @@ -1389,6 +1390,7 @@ namespace OpenSim.Region.Environment.Scenes m_sceneGridService.OnCloseAgentConnection += CloseConnection; m_sceneGridService.OnRegionUp += OtherRegionUp; m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; + m_sceneGridService.KillObject = SendKillObject; @@ -1509,7 +1511,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - public void CloseConnection(ulong regionHandle, LLUUID agentID) + public bool CloseConnection(ulong regionHandle, LLUUID agentID) { if (regionHandle == m_regionHandle) { @@ -1527,8 +1529,10 @@ namespace OpenSim.Region.Environment.Scenes // Tell a single agent to disconnect from the region. libsecondlife.Packets.DisableSimulatorPacket disable = (libsecondlife.Packets.DisableSimulatorPacket) PacketPool.Instance.GetPacket(libsecondlife.Packets.PacketType.DisableSimulator); presence.ControllingClient.OutPacket(disable, ThrottleOutPacketType.Task); + presence.ControllingClient.Close(true); } } + return true; } /// diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 666edb18c3..a9c2c2f782 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -51,6 +51,7 @@ namespace OpenSim.Region.Environment.Scenes public event PrimCrossing OnPrimCrossingIntoRegion; public event RegionUp OnRegionUp; public event ChildAgentUpdate OnChildAgentUpdate; + public KillObjectDelegate KillObject; @@ -86,6 +87,7 @@ namespace OpenSim.Region.Environment.Scenes regionCommsHost.OnCloseAgentConnection += CloseConnection; regionCommsHost.OnRegionUp += newRegionUp; regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate; + } else { @@ -160,12 +162,15 @@ namespace OpenSim.Region.Environment.Scenes } } - protected void CloseConnection(ulong regionHandle, LLUUID agentID) + protected bool CloseConnection(ulong regionHandle, LLUUID agentID) { + MainLog.Instance.Verbose("INTERREGION", "Incoming Agent Close Request for agent: " + agentID.ToString()); + if (OnCloseAgentConnection != null) { - OnCloseAgentConnection(regionHandle, agentID); + return OnCloseAgentConnection(regionHandle, agentID); } + return false; } #endregion @@ -366,6 +371,50 @@ namespace OpenSim.Region.Environment.Scenes d); } + public delegate void SendCloseChildAgentDelegate( ScenePresence presence); + + /// + /// This informs all neighboring regions about the settings of it's child agent. + /// Calls an asynchronous method to do so.. so it doesn't lag the sim. + /// + /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. + /// + /// + private void SendCloseChildAgentAsync(ScenePresence presence) + { + + foreach (ulong regionHandle in presence.KnownChildRegions) + { + bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, presence.ControllingClient.AgentId); + + if (regionAccepted) + { + MainLog.Instance.Notice("INTERGRID", "Completed sending agent Close agent Request to neighbor"); + presence.RemoveNeighbourRegion(regionHandle); + } + else + { + MainLog.Instance.Notice("INTERGRID", "Failed sending agent Close agent Request to neighbor"); + + } + + } + } + + private void SendCloseChildAgentCompleted(IAsyncResult iar) + { + SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState; + icon.EndInvoke(iar); + } + + public void SendCloseChildAgentConnections(ScenePresence presence) + { + // This assumes that we know what our neighbors are. + SendCloseChildAgentDelegate d = SendCloseChildAgentAsync; + d.BeginInvoke(presence, + SendCloseChildAgentCompleted, + d); + } /// /// Helper function to request neighbors from grid-comms @@ -454,7 +503,7 @@ namespace OpenSim.Region.Environment.Scenes uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); if (Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) { - CloseChildAgentConnections(avatar); + SendCloseChildAgentConnections(avatar); } } else @@ -481,15 +530,6 @@ namespace OpenSim.Region.Environment.Scenes return m_commsProvider.InterRegion.ExpectPrimCrossing(regionhandle, primID, position, isPhysical); } - public void CloseChildAgentConnections(ScenePresence presence) - { - foreach (ulong regionHandle in presence.KnownChildRegions) - { - m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, - presence.ControllingClient.AgentId); - presence.RemoveNeighbourRegion(regionHandle); - } - } public Dictionary GetGridSettings() {