aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Addons/Groups/GroupsMessagingModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Addons/Groups/GroupsMessagingModule.cs')
-rw-r--r--OpenSim/Addons/Groups/GroupsMessagingModule.cs385
1 files changed, 270 insertions, 115 deletions
diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
index 31e9175..be76ef1 100644
--- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs
+++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
@@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 43
43namespace OpenSim.Groups 44namespace OpenSim.Groups
44{ 45{
@@ -79,6 +80,10 @@ namespace OpenSim.Groups
79 80
80 private int m_usersOnlineCacheExpirySeconds = 20; 81 private int m_usersOnlineCacheExpirySeconds = 20;
81 82
83 private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
84 private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
85
86
82 #region Region Module interfaceBase Members 87 #region Region Module interfaceBase Members
83 88
84 public void Initialise(IConfigSource config) 89 public void Initialise(IConfigSource config)
@@ -227,62 +232,50 @@ namespace OpenSim.Groups
227 232
228 public void SendMessageToGroup(GridInstantMessage im, UUID groupID) 233 public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
229 { 234 {
230 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID); 235 UUID fromAgentID = new UUID(im.fromAgentID);
236 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(fromAgentID.ToString(), groupID);
231 int groupMembersCount = groupMembers.Count; 237 int groupMembersCount = groupMembers.Count;
238 PresenceInfo[] onlineAgents = null;
232 239
233 if (m_messageOnlineAgentsOnly) 240 // In V2 we always only send to online members.
234 { 241 // Sending to offline members is not an option.
235 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray(); 242 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
236 243
237 // We cache in order not to overwhlem the presence service on large grids with many groups. This does 244 // We cache in order not to overwhlem the presence service on large grids with many groups. This does
238 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. 245 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
239 // (assuming this is the same across all grid simulators). 246 // (assuming this is the same across all grid simulators).
240 PresenceInfo[] onlineAgents; 247 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
241 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) 248 {
242 { 249 onlineAgents = m_presenceService.GetAgents(t1);
243 onlineAgents = m_presenceService.GetAgents(t1); 250 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
244 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); 251 }
245 }
246 252
247 HashSet<string> onlineAgentsUuidSet = new HashSet<string>(); 253 HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
248 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); 254 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
249 255
250 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); 256 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
251 257
252 // if (m_debugEnabled) 258// if (m_debugEnabled)
253// m_log.DebugFormat( 259// m_log.DebugFormat(
254// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", 260// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
255// groupID, groupMembersCount, groupMembers.Count()); 261// groupID, groupMembersCount, groupMembers.Count());
256 }
257 else
258 {
259 if (m_debugEnabled)
260 m_log.DebugFormat(
261 "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members",
262 groupID, groupMembers.Count);
263 }
264 262
265 int requestStartTick = Environment.TickCount; 263 int requestStartTick = Environment.TickCount;
266 264
267 // Copy Message 265 im.imSessionID = groupID.Guid;
268 GridInstantMessage msg = new GridInstantMessage(); 266 im.fromGroup = true;
269 msg.imSessionID = groupID.Guid; 267 IClientAPI thisClient = GetActiveClient(fromAgentID);
270 msg.fromAgentName = im.fromAgentName; 268 if (thisClient != null)
271 msg.message = im.message; 269 {
272 msg.dialog = im.dialog; 270 im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
273 msg.offline = im.offline; 271 }
274 msg.ParentEstateID = im.ParentEstateID;
275 msg.Position = im.Position;
276 msg.RegionID = im.RegionID;
277 msg.binaryBucket = im.binaryBucket;
278 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
279
280 msg.fromAgentID = im.fromAgentID;
281 msg.fromGroup = true;
282 272
283 // Send to self first of all 273 // Send to self first of all
284 msg.toAgentID = msg.fromAgentID; 274 im.toAgentID = im.fromAgentID;
285 ProcessMessageFromGroupSession(msg); 275 ProcessMessageFromGroupSession(im);
276
277 List<UUID> regions = new List<UUID>();
278 List<UUID> clientsAlreadySent = new List<UUID>();
286 279
287 // Then send to everybody else 280 // Then send to everybody else
288 foreach (GroupMembersData member in groupMembers) 281 foreach (GroupMembersData member in groupMembers)
@@ -290,27 +283,50 @@ namespace OpenSim.Groups
290 if (member.AgentID.Guid == im.fromAgentID) 283 if (member.AgentID.Guid == im.fromAgentID)
291 continue; 284 continue;
292 285
293 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) 286 if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
294 { 287 {
295 // Don't deliver messages to people who have dropped this session 288 // Don't deliver messages to people who have dropped this session
296 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); 289 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
297 continue; 290 continue;
298 } 291 }
299 292
300 msg.toAgentID = member.AgentID.Guid; 293 im.toAgentID = member.AgentID.Guid;
301 294
302 IClientAPI client = GetActiveClient(member.AgentID); 295 IClientAPI client = GetActiveClient(member.AgentID);
303 if (client == null) 296 if (client == null)
304 { 297 {
305 // If they're not local, forward across the grid 298 // If they're not local, forward across the grid
299 // BUT do it only once per region, please! Sim would be even better!
306 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); 300 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
307 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); 301
302 bool reallySend = true;
303 if (onlineAgents != null)
304 {
305 PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
306 if (regions.Contains(presence.RegionID))
307 reallySend = false;
308 else
309 regions.Add(presence.RegionID);
310 }
311
312 if (reallySend)
313 {
314 // We have to create a new IM structure because the transfer module
315 // uses async send
316 GridInstantMessage msg = new GridInstantMessage(im, true);
317 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
318 }
308 } 319 }
309 else 320 else
310 { 321 {
311 // Deliver locally, directly 322 // Deliver locally, directly
312 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); 323 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
313 ProcessMessageFromGroupSession(msg); 324
325 if (clientsAlreadySent.Contains(member.AgentID))
326 continue;
327 clientsAlreadySent.Add(member.AgentID);
328
329 ProcessMessageFromGroupSession(im);
314 } 330 }
315 } 331 }
316 332
@@ -343,21 +359,90 @@ namespace OpenSim.Groups
343 // Any other message type will not be delivered to a client by the 359 // Any other message type will not be delivered to a client by the
344 // Instant Message Module 360 // Instant Message Module
345 361
346 362 UUID regionID = new UUID(msg.RegionID);
347 if (m_debugEnabled) 363 if (m_debugEnabled)
348 { 364 {
349 m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 365 m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
366 System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
350 367
351 DebugGridInstantMessage(msg); 368 DebugGridInstantMessage(msg);
352 } 369 }
353 370
354 // Incoming message from a group 371 // Incoming message from a group
355 if ((msg.fromGroup == true) && 372 if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
356 ((msg.dialog == (byte)InstantMessageDialog.SessionSend)
357 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
358 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
359 { 373 {
360 ProcessMessageFromGroupSession(msg); 374 // We have to redistribute the message across all members of the group who are here
375 // on this sim
376
377 UUID GroupID = new UUID(msg.imSessionID);
378
379 Scene aScene = m_sceneList[0];
380 GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
381
382 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(msg.fromAgentID).ToString(), GroupID);
383 List<UUID> alreadySeen = new List<UUID>();
384
385 foreach (Scene s in m_sceneList)
386 {
387 s.ForEachScenePresence(sp =>
388 {
389 // We need this, because we are searching through all
390 // SPs, both root and children
391 if (alreadySeen.Contains(sp.UUID))
392 {
393 if (m_debugEnabled)
394 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because we've already seen it", sp.UUID);
395 return;
396 }
397 alreadySeen.Add(sp.UUID);
398
399 GroupMembersData m = groupMembers.Find(gmd =>
400 {
401 return gmd.AgentID == sp.UUID;
402 });
403 if (m.AgentID == UUID.Zero)
404 {
405 if (m_debugEnabled)
406 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
407 return;
408 }
409
410 // Check if the user has an agent in the region where
411 // the IM came from, and if so, skip it, because the IM
412 // was already sent via that agent
413 if (regionOfOrigin != null)
414 {
415 AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
416 if (aCircuit != null)
417 {
418 if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
419 {
420 if (m_debugEnabled)
421 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
422 return;
423 }
424 else
425 {
426 if (m_debugEnabled)
427 m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
428 }
429 }
430 }
431
432 UUID AgentID = sp.UUID;
433 msg.toAgentID = AgentID.Guid;
434
435 if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)
436 && !hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
437 {
438 AddAgentToSession(AgentID, GroupID, msg);
439 }
440
441 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
442
443 ProcessMessageFromGroupSession(msg);
444 });
445 }
361 } 446 }
362 } 447 }
363 448
@@ -367,82 +452,40 @@ namespace OpenSim.Groups
367 452
368 UUID AgentID = new UUID(msg.fromAgentID); 453 UUID AgentID = new UUID(msg.fromAgentID);
369 UUID GroupID = new UUID(msg.imSessionID); 454 UUID GroupID = new UUID(msg.imSessionID);
455 UUID toAgentID = new UUID(msg.toAgentID);
370 456
371 switch (msg.dialog) 457 switch (msg.dialog)
372 { 458 {
373 case (byte)InstantMessageDialog.SessionAdd: 459 case (byte)InstantMessageDialog.SessionAdd:
374 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 460 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
375 break; 461 break;
376 462
377 case (byte)InstantMessageDialog.SessionDrop: 463 case (byte)InstantMessageDialog.SessionDrop:
378 m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); 464 AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
379 break; 465 break;
380 466
381 case (byte)InstantMessageDialog.SessionSend: 467 case (byte)InstantMessageDialog.SessionSend:
382 if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID) 468 // User hasn't dropped, so they're in the session,
383 && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID) 469 // maybe we should deliver it.
384 ) 470 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
471 if (client != null)
385 { 472 {
386 // Agent not in session and hasn't dropped from session 473 // Deliver locally, directly
387 // Add them to the session for now, and Invite them 474 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
388 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
389 475
390 UUID toAgentID = new UUID(msg.toAgentID); 476 if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
391 IClientAPI activeClient = GetActiveClient(toAgentID);
392 if (activeClient != null)
393 { 477 {
394 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); 478 if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
395 if (groupInfo != null) 479 // This actually sends the message too, so no need to resend it
396 { 480 // with client.SendInstantMessage
397 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); 481 AddAgentToSession(toAgentID, GroupID, msg);
398 482 else
399 // Force? open the group session dialog??? 483 client.SendInstantMessage(msg);
400 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
401 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
402 eq.ChatterboxInvitation(
403 GroupID
404 , groupInfo.GroupName
405 , new UUID(msg.fromAgentID)
406 , msg.message
407 , new UUID(msg.toAgentID)
408 , msg.fromAgentName
409 , msg.dialog
410 , msg.timestamp
411 , msg.offline == 1
412 , (int)msg.ParentEstateID
413 , msg.Position
414 , 1
415 , new UUID(msg.imSessionID)
416 , msg.fromGroup
417 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
418 );
419
420 eq.ChatterBoxSessionAgentListUpdates(
421 new UUID(GroupID)
422 , new UUID(msg.fromAgentID)
423 , new UUID(msg.toAgentID)
424 , false //canVoiceChat
425 , false //isModerator
426 , false //text mute
427 );
428 }
429 } 484 }
430 } 485 }
431 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) 486 else
432 { 487 {
433 // User hasn't dropped, so they're in the session, 488 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
434 // maybe we should deliver it.
435 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
436 if (client != null)
437 {
438 // Deliver locally, directly
439 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
440 client.SendInstantMessage(msg);
441 }
442 else
443 {
444 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
445 }
446 } 489 }
447 break; 490 break;
448 491
@@ -452,6 +495,53 @@ namespace OpenSim.Groups
452 } 495 }
453 } 496 }
454 497
498 private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
499 {
500 // Agent not in session and hasn't dropped from session
501 // Add them to the session for now, and Invite them
502 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
503
504 IClientAPI activeClient = GetActiveClient(AgentID);
505 if (activeClient != null)
506 {
507 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
508 if (groupInfo != null)
509 {
510 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
511
512 // Force? open the group session dialog???
513 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
514 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
515 eq.ChatterboxInvitation(
516 GroupID
517 , groupInfo.GroupName
518 , new UUID(msg.fromAgentID)
519 , msg.message
520 , AgentID
521 , msg.fromAgentName
522 , msg.dialog
523 , msg.timestamp
524 , msg.offline == 1
525 , (int)msg.ParentEstateID
526 , msg.Position
527 , 1
528 , new UUID(msg.imSessionID)
529 , msg.fromGroup
530 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
531 );
532
533 eq.ChatterBoxSessionAgentListUpdates(
534 new UUID(GroupID)
535 , AgentID
536 , new UUID(msg.toAgentID)
537 , false //canVoiceChat
538 , false //isModerator
539 , false //text mute
540 );
541 }
542 }
543 }
544
455 #endregion 545 #endregion
456 546
457 547
@@ -477,7 +567,7 @@ namespace OpenSim.Groups
477 567
478 if (groupInfo != null) 568 if (groupInfo != null)
479 { 569 {
480 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 570 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
481 571
482 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); 572 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
483 573
@@ -503,7 +593,7 @@ namespace OpenSim.Groups
503 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); 593 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
504 594
505 //If this agent is sending a message, then they want to be in the session 595 //If this agent is sending a message, then they want to be in the session
506 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 596 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
507 597
508 SendMessageToGroup(im, GroupID); 598 SendMessageToGroup(im, GroupID);
509 } 599 }
@@ -598,5 +688,70 @@ namespace OpenSim.Groups
598 } 688 }
599 689
600 #endregion 690 #endregion
691
692 #region GroupSessionTracking
693
694 public void ResetAgentGroupChatSessions(string agentID)
695 {
696 foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
697 {
698 agentList.Remove(agentID);
699 }
700 }
701
702 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
703 {
704 // If we're tracking this group, and we can find them in the tracking, then they've been invited
705 return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
706 && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
707 }
708
709 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
710 {
711 // If we're tracking drops for this group,
712 // and we find them, well... then they've dropped
713 return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
714 && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
715 }
716
717 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
718 {
719 if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
720 {
721 // If not in dropped list, add
722 if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
723 {
724 m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
725 }
726 }
727 }
728
729 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
730 {
731 // Add Session Status if it doesn't exist for this session
732 CreateGroupChatSessionTracking(groupID);
733
734 // If nessesary, remove from dropped list
735 if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
736 {
737 m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
738 }
739
740 // Add to invited
741 if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
742 m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
743 }
744
745 private void CreateGroupChatSessionTracking(UUID groupID)
746 {
747 if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
748 {
749 m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
750 m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
751 }
752
753 }
754 #endregion
755
601 } 756 }
602} 757}