aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs160
1 files changed, 92 insertions, 68 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 5573c94..3c82fd9 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
188 SendGridInstantMessageViaXMLRPC(im, result); 188 SendGridInstantMessageViaXMLRPC(im, result);
189 } 189 }
190 190
191 public void HandleUndeliverableMessage(GridInstantMessage im, MessageResultNotification result) 191 public virtual void HandleUndeliverableMessage(GridInstantMessage im, MessageResultNotification result)
192 { 192 {
193 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; 193 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
194 194
@@ -445,14 +445,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
445 return resp; 445 return resp;
446 } 446 }
447 447
448<<<<<<< HEAD 448
449 /// <summary> 449 /// <summary>
450 /// delegate for sending a grid instant message asynchronously 450 /// delegate for sending a grid instant message asynchronously
451 /// </summary> 451 /// </summary>
452 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
453=======
454 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 452 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
455>>>>>>> avn/ubitvar
456 453
457 private class GIM { 454 private class GIM {
458 public GridInstantMessage im; 455 public GridInstantMessage im;
@@ -479,31 +476,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
479 } 476 }
480 } 477 }
481 478
482<<<<<<< HEAD 479
483 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
484=======
485 private void GridInstantMessageCompleted(IAsyncResult iar) 480 private void GridInstantMessageCompleted(IAsyncResult iar)
486 { 481 {
487 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState; 482 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
488 d.EndInvoke(iar); 483 d.EndInvoke(iar);
489>>>>>>> avn/ubitvar
490 } 484 }
491 485
492 /// <summary> 486 /// <summary>
493 /// Internal SendGridInstantMessage over XMLRPC method. 487 /// Internal SendGridInstantMessage over XMLRPC method.
494 /// </summary> 488 /// </summary>
495<<<<<<< HEAD 489
496 /// <remarks>
497 /// This is called from within a dedicated thread.
498 /// </remarks>
499 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
500=======
501 /// <param name="prevRegionHandle"> 490 /// <param name="prevRegionHandle">
502 /// Pass in 0 the first time this method is called. It will be called recursively with the last 491 /// Pass in 0 the first time this method is called. It will be called recursively with the last
503 /// regionhandle tried 492 /// regionhandle tried
504 /// </param> 493 /// </param>
505 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result) 494 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
506>>>>>>> avn/ubitvar
507 { 495 {
508 GIM gim; 496 GIM gim;
509 do { 497 do {
@@ -525,87 +513,124 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
525 } 513 }
526 } while (gim != null); 514 } while (gim != null);
527 } 515 }
516
528 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 517 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
529 { 518 {
530 519
531 UUID toAgentID = new UUID(im.toAgentID); 520 UUID toAgentID = new UUID(im.toAgentID);
521 PresenceInfo upd = null;
532 UUID regionID; 522 UUID regionID;
533 bool needToLookupAgent; 523 bool lookupAgent = false;
534 524
535 lock (m_UserRegionMap) 525 lock (m_UserRegionMap)
536 needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);
537
538 while (true)
539 { 526 {
540 if (needToLookupAgent) 527 if (m_UserRegionMap.ContainsKey(toAgentID))
541 { 528 {
542 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 529 upd = new PresenceInfo();
530 upd.RegionID = m_UserRegionMap[toAgentID];
531
532 // We need to compare the current regionhandle with the previous region handle
533 // or the recursive loop will never end because it will never try to lookup the agent again
534 if (prevRegionID == upd.RegionID)
535 {
536 lookupAgent = true;
537 }
538 }
539 else
540 {
541 lookupAgent = true;
542 }
543 }
543 544
544 UUID foundRegionID = UUID.Zero;
545 545
546 if (presences != null) 546 // Are we needing to look-up an agent?
547 if (lookupAgent)
548 {
549 // Non-cached user agent lookup.
550 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
551 if (presences != null && presences.Length > 0)
552 {
553 foreach (PresenceInfo p in presences)
547 { 554 {
548 foreach (PresenceInfo p in presences) 555 if (p.RegionID != UUID.Zero)
549 { 556 {
550 if (p.RegionID != UUID.Zero) 557 upd = p;
551 { 558 break;
552 foundRegionID = p.RegionID;
553 break;
554 }
555 } 559 }
556 } 560 }
557
558 // If not found or the found region is the same as the last lookup, then message is undeliverable
559 if (foundRegionID == UUID.Zero || foundRegionID == regionID)
560 break;
561 else
562 regionID = foundRegionID;
563 } 561 }
564 562
565 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID); 563 if (upd != null)
566 if (reginfo == null)
567 { 564 {
568 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID); 565 // check if we've tried this before..
569 break; 566 // This is one way to end the recursive loop
567 //
568 if (upd.RegionID == prevRegionID)
569 {
570 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
571 HandleUndeliverableMessage(im, result);
572 return;
573 }
570 } 574 }
575 else
576 {
577 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
578 HandleUndeliverableMessage(im, result);
579 return;
580 }
581 }
571 582
572<<<<<<< HEAD
573 // Try to send the message to the agent via the retrieved region.
574 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
575 msgdata["region_handle"] = 0;
576 bool imresult = doIMSending(reginfo, msgdata);
577
578 // If the message delivery was successful, then cache the entry.
579 if (imresult)
580=======
581 if (upd != null) 583 if (upd != null)
582 { 584 {
583 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero, 585 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
584 upd.RegionID); 586 upd.RegionID);
585 if (reginfo != null) 587 if (reginfo != null)
586>>>>>>> avn/ubitvar
587 { 588 {
588 lock (m_UserRegionMap) 589 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
590 // Not actually used anymore, left in for compatibility
591 // Remove at next interface change
592 //
593 msgdata["region_handle"] = 0;
594 bool imresult = doIMSending(reginfo, msgdata);
595 if (imresult)
596 {
597 // IM delivery successful, so store the Agent's location in our local cache.
598 lock (m_UserRegionMap)
599 {
600 if (m_UserRegionMap.ContainsKey(toAgentID))
601 {
602 m_UserRegionMap[toAgentID] = upd.RegionID;
603 }
604 else
605 {
606 m_UserRegionMap.Add(toAgentID, upd.RegionID);
607 }
608 }
609 result(true);
610 }
611 else
589 { 612 {
590 m_UserRegionMap[toAgentID] = regionID; 613 // try again, but lookup user this time.
614 // Warning, this must call the Async version
615 // of this method or we'll be making thousands of threads
616 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
617 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
618
619 // This is recursive!!!!!
620 SendGridInstantMessageViaXMLRPCAsync(im, result,
621 upd.RegionID);
591 } 622 }
592 result(true);
593 return;
594 } 623 }
595 624 else
596 // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried 625 {
597 // to use a locally cached region ID. All subsequent attempts need to lookup agent details from 626 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
598 // the presence service. 627 HandleUndeliverableMessage(im, result);
599 needToLookupAgent = true; 628 }
629 }
630 else
631 {
632 HandleUndeliverableMessage(im, result);
600 } 633 }
601
602 // If we reached this point then the message was not deliverable. Remove the bad cache entry and
603 // signal the delivery failure.
604 lock (m_UserRegionMap)
605 m_UserRegionMap.Remove(toAgentID);
606
607 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
608 HandleUndeliverableMessage(im, result);
609 } 634 }
610 635
611 /// <summary> 636 /// <summary>
@@ -709,6 +734,5 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
709 gim["message_key"] = m_MessageKey; 734 gim["message_key"] = m_MessageKey;
710 return gim; 735 return gim;
711 } 736 }
712
713 } 737 }
714} 738}