diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/InstantMessage')
5 files changed, 255 insertions, 471 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index 9a68749..ab141eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -24,6 +24,7 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | ||
27 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
28 | using System.Reflection; | 29 | using System.Reflection; |
29 | using log4net; | 30 | using log4net; |
@@ -36,9 +37,10 @@ using OpenSim.Region.Framework.Scenes; | |||
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 38 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
38 | { | 39 | { |
39 | public class InstantMessageModule : IRegionModule | 40 | public class InstantMessageModule : ISharedRegionModule |
40 | { | 41 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger( |
43 | MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | 44 | ||
43 | /// <value> | 45 | /// <value> |
44 | /// Is this module enabled? | 46 | /// Is this module enabled? |
@@ -51,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
51 | 53 | ||
52 | private IMessageTransferModule m_TransferModule = null; | 54 | private IMessageTransferModule m_TransferModule = null; |
53 | 55 | ||
54 | public void Initialise(Scene scene, IConfigSource config) | 56 | public void Initialise(IConfigSource config) |
55 | { | 57 | { |
56 | if (config.Configs["Messaging"] != null) | 58 | if (config.Configs["Messaging"] != null) |
57 | { | 59 | { |
@@ -62,6 +64,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
62 | } | 64 | } |
63 | 65 | ||
64 | m_enabled = true; | 66 | m_enabled = true; |
67 | } | ||
68 | |||
69 | public void AddRegion(Scene scene) | ||
70 | { | ||
71 | if (!m_enabled) | ||
72 | return; | ||
65 | 73 | ||
66 | lock (m_scenes) | 74 | lock (m_scenes) |
67 | { | 75 | { |
@@ -74,6 +82,39 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
74 | } | 82 | } |
75 | } | 83 | } |
76 | 84 | ||
85 | public void RegionLoaded(Scene scene) | ||
86 | { | ||
87 | if (!m_enabled) | ||
88 | return; | ||
89 | |||
90 | if (m_TransferModule == null) | ||
91 | { | ||
92 | m_TransferModule = | ||
93 | scene.RequestModuleInterface<IMessageTransferModule>(); | ||
94 | |||
95 | if (m_TransferModule == null) | ||
96 | { | ||
97 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, IM will not work!"); | ||
98 | scene.EventManager.OnClientConnect -= OnClientConnect; | ||
99 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | ||
100 | |||
101 | m_scenes.Clear(); | ||
102 | m_enabled = false; | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | public void RemoveRegion(Scene scene) | ||
108 | { | ||
109 | if (!m_enabled) | ||
110 | return; | ||
111 | |||
112 | lock (m_scenes) | ||
113 | { | ||
114 | m_scenes.Remove(scene); | ||
115 | } | ||
116 | } | ||
117 | |||
77 | void OnClientConnect(IClientCore client) | 118 | void OnClientConnect(IClientCore client) |
78 | { | 119 | { |
79 | IClientIM clientIM; | 120 | IClientIM clientIM; |
@@ -85,15 +126,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
85 | 126 | ||
86 | public void PostInitialise() | 127 | public void PostInitialise() |
87 | { | 128 | { |
88 | if (!m_enabled) | ||
89 | return; | ||
90 | |||
91 | m_TransferModule = | ||
92 | m_scenes[0].RequestModuleInterface<IMessageTransferModule>(); | ||
93 | |||
94 | if (m_TransferModule == null) | ||
95 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ | ||
96 | "IM will not work!"); | ||
97 | } | 129 | } |
98 | 130 | ||
99 | public void Close() | 131 | public void Close() |
@@ -105,9 +137,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
105 | get { return "InstantMessageModule"; } | 137 | get { return "InstantMessageModule"; } |
106 | } | 138 | } |
107 | 139 | ||
108 | public bool IsSharedModule | 140 | public Type ReplaceableInterface |
109 | { | 141 | { |
110 | get { return true; } | 142 | get { return null; } |
111 | } | 143 | } |
112 | 144 | ||
113 | #endregion | 145 | #endregion |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index e5159b3..c0d3f31 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | |||
@@ -37,21 +37,33 @@ using OpenSim.Framework; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 39 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
40 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | ||
41 | using OpenSim.Services.Interfaces; | ||
40 | 42 | ||
41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 43 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
42 | { | 44 | { |
43 | public class MessageTransferModule : IRegionModule, IMessageTransferModule | 45 | public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule |
44 | { | 46 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 48 | ||
47 | // private bool m_Enabled = false; | 49 | private bool m_Enabled = false; |
48 | protected bool m_Gridmode = false; | ||
49 | protected List<Scene> m_Scenes = new List<Scene>(); | 50 | protected List<Scene> m_Scenes = new List<Scene>(); |
50 | protected Dictionary<UUID, ulong> m_UserRegionMap = new Dictionary<UUID, ulong>(); | 51 | protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); |
51 | 52 | ||
52 | public event UndeliveredMessage OnUndeliveredMessage; | 53 | public event UndeliveredMessage OnUndeliveredMessage; |
53 | 54 | ||
54 | public virtual void Initialise(Scene scene, IConfigSource config) | 55 | private IPresenceService m_PresenceService; |
56 | protected IPresenceService PresenceService | ||
57 | { | ||
58 | get | ||
59 | { | ||
60 | if (m_PresenceService == null) | ||
61 | m_PresenceService = m_Scenes[0].RequestModuleInterface<IPresenceService>(); | ||
62 | return m_PresenceService; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | public virtual void Initialise(IConfigSource config) | ||
55 | { | 67 | { |
56 | IConfig cnf = config.Configs["Messaging"]; | 68 | IConfig cnf = config.Configs["Messaging"]; |
57 | if (cnf != null && cnf.GetString( | 69 | if (cnf != null && cnf.GetString( |
@@ -62,20 +74,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
62 | return; | 74 | return; |
63 | } | 75 | } |
64 | 76 | ||
65 | cnf = config.Configs["Startup"]; | 77 | m_Enabled = true; |
66 | if (cnf != null) | 78 | } |
67 | m_Gridmode = cnf.GetBoolean("gridmode", false); | ||
68 | 79 | ||
69 | // m_Enabled = true; | 80 | public virtual void AddRegion(Scene scene) |
81 | { | ||
82 | if (!m_Enabled) | ||
83 | return; | ||
70 | 84 | ||
71 | lock (m_Scenes) | 85 | lock (m_Scenes) |
72 | { | 86 | { |
73 | if (m_Scenes.Count == 0) | ||
74 | { | ||
75 | MainServer.Instance.AddXmlRPCHandler( | ||
76 | "grid_instant_message", processXMLRPCGridInstantMessage); | ||
77 | } | ||
78 | |||
79 | m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); | 87 | m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); |
80 | scene.RegisterModuleInterface<IMessageTransferModule>(this); | 88 | scene.RegisterModuleInterface<IMessageTransferModule>(this); |
81 | m_Scenes.Add(scene); | 89 | m_Scenes.Add(scene); |
@@ -84,6 +92,26 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
84 | 92 | ||
85 | public virtual void PostInitialise() | 93 | public virtual void PostInitialise() |
86 | { | 94 | { |
95 | if (!m_Enabled) | ||
96 | return; | ||
97 | |||
98 | MainServer.Instance.AddXmlRPCHandler( | ||
99 | "grid_instant_message", processXMLRPCGridInstantMessage); | ||
100 | } | ||
101 | |||
102 | public virtual void RegionLoaded(Scene scene) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | public virtual void RemoveRegion(Scene scene) | ||
107 | { | ||
108 | if (!m_Enabled) | ||
109 | return; | ||
110 | |||
111 | lock(m_Scenes) | ||
112 | { | ||
113 | m_Scenes.Remove(scene); | ||
114 | } | ||
87 | } | 115 | } |
88 | 116 | ||
89 | public virtual void Close() | 117 | public virtual void Close() |
@@ -95,9 +123,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
95 | get { return "MessageTransferModule"; } | 123 | get { return "MessageTransferModule"; } |
96 | } | 124 | } |
97 | 125 | ||
98 | public virtual bool IsSharedModule | 126 | public virtual Type ReplaceableInterface |
99 | { | 127 | { |
100 | get { return true; } | 128 | get { return null; } |
101 | } | 129 | } |
102 | 130 | ||
103 | public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) | 131 | public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) |
@@ -148,15 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
148 | } | 176 | } |
149 | } | 177 | } |
150 | 178 | ||
151 | if (m_Gridmode) | 179 | SendGridInstantMessageViaXMLRPC(im, result); |
152 | { | ||
153 | //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid"); | ||
154 | // Still here, try send via Grid | ||
155 | SendGridInstantMessageViaXMLRPC(im, result); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | HandleUndeliveredMessage(im, result); | ||
160 | 180 | ||
161 | return; | 181 | return; |
162 | } | 182 | } |
@@ -409,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
409 | /// <summary> | 429 | /// <summary> |
410 | /// delegate for sending a grid instant message asynchronously | 430 | /// delegate for sending a grid instant message asynchronously |
411 | /// </summary> | 431 | /// </summary> |
412 | public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, ulong prevRegionHandle); | 432 | public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID); |
413 | 433 | ||
414 | protected virtual void GridInstantMessageCompleted(IAsyncResult iar) | 434 | protected virtual void GridInstantMessageCompleted(IAsyncResult iar) |
415 | { | 435 | { |
@@ -423,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
423 | { | 443 | { |
424 | GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; | 444 | GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; |
425 | 445 | ||
426 | d.BeginInvoke(im, result, 0, GridInstantMessageCompleted, d); | 446 | d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); |
427 | } | 447 | } |
428 | 448 | ||
429 | /// <summary> | 449 | /// <summary> |
@@ -438,11 +458,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
438 | /// Pass in 0 the first time this method is called. It will be called recursively with the last | 458 | /// Pass in 0 the first time this method is called. It will be called recursively with the last |
439 | /// regionhandle tried | 459 | /// regionhandle tried |
440 | /// </param> | 460 | /// </param> |
441 | protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, ulong prevRegionHandle) | 461 | protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) |
442 | { | 462 | { |
443 | UUID toAgentID = new UUID(im.toAgentID); | 463 | UUID toAgentID = new UUID(im.toAgentID); |
444 | 464 | ||
445 | UserAgentData upd = null; | 465 | PresenceInfo upd = null; |
446 | 466 | ||
447 | bool lookupAgent = false; | 467 | bool lookupAgent = false; |
448 | 468 | ||
@@ -450,13 +470,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
450 | { | 470 | { |
451 | if (m_UserRegionMap.ContainsKey(toAgentID)) | 471 | if (m_UserRegionMap.ContainsKey(toAgentID)) |
452 | { | 472 | { |
453 | upd = new UserAgentData(); | 473 | upd = new PresenceInfo(); |
454 | upd.AgentOnline = true; | 474 | upd.Online = true; |
455 | upd.Handle = m_UserRegionMap[toAgentID]; | 475 | upd.RegionID = m_UserRegionMap[toAgentID]; |
456 | 476 | ||
457 | // We need to compare the current regionhandle with the previous region handle | 477 | // We need to compare the current regionhandle with the previous region handle |
458 | // or the recursive loop will never end because it will never try to lookup the agent again | 478 | // or the recursive loop will never end because it will never try to lookup the agent again |
459 | if (prevRegionHandle == upd.Handle) | 479 | if (prevRegionID == upd.RegionID) |
460 | { | 480 | { |
461 | lookupAgent = true; | 481 | lookupAgent = true; |
462 | } | 482 | } |
@@ -472,14 +492,23 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
472 | if (lookupAgent) | 492 | if (lookupAgent) |
473 | { | 493 | { |
474 | // Non-cached user agent lookup. | 494 | // Non-cached user agent lookup. |
475 | upd = m_Scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID); | 495 | PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); |
496 | if (presences != null) | ||
497 | { | ||
498 | foreach (PresenceInfo p in presences) | ||
499 | if (p.Online) | ||
500 | { | ||
501 | upd = presences[0]; | ||
502 | break; | ||
503 | } | ||
504 | } | ||
476 | 505 | ||
477 | if (upd != null) | 506 | if (upd != null) |
478 | { | 507 | { |
479 | // check if we've tried this before.. | 508 | // check if we've tried this before.. |
480 | // This is one way to end the recursive loop | 509 | // This is one way to end the recursive loop |
481 | // | 510 | // |
482 | if (upd.Handle == prevRegionHandle) | 511 | if (upd.RegionID == prevRegionID) |
483 | { | 512 | { |
484 | m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); | 513 | m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); |
485 | HandleUndeliveredMessage(im, result); | 514 | HandleUndeliveredMessage(im, result); |
@@ -496,12 +525,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
496 | 525 | ||
497 | if (upd != null) | 526 | if (upd != null) |
498 | { | 527 | { |
499 | if (upd.AgentOnline) | 528 | if (upd.Online) |
500 | { | 529 | { |
501 | uint x = 0, y = 0; | 530 | GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, |
502 | Utils.LongToUInts(upd.Handle, out x, out y); | 531 | upd.RegionID); |
503 | GridRegion reginfo = m_Scenes[0].GridService.GetRegionByPosition(m_Scenes[0].RegionInfo.ScopeID, | ||
504 | (int)x, (int)y); | ||
505 | if (reginfo != null) | 532 | if (reginfo != null) |
506 | { | 533 | { |
507 | Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); | 534 | Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); |
@@ -517,11 +544,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
517 | { | 544 | { |
518 | if (m_UserRegionMap.ContainsKey(toAgentID)) | 545 | if (m_UserRegionMap.ContainsKey(toAgentID)) |
519 | { | 546 | { |
520 | m_UserRegionMap[toAgentID] = upd.Handle; | 547 | m_UserRegionMap[toAgentID] = upd.RegionID; |
521 | } | 548 | } |
522 | else | 549 | else |
523 | { | 550 | { |
524 | m_UserRegionMap.Add(toAgentID, upd.Handle); | 551 | m_UserRegionMap.Add(toAgentID, upd.RegionID); |
525 | } | 552 | } |
526 | } | 553 | } |
527 | result(true); | 554 | result(true); |
@@ -536,12 +563,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
536 | 563 | ||
537 | // This is recursive!!!!! | 564 | // This is recursive!!!!! |
538 | SendGridInstantMessageViaXMLRPCAsync(im, result, | 565 | SendGridInstantMessageViaXMLRPCAsync(im, result, |
539 | upd.Handle); | 566 | upd.RegionID); |
540 | } | 567 | } |
541 | } | 568 | } |
542 | else | 569 | else |
543 | { | 570 | { |
544 | m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.Handle); | 571 | m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID); |
545 | HandleUndeliveredMessage(im, result); | 572 | HandleUndeliveredMessage(im, result); |
546 | } | 573 | } |
547 | } | 574 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs index 2d4a635..24cbaeb 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs | |||
@@ -37,9 +37,9 @@ using OpenSim.Framework.Client; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.MuteList | 40 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
41 | { | 41 | { |
42 | public class MuteListModule : IRegionModule | 42 | public class MuteListModule : ISharedRegionModule |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
@@ -47,11 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
47 | private List<Scene> m_SceneList = new List<Scene>(); | 47 | private List<Scene> m_SceneList = new List<Scene>(); |
48 | private string m_RestURL = String.Empty; | 48 | private string m_RestURL = String.Empty; |
49 | 49 | ||
50 | public void Initialise(Scene scene, IConfigSource config) | 50 | public void Initialise(IConfigSource config) |
51 | { | 51 | { |
52 | if (!enabled) | ||
53 | return; | ||
54 | |||
55 | IConfig cnf = config.Configs["Messaging"]; | 52 | IConfig cnf = config.Configs["Messaging"]; |
56 | if (cnf == null) | 53 | if (cnf == null) |
57 | { | 54 | { |
@@ -59,39 +56,53 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
59 | return; | 56 | return; |
60 | } | 57 | } |
61 | 58 | ||
62 | if (cnf != null && cnf.GetString( | 59 | if (cnf != null && cnf.GetString("MuteListModule", "None") != |
63 | "MuteListModule", "None") != | ||
64 | "MuteListModule") | 60 | "MuteListModule") |
65 | { | 61 | { |
66 | enabled = false; | 62 | enabled = false; |
67 | return; | 63 | return; |
68 | } | 64 | } |
69 | 65 | ||
66 | m_RestURL = cnf.GetString("MuteListURL", ""); | ||
67 | if (m_RestURL == "") | ||
68 | { | ||
69 | m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); | ||
70 | enabled = false; | ||
71 | return; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void AddRegion(Scene scene) | ||
76 | { | ||
77 | if (!enabled) | ||
78 | return; | ||
79 | |||
70 | lock (m_SceneList) | 80 | lock (m_SceneList) |
71 | { | 81 | { |
72 | if (m_SceneList.Count == 0) | 82 | m_SceneList.Add(scene); |
73 | { | ||
74 | m_RestURL = cnf.GetString("MuteListURL", ""); | ||
75 | if (m_RestURL == "") | ||
76 | { | ||
77 | m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); | ||
78 | enabled = false; | ||
79 | return; | ||
80 | } | ||
81 | } | ||
82 | if (!m_SceneList.Contains(scene)) | ||
83 | m_SceneList.Add(scene); | ||
84 | 83 | ||
85 | scene.EventManager.OnNewClient += OnNewClient; | 84 | scene.EventManager.OnNewClient += OnNewClient; |
86 | } | 85 | } |
87 | } | 86 | } |
88 | 87 | ||
89 | public void PostInitialise() | 88 | public void RegionLoaded(Scene scene) |
89 | { | ||
90 | } | ||
91 | |||
92 | public void RemoveRegion(Scene scene) | ||
90 | { | 93 | { |
91 | if (!enabled) | 94 | if (!enabled) |
92 | return; | 95 | return; |
93 | 96 | ||
94 | if (m_SceneList.Count == 0) | 97 | lock (m_SceneList) |
98 | { | ||
99 | m_SceneList.Remove(scene); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | public void PostInitialise() | ||
104 | { | ||
105 | if (!enabled) | ||
95 | return; | 106 | return; |
96 | 107 | ||
97 | m_log.Debug("[MUTE LIST] Mute list enabled"); | 108 | m_log.Debug("[MUTE LIST] Mute list enabled"); |
@@ -102,26 +113,15 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
102 | get { return "MuteListModule"; } | 113 | get { return "MuteListModule"; } |
103 | } | 114 | } |
104 | 115 | ||
105 | public bool IsSharedModule | 116 | public Type ReplaceableInterface |
106 | { | 117 | { |
107 | get { return true; } | 118 | get { return null; } |
108 | } | 119 | } |
109 | 120 | ||
110 | public void Close() | 121 | public void Close() |
111 | { | 122 | { |
112 | } | 123 | } |
113 | 124 | ||
114 | // private IClientAPI FindClient(UUID agentID) | ||
115 | // { | ||
116 | // foreach (Scene s in m_SceneList) | ||
117 | // { | ||
118 | // ScenePresence presence = s.GetScenePresence(agentID); | ||
119 | // if (presence != null && !presence.IsChildAgent) | ||
120 | // return presence.ControllingClient; | ||
121 | // } | ||
122 | // return null; | ||
123 | // } | ||
124 | |||
125 | private void OnNewClient(IClientAPI client) | 125 | private void OnNewClient(IClientAPI client) |
126 | { | 126 | { |
127 | client.OnMuteListRequest += OnMuteListRequest; | 127 | client.OnMuteListRequest += OnMuteListRequest; |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 0727fa9..9412735 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -40,82 +40,91 @@ using OpenSim.Region.Framework.Scenes; | |||
40 | 40 | ||
41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
42 | { | 42 | { |
43 | public class OfflineMessageModule : IRegionModule | 43 | public class OfflineMessageModule : ISharedRegionModule |
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private bool enabled = true; | 47 | private bool enabled = true; |
48 | private List<Scene> m_SceneList = new List<Scene>(); | 48 | private List<Scene> m_SceneList = new List<Scene>(); |
49 | private string m_RestURL = String.Empty; | 49 | private string m_RestURL = String.Empty; |
50 | IMessageTransferModule m_TransferModule = null; | ||
50 | private bool m_ForwardOfflineGroupMessages = true; | 51 | private bool m_ForwardOfflineGroupMessages = true; |
51 | 52 | ||
52 | public void Initialise(Scene scene, IConfigSource config) | 53 | public void Initialise(IConfigSource config) |
53 | { | 54 | { |
54 | if (!enabled) | ||
55 | return; | ||
56 | |||
57 | IConfig cnf = config.Configs["Messaging"]; | 55 | IConfig cnf = config.Configs["Messaging"]; |
58 | if (cnf == null) | 56 | if (cnf == null) |
59 | { | 57 | { |
60 | enabled = false; | 58 | enabled = false; |
61 | return; | 59 | return; |
62 | } | 60 | } |
63 | if (cnf != null && cnf.GetString( | 61 | if (cnf != null && cnf.GetString("OfflineMessageModule", "None") != |
64 | "OfflineMessageModule", "None") != | ||
65 | "OfflineMessageModule") | 62 | "OfflineMessageModule") |
66 | { | 63 | { |
67 | enabled = false; | 64 | enabled = false; |
68 | return; | 65 | return; |
69 | } | 66 | } |
70 | 67 | ||
71 | if (cnf != null) | 68 | m_RestURL = cnf.GetString("OfflineMessageURL", ""); |
72 | m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages); | 69 | if (m_RestURL == "") |
70 | { | ||
71 | m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling"); | ||
72 | enabled = false; | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages); | ||
77 | } | ||
78 | |||
79 | public void AddRegion(Scene scene) | ||
80 | { | ||
81 | if (!enabled) | ||
82 | return; | ||
73 | 83 | ||
74 | lock (m_SceneList) | 84 | lock (m_SceneList) |
75 | { | 85 | { |
76 | if (m_SceneList.Count == 0) | 86 | m_SceneList.Add(scene); |
77 | { | ||
78 | m_RestURL = cnf.GetString("OfflineMessageURL", ""); | ||
79 | if (m_RestURL == "") | ||
80 | { | ||
81 | m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling"); | ||
82 | enabled = false; | ||
83 | return; | ||
84 | } | ||
85 | } | ||
86 | if (!m_SceneList.Contains(scene)) | ||
87 | m_SceneList.Add(scene); | ||
88 | 87 | ||
89 | scene.EventManager.OnNewClient += OnNewClient; | 88 | scene.EventManager.OnNewClient += OnNewClient; |
90 | } | 89 | } |
91 | } | 90 | } |
92 | 91 | ||
93 | public void PostInitialise() | 92 | public void RegionLoaded(Scene scene) |
94 | { | 93 | { |
95 | if (!enabled) | 94 | if (!enabled) |
96 | return; | 95 | return; |
97 | 96 | ||
98 | if (m_SceneList.Count == 0) | 97 | if (m_TransferModule == null) |
99 | return; | ||
100 | |||
101 | IMessageTransferModule trans = m_SceneList[0].RequestModuleInterface<IMessageTransferModule>(); | ||
102 | if (trans == null) | ||
103 | { | 98 | { |
104 | enabled = false; | 99 | m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); |
105 | 100 | if (m_TransferModule == null) | |
106 | lock (m_SceneList) | ||
107 | { | 101 | { |
108 | foreach (Scene s in m_SceneList) | 102 | scene.EventManager.OnNewClient -= OnNewClient; |
109 | s.EventManager.OnNewClient -= OnNewClient; | ||
110 | 103 | ||
104 | enabled = false; | ||
111 | m_SceneList.Clear(); | 105 | m_SceneList.Clear(); |
106 | |||
107 | m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages"); | ||
112 | } | 108 | } |
109 | m_TransferModule.OnUndeliveredMessage += UndeliveredMessage; | ||
110 | } | ||
111 | } | ||
113 | 112 | ||
114 | m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages"); | 113 | public void RemoveRegion(Scene scene) |
114 | { | ||
115 | if (!enabled) | ||
115 | return; | 116 | return; |
117 | |||
118 | lock (m_SceneList) | ||
119 | { | ||
120 | m_SceneList.Remove(scene); | ||
116 | } | 121 | } |
122 | } | ||
117 | 123 | ||
118 | trans.OnUndeliveredMessage += UndeliveredMessage; | 124 | public void PostInitialise() |
125 | { | ||
126 | if (!enabled) | ||
127 | return; | ||
119 | 128 | ||
120 | m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); | 129 | m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); |
121 | } | 130 | } |
@@ -125,9 +134,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
125 | get { return "OfflineMessageModule"; } | 134 | get { return "OfflineMessageModule"; } |
126 | } | 135 | } |
127 | 136 | ||
128 | public bool IsSharedModule | 137 | public Type ReplaceableInterface |
129 | { | 138 | { |
130 | get { return true; } | 139 | get { return null; } |
131 | } | 140 | } |
132 | 141 | ||
133 | public void Close() | 142 | public void Close() |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index f5ab454..bafad82 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs | |||
@@ -24,6 +24,7 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | ||
27 | using System.Collections; | 28 | using System.Collections; |
28 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
29 | using System.Net; | 30 | using System.Net; |
@@ -35,408 +36,123 @@ using OpenMetaverse; | |||
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Services.Interfaces; | ||
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 40 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
41 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | ||
39 | 42 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 43 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
41 | { | 44 | { |
42 | public class PresenceModule : IRegionModule, IPresenceModule | 45 | public class PresenceModule : ISharedRegionModule, IPresenceModule |
43 | { | 46 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger( |
45 | 48 | MethodBase.GetCurrentMethod().DeclaringType); | |
46 | private bool m_Enabled = false; | ||
47 | private bool m_Gridmode = false; | ||
48 | |||
49 | // some default scene for doing things that aren't connected to a specific scene. Avoids locking. | ||
50 | private Scene m_initialScene; | ||
51 | |||
52 | private List<Scene> m_Scenes = new List<Scene>(); | ||
53 | |||
54 | // we currently are only interested in root-agents. If the root isn't here, we don't know the region the | ||
55 | // user is in, so we have to ask the messaging server anyway. | ||
56 | private Dictionary<UUID, Scene> m_RootAgents = | ||
57 | new Dictionary<UUID, Scene>(); | ||
58 | 49 | ||
59 | public event PresenceChange OnPresenceChange; | 50 | public event PresenceChange OnPresenceChange; |
60 | public event BulkPresenceData OnBulkPresenceData; | 51 | public event BulkPresenceData OnBulkPresenceData; |
61 | 52 | ||
62 | public void Initialise(Scene scene, IConfigSource config) | 53 | protected List<Scene> m_Scenes = new List<Scene>(); |
63 | { | ||
64 | lock (m_Scenes) | ||
65 | { | ||
66 | // This is a shared module; Initialise will be called for every region on this server. | ||
67 | // Only check config once for the first region. | ||
68 | if (m_Scenes.Count == 0) | ||
69 | { | ||
70 | IConfig cnf = config.Configs["Messaging"]; | ||
71 | if (cnf != null && cnf.GetString( | ||
72 | "PresenceModule", "PresenceModule") != | ||
73 | "PresenceModule") | ||
74 | return; | ||
75 | |||
76 | cnf = config.Configs["Startup"]; | ||
77 | if (cnf != null) | ||
78 | m_Gridmode = cnf.GetBoolean("gridmode", false); | ||
79 | 54 | ||
80 | m_Enabled = true; | 55 | protected IPresenceService m_PresenceService = null; |
81 | 56 | ||
82 | m_initialScene = scene; | 57 | protected IPresenceService PresenceService |
83 | } | ||
84 | |||
85 | if (m_Gridmode) | ||
86 | NotifyMessageServerOfStartup(scene); | ||
87 | |||
88 | m_Scenes.Add(scene); | ||
89 | } | ||
90 | |||
91 | scene.RegisterModuleInterface<IPresenceModule>(this); | ||
92 | |||
93 | scene.EventManager.OnNewClient += OnNewClient; | ||
94 | scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; | ||
95 | scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; | ||
96 | } | ||
97 | |||
98 | public void PostInitialise() | ||
99 | { | ||
100 | } | ||
101 | |||
102 | public void Close() | ||
103 | { | 58 | { |
104 | if (!m_Gridmode || !m_Enabled) | 59 | get |
105 | return; | ||
106 | |||
107 | if (OnPresenceChange != null) | ||
108 | { | 60 | { |
109 | lock (m_RootAgents) | 61 | if (m_PresenceService == null) |
110 | { | 62 | { |
111 | // on shutdown, users are kicked, too | 63 | if (m_Scenes.Count > 0) |
112 | foreach (KeyValuePair<UUID, Scene> pair in m_RootAgents) | 64 | m_PresenceService = m_Scenes[0].RequestModuleInterface<IPresenceService>(); |
113 | { | ||
114 | OnPresenceChange(new PresenceInfo(pair.Key, UUID.Zero)); | ||
115 | } | ||
116 | } | 65 | } |
117 | } | ||
118 | 66 | ||
119 | lock (m_Scenes) | 67 | return m_PresenceService; |
120 | { | ||
121 | foreach (Scene scene in m_Scenes) | ||
122 | NotifyMessageServerOfShutdown(scene); | ||
123 | } | 68 | } |
124 | } | 69 | } |
125 | 70 | ||
126 | public string Name | 71 | public void Initialise(IConfigSource config) |
127 | { | ||
128 | get { return "PresenceModule"; } | ||
129 | } | ||
130 | |||
131 | public bool IsSharedModule | ||
132 | { | 72 | { |
133 | get { return true; } | ||
134 | } | 73 | } |
135 | 74 | ||
136 | public void RequestBulkPresenceData(UUID[] users) | 75 | public void AddRegion(Scene scene) |
137 | { | 76 | { |
138 | if (OnBulkPresenceData != null) | 77 | m_Scenes.Add(scene); |
139 | { | ||
140 | PresenceInfo[] result = new PresenceInfo[users.Length]; | ||
141 | if (m_Gridmode) | ||
142 | { | ||
143 | // first check the local information | ||
144 | List<UUID> uuids = new List<UUID>(); // the uuids to check remotely | ||
145 | List<int> indices = new List<int>(); // just for performance. | ||
146 | lock (m_RootAgents) | ||
147 | { | ||
148 | for (int i = 0; i < uuids.Count; ++i) | ||
149 | { | ||
150 | Scene scene; | ||
151 | if (m_RootAgents.TryGetValue(users[i], out scene)) | ||
152 | { | ||
153 | result[i] = new PresenceInfo(users[i], scene.RegionInfo.RegionID); | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | uuids.Add(users[i]); | ||
158 | indices.Add(i); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | 78 | ||
163 | // now we have filtered out all the local root agents. The rest we have to request info about | 79 | scene.EventManager.OnNewClient += OnNewClient; |
164 | Dictionary<UUID, FriendRegionInfo> infos = m_initialScene.GetFriendRegionInfos(uuids); | ||
165 | for (int i = 0; i < uuids.Count; ++i) | ||
166 | { | ||
167 | FriendRegionInfo info; | ||
168 | if (infos.TryGetValue(uuids[i], out info) && info.isOnline) | ||
169 | { | ||
170 | UUID regionID = info.regionID; | ||
171 | if (regionID == UUID.Zero) | ||
172 | { | ||
173 | // TODO this is the old messaging-server protocol; only the regionHandle is available. | ||
174 | // Fetch region-info to get the id | ||
175 | uint x = 0, y = 0; | ||
176 | Utils.LongToUInts(info.regionHandle, out x, out y); | ||
177 | GridRegion regionInfo = m_initialScene.GridService.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, | ||
178 | (int)x, (int)y); | ||
179 | regionID = regionInfo.RegionID; | ||
180 | } | ||
181 | result[indices[i]] = new PresenceInfo(uuids[i], regionID); | ||
182 | } | ||
183 | else result[indices[i]] = new PresenceInfo(uuids[i], UUID.Zero); | ||
184 | } | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | // in standalone mode, we have all the info locally available. | ||
189 | lock (m_RootAgents) | ||
190 | { | ||
191 | for (int i = 0; i < users.Length; ++i) | ||
192 | { | ||
193 | Scene scene; | ||
194 | if (m_RootAgents.TryGetValue(users[i], out scene)) | ||
195 | { | ||
196 | result[i] = new PresenceInfo(users[i], scene.RegionInfo.RegionID); | ||
197 | } | ||
198 | else | ||
199 | { | ||
200 | result[i] = new PresenceInfo(users[i], UUID.Zero); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | 80 | ||
206 | // tell everyone | 81 | scene.RegisterModuleInterface<IPresenceModule>(this); |
207 | OnBulkPresenceData(result); | ||
208 | } | ||
209 | } | 82 | } |
210 | 83 | ||
211 | // new client doesn't mean necessarily that user logged in, it just means it entered one of the | 84 | public void RegionLoaded(Scene scene) |
212 | // the regions on this server | ||
213 | public void OnNewClient(IClientAPI client) | ||
214 | { | 85 | { |
215 | client.OnConnectionClosed += OnConnectionClosed; | ||
216 | client.OnLogout += OnLogout; | ||
217 | |||
218 | // KLUDGE: See handler for details. | ||
219 | client.OnEconomyDataRequest += OnEconomyDataRequest; | ||
220 | } | 86 | } |
221 | 87 | ||
222 | // connection closed just means *one* client connection has been closed. It doesn't mean that the | 88 | public void RemoveRegion(Scene scene) |
223 | // user has logged off; it might have just TPed away. | ||
224 | public void OnConnectionClosed(IClientAPI client) | ||
225 | { | 89 | { |
226 | // TODO: Have to think what we have to do here... | 90 | m_Scenes.Remove(scene); |
227 | // Should we just remove the root from the list (if scene matches)? | ||
228 | if (!(client.Scene is Scene)) | ||
229 | return; | ||
230 | Scene scene = (Scene)client.Scene; | ||
231 | |||
232 | lock (m_RootAgents) | ||
233 | { | ||
234 | Scene rootScene; | ||
235 | if (!(m_RootAgents.TryGetValue(client.AgentId, out rootScene)) || scene != rootScene) | ||
236 | return; | ||
237 | |||
238 | m_RootAgents.Remove(client.AgentId); | ||
239 | } | ||
240 | |||
241 | // Should it have logged off, we'll do the logout part in OnLogout, even if no root is stored | ||
242 | // anymore. It logged off, after all... | ||
243 | } | 91 | } |
244 | 92 | ||
245 | // Triggered when the user logs off. | 93 | public void PostInitialise() |
246 | public void OnLogout(IClientAPI client) | ||
247 | { | 94 | { |
248 | if (!(client.Scene is Scene)) | ||
249 | return; | ||
250 | Scene scene = (Scene)client.Scene; | ||
251 | |||
252 | // On logout, we really remove the client from rootAgents, even if the scene doesn't match | ||
253 | lock (m_RootAgents) | ||
254 | { | ||
255 | if (m_RootAgents.ContainsKey(client.AgentId)) m_RootAgents.Remove(client.AgentId); | ||
256 | } | ||
257 | |||
258 | // now inform the messaging server and anyone who is interested | ||
259 | NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | ||
260 | if (OnPresenceChange != null) OnPresenceChange(new PresenceInfo(client.AgentId, UUID.Zero)); | ||
261 | } | 95 | } |
262 | 96 | ||
263 | public void OnSetRootAgentScene(UUID agentID, Scene scene) | 97 | public void Close() |
264 | { | 98 | { |
265 | // OnSetRootAgentScene can be called from several threads at once (with different agentID). | ||
266 | // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without | ||
267 | // correct locking). | ||
268 | lock (m_RootAgents) | ||
269 | { | ||
270 | Scene rootScene; | ||
271 | if (m_RootAgents.TryGetValue(agentID, out rootScene) && scene == rootScene) | ||
272 | { | ||
273 | return; | ||
274 | } | ||
275 | m_RootAgents[agentID] = scene; | ||
276 | } | ||
277 | |||
278 | // inform messaging server that agent changed the region | ||
279 | Util.FireAndForget( | ||
280 | delegate(object o) | ||
281 | { | ||
282 | NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | ||
283 | } | ||
284 | ); | ||
285 | } | 99 | } |
286 | 100 | ||
287 | private void OnEconomyDataRequest(UUID agentID) | 101 | public string Name |
288 | { | 102 | { |
289 | // KLUDGE: This is the only way I found to get a message (only) after login was completed and the | 103 | get { return "PresenceModule"; } |
290 | // client is connected enough to receive UDP packets. | ||
291 | // This packet seems to be sent only once, just after connection was established to the first | ||
292 | // region after login. | ||
293 | // We use it here to trigger a presence update; the old update-on-login was never be heard by | ||
294 | // the freshly logged in viewer, as it wasn't connected to the region at that time. | ||
295 | // TODO: Feel free to replace this by a better solution if you find one. | ||
296 | |||
297 | // get the agent. This should work every time, as we just got a packet from it | ||
298 | ScenePresence agent = null; | ||
299 | lock (m_Scenes) | ||
300 | { | ||
301 | foreach (Scene scene in m_Scenes) | ||
302 | { | ||
303 | agent = scene.GetScenePresence(agentID); | ||
304 | if (agent != null) break; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | // just to be paranoid... | ||
309 | if (agent == null) | ||
310 | { | ||
311 | m_log.ErrorFormat("[PRESENCE]: Got a packet from agent {0} who can't be found anymore!?", agentID); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | // we are a bit premature here, but the next packet will switch this child agent to root. | ||
316 | if (OnPresenceChange != null) OnPresenceChange(new PresenceInfo(agentID, agent.Scene.RegionInfo.RegionID)); | ||
317 | } | 104 | } |
318 | 105 | ||
319 | public void OnMakeChildAgent(ScenePresence agent) | 106 | public Type ReplaceableInterface |
320 | { | 107 | { |
321 | // OnMakeChildAgent can be called from several threads at once (with different agent). | 108 | get { return null; } |
322 | // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without | ||
323 | // correct locking). | ||
324 | lock (m_RootAgents) | ||
325 | { | ||
326 | Scene rootScene; | ||
327 | if (m_RootAgents.TryGetValue(agent.UUID, out rootScene) && agent.Scene == rootScene) | ||
328 | { | ||
329 | m_RootAgents.Remove(agent.UUID); | ||
330 | } | ||
331 | } | ||
332 | // don't notify the messaging-server; either this agent just had been downgraded and another one will be upgraded | ||
333 | // to root momentarily (which will notify the messaging-server), or possibly it will be closed in a moment, | ||
334 | // which will update the messaging-server, too. | ||
335 | } | 109 | } |
336 | 110 | ||
337 | private void NotifyMessageServerOfStartup(Scene scene) | 111 | public void RequestBulkPresenceData(UUID[] users) |
338 | { | 112 | { |
339 | Hashtable xmlrpcdata = new Hashtable(); | ||
340 | xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); | ||
341 | ArrayList SendParams = new ArrayList(); | ||
342 | SendParams.Add(xmlrpcdata); | ||
343 | try | ||
344 | { | ||
345 | XmlRpcRequest UpRequest = new XmlRpcRequest("region_startup", SendParams); | ||
346 | XmlRpcResponse resp = UpRequest.Send(scene.CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
347 | |||
348 | Hashtable responseData = (Hashtable)resp.Value; | ||
349 | if (responseData == null || (!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
350 | { | ||
351 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region startup for region {0}", scene.RegionInfo.RegionName); | ||
352 | } | ||
353 | } | ||
354 | catch (WebException) | ||
355 | { | ||
356 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region startup for region {0}", scene.RegionInfo.RegionName); | ||
357 | } | ||
358 | } | 113 | } |
359 | 114 | ||
360 | private void NotifyMessageServerOfShutdown(Scene scene) | 115 | public void OnNewClient(IClientAPI client) |
361 | { | 116 | { |
362 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | 117 | client.AddGenericPacketHandler("requestonlinenotification", OnRequestOnlineNotification); |
363 | return; | ||
364 | |||
365 | Hashtable xmlrpcdata = new Hashtable(); | ||
366 | xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); | ||
367 | ArrayList SendParams = new ArrayList(); | ||
368 | SendParams.Add(xmlrpcdata); | ||
369 | try | ||
370 | { | ||
371 | XmlRpcRequest DownRequest = new XmlRpcRequest("region_shutdown", SendParams); | ||
372 | XmlRpcResponse resp = DownRequest.Send(scene.CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
373 | |||
374 | Hashtable responseData = (Hashtable)resp.Value; | ||
375 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
376 | { | ||
377 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region shutdown for region {0}", scene.RegionInfo.RegionName); | ||
378 | } | ||
379 | } | ||
380 | catch (WebException) | ||
381 | { | ||
382 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region shutdown for region {0}", scene.RegionInfo.RegionName); | ||
383 | } | ||
384 | } | 118 | } |
385 | 119 | ||
386 | private void NotifyMessageServerOfAgentLocation(UUID agentID, UUID region, ulong regionHandle) | 120 | public void OnRequestOnlineNotification(Object sender, string method, List<String> args) |
387 | { | 121 | { |
388 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | 122 | if (!(sender is IClientAPI)) |
389 | return; | 123 | return; |
390 | 124 | ||
391 | Hashtable xmlrpcdata = new Hashtable(); | 125 | IClientAPI client = (IClientAPI)sender; |
392 | xmlrpcdata["AgentID"] = agentID.ToString(); | 126 | m_log.DebugFormat("[PRESENCE MODULE]: OnlineNotification requested by {0}", client.Name); |
393 | xmlrpcdata["RegionUUID"] = region.ToString(); | ||
394 | xmlrpcdata["RegionHandle"] = regionHandle.ToString(); | ||
395 | ArrayList SendParams = new ArrayList(); | ||
396 | SendParams.Add(xmlrpcdata); | ||
397 | try | ||
398 | { | ||
399 | XmlRpcRequest LocationRequest = new XmlRpcRequest("agent_location", SendParams); | ||
400 | XmlRpcResponse resp = LocationRequest.Send(m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
401 | 127 | ||
402 | Hashtable responseData = (Hashtable)resp.Value; | 128 | PresenceInfo[] status = PresenceService.GetAgents(args.ToArray()); |
403 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
404 | { | ||
405 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent location for {0}", agentID.ToString()); | ||
406 | } | ||
407 | } | ||
408 | catch (WebException) | ||
409 | { | ||
410 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent location for {0}", agentID.ToString()); | ||
411 | } | ||
412 | } | ||
413 | 129 | ||
414 | private void NotifyMessageServerOfAgentLeaving(UUID agentID, UUID region, ulong regionHandle) | 130 | List<UUID> online = new List<UUID>(); |
415 | { | 131 | List<UUID> offline = new List<UUID>(); |
416 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | ||
417 | return; | ||
418 | 132 | ||
419 | Hashtable xmlrpcdata = new Hashtable(); | 133 | foreach (PresenceInfo pi in status) |
420 | xmlrpcdata["AgentID"] = agentID.ToString(); | ||
421 | xmlrpcdata["RegionUUID"] = region.ToString(); | ||
422 | xmlrpcdata["RegionHandle"] = regionHandle.ToString(); | ||
423 | ArrayList SendParams = new ArrayList(); | ||
424 | SendParams.Add(xmlrpcdata); | ||
425 | try | ||
426 | { | 134 | { |
427 | XmlRpcRequest LeavingRequest = new XmlRpcRequest("agent_leaving", SendParams); | 135 | UUID uuid = new UUID(pi.UserID); |
428 | XmlRpcResponse resp = LeavingRequest.Send(m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL, 5000); | 136 | if (pi.Online) |
429 | |||
430 | Hashtable responseData = (Hashtable)resp.Value; | ||
431 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
432 | { | 137 | { |
433 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString()); | 138 | if (!online.Contains(uuid)) |
139 | { | ||
140 | online.Add(uuid); | ||
141 | if (offline.Contains(uuid)) | ||
142 | offline.Remove(uuid); | ||
143 | } | ||
144 | } | ||
145 | else | ||
146 | { | ||
147 | if (!online.Contains(uuid) && !offline.Contains(uuid)) | ||
148 | offline.Add(uuid); | ||
434 | } | 149 | } |
435 | } | 150 | } |
436 | catch (WebException) | 151 | |
437 | { | 152 | if (online.Count > 0) |
438 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString()); | 153 | client.SendAgentOnline(online.ToArray()); |
439 | } | 154 | if (offline.Count > 0) |
155 | client.SendAgentOffline(offline.ToArray()); | ||
440 | } | 156 | } |
441 | } | 157 | } |
442 | } | 158 | } |