aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
diff options
context:
space:
mode:
authorCharles Krinke2009-04-25 18:58:18 +0000
committerCharles Krinke2009-04-25 18:58:18 +0000
commitc17a12544561de8103e1631c1a23dd225bd39698 (patch)
tree104af1bbb1dd1724b38731b37cf9b82f8d0b6fab /OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
parentFix another typo in the ini example (diff)
downloadopensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.zip
opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.gz
opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.bz2
opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.xz
Thank you kindly, MCortez for a patch that:
The attached patch fixes a few problems that people were having with the Messaging provided by the XmlRpcGroups optional module, namely: * Fixes 2x echo in group messaging * Fixes problems with cross instance, non-neighbor, messaging
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs423
1 files changed, 278 insertions, 145 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
index b1b25aa..b1322ab 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
@@ -26,7 +26,6 @@
26 */ 26 */
27 27
28using System; 28using System;
29//using System.Collections;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using System.Reflection; 30using System.Reflection;
32 31
@@ -47,25 +46,27 @@ using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
47 46
48namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 47namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
49{ 48{
50 public class XmlRpcGroupsMessaging : INonSharedRegionModule 49 public class XmlRpcGroupsMessaging : ISharedRegionModule
51 { 50 {
52 51
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 53
55 private List<Scene> m_SceneList = new List<Scene>(); 54 private List<Scene> m_sceneList = new List<Scene>();
56 55
57 // must be NonShared for this to work, otherewise we may actually get multiple active clients 56 private IMessageTransferModule m_msgTransferModule = null;
58 private Dictionary<Guid, IClientAPI> m_ActiveClients = new Dictionary<Guid, IClientAPI>();
59 57
60 private IMessageTransferModule m_MsgTransferModule = null; 58 private IGroupsModule m_groupsModule = null;
59
60 // TODO: Move this off to the xmlrpc server
61 public Dictionary<Guid, List<Guid>> m_agentsInGroupSession = new Dictionary<Guid, List<Guid>>();
62 public Dictionary<Guid, List<Guid>> m_agentsDroppedSession = new Dictionary<Guid, List<Guid>>();
61 63
62 private IGroupsModule m_GroupsModule = null;
63 64
64 // Config Options 65 // Config Options
65 private bool m_GroupMessagingEnabled = true; 66 private bool m_groupMessagingEnabled = true;
66 private bool m_debugEnabled = true; 67 private bool m_debugEnabled = true;
67 68
68 #region IRegionModule Members 69 #region IRegionModuleBase Members
69 70
70 public void Initialise(IConfigSource config) 71 public void Initialise(IConfigSource config)
71 { 72 {
@@ -90,14 +91,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
90 if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") 91 if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups")
91 { 92 {
92 m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); 93 m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups");
93 m_GroupMessagingEnabled = false; 94 m_groupMessagingEnabled = false;
94 95
95 return; 96 return;
96 } 97 }
97 98
98 m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); 99 m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true);
99 100
100 if (!m_GroupMessagingEnabled) 101 if (!m_groupMessagingEnabled)
101 { 102 {
102 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); 103 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled.");
103 return; 104 return;
@@ -113,76 +114,74 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
113 114
114 public void AddRegion(Scene scene) 115 public void AddRegion(Scene scene)
115 { 116 {
117 // NoOp
116 } 118 }
117 public void RegionLoaded(Scene scene) 119 public void RegionLoaded(Scene scene)
118 { 120 {
119 if (!m_GroupMessagingEnabled) 121 if (!m_groupMessagingEnabled)
120 return; 122 return;
121 123
122 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 124 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
123 125
124 126
125 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 127 m_groupsModule = scene.RequestModuleInterface<IGroupsModule>();
126 128
127 // No groups module, no groups messaging 129 // No groups module, no groups messaging
128 if (m_GroupsModule == null) 130 if (m_groupsModule == null)
129 { 131 {
130 m_GroupMessagingEnabled = false; 132 m_groupMessagingEnabled = false;
131 m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); 133 m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled.");
132 Close(); 134 Close();
133 return; 135 return;
134 } 136 }
135 137
136 m_MsgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); 138 m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
137 139
138 // No message transfer module, no groups messaging 140 // No message transfer module, no groups messaging
139 if (m_MsgTransferModule == null) 141 if (m_msgTransferModule == null)
140 { 142 {
141 m_GroupMessagingEnabled = false; 143 m_groupMessagingEnabled = false;
142 m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); 144 m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule");
143 Close(); 145 Close();
144 return; 146 return;
145 } 147 }
146 148
147 149
148 m_SceneList.Add(scene); 150 m_sceneList.Add(scene);
149 151
150 scene.EventManager.OnNewClient += OnNewClient; 152 scene.EventManager.OnNewClient += OnNewClient;
151 scene.EventManager.OnClientClosed += OnClientClosed;
152 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 153 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
153 154
154 } 155 }
155 156
156 public void RemoveRegion(Scene scene) 157 public void RemoveRegion(Scene scene)
157 { 158 {
158 if (!m_GroupMessagingEnabled) 159 if (!m_groupMessagingEnabled)
159 return; 160 return;
160 161
161 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 162 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
162 163
163 m_SceneList.Remove(scene); 164 m_sceneList.Remove(scene);
164 } 165 }
165 166
166 167
167 public void Close() 168 public void Close()
168 { 169 {
169 if (!m_GroupMessagingEnabled) 170 if (!m_groupMessagingEnabled)
170 return; 171 return;
171 172
172 m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); 173 if(m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module.");
173
174 174
175 foreach (Scene scene in m_SceneList) 175 foreach (Scene scene in m_sceneList)
176 { 176 {
177 scene.EventManager.OnNewClient -= OnNewClient; 177 scene.EventManager.OnNewClient -= OnNewClient;
178 scene.EventManager.OnClientClosed -= OnClientClosed;
179 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; 178 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
180 } 179 }
181 180
182 m_SceneList.Clear(); 181 m_sceneList.Clear();
183 182
184 m_GroupsModule = null; 183 m_groupsModule = null;
185 m_MsgTransferModule = null; 184 m_msgTransferModule = null;
186 } 185 }
187 186
188 public string Name 187 public string Name
@@ -192,195 +191,293 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
192 191
193 #endregion 192 #endregion
194 193
195 #region SimGridEventHandlers 194 #region ISharedRegionModule Members
196 195
197 private void OnNewClient(IClientAPI client) 196 public void PostInitialise()
198 { 197 {
199 RegisterClientAgent(client); 198 // NoOp
200 } 199 }
201 private void OnClientClosed(UUID AgentId) 200
201 #endregion
202
203 #region SimGridEventHandlers
204
205 private void OnNewClient(IClientAPI client)
202 { 206 {
203 UnregisterClientAgent(AgentId); 207 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name);
208
209 client.OnInstantMessage += OnInstantMessage;
204 } 210 }
205 211
206 private void OnGridInstantMessage(GridInstantMessage msg) 212 private void OnGridInstantMessage(GridInstantMessage msg)
207 { 213 {
208 m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 214 // The instant message module will only deliver messages of dialog types:
215 // MessageFromAgent, StartTyping, StopTyping, MessageFromObject
216 //
217 // Any other message type will not be delivered to a client by the
218 // Instant Message Module
219
220
221 if (m_debugEnabled)
222 {
223 m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
209 224
210 DebugGridInstantMessage(msg); 225 DebugGridInstantMessage(msg);
226 }
211 227
212 // Incoming message from a group 228 // Incoming message from a group
213 if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) 229 if ((msg.fromGroup == true) &&
230 ( (msg.dialog == (byte)InstantMessageDialog.SessionSend)
231 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
232 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)
233 ))
234 {
235 ProcessMessageFromGroupSession(msg);
236 }
237
238 }
239
240 private void ProcessMessageFromGroupSession(GridInstantMessage msg)
241 {
242 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID);
243
244 switch (msg.dialog)
245 {
246 case (byte)InstantMessageDialog.SessionAdd:
247 AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID);
248 break;
249
250 case (byte)InstantMessageDialog.SessionDrop:
251 RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID);
252 break;
253
254 case (byte)InstantMessageDialog.SessionSend:
255 if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID)
256 && !m_agentsDroppedSession.ContainsKey(msg.toAgentID))
214 { 257 {
215 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnGridInstantMessage from group session {0} going to agent {1}", msg.fromAgentID, msg.toAgentID); 258 // Agent not in session and hasn't dropped from session
259 // Add them to the session for now, and Invite them
260 AddAgentToGroupSession(msg.toAgentID, msg.imSessionID);
216 261
217 if (m_ActiveClients.ContainsKey(msg.toAgentID)) 262 UUID toAgentID = new UUID(msg.toAgentID);
263 IClientAPI activeClient = GetActiveClient(toAgentID);
264 if (activeClient != null)
218 { 265 {
219 UUID GroupID = new UUID(msg.fromAgentID); 266 UUID groupID = new UUID(msg.fromAgentID);
220 // SendMessageToGroup(im);
221 267
222 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); 268 GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID);
223 if (GroupInfo != null) 269 if (groupInfo != null)
224 { 270 {
225 // TODO: Check to see if already a member of session, if so, do not send chatterbox, just forward message 271 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message");
226
227 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message");
228 272
229 // Force? open the group session dialog??? 273 // Force? open the group session dialog???
230 IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface<IEventQueue>(); 274 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
231 eq.ChatterboxInvitation( 275 eq.ChatterboxInvitation(
232 GroupID, 276 groupID
233 GroupInfo.GroupName, 277 , groupInfo.GroupName
234 new UUID(msg.fromAgentID), 278 , new UUID(msg.fromAgentID)
235 msg.message, new UUID(msg.toAgentID), 279 , msg.message, new UUID(msg.toAgentID)
236 msg.fromAgentName, 280 , msg.fromAgentName
237 msg.dialog, 281 , msg.dialog
238 msg.timestamp, 282 , msg.timestamp
239 msg.offline == 1, 283 , msg.offline == 1
240 (int)msg.ParentEstateID, 284 , (int)msg.ParentEstateID
241 msg.Position, 285 , msg.Position
242 1, 286 , 1
243 new UUID(msg.imSessionID), 287 , new UUID(msg.imSessionID)
244 msg.fromGroup, 288 , msg.fromGroup
245 Utils.StringToBytes(GroupInfo.GroupName)); 289 , Utils.StringToBytes(groupInfo.GroupName)
290 );
246 291
247 eq.ChatterBoxSessionAgentListUpdates( 292 eq.ChatterBoxSessionAgentListUpdates(
248 new UUID(GroupID), 293 new UUID(groupID)
249 new UUID(msg.fromAgentID), 294 , new UUID(msg.fromAgentID)
250 new UUID(msg.toAgentID), 295 , new UUID(msg.toAgentID)
251 false, //canVoiceChat 296 , false //canVoiceChat
252 false, //isModerator 297 , false //isModerator
253 false); //text mute 298 , false //text mute
299 );
300
254 } 301 }
255 } 302 }
256 } 303 }
304 else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID))
305 {
306 // User hasn't dropped, so they're in the session,
307 // maybe we should deliver it.
308 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
309 if (client != null)
310 {
311 // Deliver locally, directly
312 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} locally", client.Name);
313 client.SendInstantMessage(msg);
314 }
315 else
316 {
317 m_log.WarnFormat("[GROUPS-MESSAGING] Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
318 }
319 }
320 break;
257 321
322 default:
323 m_log.WarnFormat("[GROUPS-MESSAGING] I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString());
324 break;
325 }
258 } 326 }
259 327
328
329
260 #endregion 330 #endregion
261 331
262 #region ClientEvents 332 #region ClientEvents
263 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
264 {
265 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
266
267 DebugGridInstantMessage(im);
268 333
269 // Start group IM session 334 private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID)
270 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) 335 {
336 if( m_agentsInGroupSession.ContainsKey(sessionID) )
271 { 337 {
272 UUID GroupID = new UUID(im.toAgentID); 338 // If in session remove
273 339 if( m_agentsInGroupSession[sessionID].Contains(agentID) )
274 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID);
275 if (GroupInfo != null)
276 { 340 {
277 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); 341 m_agentsInGroupSession[sessionID].Remove(agentID);
278 342 }
279 // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0]));
280
281 ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID);
282 343
283 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); 344 // If not in dropped list, add
284 queue.ChatterBoxSessionAgentListUpdates( 345 if( !m_agentsDroppedSession[sessionID].Contains(agentID) )
285 new UUID(GroupID), 346 {
286 new UUID(im.fromAgentID), 347 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Dropped {1} from session {0}", sessionID, agentID);
287 new UUID(im.toAgentID), 348 m_agentsDroppedSession[sessionID].Add(agentID);
288 false, //canVoiceChat
289 false, //isModerator
290 false); //text mute
291 } 349 }
292 } 350 }
351 }
293 352
294 // Send a message to a group 353 private void AddAgentToGroupSession(Guid agentID, Guid sessionID)
295 if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) 354 {
296 { 355 // Add Session Status if it doesn't exist for this session
297 UUID GroupID = new UUID(im.toAgentID); 356 CreateGroupSessionTracking(sessionID);
298 357
299 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); 358 // If nessesary, remove from dropped list
359 if( m_agentsDroppedSession[sessionID].Contains(agentID) )
360 {
361 m_agentsDroppedSession[sessionID].Remove(agentID);
362 }
300 363
301 SendMessageToGroup(im, GroupID); 364 // If nessesary, add to in session list
365 if( !m_agentsInGroupSession[sessionID].Contains(agentID) )
366 {
367 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Added {1} to session {0}", sessionID, agentID);
368 m_agentsInGroupSession[sessionID].Add(agentID);
302 } 369 }
370 }
303 371
304 // Incoming message from a group 372 private void CreateGroupSessionTracking(Guid sessionID)
305 if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) 373 {
374 if (!m_agentsInGroupSession.ContainsKey(sessionID))
306 { 375 {
307 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); 376 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Creating session tracking for : {0}", sessionID);
377 m_agentsInGroupSession.Add(sessionID, new List<Guid>());
378 m_agentsDroppedSession.Add(sessionID, new List<Guid>());
308 } 379 }
309 } 380 }
310 #endregion
311 381
312 private void RegisterClientAgent(IClientAPI client) 382 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
313 { 383 {
314 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 384 if (m_debugEnabled)
385 {
386 m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
315 387
316 lock (m_ActiveClients) 388 DebugGridInstantMessage(im);
389 }
390
391 // Start group IM session
392 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
317 { 393 {
318 if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) 394 UUID groupID = new UUID(im.toAgentID);
395
396 GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID);
397 if (groupInfo != null)
319 { 398 {
320 client.OnInstantMessage += OnInstantMessage; 399 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Start Group Session for {0}", groupInfo.GroupName);
321 400
322 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); 401 AddAgentToGroupSession(im.fromAgentID, im.imSessionID);
323 402
324 m_ActiveClients.Add(client.AgentId.Guid, client); 403 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID);
325 }
326 else
327 {
328 // Remove old client connection for this agent
329 UnregisterClientAgent(client.AgentId);
330 404
331 // Add new client connection 405 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
332 RegisterClientAgent(client); 406 queue.ChatterBoxSessionAgentListUpdates(
407 new UUID(groupID)
408 , new UUID(im.fromAgentID)
409 , new UUID(im.toAgentID)
410 , false //canVoiceChat
411 , false //isModerator
412 , false //text mute
413 );
333 } 414 }
334 } 415 }
335 } 416
336 private void UnregisterClientAgent(UUID agentID) 417 // Send a message from locally connected client to a group
337 { 418 if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
338 lock (m_ActiveClients)
339 { 419 {
340 if (m_ActiveClients.ContainsKey(agentID.Guid)) 420 UUID groupID = new UUID(im.toAgentID);
341 {
342 IClientAPI client = m_ActiveClients[agentID.Guid];
343 client.OnInstantMessage -= OnInstantMessage;
344 421
345 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); 422 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString());
346 423
347 m_ActiveClients.Remove(agentID.Guid); 424 SendMessageToGroup(im, groupID);
348 }
349 else
350 {
351 m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here.");
352 }
353 } 425 }
354 } 426 }
427 #endregion
355 428
356 private void SendMessageToGroup(GridInstantMessage im, UUID groupID) 429 private void SendMessageToGroup(GridInstantMessage im, UUID groupID)
357 { 430 {
358 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 431 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
432
359 433
434 foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID))
435 {
436 if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid))
437 {
438 // Don't deliver messages to people who have dropped this session
439 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} has dropped session, not delivering to them", member.AgentID);
440 continue;
441 }
442
443 // Copy Message
360 GridInstantMessage msg = new GridInstantMessage(); 444 GridInstantMessage msg = new GridInstantMessage();
361 msg.imSessionID = im.imSessionID; 445 msg.imSessionID = im.imSessionID;
362 msg.fromAgentID = im.imSessionID; // GroupID
363 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
364 msg.fromAgentName = im.fromAgentName; 446 msg.fromAgentName = im.fromAgentName;
365 msg.message = im.message; 447 msg.message = im.message;
366 msg.dialog = im.dialog; 448 msg.dialog = im.dialog;
367 msg.fromGroup = true; 449 msg.offline = im.offline;
368 msg.offline = (byte)0;
369 msg.ParentEstateID = im.ParentEstateID; 450 msg.ParentEstateID = im.ParentEstateID;
370 msg.Position = im.Position; 451 msg.Position = im.Position;
371 msg.RegionID = im.RegionID; 452 msg.RegionID = im.RegionID;
372 msg.binaryBucket = new byte[1]{0}; 453 msg.binaryBucket = im.binaryBucket;
454 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
455
456 // Updat Pertinate fields to make it a "group message"
457 msg.fromAgentID = groupID.Guid;
458 msg.fromGroup = true;
373 459
374 foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID))
375 {
376 msg.toAgentID = member.AgentID.Guid; 460 msg.toAgentID = member.AgentID.Guid;
377 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); 461
462 IClientAPI client = GetActiveClient(member.AgentID);
463 if (client == null)
464 {
465 // If they're not local, forward across the grid
466 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} via Grid", member.AgentID);
467 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
468 }
469 else
470 {
471 // Deliver locally, directly
472 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
473 ProcessMessageFromGroupSession(msg);
474 }
378 } 475 }
379 } 476 }
380 477
381 void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) 478 void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
382 { 479 {
383 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 480 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
384 481
385 OSDMap moderatedMap = new OSDMap(4); 482 OSDMap moderatedMap = new OSDMap(4);
386 moderatedMap.Add("voice", OSD.FromBoolean(false)); 483 moderatedMap.Add("voice", OSD.FromBoolean(false));
@@ -398,12 +495,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
398 bodyMap.Add("success", OSD.FromBoolean(true)); 495 bodyMap.Add("success", OSD.FromBoolean(true));
399 bodyMap.Add("session_info", sessionMap); 496 bodyMap.Add("session_info", sessionMap);
400 497
498
401 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); 499 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
402 500
403 if (queue != null) 501 if (queue != null)
404 { 502 {
405 queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); 503 queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
406 } 504 }
505
407 } 506 }
408 507
409 508
@@ -422,5 +521,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
422 m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); 521 m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
423 } 522 }
424 } 523 }
524
525 #region Client Tools
526
527 /// <summary>
528 /// Try to find an active IClientAPI reference for agentID giving preference to root connections
529 /// </summary>
530 private IClientAPI GetActiveClient(UUID agentID)
531 {
532 IClientAPI child = null;
533
534 // Try root avatar first
535 foreach (Scene scene in m_sceneList)
536 {
537 if (scene.Entities.ContainsKey(agentID) &&
538 scene.Entities[agentID] is ScenePresence)
539 {
540 ScenePresence user = (ScenePresence)scene.Entities[agentID];
541 if (!user.IsChildAgent)
542 {
543 return user.ControllingClient;
544 }
545 else
546 {
547 child = user.ControllingClient;
548 }
549 }
550 }
551
552 // If we didn't find a root, then just return whichever child we found, or null if none
553 return child;
554 }
555
556 #endregion
425 } 557 }
558
426} 559}