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