diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/InstantMessage')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs | 257 |
1 files changed, 246 insertions, 11 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs index d9d2875..fdded90 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -27,7 +27,11 @@ | |||
27 | using System; | 27 | using System; |
28 | using System.Collections; | 28 | using System.Collections; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | ||
31 | using System.Net; | ||
32 | using System.Threading; | ||
30 | using libsecondlife; | 33 | using libsecondlife; |
34 | using log4net; | ||
31 | using Nini.Config; | 35 | using Nini.Config; |
32 | using Nwc.XmlRpc; | 36 | using Nwc.XmlRpc; |
33 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
@@ -38,11 +42,15 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
38 | { | 42 | { |
39 | public class InstantMessageModule : IRegionModule | 43 | public class InstantMessageModule : IRegionModule |
40 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
41 | private readonly List<Scene> m_scenes = new List<Scene>(); | 47 | private readonly List<Scene> m_scenes = new List<Scene>(); |
48 | private Dictionary<LLUUID, ulong> m_userRegionMap = new Dictionary<LLUUID, ulong>(); | ||
42 | 49 | ||
43 | #region IRegionModule Members | 50 | #region IRegionModule Members |
44 | 51 | ||
45 | private bool gridmode = false; | 52 | private bool gridmode = false; |
53 | |||
46 | 54 | ||
47 | public void Initialise(Scene scene, IConfigSource config) | 55 | public void Initialise(Scene scene, IConfigSource config) |
48 | { | 56 | { |
@@ -150,14 +158,19 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
150 | return; | 158 | return; |
151 | } | 159 | } |
152 | } | 160 | } |
161 | if (gridmode) | ||
162 | { | ||
163 | // Still here, try send via Grid | ||
164 | // TODO | ||
165 | if (client != null) | ||
166 | { | ||
167 | if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop) | ||
168 | client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); | ||
169 | } | ||
170 | } | ||
153 | } | 171 | } |
154 | 172 | ||
155 | if (gridmode) | 173 | |
156 | { | ||
157 | // Still here, try send via Grid | ||
158 | // TODO | ||
159 | |||
160 | } | ||
161 | } | 174 | } |
162 | 175 | ||
163 | // Trusty OSG1 called method. This method also gets called from the FriendsModule | 176 | // Trusty OSG1 called method. This method also gets called from the FriendsModule |
@@ -174,6 +187,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
174 | } | 187 | } |
175 | protected virtual XmlRpcResponse processXMLRPCGridInstantMessage(XmlRpcRequest request) | 188 | protected virtual XmlRpcResponse processXMLRPCGridInstantMessage(XmlRpcRequest request) |
176 | { | 189 | { |
190 | bool successful = false; | ||
177 | // various rational defaults | 191 | // various rational defaults |
178 | LLUUID fromAgentID = LLUUID.Zero; | 192 | LLUUID fromAgentID = LLUUID.Zero; |
179 | LLUUID fromAgentSession = LLUUID.Zero; | 193 | LLUUID fromAgentSession = LLUUID.Zero; |
@@ -185,7 +199,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
185 | byte dialog = (byte)0; | 199 | byte dialog = (byte)0; |
186 | bool fromGroup = false; | 200 | bool fromGroup = false; |
187 | byte offline = (byte)0; | 201 | byte offline = (byte)0; |
188 | uint ParentEstateID; | 202 | uint ParentEstateID=0; |
189 | LLVector3 Position = LLVector3.Zero; | 203 | LLVector3 Position = LLVector3.Zero; |
190 | LLUUID RegionID = LLUUID.Zero ; | 204 | LLUUID RegionID = LLUUID.Zero ; |
191 | byte[] binaryBucket = new byte[0]; | 205 | byte[] binaryBucket = new byte[0]; |
@@ -303,12 +317,48 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
303 | 317 | ||
304 | Position = new LLVector3(pos_x, pos_y, pos_z); | 318 | Position = new LLVector3(pos_x, pos_y, pos_z); |
305 | binaryBucket = (byte[])requestData["binary_bucket"]; | 319 | binaryBucket = (byte[])requestData["binary_bucket"]; |
320 | GridInstantMessage gim = new GridInstantMessage(); | ||
321 | gim.fromAgentID = fromAgentID.UUID; | ||
322 | gim.fromAgentName = fromAgentName; | ||
323 | gim.fromAgentSession = fromAgentSession.UUID; | ||
324 | gim.fromGroup = fromGroup; | ||
325 | gim.imSessionID = imSessionID.UUID; | ||
326 | gim.RegionID = RegionID.UUID; | ||
327 | gim.timestamp = timestamp; | ||
328 | gim.toAgentID = toAgentID.UUID; | ||
329 | gim.message = message; | ||
330 | gim.dialog = dialog; | ||
331 | gim.offline = offline; | ||
332 | gim.ParentEstateID = ParentEstateID; | ||
333 | gim.Position = new sLLVector3(Position); | ||
334 | gim.binaryBucket = binaryBucket; | ||
335 | |||
336 | |||
337 | foreach (Scene scene in m_scenes) | ||
338 | { | ||
339 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) | ||
340 | { | ||
341 | // Local message | ||
342 | ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; | ||
343 | if (!user.IsChildAgent) | ||
344 | { | ||
345 | scene.EventManager.TriggerGridInstantMessage(gim, InstantMessageReceiver.FriendsModule | InstantMessageReceiver.GroupsModule | InstantMessageReceiver.IMModule); | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | OnGridInstantMessage(gim); | ||
350 | successful = true; | ||
306 | } | 351 | } |
307 | 352 | ||
308 | return new XmlRpcResponse(); | 353 | XmlRpcResponse resp = new XmlRpcResponse(); |
309 | //(string) | 354 | Hashtable respdata = new Hashtable(); |
310 | //(string)requestData["message"]; | 355 | if (successful) |
356 | respdata["success"] = "TRUE"; | ||
357 | else | ||
358 | respdata["success"] = "FALSE"; | ||
359 | resp.Value = respdata; | ||
311 | 360 | ||
361 | return resp; | ||
312 | } | 362 | } |
313 | 363 | ||
314 | protected virtual void SendGridInstantMessageViaXMLRPC(IClientAPI client, LLUUID fromAgentID, | 364 | protected virtual void SendGridInstantMessageViaXMLRPC(IClientAPI client, LLUUID fromAgentID, |
@@ -316,9 +366,194 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |||
316 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 366 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
317 | string message, byte dialog, bool fromGroup, byte offline, | 367 | string message, byte dialog, bool fromGroup, byte offline, |
318 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 368 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
319 | byte[] binaryBucket) | 369 | byte[] binaryBucket, ulong regionhandle, ulong prevRegionHandle) |
370 | { | ||
371 | UserAgentData upd = null; | ||
372 | |||
373 | bool lookupAgent = false; | ||
374 | |||
375 | lock (m_userRegionMap) | ||
376 | { | ||
377 | if (m_userRegionMap.ContainsKey(toAgentID) && prevRegionHandle == 0) | ||
378 | { | ||
379 | upd = new UserAgentData(); | ||
380 | upd.AgentOnline = true; | ||
381 | upd.Handle = m_userRegionMap[toAgentID]; | ||
382 | |||
383 | } | ||
384 | else | ||
385 | { | ||
386 | lookupAgent = true; | ||
387 | |||
388 | |||
389 | } | ||
390 | } | ||
391 | |||
392 | if (lookupAgent) | ||
393 | { | ||
394 | upd = m_scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID); | ||
395 | |||
396 | // check if we've tried this before.. | ||
397 | if (upd.Handle == prevRegionHandle) | ||
398 | { | ||
399 | m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); | ||
400 | if (client != null) | ||
401 | client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject,(uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); | ||
402 | return; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | if (upd != null) | ||
407 | { | ||
408 | if (upd.AgentOnline) | ||
409 | { | ||
410 | RegionInfo reginfo = m_scenes[0].CommsManager.GridService.RequestNeighbourInfo(upd.Handle); | ||
411 | if (reginfo != null) | ||
412 | { | ||
413 | GridInstantMessage msg = new GridInstantMessage(); | ||
414 | msg.fromAgentID = fromAgentID.UUID; | ||
415 | msg.fromAgentSession = fromAgentSession.UUID; | ||
416 | msg.toAgentID = toAgentID.UUID; | ||
417 | msg.imSessionID = imSessionID.UUID; | ||
418 | msg.timestamp = timestamp; | ||
419 | msg.fromAgentName = fromAgentName; | ||
420 | msg.message = message; | ||
421 | msg.dialog = dialog; | ||
422 | msg.fromGroup = fromGroup; | ||
423 | msg.offline = offline; | ||
424 | msg.ParentEstateID = ParentEstateID; | ||
425 | msg.Position = new sLLVector3(Position); | ||
426 | msg.RegionID = RegionID.UUID; | ||
427 | msg.binaryBucket = binaryBucket; | ||
428 | |||
429 | Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(msg); | ||
430 | msgdata["region_handle"] = getLocalRegionHandleFromUUID(RegionID); | ||
431 | bool imresult = doIMSending(reginfo, msgdata); | ||
432 | if (imresult) | ||
433 | { | ||
434 | lock (m_userRegionMap) | ||
435 | { | ||
436 | if (m_userRegionMap.ContainsKey(toAgentID)) | ||
437 | { | ||
438 | m_userRegionMap[toAgentID] = upd.Handle; | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | m_userRegionMap.Add(toAgentID, upd.Handle); | ||
443 | } | ||
444 | } | ||
445 | m_log.Info("[GRID INSTANT MESSAGE]: Successfully sent a message"); | ||
446 | } | ||
447 | else | ||
448 | { | ||
449 | // try again, but lookup user this time. | ||
450 | SendGridInstantMessageViaXMLRPC(client, fromAgentID, | ||
451 | fromAgentSession, toAgentID, | ||
452 | imSessionID, timestamp, fromAgentName, | ||
453 | message, dialog, fromGroup, offline, | ||
454 | ParentEstateID, Position, RegionID, | ||
455 | binaryBucket, regionhandle, upd.Handle); | ||
456 | } | ||
457 | |||
458 | } | ||
459 | } | ||
460 | else | ||
461 | { | ||
462 | // send Agent Offline message | ||
463 | if (client != null) | ||
464 | client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); | ||
465 | } | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | // send Agent Offline message | ||
470 | if (client != null) | ||
471 | client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); | ||
472 | } | ||
473 | |||
474 | } | ||
475 | |||
476 | private bool doIMSending(RegionInfo reginfo, Hashtable xmlrpcdata) | ||
477 | { | ||
478 | |||
479 | ArrayList SendParams = new ArrayList(); | ||
480 | SendParams.Add(xmlrpcdata); | ||
481 | XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); | ||
482 | try | ||
483 | { | ||
484 | |||
485 | XmlRpcResponse GridResp = GridReq.Send("http://" + reginfo.ExternalHostName + ":" + reginfo.HttpPort, 3000); | ||
486 | |||
487 | Hashtable responseData = (Hashtable)GridResp.Value; | ||
488 | |||
489 | if (responseData.ContainsKey("success")) | ||
490 | { | ||
491 | if ((string)responseData["success"] == "TRUE") | ||
492 | { | ||
493 | return true; | ||
494 | } | ||
495 | else | ||
496 | { | ||
497 | return false; | ||
498 | } | ||
499 | } | ||
500 | else | ||
501 | { | ||
502 | return false; | ||
503 | } | ||
504 | } | ||
505 | catch (WebException) | ||
506 | { | ||
507 | m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond", "http://" + reginfo.ExternalHostName + ":" + reginfo.HttpPort); | ||
508 | } | ||
509 | |||
510 | return false; | ||
511 | } | ||
512 | |||
513 | private ulong getLocalRegionHandleFromUUID(LLUUID regionID) | ||
320 | { | 514 | { |
515 | ulong returnhandle = 0; | ||
321 | 516 | ||
517 | lock (m_scenes) | ||
518 | { | ||
519 | foreach (Scene sn in m_scenes) | ||
520 | { | ||
521 | if (sn.RegionInfo.RegionID == regionID) | ||
522 | { | ||
523 | returnhandle = sn.RegionInfo.RegionHandle; | ||
524 | break; | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | return returnhandle; | ||
322 | } | 529 | } |
530 | |||
531 | private Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg) | ||
532 | { | ||
533 | Hashtable gim = new Hashtable(); | ||
534 | gim["from_agent_id"] = msg.fromAgentID.ToString(); | ||
535 | gim["from_agent_session"] = msg.fromAgentSession.ToString(); | ||
536 | gim["to_agent_id"] = msg.toAgentID.ToString(); | ||
537 | gim["im_session_id"] = msg.imSessionID.ToString(); | ||
538 | gim["timestamp"] = msg.timestamp.ToString(); | ||
539 | gim["from_agent_name"] = msg.fromAgentName; | ||
540 | gim["message"] = msg.message; | ||
541 | gim["dialog"] = msg.dialog; | ||
542 | |||
543 | if (msg.fromGroup) | ||
544 | gim["from_group"] = "TRUE"; | ||
545 | else | ||
546 | gim["from_group"] = "FALSE"; | ||
547 | |||
548 | gim["offline"] = msg.offline; | ||
549 | gim["parent_estate_id"] = msg.ParentEstateID.ToString(); | ||
550 | gim["position_x"] = msg.Position.x.ToString(); | ||
551 | gim["position_y"] = msg.Position.y.ToString(); | ||
552 | gim["position_z"] = msg.Position.z.ToString(); | ||
553 | gim["region_id"] = msg.RegionID.ToString(); | ||
554 | gim["binary_bucket"] = msg.binaryBucket; | ||
555 | return gim; | ||
556 | } | ||
557 | |||
323 | } | 558 | } |
324 | } \ No newline at end of file | 559 | } \ No newline at end of file |