aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs423
1 files changed, 423 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
new file mode 100644
index 0000000..d14d135
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
@@ -0,0 +1,423 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29//using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32
33
34using log4net;
35using Nini.Config;
36
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39
40using OpenSim.Framework;
41using OpenSim.Region.CoreModules.Framework.EventQueue;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44
45
46using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
47
48namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
49{
50 public class XmlRpcGroupsMessaging : INonSharedRegionModule
51 {
52
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private List<Scene> m_SceneList = new List<Scene>();
56
57 // must be NonShared for this to work, otherewise we may actually get multiple active clients
58 private Dictionary<Guid, IClientAPI> m_ActiveClients = new Dictionary<Guid, IClientAPI>();
59
60 private IMessageTransferModule m_MsgTransferModule = null;
61
62 private IGroupsModule m_GroupsModule = null;
63
64 // Config Options
65 private bool m_GroupMessagingEnabled = true;
66 private bool m_debugEnabled = true;
67
68 #region IRegionModule Members
69
70 public void Initialise(IConfigSource config)
71 {
72 IConfig groupsConfig = config.Configs["Groups"];
73
74 m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging");
75
76 if (groupsConfig == null)
77 {
78 // Do not run this module by default.
79 m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging");
80 return;
81 }
82 else
83 {
84 if (!groupsConfig.GetBoolean("Enabled", false))
85 {
86 m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration");
87 return;
88 }
89
90 if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups")
91 {
92 m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups");
93
94 return;
95 }
96
97 m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true);
98
99 if (!m_GroupMessagingEnabled)
100 {
101 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled.");
102 return;
103 }
104
105 m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true);
106
107 }
108
109 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up");
110
111 }
112
113 public void AddRegion(Scene scene)
114 {
115 }
116 public void RegionLoaded(Scene scene)
117 {
118 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
119
120 if (!m_GroupMessagingEnabled)
121 return;
122
123
124 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
125
126 // No groups module, no groups messaging
127 if (m_GroupsModule == null)
128 {
129 m_GroupMessagingEnabled = false;
130 m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled.");
131 Close();
132 return;
133 }
134
135 m_MsgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
136
137 // No message transfer module, no groups messaging
138 if (m_MsgTransferModule == null)
139 {
140 m_GroupMessagingEnabled = false;
141 m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule");
142 Close();
143 return;
144 }
145
146
147 m_SceneList.Add(scene);
148
149 scene.EventManager.OnNewClient += OnNewClient;
150 scene.EventManager.OnClientClosed += OnClientClosed;
151 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
152
153 }
154
155 public void RemoveRegion(Scene scene)
156 {
157 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
158
159 m_SceneList.Remove(scene);
160 }
161
162
163 public void Close()
164 {
165 m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module.");
166
167
168 foreach (Scene scene in m_SceneList)
169 {
170 scene.EventManager.OnNewClient -= OnNewClient;
171 scene.EventManager.OnClientClosed -= OnClientClosed;
172 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
173 }
174
175 m_SceneList.Clear();
176
177 m_GroupsModule = null;
178 m_MsgTransferModule = null;
179 }
180
181 public string Name
182 {
183 get { return "XmlRpcGroupsMessaging"; }
184 }
185
186 #endregion
187
188 #region SimGridEventHandlers
189
190 private void OnNewClient(IClientAPI client)
191 {
192 RegisterClientAgent(client);
193 }
194 private void OnClientClosed(UUID AgentId)
195 {
196 UnregisterClientAgent(AgentId);
197 }
198
199 private void OnGridInstantMessage(GridInstantMessage msg)
200 {
201 m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
202
203 DebugGridInstantMessage(msg);
204
205 // Incoming message from a group
206 if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true))
207 {
208 if (m_ActiveClients.ContainsKey(msg.toAgentID))
209 {
210 UUID GroupID = new UUID(msg.fromAgentID);
211 // SendMessageToGroup(im);
212
213 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID);
214 if (GroupInfo != null)
215 {
216
217 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message");
218
219 // Force? open the group session dialog???
220 IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface<IEventQueue>();
221 eq.ChatterboxInvitation(
222 GroupID
223 , GroupInfo.GroupName
224 , new UUID(msg.fromAgentID)
225 , msg.message, new UUID(msg.toAgentID)
226 , msg.fromAgentName
227 , msg.dialog
228 , msg.timestamp
229 , msg.offline==1
230 , (int)msg.ParentEstateID
231 , msg.Position
232 , 1
233 , new UUID(msg.imSessionID)
234 , msg.fromGroup
235 , Utils.StringToBytes(GroupInfo.GroupName)
236 );
237
238 eq.ChatterBoxSessionAgentListUpdates(
239 new UUID(GroupID)
240 , new UUID(msg.fromAgentID)
241 , new UUID(msg.toAgentID)
242 , false //canVoiceChat
243 , false //isModerator
244 , false //text mute
245 );
246
247 }
248 }
249 }
250
251 }
252
253 #endregion
254
255 #region ClientEvents
256 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
257 {
258 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
259
260 DebugGridInstantMessage(im);
261
262 // Start group IM session
263 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
264 {
265 UUID GroupID = new UUID(im.toAgentID);
266
267 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID);
268 if (GroupInfo != null)
269 {
270 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName);
271
272 // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0]));
273
274 ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID);
275
276 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
277 queue.ChatterBoxSessionAgentListUpdates(
278 new UUID(GroupID)
279 , new UUID(im.fromAgentID)
280 , new UUID(im.toAgentID)
281 , false //canVoiceChat
282 , false //isModerator
283 , false //text mute
284 );
285 }
286 }
287
288 // Send a message to a group
289 if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
290 {
291 UUID GroupID = new UUID(im.toAgentID);
292
293 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID);
294
295 SendMessageToGroup(im, GroupID);
296 }
297
298 // Incoming message from a group
299 if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true))
300 {
301 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID);
302 }
303 }
304 #endregion
305
306 private void RegisterClientAgent(IClientAPI client)
307 {
308 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
309
310 lock (m_ActiveClients)
311 {
312 if (!m_ActiveClients.ContainsKey(client.AgentId.Guid))
313 {
314 client.OnInstantMessage += OnInstantMessage;
315
316 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name);
317
318 m_ActiveClients.Add(client.AgentId.Guid, client);
319 }
320 else
321 {
322 // Remove old client connection for this agent
323 UnregisterClientAgent(client.AgentId);
324
325 // Add new client connection
326 RegisterClientAgent(client);
327 }
328 }
329 }
330 private void UnregisterClientAgent(UUID agentID)
331 {
332 lock (m_ActiveClients)
333 {
334 if (m_ActiveClients.ContainsKey(agentID.Guid))
335 {
336 IClientAPI client = m_ActiveClients[agentID.Guid];
337 client.OnInstantMessage -= OnInstantMessage;
338
339 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name);
340
341 m_ActiveClients.Remove(agentID.Guid);
342 }
343 else
344 {
345 m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here.");
346 }
347 }
348 }
349
350 private void SendMessageToGroup(GridInstantMessage im, UUID groupID)
351 {
352 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
353
354 GridInstantMessage msg = new GridInstantMessage();
355 msg.imSessionID = im.imSessionID;
356 msg.fromAgentID = im.imSessionID; // GroupID
357 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
358 msg.fromAgentName = im.fromAgentName;
359 msg.message = im.message;
360 msg.dialog = im.dialog;
361 msg.fromGroup = true;
362 msg.offline = (byte)0;
363 msg.ParentEstateID = im.ParentEstateID;
364 msg.Position = im.Position;
365 msg.RegionID = im.RegionID;
366 msg.binaryBucket = new byte[1] { 0 };
367
368 foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID))
369 {
370 msg.toAgentID = member.AgentID.Guid;
371 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
372 }
373 }
374
375 void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
376 {
377 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
378
379 OSDMap moderatedMap = new OSDMap(4);
380 moderatedMap.Add("voice", OSD.FromBoolean(false));
381
382 OSDMap sessionMap = new OSDMap(4);
383 sessionMap.Add("moderated_mode", moderatedMap);
384 sessionMap.Add("session_name", OSD.FromString(groupName));
385 sessionMap.Add("type", OSD.FromInteger(0));
386 sessionMap.Add("voice_enabled", OSD.FromBoolean(false));
387
388
389 OSDMap bodyMap = new OSDMap(4);
390 bodyMap.Add("session_id", OSD.FromUUID(groupID));
391 bodyMap.Add("temp_session_id", OSD.FromUUID(groupID));
392 bodyMap.Add("success", OSD.FromBoolean(true));
393 bodyMap.Add("session_info", sessionMap);
394
395
396 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
397
398 if (queue != null)
399 {
400 queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
401 }
402
403 }
404
405
406 private void DebugGridInstantMessage(GridInstantMessage im)
407 {
408 if (m_debugEnabled)
409 {
410 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False");
411 m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString());
412 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString());
413 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString());
414 m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString());
415 m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString());
416 m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString());
417 m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString());
418 m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
419 }
420 }
421
422 }
423}