diff options
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | 534 |
1 files changed, 265 insertions, 269 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 91bbdb7..b44847b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | |||
@@ -43,13 +43,47 @@ namespace OpenSim.Region.Environment.Scenes | |||
43 | 43 | ||
44 | public class SceneCommunicationService //one instance per region | 44 | public class SceneCommunicationService //one instance per region |
45 | { | 45 | { |
46 | #region Delegates | ||
47 | |||
48 | public delegate void InformNeighbourThatRegionUpDelegate(RegionInfo region, ulong regionhandle); | ||
49 | |||
50 | public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); | ||
51 | |||
52 | public delegate void SendCloseChildAgentDelegate(LLUUID agentID, List<ulong> regionlst); | ||
53 | |||
54 | #endregion | ||
55 | |||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
57 | public string _debugRegionName = String.Empty; | ||
58 | private AgentCrossing handlerAvatarCrossingIntoRegion; // OnAvatarCrossingIntoRegion; | ||
59 | private ChildAgentUpdate handlerChildAgentUpdate; // OnChildAgentUpdate; | ||
60 | private CloseAgentConnection handlerCloseAgentConnection; // OnCloseAgentConnection; | ||
61 | private ExpectPrimDelegate handlerExpectPrim; // OnExpectPrim; | ||
62 | private ExpectUserDelegate handlerExpectUser; // OnExpectUser; | ||
63 | private PrimCrossing handlerPrimCrossingIntoRegion; // OnPrimCrossingIntoRegion; | ||
64 | private RegionUp handlerRegionUp; // OnRegionUp; | ||
65 | private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar; // OnRemoveKnownRegionFromAvatar; | ||
66 | |||
67 | public KillObjectDelegate KillObject; | ||
47 | 68 | ||
48 | protected CommunicationsManager m_commsProvider; | 69 | protected CommunicationsManager m_commsProvider; |
49 | protected RegionInfo m_regionInfo; | 70 | protected RegionInfo m_regionInfo; |
50 | 71 | ||
51 | protected RegionCommsListener regionCommsHost; | 72 | protected RegionCommsListener regionCommsHost; |
52 | 73 | ||
74 | public SceneCommunicationService(CommunicationsManager commsMan) | ||
75 | { | ||
76 | m_commsProvider = commsMan; | ||
77 | m_commsProvider.GridService.gdebugRegionName = _debugRegionName; | ||
78 | m_commsProvider.InterRegion.rdebugRegionName = _debugRegionName; | ||
79 | } | ||
80 | |||
81 | public string debugRegionName | ||
82 | { | ||
83 | get { return _debugRegionName; } | ||
84 | set { _debugRegionName = value; } | ||
85 | } | ||
86 | |||
53 | public event AgentCrossing OnAvatarCrossingIntoRegion; | 87 | public event AgentCrossing OnAvatarCrossingIntoRegion; |
54 | public event ExpectUserDelegate OnExpectUser; | 88 | public event ExpectUserDelegate OnExpectUser; |
55 | public event ExpectPrimDelegate OnExpectPrim; | 89 | public event ExpectPrimDelegate OnExpectPrim; |
@@ -59,31 +93,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
59 | public event ChildAgentUpdate OnChildAgentUpdate; | 93 | public event ChildAgentUpdate OnChildAgentUpdate; |
60 | public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; | 94 | public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; |
61 | 95 | ||
62 | private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; | ||
63 | private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; | ||
64 | private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim; | ||
65 | private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; | ||
66 | private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; | ||
67 | private RegionUp handlerRegionUp = null; // OnRegionUp; | ||
68 | private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; | ||
69 | private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar; | ||
70 | |||
71 | public KillObjectDelegate KillObject; | ||
72 | public string _debugRegionName = String.Empty; | ||
73 | |||
74 | public string debugRegionName | ||
75 | { | ||
76 | get { return _debugRegionName; } | ||
77 | set { _debugRegionName = value; } | ||
78 | } | ||
79 | |||
80 | public SceneCommunicationService(CommunicationsManager commsMan) | ||
81 | { | ||
82 | m_commsProvider = commsMan; | ||
83 | m_commsProvider.GridService.gdebugRegionName = _debugRegionName; | ||
84 | m_commsProvider.InterRegion.rdebugRegionName = _debugRegionName; | ||
85 | } | ||
86 | |||
87 | public void RegisterRegion(RegionInfo regionInfos) | 96 | public void RegisterRegion(RegionInfo regionInfos) |
88 | { | 97 | { |
89 | m_regionInfo = regionInfos; | 98 | m_regionInfo = regionInfos; |
@@ -99,7 +108,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
99 | regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; | 108 | regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; |
100 | regionCommsHost.OnCloseAgentConnection += CloseConnection; | 109 | regionCommsHost.OnCloseAgentConnection += CloseConnection; |
101 | regionCommsHost.OnRegionUp += newRegionUp; | 110 | regionCommsHost.OnRegionUp += newRegionUp; |
102 | regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate; | 111 | regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate; |
103 | } | 112 | } |
104 | else | 113 | else |
105 | { | 114 | { |
@@ -122,218 +131,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
122 | } | 131 | } |
123 | } | 132 | } |
124 | 133 | ||
125 | #region CommsManager Event handlers | ||
126 | |||
127 | /// <summary> | ||
128 | /// | ||
129 | /// </summary> | ||
130 | /// <param name="regionHandle"></param> | ||
131 | /// <param name="agent"></param> | ||
132 | /// | ||
133 | protected void NewUserConnection(ulong regionHandle, AgentCircuitData agent) | ||
134 | { | ||
135 | handlerExpectUser = OnExpectUser; | ||
136 | if (handlerExpectUser != null) | ||
137 | { | ||
138 | //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: OnExpectUser Fired for User:" + agent.firstname + " " + agent.lastname); | ||
139 | handlerExpectUser(regionHandle, agent); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | protected bool newRegionUp(RegionInfo region) | ||
144 | { | ||
145 | handlerRegionUp = OnRegionUp; | ||
146 | if (handlerRegionUp != null) | ||
147 | { | ||
148 | //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: newRegionUp Fired for User:" + region.RegionName); | ||
149 | handlerRegionUp(region); | ||
150 | } | ||
151 | return true; | ||
152 | } | ||
153 | |||
154 | protected bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) | ||
155 | { | ||
156 | handlerChildAgentUpdate = OnChildAgentUpdate; | ||
157 | if (handlerChildAgentUpdate != null) | ||
158 | handlerChildAgentUpdate(regionHandle, cAgentData); | ||
159 | |||
160 | |||
161 | return true; | ||
162 | } | ||
163 | |||
164 | protected void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) | ||
165 | { | ||
166 | handlerAvatarCrossingIntoRegion = OnAvatarCrossingIntoRegion; | ||
167 | if (handlerAvatarCrossingIntoRegion != null) | ||
168 | { | ||
169 | handlerAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | protected bool IncomingPrimCrossing(ulong regionHandle, LLUUID primID, String objXMLData, int XMLMethod) | ||
174 | { | ||
175 | handlerExpectPrim = OnExpectPrim; | ||
176 | if (handlerExpectPrim != null) | ||
177 | { | ||
178 | return handlerExpectPrim(regionHandle, primID, objXMLData, XMLMethod); | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | return false; | ||
183 | } | ||
184 | |||
185 | } | ||
186 | |||
187 | protected void PrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isPhysical) | ||
188 | { | ||
189 | handlerPrimCrossingIntoRegion = OnPrimCrossingIntoRegion; | ||
190 | if (handlerPrimCrossingIntoRegion != null) | ||
191 | { | ||
192 | handlerPrimCrossingIntoRegion(regionHandle, primID, position, isPhysical); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | protected bool CloseConnection(ulong regionHandle, LLUUID agentID) | ||
197 | { | ||
198 | m_log.Info("[INTERREGION]: Incoming Agent Close Request for agent: " + agentID.ToString()); | ||
199 | handlerCloseAgentConnection = OnCloseAgentConnection; | ||
200 | if (handlerCloseAgentConnection != null) | ||
201 | { | ||
202 | return handlerCloseAgentConnection(regionHandle, agentID); | ||
203 | } | ||
204 | return false; | ||
205 | } | ||
206 | |||
207 | #endregion | ||
208 | |||
209 | #region Inform Client of Neighbours | ||
210 | |||
211 | private delegate void InformClientOfNeighbourDelegate( | ||
212 | ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); | ||
213 | |||
214 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) | ||
215 | { | ||
216 | InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate) iar.AsyncState; | ||
217 | icon.EndInvoke(iar); | ||
218 | } | ||
219 | |||
220 | /// <summary> | ||
221 | /// Async compnent for informing client of which neighbours exists | ||
222 | /// </summary> | ||
223 | /// <remarks> | ||
224 | /// This needs to run asynchronesously, as a network timeout may block the thread for a long while | ||
225 | /// </remarks> | ||
226 | /// <param name="remoteClient"></param> | ||
227 | /// <param name="a"></param> | ||
228 | /// <param name="regionHandle"></param> | ||
229 | /// <param name="endPoint"></param> | ||
230 | private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, | ||
231 | IPEndPoint endPoint) | ||
232 | { | ||
233 | m_log.Info("[INTERGRID]: Starting to inform client about neighbours"); | ||
234 | bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); | ||
235 | |||
236 | if (regionAccepted) | ||
237 | { | ||
238 | avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); | ||
239 | avatar.AddNeighbourRegion(regionHandle); | ||
240 | m_log.Info("[INTERGRID]: Completed inform client about neighbours"); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | public void RequestNeighbors(RegionInfo region) | ||
245 | { | ||
246 | List<SimpleRegionInfo> neighbours = | ||
247 | m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
248 | //IPEndPoint blah = new IPEndPoint(); | ||
249 | |||
250 | //blah.Address = region.RemotingAddress; | ||
251 | //blah.Port = region.RemotingPort; | ||
252 | } | ||
253 | |||
254 | /// <summary> | ||
255 | /// This informs all neighboring regions about agent "avatar". | ||
256 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
257 | /// </summary> | ||
258 | public void EnableNeighbourChildAgents(ScenePresence avatar, List<RegionInfo> lstneighbours) | ||
259 | { | ||
260 | List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>(); | ||
261 | |||
262 | //m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
263 | for (int i = 0; i < lstneighbours.Count; i++) | ||
264 | { | ||
265 | // We don't want to keep sending to regions that consistently fail on comms. | ||
266 | if (!(lstneighbours[i].commFailTF)) | ||
267 | { | ||
268 | neighbours.Add(new SimpleRegionInfo(lstneighbours[i])); | ||
269 | } | ||
270 | } | ||
271 | // we're going to be using the above code once neighbour cache is correct. Currently it doesn't appear to be | ||
272 | // So we're temporarily going back to the old method of grabbing it from the Grid Server Every time :/ | ||
273 | neighbours = | ||
274 | m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
275 | |||
276 | if (neighbours != null) | ||
277 | { | ||
278 | for (int i = 0; i < neighbours.Count; i++) | ||
279 | { | ||
280 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
281 | agent.BaseFolder = LLUUID.Zero; | ||
282 | agent.InventoryFolder = LLUUID.Zero; | ||
283 | agent.startpos = new LLVector3(128, 128, 70); | ||
284 | agent.child = true; | ||
285 | |||
286 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
287 | |||
288 | try | ||
289 | { | ||
290 | d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, | ||
291 | InformClientOfNeighbourCompleted, | ||
292 | d); | ||
293 | } | ||
294 | catch (Exception e) | ||
295 | { | ||
296 | m_log.ErrorFormat( | ||
297 | "[REGIONINFO]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", | ||
298 | neighbours[i].ExternalHostName, | ||
299 | neighbours[i].RegionHandle, | ||
300 | neighbours[i].RegionLocX, | ||
301 | neighbours[i].RegionLocY, | ||
302 | e); | ||
303 | |||
304 | // FIXME: Okay, even though we've failed, we're still going to throw the exception on, | ||
305 | // since I don't know what will happen if we just let the client continue | ||
306 | |||
307 | // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. | ||
308 | // throw e; | ||
309 | |||
310 | } | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /// <summary> | ||
316 | /// This informs a single neighboring region about agent "avatar". | ||
317 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
318 | /// </summary> | ||
319 | public void InformNeighborChildAgent(ScenePresence avatar, RegionInfo region, List<RegionInfo> neighbours) | ||
320 | { | ||
321 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
322 | agent.BaseFolder = LLUUID.Zero; | ||
323 | agent.InventoryFolder = LLUUID.Zero; | ||
324 | agent.startpos = new LLVector3(128, 128, 70); | ||
325 | agent.child = true; | ||
326 | |||
327 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
328 | d.BeginInvoke(avatar, agent, region.RegionHandle, region.ExternalEndPoint, | ||
329 | InformClientOfNeighbourCompleted, | ||
330 | d); | ||
331 | } | ||
332 | |||
333 | #endregion | ||
334 | |||
335 | public delegate void InformNeighbourThatRegionUpDelegate(RegionInfo region, ulong regionhandle); | ||
336 | |||
337 | private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar) | 134 | private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar) |
338 | { | 135 | { |
339 | InformNeighbourThatRegionUpDelegate icon = (InformNeighbourThatRegionUpDelegate) iar.AsyncState; | 136 | InformNeighbourThatRegionUpDelegate icon = (InformNeighbourThatRegionUpDelegate) iar.AsyncState; |
@@ -390,8 +187,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
390 | //bool val = m_commsProvider.InterRegion.RegionUp(new SearializableRegionInfo(region)); | 187 | //bool val = m_commsProvider.InterRegion.RegionUp(new SearializableRegionInfo(region)); |
391 | } | 188 | } |
392 | 189 | ||
393 | public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); | ||
394 | |||
395 | /// <summary> | 190 | /// <summary> |
396 | /// This informs all neighboring regions about the settings of it's child agent. | 191 | /// This informs all neighboring regions about the settings of it's child agent. |
397 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 192 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
@@ -422,7 +217,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
422 | { | 217 | { |
423 | // We're ignoring a collection was modified error because this data gets old and outdated fast. | 218 | // We're ignoring a collection was modified error because this data gets old and outdated fast. |
424 | } | 219 | } |
425 | |||
426 | } | 220 | } |
427 | 221 | ||
428 | private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) | 222 | private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) |
@@ -435,20 +229,17 @@ namespace OpenSim.Region.Environment.Scenes | |||
435 | { | 229 | { |
436 | // This assumes that we know what our neighbors are. | 230 | // This assumes that we know what our neighbors are. |
437 | SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; | 231 | SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; |
438 | d.BeginInvoke(cAgentData,presence, | 232 | d.BeginInvoke(cAgentData, presence, |
439 | SendChildAgentDataUpdateCompleted, | 233 | SendChildAgentDataUpdateCompleted, |
440 | d); | 234 | d); |
441 | } | 235 | } |
442 | 236 | ||
443 | public delegate void SendCloseChildAgentDelegate( LLUUID agentID, List<ulong> regionlst); | ||
444 | |||
445 | /// <summary> | 237 | /// <summary> |
446 | /// This Closes child agents on neighboring regions | 238 | /// This Closes child agents on neighboring regions |
447 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 239 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
448 | /// </summary> | 240 | /// </summary> |
449 | private void SendCloseChildAgentAsync(LLUUID agentID, List<ulong> regionlst) | 241 | private void SendCloseChildAgentAsync(LLUUID agentID, List<ulong> regionlst) |
450 | { | 242 | { |
451 | |||
452 | foreach (ulong regionHandle in regionlst) | 243 | foreach (ulong regionHandle in regionlst) |
453 | { | 244 | { |
454 | bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | 245 | bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); |
@@ -456,14 +247,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
456 | if (regionAccepted) | 247 | if (regionAccepted) |
457 | { | 248 | { |
458 | m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor"); | 249 | m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor"); |
459 | |||
460 | } | 250 | } |
461 | else | 251 | else |
462 | { | 252 | { |
463 | m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor"); | 253 | m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor"); |
464 | |||
465 | } | 254 | } |
466 | |||
467 | } | 255 | } |
468 | // We remove the list of known regions from the agent's known region list through an event | 256 | // We remove the list of known regions from the agent's known region list through an event |
469 | // to scene, because, if an agent logged of, it's likely that there will be no scene presence | 257 | // to scene, because, if an agent logged of, it's likely that there will be no scene presence |
@@ -477,7 +265,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
477 | 265 | ||
478 | private void SendCloseChildAgentCompleted(IAsyncResult iar) | 266 | private void SendCloseChildAgentCompleted(IAsyncResult iar) |
479 | { | 267 | { |
480 | SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState; | 268 | SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate) iar.AsyncState; |
481 | icon.EndInvoke(iar); | 269 | icon.EndInvoke(iar); |
482 | } | 270 | } |
483 | 271 | ||
@@ -556,28 +344,28 @@ namespace OpenSim.Region.Environment.Scenes | |||
556 | // assume local regions are always up | 344 | // assume local regions are always up |
557 | destRegionUp = true; | 345 | destRegionUp = true; |
558 | } | 346 | } |
559 | if(destRegionUp) | 347 | if (destRegionUp) |
560 | { | 348 | { |
561 | avatar.Close(); | 349 | avatar.Close(); |
562 | 350 | ||
563 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | 351 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport |
564 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | 352 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail |
565 | // once we reach here... | 353 | // once we reach here... |
566 | avatar.Scene.RemoveCapsHandler(avatar.UUID); | 354 | avatar.Scene.RemoveCapsHandler(avatar.UUID); |
567 | 355 | ||
568 | m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent); | 356 | m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent); |
569 | m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, | 357 | m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, |
570 | position, false); | 358 | position, false); |
571 | AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); | 359 | AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); |
572 | 360 | ||
573 | // TODO Should construct this behind a method | 361 | // TODO Should construct this behind a method |
574 | string capsPath = | 362 | string capsPath = |
575 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | 363 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort |
576 | + "/CAPS/" + circuitdata.CapsPath + "0000/"; | 364 | + "/CAPS/" + circuitdata.CapsPath + "0000/"; |
577 | 365 | ||
578 | m_log.DebugFormat( | 366 | m_log.DebugFormat( |
579 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); | 367 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); |
580 | 368 | ||
581 | avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), | 369 | avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), |
582 | capsPath); | 370 | capsPath); |
583 | avatar.MakeChildAgent(); | 371 | avatar.MakeChildAgent(); |
@@ -587,13 +375,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
587 | { | 375 | { |
588 | KillObject(avatar.LocalId); | 376 | KillObject(avatar.LocalId); |
589 | } | 377 | } |
590 | uint newRegionX = (uint)(regionHandle >> 40); | 378 | uint newRegionX = (uint) (regionHandle >> 40); |
591 | uint newRegionY = (((uint)(regionHandle)) >> 8); | 379 | uint newRegionY = (((uint) (regionHandle)) >> 8); |
592 | uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); | 380 | uint oldRegionX = (uint) (m_regionInfo.RegionHandle >> 40); |
593 | uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); | 381 | uint oldRegionY = (((uint) (m_regionInfo.RegionHandle)) >> 8); |
594 | if (Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) | 382 | if (Util.fast_distance2d((int) (newRegionX - oldRegionX), (int) (newRegionY - oldRegionY)) > 3) |
595 | { | 383 | { |
596 | SendCloseChildAgentConnections(avatar.UUID,avatar.GetKnownRegionList()); | 384 | SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); |
597 | } | 385 | } |
598 | } | 386 | } |
599 | else | 387 | else |
@@ -628,7 +416,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
628 | 416 | ||
629 | public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz) | 417 | public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz) |
630 | { | 418 | { |
631 | m_commsProvider.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); | 419 | m_commsProvider.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); |
632 | } | 420 | } |
633 | 421 | ||
634 | public void ClearUserAgent(LLUUID avatarID) | 422 | public void ClearUserAgent(LLUUID avatarID) |
@@ -656,7 +444,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
656 | return m_commsProvider.GetUserFriendList(friendlistowner); | 444 | return m_commsProvider.GetUserFriendList(friendlistowner); |
657 | } | 445 | } |
658 | 446 | ||
659 | public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) | 447 | public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) |
660 | { | 448 | { |
661 | return m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); | 449 | return m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); |
662 | } | 450 | } |
@@ -665,5 +453,213 @@ namespace OpenSim.Region.Environment.Scenes | |||
665 | { | 453 | { |
666 | return m_commsProvider.GenerateAgentPickerRequestResponse(queryID, query); | 454 | return m_commsProvider.GenerateAgentPickerRequestResponse(queryID, query); |
667 | } | 455 | } |
456 | |||
457 | #region CommsManager Event handlers | ||
458 | |||
459 | /// <summary> | ||
460 | /// | ||
461 | /// </summary> | ||
462 | /// <param name="regionHandle"></param> | ||
463 | /// <param name="agent"></param> | ||
464 | /// | ||
465 | protected void NewUserConnection(ulong regionHandle, AgentCircuitData agent) | ||
466 | { | ||
467 | handlerExpectUser = OnExpectUser; | ||
468 | if (handlerExpectUser != null) | ||
469 | { | ||
470 | //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: OnExpectUser Fired for User:" + agent.firstname + " " + agent.lastname); | ||
471 | handlerExpectUser(regionHandle, agent); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | protected bool newRegionUp(RegionInfo region) | ||
476 | { | ||
477 | handlerRegionUp = OnRegionUp; | ||
478 | if (handlerRegionUp != null) | ||
479 | { | ||
480 | //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: newRegionUp Fired for User:" + region.RegionName); | ||
481 | handlerRegionUp(region); | ||
482 | } | ||
483 | return true; | ||
484 | } | ||
485 | |||
486 | protected bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) | ||
487 | { | ||
488 | handlerChildAgentUpdate = OnChildAgentUpdate; | ||
489 | if (handlerChildAgentUpdate != null) | ||
490 | handlerChildAgentUpdate(regionHandle, cAgentData); | ||
491 | |||
492 | |||
493 | return true; | ||
494 | } | ||
495 | |||
496 | protected void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) | ||
497 | { | ||
498 | handlerAvatarCrossingIntoRegion = OnAvatarCrossingIntoRegion; | ||
499 | if (handlerAvatarCrossingIntoRegion != null) | ||
500 | { | ||
501 | handlerAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | protected bool IncomingPrimCrossing(ulong regionHandle, LLUUID primID, String objXMLData, int XMLMethod) | ||
506 | { | ||
507 | handlerExpectPrim = OnExpectPrim; | ||
508 | if (handlerExpectPrim != null) | ||
509 | { | ||
510 | return handlerExpectPrim(regionHandle, primID, objXMLData, XMLMethod); | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | return false; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | protected void PrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isPhysical) | ||
519 | { | ||
520 | handlerPrimCrossingIntoRegion = OnPrimCrossingIntoRegion; | ||
521 | if (handlerPrimCrossingIntoRegion != null) | ||
522 | { | ||
523 | handlerPrimCrossingIntoRegion(regionHandle, primID, position, isPhysical); | ||
524 | } | ||
525 | } | ||
526 | |||
527 | protected bool CloseConnection(ulong regionHandle, LLUUID agentID) | ||
528 | { | ||
529 | m_log.Info("[INTERREGION]: Incoming Agent Close Request for agent: " + agentID); | ||
530 | handlerCloseAgentConnection = OnCloseAgentConnection; | ||
531 | if (handlerCloseAgentConnection != null) | ||
532 | { | ||
533 | return handlerCloseAgentConnection(regionHandle, agentID); | ||
534 | } | ||
535 | return false; | ||
536 | } | ||
537 | |||
538 | #endregion | ||
539 | |||
540 | #region Inform Client of Neighbours | ||
541 | |||
542 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) | ||
543 | { | ||
544 | InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate) iar.AsyncState; | ||
545 | icon.EndInvoke(iar); | ||
546 | } | ||
547 | |||
548 | /// <summary> | ||
549 | /// Async compnent for informing client of which neighbours exists | ||
550 | /// </summary> | ||
551 | /// <remarks> | ||
552 | /// This needs to run asynchronesously, as a network timeout may block the thread for a long while | ||
553 | /// </remarks> | ||
554 | /// <param name="remoteClient"></param> | ||
555 | /// <param name="a"></param> | ||
556 | /// <param name="regionHandle"></param> | ||
557 | /// <param name="endPoint"></param> | ||
558 | private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, | ||
559 | IPEndPoint endPoint) | ||
560 | { | ||
561 | m_log.Info("[INTERGRID]: Starting to inform client about neighbours"); | ||
562 | bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); | ||
563 | |||
564 | if (regionAccepted) | ||
565 | { | ||
566 | avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); | ||
567 | avatar.AddNeighbourRegion(regionHandle); | ||
568 | m_log.Info("[INTERGRID]: Completed inform client about neighbours"); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | public void RequestNeighbors(RegionInfo region) | ||
573 | { | ||
574 | List<SimpleRegionInfo> neighbours = | ||
575 | m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
576 | //IPEndPoint blah = new IPEndPoint(); | ||
577 | |||
578 | //blah.Address = region.RemotingAddress; | ||
579 | //blah.Port = region.RemotingPort; | ||
580 | } | ||
581 | |||
582 | /// <summary> | ||
583 | /// This informs all neighboring regions about agent "avatar". | ||
584 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
585 | /// </summary> | ||
586 | public void EnableNeighbourChildAgents(ScenePresence avatar, List<RegionInfo> lstneighbours) | ||
587 | { | ||
588 | List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>(); | ||
589 | |||
590 | //m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
591 | for (int i = 0; i < lstneighbours.Count; i++) | ||
592 | { | ||
593 | // We don't want to keep sending to regions that consistently fail on comms. | ||
594 | if (!(lstneighbours[i].commFailTF)) | ||
595 | { | ||
596 | neighbours.Add(new SimpleRegionInfo(lstneighbours[i])); | ||
597 | } | ||
598 | } | ||
599 | // we're going to be using the above code once neighbour cache is correct. Currently it doesn't appear to be | ||
600 | // So we're temporarily going back to the old method of grabbing it from the Grid Server Every time :/ | ||
601 | neighbours = | ||
602 | m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | ||
603 | |||
604 | if (neighbours != null) | ||
605 | { | ||
606 | for (int i = 0; i < neighbours.Count; i++) | ||
607 | { | ||
608 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
609 | agent.BaseFolder = LLUUID.Zero; | ||
610 | agent.InventoryFolder = LLUUID.Zero; | ||
611 | agent.startpos = new LLVector3(128, 128, 70); | ||
612 | agent.child = true; | ||
613 | |||
614 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
615 | |||
616 | try | ||
617 | { | ||
618 | d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, | ||
619 | InformClientOfNeighbourCompleted, | ||
620 | d); | ||
621 | } | ||
622 | catch (Exception e) | ||
623 | { | ||
624 | m_log.ErrorFormat( | ||
625 | "[REGIONINFO]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", | ||
626 | neighbours[i].ExternalHostName, | ||
627 | neighbours[i].RegionHandle, | ||
628 | neighbours[i].RegionLocX, | ||
629 | neighbours[i].RegionLocY, | ||
630 | e); | ||
631 | |||
632 | // FIXME: Okay, even though we've failed, we're still going to throw the exception on, | ||
633 | // since I don't know what will happen if we just let the client continue | ||
634 | |||
635 | // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. | ||
636 | // throw e; | ||
637 | } | ||
638 | } | ||
639 | } | ||
640 | } | ||
641 | |||
642 | /// <summary> | ||
643 | /// This informs a single neighboring region about agent "avatar". | ||
644 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
645 | /// </summary> | ||
646 | public void InformNeighborChildAgent(ScenePresence avatar, RegionInfo region, List<RegionInfo> neighbours) | ||
647 | { | ||
648 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | ||
649 | agent.BaseFolder = LLUUID.Zero; | ||
650 | agent.InventoryFolder = LLUUID.Zero; | ||
651 | agent.startpos = new LLVector3(128, 128, 70); | ||
652 | agent.child = true; | ||
653 | |||
654 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
655 | d.BeginInvoke(avatar, agent, region.RegionHandle, region.ExternalEndPoint, | ||
656 | InformClientOfNeighbourCompleted, | ||
657 | d); | ||
658 | } | ||
659 | |||
660 | private delegate void InformClientOfNeighbourDelegate( | ||
661 | ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); | ||
662 | |||
663 | #endregion | ||
668 | } | 664 | } |
669 | } | 665 | } \ No newline at end of file |