aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs')
-rw-r--r--OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs509
1 files changed, 509 insertions, 0 deletions
diff --git a/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs b/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs
new file mode 100644
index 0000000..b98c614
--- /dev/null
+++ b/OpenSim/Grid/UserServer.Modules/MessageServersConnector.cs
@@ -0,0 +1,509 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using Nwc.XmlRpc;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers;
38
39namespace OpenSim.Grid.UserServer.Modules
40{
41 public enum NotificationRequest : int
42 {
43 Login = 0,
44 Logout = 1,
45 Shutdown = 2
46 }
47
48 public struct PresenceNotification
49 {
50 public NotificationRequest request;
51 public UUID agentID;
52 public UUID sessionID;
53 public UUID RegionID;
54 public ulong regionhandle;
55 public float positionX;
56 public float positionY;
57 public float positionZ;
58 public string firstname;
59 public string lastname;
60 }
61
62 public delegate void AgentLocationDelegate(UUID agentID, UUID regionID, ulong regionHandle);
63 public delegate void AgentLeavingDelegate(UUID agentID, UUID regionID, ulong regionHandle);
64 public delegate void RegionStartupDelegate(UUID regionID);
65 public delegate void RegionShutdownDelegate(UUID regionID);
66
67
68 public class MessageServersConnector
69 {
70 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
71
72 public Dictionary<string, MessageServerInfo> MessageServers;
73
74 private BaseHttpServer m_httpServer;
75
76 private BlockingQueue<PresenceNotification> m_NotifyQueue =
77 new BlockingQueue<PresenceNotification>();
78
79 Thread m_NotifyThread;
80
81 public event AgentLocationDelegate OnAgentLocation;
82 public event AgentLeavingDelegate OnAgentLeaving;
83 public event RegionStartupDelegate OnRegionStartup;
84 public event RegionShutdownDelegate OnRegionShutdown;
85
86 public MessageServersConnector()
87 {
88 MessageServers = new Dictionary<string, MessageServerInfo>();
89 m_NotifyThread = new Thread(new ThreadStart(NotifyQueueRunner));
90 m_NotifyThread.Start();
91 }
92
93 public void Initialise()
94 {
95
96 }
97
98 public void PostInitialise()
99 {
100
101 }
102
103 public void RegisterHandlers(BaseHttpServer httpServer)
104 {
105 m_httpServer = httpServer;
106
107 m_httpServer.AddXmlRPCHandler("region_startup", RegionStartup);
108 m_httpServer.AddXmlRPCHandler("region_shutdown", RegionShutdown);
109 m_httpServer.AddXmlRPCHandler("agent_location", AgentLocation);
110 m_httpServer.AddXmlRPCHandler("agent_leaving", AgentLeaving);
111 // Message Server ---> User Server
112 m_httpServer.AddXmlRPCHandler("register_messageserver", XmlRPCRegisterMessageServer);
113 m_httpServer.AddXmlRPCHandler("agent_change_region", XmlRPCUserMovedtoRegion);
114 m_httpServer.AddXmlRPCHandler("deregister_messageserver", XmlRPCDeRegisterMessageServer);
115 }
116
117 public void RegisterMessageServer(string URI, MessageServerInfo serverData)
118 {
119 lock (MessageServers)
120 {
121 if (!MessageServers.ContainsKey(URI))
122 MessageServers.Add(URI, serverData);
123 }
124 }
125
126 public void DeRegisterMessageServer(string URI)
127 {
128 lock (MessageServers)
129 {
130 if (MessageServers.ContainsKey(URI))
131 MessageServers.Remove(URI);
132 }
133 }
134
135 public void AddResponsibleRegion(string URI, ulong regionhandle)
136 {
137 if (!MessageServers.ContainsKey(URI))
138 {
139 m_log.Warn("[MSGSERVER]: Got addResponsibleRegion Request for a MessageServer that isn't registered");
140 }
141 else
142 {
143 MessageServerInfo msginfo = MessageServers["URI"];
144 msginfo.responsibleForRegions.Add(regionhandle);
145 MessageServers["URI"] = msginfo;
146 }
147 }
148 public void RemoveResponsibleRegion(string URI, ulong regionhandle)
149 {
150 if (!MessageServers.ContainsKey(URI))
151 {
152 m_log.Warn("[MSGSERVER]: Got RemoveResponsibleRegion Request for a MessageServer that isn't registered");
153 }
154 else
155 {
156 MessageServerInfo msginfo = MessageServers["URI"];
157 if (msginfo.responsibleForRegions.Contains(regionhandle))
158 {
159 msginfo.responsibleForRegions.Remove(regionhandle);
160 MessageServers["URI"] = msginfo;
161 }
162 }
163
164 }
165 public XmlRpcResponse XmlRPCRegisterMessageServer(XmlRpcRequest request)
166 {
167 XmlRpcResponse response = new XmlRpcResponse();
168 Hashtable requestData = (Hashtable)request.Params[0];
169 Hashtable responseData = new Hashtable();
170
171 if (requestData.Contains("uri"))
172 {
173 string URI = (string)requestData["uri"];
174 string sendkey=(string)requestData["sendkey"];
175 string recvkey=(string)requestData["recvkey"];
176 MessageServerInfo m = new MessageServerInfo();
177 m.URI = URI;
178 m.sendkey = sendkey;
179 m.recvkey = recvkey;
180 RegisterMessageServer(URI, m);
181 responseData["responsestring"] = "TRUE";
182 response.Value = responseData;
183 }
184 return response;
185 }
186 public XmlRpcResponse XmlRPCDeRegisterMessageServer(XmlRpcRequest request)
187 {
188 XmlRpcResponse response = new XmlRpcResponse();
189 Hashtable requestData = (Hashtable)request.Params[0];
190 Hashtable responseData = new Hashtable();
191
192 if (requestData.Contains("uri"))
193 {
194 string URI = (string)requestData["uri"];
195
196 DeRegisterMessageServer(URI);
197 responseData["responsestring"] = "TRUE";
198 response.Value = responseData;
199 }
200 return response;
201 }
202 public XmlRpcResponse XmlRPCUserMovedtoRegion(XmlRpcRequest request)
203 {
204 XmlRpcResponse response = new XmlRpcResponse();
205 Hashtable requestData = (Hashtable)request.Params[0];
206 Hashtable responseData = new Hashtable();
207
208 if (requestData.Contains("fromuri"))
209 {
210 // string sURI = (string)requestData["fromuri"];
211 // string sagentID = (string)requestData["agentid"];
212 // string ssessionID = (string)requestData["sessionid"];
213 // string scurrentRegionID = (string)requestData["regionid"];
214 // string sregionhandle = (string)requestData["regionhandle"];
215 // string scurrentpos = (string)requestData["currentpos"];
216 //Vector3.TryParse((string)reader["currentPos"], out retval.currentPos);
217 // TODO: Okay now raise event so the user server can pass this data to the Usermanager
218
219 responseData["responsestring"] = "TRUE";
220 response.Value = responseData;
221 }
222 return response;
223 }
224
225 public void TellMessageServersAboutUser(UUID agentID, UUID sessionID, UUID RegionID,
226 ulong regionhandle, float positionX, float positionY,
227 float positionZ, string firstname, string lastname)
228 {
229 PresenceNotification notification = new PresenceNotification();
230
231 notification.request = NotificationRequest.Login;
232 notification.agentID = agentID;
233 notification.sessionID = sessionID;
234 notification.RegionID = RegionID;
235 notification.regionhandle = regionhandle;
236 notification.positionX = positionX;
237 notification.positionY = positionY;
238 notification.positionZ = positionZ;
239 notification.firstname = firstname;
240 notification.lastname = lastname;
241
242 m_NotifyQueue.Enqueue(notification);
243 }
244
245 private void TellMessageServersAboutUserInternal(UUID agentID, UUID sessionID, UUID RegionID,
246 ulong regionhandle, float positionX, float positionY,
247 float positionZ, string firstname, string lastname)
248 {
249 // Loop over registered Message Servers (AND THERE WILL BE MORE THEN ONE :D)
250 lock (MessageServers)
251 {
252 if (MessageServers.Count > 0)
253 {
254 m_log.Info("[MSGCONNECTOR]: Sending login notice to registered message servers");
255 }
256// else
257// {
258// m_log.Debug("[MSGCONNECTOR]: No Message Servers registered, ignoring");
259// }
260 foreach (MessageServerInfo serv in MessageServers.Values)
261 {
262 NotifyMessageServerAboutUser(serv, agentID, sessionID, RegionID,
263 regionhandle, positionX, positionY, positionZ,
264 firstname, lastname);
265 }
266 }
267 }
268
269 private void TellMessageServersAboutUserLogoffInternal(UUID agentID)
270 {
271 lock (MessageServers)
272 {
273 if (MessageServers.Count > 0)
274 {
275 m_log.Info("[MSGCONNECTOR]: Sending logoff notice to registered message servers");
276 }
277 else
278 {
279// m_log.Debug("[MSGCONNECTOR]: No Message Servers registered, ignoring");
280 }
281 foreach (MessageServerInfo serv in MessageServers.Values)
282 {
283 NotifyMessageServerAboutUserLogoff(serv,agentID);
284 }
285 }
286 }
287
288 private void TellMessageServersAboutRegionShutdownInternal(UUID regionID)
289 {
290 lock (MessageServers)
291 {
292 if (MessageServers.Count > 0)
293 {
294 m_log.Info("[MSGCONNECTOR]: Sending region down notice to registered message servers");
295 }
296 else
297 {
298// m_log.Debug("[MSGCONNECTOR]: No Message Servers registered, ignoring");
299 }
300 foreach (MessageServerInfo serv in MessageServers.Values)
301 {
302 NotifyMessageServerAboutRegionShutdown(serv,regionID);
303 }
304 }
305 }
306
307 public void TellMessageServersAboutUserLogoff(UUID agentID)
308 {
309 PresenceNotification notification = new PresenceNotification();
310
311 notification.request = NotificationRequest.Logout;
312 notification.agentID = agentID;
313
314 m_NotifyQueue.Enqueue(notification);
315 }
316
317 public void TellMessageServersAboutRegionShutdown(UUID regionID)
318 {
319 PresenceNotification notification = new PresenceNotification();
320
321 notification.request = NotificationRequest.Shutdown;
322 notification.RegionID = regionID;
323
324 m_NotifyQueue.Enqueue(notification);
325 }
326
327 private void NotifyMessageServerAboutUserLogoff(MessageServerInfo serv, UUID agentID)
328 {
329 Hashtable reqparams = new Hashtable();
330 reqparams["sendkey"] = serv.sendkey;
331 reqparams["agentid"] = agentID.ToString();
332 ArrayList SendParams = new ArrayList();
333 SendParams.Add(reqparams);
334
335 XmlRpcRequest GridReq = new XmlRpcRequest("logout_of_simulator", SendParams);
336 try
337 {
338 GridReq.Send(serv.URI, 6000);
339 }
340 catch (WebException)
341 {
342 m_log.Warn("[MSGCONNECTOR]: Unable to notify Message Server about log out. Other users might still think this user is online");
343 }
344 m_log.Info("[LOGOUT]: Notified : " + serv.URI + " about user logout");
345 }
346
347 private void NotifyMessageServerAboutRegionShutdown(MessageServerInfo serv, UUID regionID)
348 {
349 Hashtable reqparams = new Hashtable();
350 reqparams["sendkey"] = serv.sendkey;
351 reqparams["regionid"] = regionID.ToString();
352 ArrayList SendParams = new ArrayList();
353 SendParams.Add(reqparams);
354
355 XmlRpcRequest GridReq = new XmlRpcRequest("process_region_shutdown", SendParams);
356 try
357 {
358 GridReq.Send(serv.URI, 6000);
359 }
360 catch (WebException)
361 {
362 m_log.Warn("[MSGCONNECTOR]: Unable to notify Message Server about region shutdown.");
363 }
364 m_log.Info("[REGION UPDOWN]: Notified : " + serv.URI + " about region state change");
365 }
366
367 private void NotifyMessageServerAboutUser(MessageServerInfo serv,
368 UUID agentID, UUID sessionID, UUID RegionID,
369 ulong regionhandle, float positionX, float positionY, float positionZ,
370 string firstname, string lastname)
371 {
372 Hashtable reqparams = new Hashtable();
373 reqparams["sendkey"] = serv.sendkey;
374 reqparams["agentid"] = agentID.ToString();
375 reqparams["sessionid"] = sessionID.ToString();
376 reqparams["regionid"] = RegionID.ToString();
377 reqparams["regionhandle"] = regionhandle.ToString();
378 reqparams["positionx"] = positionX.ToString();
379 reqparams["positiony"] = positionY.ToString();
380 reqparams["positionz"] = positionZ.ToString();
381 reqparams["firstname"] = firstname;
382 reqparams["lastname"] = lastname;
383
384 //reqparams["position"] = Position.ToString();
385
386 ArrayList SendParams = new ArrayList();
387 SendParams.Add(reqparams);
388
389 XmlRpcRequest GridReq = new XmlRpcRequest("login_to_simulator", SendParams);
390 try
391 {
392 GridReq.Send(serv.URI, 6000);
393 m_log.Info("[LOGIN]: Notified : " + serv.URI + " about user login");
394 }
395 catch (WebException)
396 {
397 m_log.Warn("[MSGCONNECTOR]: Unable to notify Message Server about login. Presence might be borked for this user");
398 }
399
400 }
401
402 private void NotifyQueueRunner()
403 {
404 while (true)
405 {
406 PresenceNotification presence = m_NotifyQueue.Dequeue();
407
408 if (presence.request == NotificationRequest.Shutdown)
409 {
410 TellMessageServersAboutRegionShutdownInternal(presence.RegionID);
411 }
412
413 if (presence.request == NotificationRequest.Login)
414 {
415 TellMessageServersAboutUserInternal(presence.agentID,
416 presence.sessionID, presence.RegionID,
417 presence.regionhandle, presence.positionX,
418 presence.positionY, presence.positionZ,
419 presence.firstname, presence.lastname);
420 }
421
422 if (presence.request == NotificationRequest.Logout)
423 {
424 TellMessageServersAboutUserLogoffInternal(presence.agentID);
425 }
426 }
427 }
428
429 public XmlRpcResponse RegionStartup(XmlRpcRequest request)
430 {
431 Hashtable requestData = (Hashtable)request.Params[0];
432 Hashtable result = new Hashtable();
433
434 UUID regionID;
435 if (UUID.TryParse((string)requestData["RegionUUID"], out regionID))
436 {
437 if (OnRegionStartup != null)
438 OnRegionStartup(regionID);
439
440 result["responsestring"] = "TRUE";
441 }
442
443 XmlRpcResponse response = new XmlRpcResponse();
444 response.Value = result;
445 return response;
446 }
447
448 public XmlRpcResponse RegionShutdown(XmlRpcRequest request)
449 {
450 Hashtable requestData = (Hashtable)request.Params[0];
451 Hashtable result = new Hashtable();
452
453 UUID regionID;
454 if (UUID.TryParse((string)requestData["RegionUUID"], out regionID))
455 {
456 if (OnRegionShutdown != null)
457 OnRegionShutdown(regionID);
458
459 result["responsestring"] = "TRUE";
460 }
461
462 XmlRpcResponse response = new XmlRpcResponse();
463 response.Value = result;
464 return response;
465 }
466
467 public XmlRpcResponse AgentLocation(XmlRpcRequest request)
468 {
469 Hashtable requestData = (Hashtable)request.Params[0];
470 Hashtable result = new Hashtable();
471
472 UUID agentID;
473 UUID regionID;
474 ulong regionHandle;
475 if (UUID.TryParse((string)requestData["AgentID"], out agentID) && UUID.TryParse((string)requestData["RegionUUID"], out regionID) && ulong.TryParse((string)requestData["RegionHandle"], out regionHandle))
476 {
477 if (OnAgentLocation != null)
478 OnAgentLocation(agentID, regionID, regionHandle);
479
480 result["responsestring"] = "TRUE";
481 }
482
483 XmlRpcResponse response = new XmlRpcResponse();
484 response.Value = result;
485 return response;
486 }
487
488 public XmlRpcResponse AgentLeaving(XmlRpcRequest request)
489 {
490 Hashtable requestData = (Hashtable)request.Params[0];
491 Hashtable result = new Hashtable();
492
493 UUID agentID;
494 UUID regionID;
495 ulong regionHandle;
496 if (UUID.TryParse((string)requestData["AgentID"], out agentID) && UUID.TryParse((string)requestData["RegionUUID"], out regionID) && ulong.TryParse((string)requestData["RegionHandle"], out regionHandle))
497 {
498 if (OnAgentLeaving != null)
499 OnAgentLeaving(agentID, regionID, regionHandle);
500
501 result["responsestring"] = "TRUE";
502 }
503
504 XmlRpcResponse response = new XmlRpcResponse();
505 response.Value = result;
506 return response;
507 }
508 }
509}