diff options
author | Diva Canto | 2013-07-27 15:38:56 -0700 |
---|---|---|
committer | Diva Canto | 2013-07-27 15:38:56 -0700 |
commit | 69975763d2a735eb2696d2e27e5796a472a208ea (patch) | |
tree | 3d3454d731471148951de01a9931aa5e67d359da /OpenSim/Addons/Groups/GroupsMessagingModule.cs | |
parent | Clarifications on documentation of Group configs (diff) | |
download | opensim-SC-69975763d2a735eb2696d2e27e5796a472a208ea.zip opensim-SC-69975763d2a735eb2696d2e27e5796a472a208ea.tar.gz opensim-SC-69975763d2a735eb2696d2e27e5796a472a208ea.tar.bz2 opensim-SC-69975763d2a735eb2696d2e27e5796a472a208ea.tar.xz |
Several major improvements to group (V2) chat. Specifically: handle join/drop appropriately, invitechatboxes.
The major departure from flotsam is to send only one message per destination region, as opposed to one message per group member. This reduces messaging considerably in large groups that have clusters of members in certain regions.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Addons/Groups/GroupsMessagingModule.cs | 385 |
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; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | 41 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; |
42 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
42 | 43 | ||
43 | namespace OpenSim.Groups | 44 | namespace 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 | } |