aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/InstantMessage
diff options
context:
space:
mode:
authorMelanie2009-12-28 01:24:15 +0000
committerMelanie2009-12-28 01:24:15 +0000
commiteebddcd5e693a4b56af326546d4222bd594286e0 (patch)
treeb36b509696710a9082627962101323aa562fc552 /OpenSim/Region/CoreModules/Avatar/InstantMessage
parentAllow lists to be embedded in query strings (diff)
downloadopensim-SC_OLD-eebddcd5e693a4b56af326546d4222bd594286e0.zip
opensim-SC_OLD-eebddcd5e693a4b56af326546d4222bd594286e0.tar.gz
opensim-SC_OLD-eebddcd5e693a4b56af326546d4222bd594286e0.tar.bz2
opensim-SC_OLD-eebddcd5e693a4b56af326546d4222bd594286e0.tar.xz
Change FriendsModule, InstantMessageModule, MessageTransferModule, MuteListModule, OfflineMessageModule, PresenceModule, InventoryTransferModule and LureModule to new style. Reduce FriendsModule and PresenceModule to shells.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/InstantMessage')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs60
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs55
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs68
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs78
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs381
5 files changed, 170 insertions, 472 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 */
27using System;
27using System.Collections.Generic; 28using System.Collections.Generic;
28using System.Reflection; 29using System.Reflection;
29using log4net; 30using log4net;
@@ -36,9 +37,10 @@ using OpenSim.Region.Framework.Scenes;
36 37
37namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 38namespace 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..b5019f1 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -40,18 +40,17 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40 40
41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
42{ 42{
43 public class MessageTransferModule : IRegionModule, IMessageTransferModule 43 public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule
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 m_Enabled = false; 47 private bool m_Enabled = false;
48 protected bool m_Gridmode = false;
49 protected List<Scene> m_Scenes = new List<Scene>(); 48 protected List<Scene> m_Scenes = new List<Scene>();
50 protected Dictionary<UUID, ulong> m_UserRegionMap = new Dictionary<UUID, ulong>(); 49 protected Dictionary<UUID, ulong> m_UserRegionMap = new Dictionary<UUID, ulong>();
51 50
52 public event UndeliveredMessage OnUndeliveredMessage; 51 public event UndeliveredMessage OnUndeliveredMessage;
53 52
54 public virtual void Initialise(Scene scene, IConfigSource config) 53 public virtual void Initialise(IConfigSource config)
55 { 54 {
56 IConfig cnf = config.Configs["Messaging"]; 55 IConfig cnf = config.Configs["Messaging"];
57 if (cnf != null && cnf.GetString( 56 if (cnf != null && cnf.GetString(
@@ -62,20 +61,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
62 return; 61 return;
63 } 62 }
64 63
65 cnf = config.Configs["Startup"]; 64 MainServer.Instance.AddXmlRPCHandler(
66 if (cnf != null) 65 "grid_instant_message", processXMLRPCGridInstantMessage);
67 m_Gridmode = cnf.GetBoolean("gridmode", false);
68 66
69 // m_Enabled = true; 67 m_Enabled = true;
68 }
69
70 public virtual void AddRegion(Scene scene)
71 {
72 if (!m_Enabled)
73 return;
70 74
71 lock (m_Scenes) 75 lock (m_Scenes)
72 { 76 {
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"); 77 m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active");
80 scene.RegisterModuleInterface<IMessageTransferModule>(this); 78 scene.RegisterModuleInterface<IMessageTransferModule>(this);
81 m_Scenes.Add(scene); 79 m_Scenes.Add(scene);
@@ -86,6 +84,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
86 { 84 {
87 } 85 }
88 86
87 public virtual void RegionLoaded(Scene scene)
88 {
89 }
90
91 public virtual void RemoveRegion(Scene scene)
92 {
93 if (!m_Enabled)
94 return;
95
96 lock(m_Scenes)
97 {
98 m_Scenes.Remove(scene);
99 }
100 }
101
89 public virtual void Close() 102 public virtual void Close()
90 { 103 {
91 } 104 }
@@ -95,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
95 get { return "MessageTransferModule"; } 108 get { return "MessageTransferModule"; }
96 } 109 }
97 110
98 public virtual bool IsSharedModule 111 public virtual Type ReplaceableInterface
99 { 112 {
100 get { return true; } 113 get { return null; }
101 } 114 }
102 115
103 public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) 116 public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
@@ -148,15 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
148 } 161 }
149 } 162 }
150 163
151 if (m_Gridmode) 164 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 165
161 return; 166 return;
162 } 167 }
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
index 2d4a635..1ff5865 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
@@ -39,7 +39,7 @@ using OpenSim.Region.Framework.Scenes;
39 39
40namespace OpenSim.Region.CoreModules.Avatar.MuteList 40namespace OpenSim.Region.CoreModules.Avatar.MuteList
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 1614b70..a835c52 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -40,78 +40,88 @@ using OpenSim.Region.Framework.Scenes;
40 40
41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace 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 51
51 public void Initialise(Scene scene, IConfigSource config) 52 public void Initialise(IConfigSource config)
52 { 53 {
53 if (!enabled)
54 return;
55
56 IConfig cnf = config.Configs["Messaging"]; 54 IConfig cnf = config.Configs["Messaging"];
57 if (cnf == null) 55 if (cnf == null)
58 { 56 {
59 enabled = false; 57 enabled = false;
60 return; 58 return;
61 } 59 }
62 if (cnf != null && cnf.GetString( 60 if (cnf != null && cnf.GetString("OfflineMessageModule", "None") !=
63 "OfflineMessageModule", "None") !=
64 "OfflineMessageModule") 61 "OfflineMessageModule")
65 { 62 {
66 enabled = false; 63 enabled = false;
67 return; 64 return;
68 } 65 }
69 66
67 m_RestURL = cnf.GetString("OfflineMessageURL", "");
68 if (m_RestURL == "")
69 {
70 m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling");
71 enabled = false;
72 return;
73 }
74 }
75
76 public void AddRegion(Scene scene)
77 {
78 if (!enabled)
79 return;
80
70 lock (m_SceneList) 81 lock (m_SceneList)
71 { 82 {
72 if (m_SceneList.Count == 0) 83 m_SceneList.Add(scene);
73 {
74 m_RestURL = cnf.GetString("OfflineMessageURL", "");
75 if (m_RestURL == "")
76 {
77 m_log.Error("[OFFLINE MESSAGING] 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 84
85 scene.EventManager.OnNewClient += OnNewClient; 85 scene.EventManager.OnNewClient += OnNewClient;
86 } 86 }
87 } 87 }
88 88
89 public void PostInitialise() 89 public void RegionLoaded(Scene scene)
90 { 90 {
91 if (!enabled) 91 if (!enabled)
92 return; 92 return;
93 93
94 if (m_SceneList.Count == 0) 94 if (m_TransferModule == null)
95 return;
96
97 IMessageTransferModule trans = m_SceneList[0].RequestModuleInterface<IMessageTransferModule>();
98 if (trans == null)
99 { 95 {
100 enabled = false; 96 m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
101 97 if (m_TransferModule == null)
102 lock (m_SceneList)
103 { 98 {
104 foreach (Scene s in m_SceneList) 99 scene.EventManager.OnNewClient -= OnNewClient;
105 s.EventManager.OnNewClient -= OnNewClient;
106 100
101 enabled = false;
107 m_SceneList.Clear(); 102 m_SceneList.Clear();
103
104 m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages");
108 } 105 }
106 m_TransferModule.OnUndeliveredMessage += UndeliveredMessage;
107 }
108 }
109 109
110 m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages"); 110 public void RemoveRegion(Scene scene)
111 {
112 if (!enabled)
111 return; 113 return;
114
115 lock (m_SceneList)
116 {
117 m_SceneList.Remove(scene);
112 } 118 }
119 }
113 120
114 trans.OnUndeliveredMessage += UndeliveredMessage; 121 public void PostInitialise()
122 {
123 if (!enabled)
124 return;
115 125
116 m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); 126 m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled");
117 } 127 }
@@ -121,9 +131,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
121 get { return "OfflineMessageModule"; } 131 get { return "OfflineMessageModule"; }
122 } 132 }
123 133
124 public bool IsSharedModule 134 public Type ReplaceableInterface
125 { 135 {
126 get { return true; } 136 get { return null; }
127 } 137 }
128 138
129 public void Close() 139 public void Close()
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
index f5ab454..267a90a 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 */
27using System;
27using System.Collections; 28using System.Collections;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Net; 30using System.Net;
@@ -39,404 +40,54 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
41{ 42{
42 public class PresenceModule : IRegionModule, IPresenceModule 43 public class PresenceModule : ISharedRegionModule, IPresenceModule
43 { 44 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(
45 46 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 47
59 public event PresenceChange OnPresenceChange; 48 public event PresenceChange OnPresenceChange;
60 public event BulkPresenceData OnBulkPresenceData; 49 public event BulkPresenceData OnBulkPresenceData;
61 50
62 public void Initialise(Scene scene, IConfigSource config) 51 public void Initialise(IConfigSource config)
63 { 52 {
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
80 m_Enabled = true;
81
82 m_initialScene = scene;
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 } 53 }
97 54
98 public void PostInitialise() 55 public void AddRegion(Scene scene)
99 { 56 {
100 } 57 }
101 58
102 public void Close() 59 public void RegionLoaded(Scene scene)
103 { 60 {
104 if (!m_Gridmode || !m_Enabled)
105 return;
106
107 if (OnPresenceChange != null)
108 {
109 lock (m_RootAgents)
110 {
111 // on shutdown, users are kicked, too
112 foreach (KeyValuePair<UUID, Scene> pair in m_RootAgents)
113 {
114 OnPresenceChange(new PresenceInfo(pair.Key, UUID.Zero));
115 }
116 }
117 }
118
119 lock (m_Scenes)
120 {
121 foreach (Scene scene in m_Scenes)
122 NotifyMessageServerOfShutdown(scene);
123 }
124 } 61 }
125 62
126 public string Name 63 public void RemoveRegion(Scene scene)
127 { 64 {
128 get { return "PresenceModule"; }
129 }
130
131 public bool IsSharedModule
132 {
133 get { return true; }
134 }
135
136 public void RequestBulkPresenceData(UUID[] users)
137 {
138 if (OnBulkPresenceData != null)
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
163 // now we have filtered out all the local root agents. The rest we have to request info about
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
206 // tell everyone
207 OnBulkPresenceData(result);
208 }
209 }
210
211 // new client doesn't mean necessarily that user logged in, it just means it entered one of the
212 // the regions on this server
213 public void OnNewClient(IClientAPI client)
214 {
215 client.OnConnectionClosed += OnConnectionClosed;
216 client.OnLogout += OnLogout;
217
218 // KLUDGE: See handler for details.
219 client.OnEconomyDataRequest += OnEconomyDataRequest;
220 } 65 }
221 66
222 // connection closed just means *one* client connection has been closed. It doesn't mean that the 67 public void PostInitialise()
223 // user has logged off; it might have just TPed away.
224 public void OnConnectionClosed(IClientAPI client)
225 {
226 // TODO: Have to think what we have to do here...
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 }
244
245 // Triggered when the user logs off.
246 public void OnLogout(IClientAPI client)
247 {
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 }
262
263 public void OnSetRootAgentScene(UUID agentID, Scene scene)
264 {
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 }
286
287 private void OnEconomyDataRequest(UUID agentID)
288 { 68 {
289 // KLUDGE: This is the only way I found to get a message (only) after login was completed and the
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 } 69 }
318 70
319 public void OnMakeChildAgent(ScenePresence agent) 71 public void Close()
320 { 72 {
321 // OnMakeChildAgent can be called from several threads at once (with different agent).
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 } 73 }
336 74
337 private void NotifyMessageServerOfStartup(Scene scene) 75 public string Name
338 { 76 {
339 Hashtable xmlrpcdata = new Hashtable(); 77 get { return "PresenceModule"; }
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 } 78 }
359 79
360 private void NotifyMessageServerOfShutdown(Scene scene) 80 public Type ReplaceableInterface
361 { 81 {
362 if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) 82 get { return null; }
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 } 83 }
385 84
386 private void NotifyMessageServerOfAgentLocation(UUID agentID, UUID region, ulong regionHandle) 85 public void RequestBulkPresenceData(UUID[] users)
387 { 86 {
388 if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty)
389 return;
390
391 Hashtable xmlrpcdata = new Hashtable();
392 xmlrpcdata["AgentID"] = agentID.ToString();
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
402 Hashtable responseData = (Hashtable)resp.Value;
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 } 87 }
413 88
414 private void NotifyMessageServerOfAgentLeaving(UUID agentID, UUID region, ulong regionHandle) 89 public void OnNewClient(IClientAPI client)
415 { 90 {
416 if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty)
417 return;
418
419 Hashtable xmlrpcdata = new Hashtable();
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 {
427 XmlRpcRequest LeavingRequest = new XmlRpcRequest("agent_leaving", SendParams);
428 XmlRpcResponse resp = LeavingRequest.Send(m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL, 5000);
429
430 Hashtable responseData = (Hashtable)resp.Value;
431 if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE")
432 {
433 m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString());
434 }
435 }
436 catch (WebException)
437 {
438 m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString());
439 }
440 } 91 }
441 } 92 }
442} 93}