diff options
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.
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | 212 |
1 files changed, 212 insertions, 0 deletions
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 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Net; | ||
4 | using System.Text; | ||
5 | using libsecondlife; | ||
6 | using OpenSim.Framework; | ||
7 | using OpenSim.Framework.Console; | ||
8 | using OpenSim.Framework.Communications; | ||
9 | |||
10 | |||
11 | namespace OpenSim.Region.Environment.Scenes | ||
12 | { | ||
13 | public class SceneCommunicationService //one instance per region | ||
14 | { | ||
15 | protected CommunicationsManager m_commsProvider; | ||
16 | protected RegionInfo m_regionInfo; | ||
17 | |||
18 | protected RegionCommsListener regionCommsHost; | ||
19 | |||
20 | public event AgentCrossing OnAvatarCrossingIntoRegion; | ||
21 | public event ExpectUserDelegate OnExpectUser; | ||
22 | |||
23 | |||
24 | public SceneCommunicationService(CommunicationsManager commsMan) | ||
25 | { | ||
26 | m_commsProvider = commsMan; | ||
27 | } | ||
28 | |||
29 | public void RegisterRegion(RegionInfo regionInfos) | ||
30 | { | ||
31 | m_regionInfo = regionInfos; | ||
32 | regionCommsHost = m_commsProvider.GridService.RegisterRegion(m_regionInfo); | ||
33 | if (regionCommsHost != null) | ||
34 | { | ||
35 | regionCommsHost.OnExpectUser += NewUserConnection; | ||
36 | regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | public void Close() | ||
41 | { | ||
42 | regionCommsHost.OnExpectUser -= NewUserConnection; | ||
43 | regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing; | ||
44 | //regionCommsHost.RemoveRegion(m_regionInfo); //TODO add to method to commsManager | ||
45 | regionCommsHost = null; | ||
46 | } | ||
47 | |||
48 | #region CommsManager Event handlers | ||
49 | /// <summary> | ||
50 | /// | ||
51 | /// </summary> | ||
52 | /// <param name="regionHandle"></param> | ||
53 | /// <param name="agent"></param> | ||
54 | public void NewUserConnection(ulong regionHandle, AgentCircuitData agent) | ||
55 | { | ||
56 | if (OnExpectUser != null) | ||
57 | { | ||
58 | OnExpectUser(regionHandle, agent); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | public void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) | ||
63 | { | ||
64 | if (OnAvatarCrossingIntoRegion != null) | ||
65 | { | ||
66 | OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); | ||
67 | } | ||
68 | } | ||
69 | #endregion | ||
70 | |||
71 | #region Inform Client of Neighbours | ||
72 | private delegate void InformClientOfNeighbourDelegate( | ||
73 | ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); | ||
74 | |||
75 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) | ||
76 | { | ||
77 | InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate)iar.AsyncState; | ||
78 | icon.EndInvoke(iar); | ||
79 | } | ||
80 | |||
81 | /// <summary> | ||
82 | /// Async compnent for informing client of which neighbours exists | ||
83 | /// </summary> | ||
84 | /// <remarks> | ||
85 | /// This needs to run asynchronesously, as a network timeout may block the thread for a long while | ||
86 | /// </remarks> | ||
87 | /// <param name="remoteClient"></param> | ||
88 | /// <param name="a"></param> | ||
89 | /// <param name="regionHandle"></param> | ||
90 | /// <param name="endPoint"></param> | ||
91 | private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, | ||
92 | IPEndPoint endPoint) | ||
93 | { | ||
94 | MainLog.Instance.Notice("INTERGRID", "Starting to inform client about neighbours"); | ||
95 | bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); | ||
96 | |||
97 | if (regionAccepted) | ||
98 | { | ||
99 | avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); | ||
100 | avatar.AddNeighbourRegion(regionHandle); | ||
101 | MainLog.Instance.Notice("INTERGRID", "Completed inform client about neighbours"); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /// <summary> | ||
106 | /// | ||
107 | /// </summary> | ||
108 | public void InformClientOfNeighbours(ScenePresence avatar) | ||
109 | { | ||
110 | List<SimpleRegionInfo> neighbours = | ||
111 | m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
112 | if (neighbours != null) | ||
113 | { | ||
114 | for (int i = 0; i < neighbours.Count; i++) | ||
115 | { | ||
116 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
117 | agent.BaseFolder = LLUUID.Zero; | ||
118 | agent.InventoryFolder = LLUUID.Zero; | ||
119 | agent.startpos = new LLVector3(128, 128, 70); | ||
120 | agent.child = true; | ||
121 | |||
122 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
123 | d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, | ||
124 | InformClientOfNeighbourCompleted, | ||
125 | d); | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | #endregion | ||
130 | |||
131 | /// <summary> | ||
132 | /// | ||
133 | /// </summary> | ||
134 | /// <param name="regionHandle"></param> | ||
135 | /// <returns></returns> | ||
136 | public virtual RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle) | ||
137 | { | ||
138 | return m_commsProvider.GridService.RequestNeighbourInfo(regionHandle); | ||
139 | } | ||
140 | |||
141 | /// <summary> | ||
142 | /// | ||
143 | /// </summary> | ||
144 | /// <param name="minX"></param> | ||
145 | /// <param name="minY"></param> | ||
146 | /// <param name="maxX"></param> | ||
147 | /// <param name="maxY"></param> | ||
148 | public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) | ||
149 | { | ||
150 | List<MapBlockData> mapBlocks; | ||
151 | mapBlocks = m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); | ||
152 | remoteClient.SendMapBlock(mapBlocks); | ||
153 | } | ||
154 | |||
155 | /// <summary> | ||
156 | /// | ||
157 | /// </summary> | ||
158 | /// <param name="remoteClient"></param> | ||
159 | /// <param name="RegionHandle"></param> | ||
160 | /// <param name="position"></param> | ||
161 | /// <param name="lookAt"></param> | ||
162 | /// <param name="flags"></param> | ||
163 | public virtual void RequestTeleportLocation(ScenePresence avatar, ulong regionHandle, LLVector3 position, | ||
164 | LLVector3 lookAt, uint flags) | ||
165 | { | ||
166 | if (regionHandle == m_regionInfo.RegionHandle) | ||
167 | { | ||
168 | |||
169 | avatar.ControllingClient.SendTeleportLocationStart(); | ||
170 | avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); | ||
171 | avatar.Teleport(position); | ||
172 | |||
173 | } | ||
174 | else | ||
175 | { | ||
176 | RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); | ||
177 | if (reg != null) | ||
178 | { | ||
179 | avatar.ControllingClient.SendTeleportLocationStart(); | ||
180 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
181 | agent.BaseFolder = LLUUID.Zero; | ||
182 | agent.InventoryFolder = LLUUID.Zero; | ||
183 | agent.startpos = position; | ||
184 | agent.child = true; | ||
185 | avatar.Close(); | ||
186 | m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent); | ||
187 | m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, position, false); | ||
188 | AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); | ||
189 | string capsPath = Util.GetCapsURL(avatar.ControllingClient.AgentId); | ||
190 | avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); | ||
191 | avatar.MakeChildAgent(); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | /// <summary> | ||
197 | /// | ||
198 | /// </summary> | ||
199 | /// <param name="regionhandle"></param> | ||
200 | /// <param name="agentID"></param> | ||
201 | /// <param name="position"></param> | ||
202 | public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position, bool isFlying) | ||
203 | { | ||
204 | return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); | ||
205 | } | ||
206 | |||
207 | public void CloseAgentConnection(ScenePresence presence) | ||
208 | { | ||
209 | throw new Exception("The method or operation is not implemented."); | ||
210 | } | ||
211 | } | ||
212 | } | ||