From dabbdec2cdf2c1056e4ebb8aec38302a1fa9eba4 Mon Sep 17 00:00:00 2001 From: MW Date: Sat, 3 Nov 2007 19:14:22 +0000 Subject: First part of Scene refactoring: Started the move of some of the methods from scene into a inner class (currently called InnerScene.cs), the idea being that the code related to the 3d scene (primitive/entities/Avatars etc) will be in this inner class, then what is now Scene.cs will be left as a kind of wrapper class around it. And once the spilt is complete can be renamed to something like RegionInstance (or any name that sounds good and ids it as the Region layer class that "has" a scene). Added SceneCommunicationService which at the moment is a kind of high level wrapper around commsManager. The idea being that it has a higher level API for the Region/Scene to send messages to the other regions on the grid. a Example of the API is that instead of having sendXmessage methods, it has more functional level method like PassAvatarToNeighbour. Hopefully this will allow more freedom to do changes in communications that doesn't break other things. --- .../Scenes/SceneCommunicationService.cs | 212 +++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs (limited to 'OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs') diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs new file mode 100644 index 0000000..2ade989 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; + + +namespace OpenSim.Region.Environment.Scenes +{ + public class SceneCommunicationService //one instance per region + { + protected CommunicationsManager m_commsProvider; + protected RegionInfo m_regionInfo; + + protected RegionCommsListener regionCommsHost; + + public event AgentCrossing OnAvatarCrossingIntoRegion; + public event ExpectUserDelegate OnExpectUser; + + + public SceneCommunicationService(CommunicationsManager commsMan) + { + m_commsProvider = commsMan; + } + + public void RegisterRegion(RegionInfo regionInfos) + { + m_regionInfo = regionInfos; + regionCommsHost = m_commsProvider.GridService.RegisterRegion(m_regionInfo); + if (regionCommsHost != null) + { + regionCommsHost.OnExpectUser += NewUserConnection; + regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; + } + } + + public void Close() + { + regionCommsHost.OnExpectUser -= NewUserConnection; + regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing; + //regionCommsHost.RemoveRegion(m_regionInfo); //TODO add to method to commsManager + regionCommsHost = null; + } + + #region CommsManager Event handlers + /// + /// + /// + /// + /// + public void NewUserConnection(ulong regionHandle, AgentCircuitData agent) + { + if (OnExpectUser != null) + { + OnExpectUser(regionHandle, agent); + } + } + + public void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (OnAvatarCrossingIntoRegion != null) + { + OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); + } + } + #endregion + + #region Inform Client of Neighbours + private delegate void InformClientOfNeighbourDelegate( + ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); + + private void InformClientOfNeighbourCompleted(IAsyncResult iar) + { + InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate)iar.AsyncState; + icon.EndInvoke(iar); + } + + /// + /// Async compnent for informing client of which neighbours exists + /// + /// + /// This needs to run asynchronesously, as a network timeout may block the thread for a long while + /// + /// + /// + /// + /// + private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, + IPEndPoint endPoint) + { + MainLog.Instance.Notice("INTERGRID", "Starting to inform client about neighbours"); + bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); + + if (regionAccepted) + { + avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); + avatar.AddNeighbourRegion(regionHandle); + MainLog.Instance.Notice("INTERGRID", "Completed inform client about neighbours"); + } + } + + /// + /// + /// + public void InformClientOfNeighbours(ScenePresence avatar) + { + List neighbours = + m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); + if (neighbours != null) + { + for (int i = 0; i < neighbours.Count; i++) + { + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + agent.startpos = new LLVector3(128, 128, 70); + agent.child = true; + + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, + InformClientOfNeighbourCompleted, + d); + } + } + } + #endregion + + /// + /// + /// + /// + /// + public virtual RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle) + { + return m_commsProvider.GridService.RequestNeighbourInfo(regionHandle); + } + + /// + /// + /// + /// + /// + /// + /// + public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) + { + List mapBlocks; + mapBlocks = m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); + remoteClient.SendMapBlock(mapBlocks); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public virtual void RequestTeleportLocation(ScenePresence avatar, ulong regionHandle, LLVector3 position, + LLVector3 lookAt, uint flags) + { + if (regionHandle == m_regionInfo.RegionHandle) + { + + avatar.ControllingClient.SendTeleportLocationStart(); + avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); + avatar.Teleport(position); + + } + else + { + RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); + if (reg != null) + { + avatar.ControllingClient.SendTeleportLocationStart(); + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + agent.startpos = position; + agent.child = true; + avatar.Close(); + m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent); + m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, position, false); + AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); + string capsPath = Util.GetCapsURL(avatar.ControllingClient.AgentId); + avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); + avatar.MakeChildAgent(); + } + } + } + + /// + /// + /// + /// + /// + /// + public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); + } + + public void CloseAgentConnection(ScenePresence presence) + { + throw new Exception("The method or operation is not implemented."); + } + } +} -- cgit v1.1