aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs517
1 files changed, 272 insertions, 245 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 1565da9..65d50bb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -50,19 +50,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
50 /// ; To use this module, you must specify the following in your OpenSim.ini 50 /// ; To use this module, you must specify the following in your OpenSim.ini
51 /// [GROUPS] 51 /// [GROUPS]
52 /// Enabled = true 52 /// Enabled = true
53 /// 53 ///
54 /// Module = GroupsModule 54 /// Module = GroupsModule
55 /// NoticesEnabled = true 55 /// NoticesEnabled = true
56 /// DebugEnabled = true 56 /// DebugEnabled = true
57 /// 57 ///
58 /// GroupsServicesConnectorModule = XmlRpcGroupsServicesConnector 58 /// GroupsServicesConnectorModule = XmlRpcGroupsServicesConnector
59 /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php 59 /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php
60 /// XmlRpcServiceReadKey = 1234 60 /// XmlRpcServiceReadKey = 1234
61 /// XmlRpcServiceWriteKey = 1234 61 /// XmlRpcServiceWriteKey = 1234
62 /// 62 ///
63 /// MessagingModule = GroupsMessagingModule 63 /// MessagingModule = GroupsMessagingModule
64 /// MessagingEnabled = true 64 /// MessagingEnabled = true
65 /// 65 ///
66 /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for 66 /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for
67 /// ; a problem discovered on some Windows based region servers. Only disable 67 /// ; a problem discovered on some Windows based region servers. Only disable
68 /// ; if you see a large number (dozens) of the following Exceptions: 68 /// ; if you see a large number (dozens) of the following Exceptions:
@@ -79,7 +79,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
79 private IMessageTransferModule m_msgTransferModule; 79 private IMessageTransferModule m_msgTransferModule;
80 80
81 private IGroupsMessagingModule m_groupsMessagingModule; 81 private IGroupsMessagingModule m_groupsMessagingModule;
82 82
83 private IGroupsServicesConnector m_groupData; 83 private IGroupsServicesConnector m_groupData;
84 84
85 // Configuration settings 85 // Configuration settings
@@ -205,10 +205,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
205 } 205 }
206 206
207 scene.EventManager.OnNewClient += OnNewClient; 207 scene.EventManager.OnNewClient += OnNewClient;
208 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
209 scene.EventManager.OnMakeChildAgent += OnMakeChild;
208 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 210 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
209 // The InstantMessageModule itself doesn't do this, 211 scene.EventManager.OnClientClosed += OnClientClosed;
210 // so lets see if things explode if we don't do it
211 // scene.EventManager.OnClientClosed += OnClientClosed;
212 212
213 } 213 }
214 214
@@ -217,6 +217,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
217 if (!m_groupsEnabled) 217 if (!m_groupsEnabled)
218 return; 218 return;
219 219
220 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
221
222 scene.EventManager.OnNewClient -= OnNewClient;
223 scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
224 scene.EventManager.OnMakeChildAgent -= OnMakeChild;
225 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
226 scene.EventManager.OnClientClosed -= OnClientClosed;
220 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 227 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
221 228
222 lock (m_sceneList) 229 lock (m_sceneList)
@@ -233,7 +240,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
233 if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); 240 if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module.");
234 } 241 }
235 242
236 public Type ReplaceableInterface 243 public Type ReplaceableInterface
237 { 244 {
238 get { return null; } 245 get { return null; }
239 } 246 }
@@ -255,84 +262,124 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
255 #endregion 262 #endregion
256 263
257 #region EventHandlers 264 #region EventHandlers
265
266 private void OnMakeRoot(ScenePresence sp)
267 {
268 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
269
270 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
271 // Used for Notices and Group Invites/Accept/Reject
272 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
273
274 // comented out because some viewers no longer suport it
275 // sp.ControllingClient.AddGenericPacketHandler("avatargroupsrequest", AvatarGroupsRequest);
276
277 // Send out group data update for compatibility.
278 // There might be some problem with the thread we're generating this on but not
279 // doing the update at this time causes problems (Mantis #7920 and #7915)
280 // TODO: move sending this update to a later time in the rootification of the client.
281 if(!sp.haveGroupInformation)
282 SendAgentGroupDataUpdate(sp.ControllingClient, false);
283 }
284
285 private void OnMakeChild(ScenePresence sp)
286 {
287 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
288
289 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
290 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
291 }
292
258 private void OnNewClient(IClientAPI client) 293 private void OnNewClient(IClientAPI client)
259 { 294 {
260 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 295 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
261 296
262 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
263 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 297 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
264 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 298 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
265 299
266 // Used for Notices and Group Invites/Accept/Reject
267 client.OnInstantMessage += OnInstantMessage;
268 300
269 // Send client their groups information.
270 SendAgentGroupDataUpdate(client, client.AgentId);
271 } 301 }
272 302
303/* this should be the right message to ask for other avatars groups
304
305 private void AvatarGroupsRequest(Object sender, string method, List<String> args)
306 {
307 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
308
309 if (!(sender is IClientAPI))
310 return;
311
312 IClientAPI remoteClient = (IClientAPI)sender;
313
314 UUID avatarID;
315 UUID.TryParse(args[0], out avatarID);
316
317 if (avatarID != UUID.Zero)
318 {
319 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
320 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
321 }
322 }
323*/
324
325 // this should not be used to send groups memberships, but some viewers do expect it
326 // it does send unnecessary memberships, when viewers just want other properties information
273 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 327 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
274 { 328 {
275 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 329 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
276 330
277 //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray();
278 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); 331 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
279 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); 332 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
280 } 333 }
281 334
282 /* 335
283 * This becomes very problematic in a shared module. In a shared module you may have more then one 336 private void OnClientClosed(UUID AgentId, Scene scene)
284 * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections.
285 * The OnClientClosed event does not provide anything to indicate which one of those should be closed
286 * nor does it provide what scene it was from so that the specific reference can be looked up.
287 * The InstantMessageModule.cs does not currently worry about unregistering the handles,
288 * and it should be an issue, since it's the client that references us not the other way around
289 * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed
290 private void OnClientClosed(UUID AgentId)
291 { 337 {
292 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 338 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
339 if (scene == null)
340 return;
293 341
294 lock (m_ActiveClients) 342 ScenePresence sp = scene.GetScenePresence(AgentId);
343 IClientAPI client = sp.ControllingClient;
344 if (client != null)
295 { 345 {
296 if (m_ActiveClients.ContainsKey(AgentId)) 346 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
347 client.OnRequestAvatarProperties -= OnRequestAvatarProperties;
348 // make child possible not called?
349 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
350 client.OnInstantMessage -= OnInstantMessage;
351 }
352
353/*
354 lock (m_ActiveClients)
297 { 355 {
298 IClientAPI client = m_ActiveClients[AgentId]; 356 if (m_ActiveClients.ContainsKey(AgentId))
299 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; 357 {
300 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; 358 IClientAPI client = m_ActiveClients[AgentId];
301 client.OnDirFindQuery -= OnDirFindQuery; 359 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
302 client.OnInstantMessage -= OnInstantMessage; 360 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
361 client.OnDirFindQuery -= OnDirFindQuery;
362 client.OnInstantMessage -= OnInstantMessage;
303 363
304 m_ActiveClients.Remove(AgentId); 364 m_ActiveClients.Remove(AgentId);
305 } 365 }
306 else 366 else
307 { 367 {
308 if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here."); 368 if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here.");
369 }
309 } 370 }
310 371*/
311
312 }
313 } 372 }
314 */
315 373
316 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 374 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
317 { 375 {
318 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 376 // this a private message for own agent only
319 377 if (dataForAgentID != GetRequestingAgentID(remoteClient))
320 UUID activeGroupID = UUID.Zero; 378 return;
321 string activeGroupTitle = string.Empty;
322 string activeGroupName = string.Empty;
323 ulong activeGroupPowers = (ulong)GroupPowers.None;
324
325 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID);
326 if (membership != null)
327 {
328 activeGroupID = membership.GroupID;
329 activeGroupTitle = membership.GroupTitle;
330 activeGroupPowers = membership.GroupPowers;
331 }
332
333 SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle);
334 379
335 SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); 380 SendAgentGroupDataUpdate(remoteClient, false);
381 // its a info request not a change, so nothing is sent to others
382 // they do get the group title with the avatar object update on arrivel to a region
336 } 383 }
337 384
338 private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) 385 private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient)
@@ -340,7 +387,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
340 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 387 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
341 388
342 string GroupName; 389 string GroupName;
343 390
344 GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); 391 GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null);
345 if (group != null) 392 if (group != null)
346 { 393 {
@@ -356,9 +403,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
356 403
357 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) 404 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
358 { 405 {
359 if (m_debugEnabled) 406 if (m_debugEnabled)
360 m_log.DebugFormat( 407 m_log.DebugFormat(
361 "[GROUPS]: {0} called for {1}, message type {2}", 408 "[GROUPS]: {0} called for {1}, message type {2}",
362 System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog); 409 System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog);
363 410
364 // Group invitations 411 // Group invitations
@@ -403,11 +450,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
403 450
404 OutgoingInstantMessage(msg, inviteInfo.AgentID); 451 OutgoingInstantMessage(msg, inviteInfo.AgentID);
405 452
406 UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); 453 IClientAPI inviteeClient = GetActiveRootClient(inviteInfo.AgentID);
407 454 if(inviteeClient !=null)
408 // TODO: If the inviter is still online, they need an agent dataupdate 455 {
409 // and maybe group membership updates for the invitee 456 SendAgentGroupDataUpdate(inviteeClient,true);
410 457 }
411 m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); 458 m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
412 } 459 }
413 460
@@ -459,8 +506,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
459 //variable will be set to null and attachment will 506 //variable will be set to null and attachment will
460 //not be included with the group notice. 507 //not be included with the group notice.
461 Scene scene = (Scene)remoteClient.Scene; 508 Scene scene = (Scene)remoteClient.Scene;
462 item = new InventoryItemBase(itemID, ownerID); 509 item = scene.InventoryService.GetItem(ownerID, itemID);
463 item = scene.InventoryService.GetItem(item);
464 510
465 if (item != null) 511 if (item != null)
466 { 512 {
@@ -523,20 +569,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
523 if (targetUser != null) 569 if (targetUser != null)
524 { 570 {
525 m_log.DebugFormat( 571 m_log.DebugFormat(
526 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", 572 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
527 NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); 573 NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
528 } 574 }
529 else 575 else
530 { 576 {
531 m_log.DebugFormat( 577 m_log.DebugFormat(
532 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", 578 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
533 NoticeID, member.AgentID, member.AcceptNotices); 579 NoticeID, member.AgentID, member.AcceptNotices);
534 } 580 }
535 } 581 }
536 } 582 }
537 } 583 }
538 584
539 GridInstantMessage msg 585 GridInstantMessage msg
540 = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); 586 = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
541 587
542 if (m_groupsMessagingModule != null) 588 if (m_groupsMessagingModule != null)
@@ -553,7 +599,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
553 599
554 UUID noticeID = new UUID(im.imSessionID); 600 UUID noticeID = new UUID(im.imSessionID);
555 601
556 if (m_debugEnabled) 602 if (m_debugEnabled)
557 m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId); 603 m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId);
558 604
559 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); 605 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
@@ -579,10 +625,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
579 } 625 }
580 else 626 else
581 { 627 {
582 if (m_debugEnabled) 628 if (m_debugEnabled)
583 m_log.DebugFormat( 629 m_log.DebugFormat(
584 "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", 630 "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
585 noticeID, remoteClient.AgentId); 631 noticeID, remoteClient.AgentId);
586 } 632 }
587 } 633 }
588 634
@@ -598,15 +644,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
598 // so we need to send local updates to the agent. 644 // so we need to send local updates to the agent.
599 645
600 UUID ejecteeID = new UUID(im.toAgentID); 646 UUID ejecteeID = new UUID(im.toAgentID);
601 647 im.imSessionID = UUID.Zero.Guid;
602 im.dialog = (byte)InstantMessageDialog.MessageFromAgent; 648 im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
603 OutgoingInstantMessage(im, ejecteeID); 649 OutgoingInstantMessage(im, ejecteeID);
604 650
605 IClientAPI ejectee = GetActiveClient(ejecteeID); 651 IClientAPI ejectee = GetActiveRootClient(ejecteeID);
606 if (ejectee != null) 652 if (ejectee != null)
607 { 653 {
608 UUID groupID = new UUID(im.imSessionID); 654 UUID groupID = new UUID(im.imSessionID);
609 ejectee.SendAgentDropGroup(groupID); 655 ejectee.SendAgentDropGroup(groupID);
656 SendAgentGroupDataUpdate(ejectee,true);
610 } 657 }
611 } 658 }
612 } 659 }
@@ -626,7 +673,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
626 case (byte)InstantMessageDialog.GroupInvitation: 673 case (byte)InstantMessageDialog.GroupInvitation:
627 case (byte)InstantMessageDialog.GroupNotice: 674 case (byte)InstantMessageDialog.GroupNotice:
628 UUID toAgentID = new UUID(msg.toAgentID); 675 UUID toAgentID = new UUID(msg.toAgentID);
629 IClientAPI localClient = GetActiveClient(toAgentID); 676 IClientAPI localClient = GetActiveRootClient(toAgentID);
630 if (localClient != null) 677 if (localClient != null)
631 { 678 {
632 localClient.SendInstantMessage(msg); 679 localClient.SendInstantMessage(msg);
@@ -651,18 +698,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
651 { 698 {
652 return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); 699 return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name);
653 } 700 }
654 701
655 public void ActivateGroup(IClientAPI remoteClient, UUID groupID) 702 public void ActivateGroup(IClientAPI remoteClient, UUID groupID)
656 { 703 {
657 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 704 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
658 705
659 m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 706 UUID agentID = GetRequestingAgentID(remoteClient);
707 m_groupData.SetAgentActiveGroup(agentID, agentID, groupID);
660 708
661 // Changing active group changes title, active powers, all kinds of things 709 // llClientView does this
662 // anyone who is in any region that can see this client, should probably be 710 SendAgentGroupDataUpdate(remoteClient, true);
663 // updated with new group info. At a minimum, they should get ScenePresence
664 // updated with new title.
665 UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
666 } 711 }
667 712
668 /// <summary> 713 /// <summary>
@@ -672,7 +717,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
672 { 717 {
673 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 718 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
674 719
675
676 List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 720 List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID);
677 GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 721 GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID);
678 722
@@ -695,10 +739,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
695 739
696 public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID) 740 public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID)
697 { 741 {
698 if (m_debugEnabled) 742 if (m_debugEnabled)
699 m_log.DebugFormat( 743 m_log.DebugFormat(
700 "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name); 744 "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name);
701 745
702 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); 746 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID);
703 747
704 if (m_debugEnabled) 748 if (m_debugEnabled)
@@ -710,7 +754,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
710 } 754 }
711 755
712 return data; 756 return data;
713
714 } 757 }
715 758
716 public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) 759 public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID)
@@ -744,7 +787,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
744 787
745 GroupProfileData profile = new GroupProfileData(); 788 GroupProfileData profile = new GroupProfileData();
746 789
747
748 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); 790 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null);
749 if (groupInfo != null) 791 if (groupInfo != null)
750 { 792 {
@@ -770,7 +812,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
770 profile.MemberTitle = memberInfo.GroupTitle; 812 profile.MemberTitle = memberInfo.GroupTitle;
771 profile.PowersMask = memberInfo.GroupPowers; 813 profile.PowersMask = memberInfo.GroupPowers;
772 } 814 }
773 815/*
816 this should save xmlrpc calls, but seems to return wrong GroupMembershipCount and GroupRolesCount
817 UUID agent = GetRequestingAgentID(remoteClient);
818 GroupProfileData profile = m_groupData.GetMemberGroupProfile(agent, groupID, agent);
819*/
774 return profile; 820 return profile;
775 } 821 }
776 822
@@ -783,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
783 829
784 public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) 830 public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID)
785 { 831 {
786 if (m_debugEnabled) 832 if (m_debugEnabled)
787 m_log.DebugFormat( 833 m_log.DebugFormat(
788 "[GROUPS]: {0} called with groupID={1}, agentID={2}", 834 "[GROUPS]: {0} called with groupID={1}, agentID={2}",
789 System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); 835 System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID);
@@ -791,6 +837,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
791 return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); 837 return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID);
792 } 838 }
793 839
840 public GroupMembershipData GetActiveMembershipData(UUID agentID)
841 {
842 return m_groupData.GetAgentActiveMembership(agentID, agentID);
843 }
844
794 public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) 845 public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
795 { 846 {
796 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 847 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -811,7 +862,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
811 { 862 {
812 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 863 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
813 864
814 if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) 865 GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name);
866
867 if (groupRecord != null)
815 { 868 {
816 remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); 869 remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists.");
817 return UUID.Zero; 870 return UUID.Zero;
@@ -824,31 +877,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
824 877
825 if (avatar != null) 878 if (avatar != null)
826 { 879 {
827 if (avatar.UserLevel < m_levelGroupCreate) 880 if (avatar.GodController.UserLevel < m_levelGroupCreate)
828 { 881 {
829 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); 882 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient permissions to create a group.");
830 return UUID.Zero; 883 return UUID.Zero;
831 } 884 }
832 } 885 }
833 886
834 // check funds 887 // check funds
835 // is there is a money module present ? 888 // is there a money module present ?
836 IMoneyModule money = scene.RequestModuleInterface<IMoneyModule>(); 889 IMoneyModule money = scene.RequestModuleInterface<IMoneyModule>();
837 if (money != null) 890 if (money != null && money.GroupCreationCharge > 0)
838 { 891 {
839 // do the transaction, that is if the agent has got sufficient funds 892 // do the transaction, that is if the agent has sufficient funds
840 if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { 893 if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) {
841 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); 894 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to create a group.");
842 return UUID.Zero; 895 return UUID.Zero;
843 } 896 }
844 money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); 897 money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name);
845 } 898 }
846 UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); 899 UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient));
847 900
848 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); 901 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully");
849 902
850 // Update the founder with new group information. 903 // Update the founder with new group information.
851 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 904 SendAgentGroupDataUpdate(remoteClient, true);
852 905
853 return groupID; 906 return groupID;
854 } 907 }
@@ -873,7 +926,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
873 if (membership != null) 926 if (membership != null)
874 { 927 {
875 return membership.GroupTitle; 928 return membership.GroupTitle;
876 } 929 }
877 return string.Empty; 930 return string.Empty;
878 } 931 }
879 932
@@ -889,10 +942,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
889 // TODO: Not sure what all is needed here, but if the active group role change is for the group 942 // TODO: Not sure what all is needed here, but if the active group role change is for the group
890 // the client currently has set active, then we need to do a scene presence update too 943 // the client currently has set active, then we need to do a scene presence update too
891 // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) 944 // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID)
892
893 UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
894 }
895 945
946 SendDataUpdate(remoteClient, true);
947 }
896 948
897 public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) 949 public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType)
898 { 950 {
@@ -929,7 +981,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
929 } 981 }
930 982
931 // TODO: This update really should send out updates for everyone in the role that just got changed. 983 // TODO: This update really should send out updates for everyone in the role that just got changed.
932 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 984 SendAgentGroupDataUpdate(remoteClient, false);
933 } 985 }
934 986
935 public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) 987 public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes)
@@ -947,7 +999,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
947 case 1: 999 case 1:
948 // Remove 1000 // Remove
949 m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); 1001 m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID);
950 1002
951 break; 1003 break;
952 default: 1004 default:
953 m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); 1005 m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes);
@@ -955,7 +1007,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
955 } 1007 }
956 1008
957 // TODO: This update really should send out updates for everyone in the role that just got changed. 1009 // TODO: This update really should send out updates for everyone in the role that just got changed.
958 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 1010 SendAgentGroupDataUpdate(remoteClient, false);
959 } 1011 }
960 1012
961 public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) 1013 public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
@@ -983,7 +1035,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
983 msg.toAgentID = agentID.Guid; 1035 msg.toAgentID = agentID.Guid;
984 msg.dialog = dialog; 1036 msg.dialog = dialog;
985 msg.fromGroup = true; 1037 msg.fromGroup = true;
986 msg.offline = (byte)0; 1038 msg.offline = (byte)1; // Allow this message to be stored for offline use
987 msg.ParentEstateID = 0; 1039 msg.ParentEstateID = 0;
988 msg.Position = Vector3.Zero; 1040 msg.Position = Vector3.Zero;
989 msg.RegionID = UUID.Zero.Guid; 1041 msg.RegionID = UUID.Zero.Guid;
@@ -1035,14 +1087,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1035 return msg; 1087 return msg;
1036 } 1088 }
1037 1089
1038 public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
1039 {
1040 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1041
1042 // Send agent information about his groups
1043 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
1044 }
1045
1046 public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) 1090 public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID)
1047 { 1091 {
1048 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1092 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -1050,10 +1094,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1050 // Should check to see if OpenEnrollment, or if there's an outstanding invitation 1094 // Should check to see if OpenEnrollment, or if there's an outstanding invitation
1051 m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); 1095 m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero);
1052 1096
1097 // check funds
1098 // is there a money module present ?
1099 GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null);
1100 IMoneyModule money = remoteClient.Scene.RequestModuleInterface<IMoneyModule>();
1101 if (money != null && groupRecord.MembershipFee > 0)
1102 {
1103 // do the transaction, that is if the agent has sufficient funds
1104 if (!money.AmountCovered(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee)) {
1105 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to join the group.");
1106 return;
1107 }
1108 money.ApplyCharge(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName);
1109 }
1110
1053 remoteClient.SendJoinGroupReply(groupID, true); 1111 remoteClient.SendJoinGroupReply(groupID, true);
1054 1112
1055 // Should this send updates to everyone in the group? 1113 SendAgentGroupDataUpdate(remoteClient, true);
1056 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
1057 } 1114 }
1058 1115
1059 public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) 1116 public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID)
@@ -1068,7 +1125,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1068 1125
1069 // SL sends out notifcations to the group messaging session that the person has left 1126 // SL sends out notifcations to the group messaging session that the person has left
1070 // Should this also update everyone who is in the group? 1127 // Should this also update everyone who is in the group?
1071 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 1128 SendAgentGroupDataUpdate(remoteClient, true);
1072 } 1129 }
1073 1130
1074 public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) 1131 public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID)
@@ -1120,17 +1177,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1120 } 1177 }
1121 1178
1122 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); 1179 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null);
1123 1180 if (groupInfo == null)
1124 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID);
1125 if ((groupInfo == null) || (account == null))
1126 {
1127 return; 1181 return;
1128 } 1182
1183
1184 IClientAPI ejecteeClient = GetActiveRootClient(ejecteeID);
1129 1185
1130 // Send Message to Ejectee 1186 // Send Message to Ejectee
1131 GridInstantMessage msg = new GridInstantMessage(); 1187 GridInstantMessage msg = new GridInstantMessage();
1132 1188
1133 msg.imSessionID = UUID.Zero.Guid; 1189 string ejecteeName = "Unknown member";
1190 // if local send a normal message
1191 if(ejecteeClient != null)
1192 {
1193 msg.imSessionID = UUID.Zero.Guid;
1194 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
1195 // also execute and send update
1196 ejecteeClient.SendAgentDropGroup(groupID);
1197 SendAgentGroupDataUpdate(ejecteeClient,true);
1198 ejecteeName = ejecteeClient.Name;
1199 }
1200 else // send
1201 {
1202 // Interop, received special 210 code for ejecting a group member
1203 // this only works within the comms servers domain, and won't work hypergrid
1204 // TODO:FIXME: Use a presence server of some kind to find out where the
1205 // client actually is, and try contacting that region directly to notify them,
1206 // or provide the notification via xmlrpc update queue
1207
1208 msg.imSessionID = groupInfo.GroupID.Guid;
1209 msg.dialog = (byte)210; //interop
1210 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID);
1211 if (account != null)
1212 ejecteeName = account.FirstName + " " + account.LastName;
1213 }
1214
1134 msg.fromAgentID = agentID.Guid; 1215 msg.fromAgentID = agentID.Guid;
1135 // msg.fromAgentID = info.GroupID; 1216 // msg.fromAgentID = info.GroupID;
1136 msg.toAgentID = ejecteeID.Guid; 1217 msg.toAgentID = ejecteeID.Guid;
@@ -1138,7 +1219,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1138 msg.timestamp = 0; 1219 msg.timestamp = 0;
1139 msg.fromAgentName = agentName; 1220 msg.fromAgentName = agentName;
1140 msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); 1221 msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName);
1141 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; 1222//
1142 msg.fromGroup = false; 1223 msg.fromGroup = false;
1143 msg.offline = (byte)0; 1224 msg.offline = (byte)0;
1144 msg.ParentEstateID = 0; 1225 msg.ParentEstateID = 0;
@@ -1148,11 +1229,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1148 OutgoingInstantMessage(msg, ejecteeID); 1229 OutgoingInstantMessage(msg, ejecteeID);
1149 1230
1150 // Message to ejector 1231 // Message to ejector
1151 // Interop, received special 210 code for ejecting a group member
1152 // this only works within the comms servers domain, and won't work hypergrid
1153 // TODO:FIXME: Use a presence server of some kind to find out where the
1154 // client actually is, and try contacting that region directly to notify them,
1155 // or provide the notification via xmlrpc update queue
1156 1232
1157 msg = new GridInstantMessage(); 1233 msg = new GridInstantMessage();
1158 msg.imSessionID = UUID.Zero.Guid; 1234 msg.imSessionID = UUID.Zero.Guid;
@@ -1160,15 +1236,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1160 msg.toAgentID = agentID.Guid; 1236 msg.toAgentID = agentID.Guid;
1161 msg.timestamp = 0; 1237 msg.timestamp = 0;
1162 msg.fromAgentName = agentName; 1238 msg.fromAgentName = agentName;
1163 if (account != null) 1239
1164 { 1240 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, ejecteeName);
1165 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, account.FirstName + " " + account.LastName); 1241
1166 } 1242// msg.dialog = (byte)210; //interop
1167 else 1243 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
1168 {
1169 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member");
1170 }
1171 msg.dialog = (byte)210; //interop
1172 msg.fromGroup = false; 1244 msg.fromGroup = false;
1173 msg.offline = (byte)0; 1245 msg.offline = (byte)0;
1174 msg.ParentEstateID = 0; 1246 msg.ParentEstateID = 0;
@@ -1176,11 +1248,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1176 msg.RegionID = regionInfo.RegionID.Guid; 1248 msg.RegionID = regionInfo.RegionID.Guid;
1177 msg.binaryBucket = new byte[0]; 1249 msg.binaryBucket = new byte[0];
1178 OutgoingInstantMessage(msg, agentID); 1250 OutgoingInstantMessage(msg, agentID);
1179
1180
1181 // SL sends out messages to everyone in the group
1182 // Who all should receive updates and what should they be updated with?
1183 UpdateAllClientsWithGroupInfo(ejecteeID);
1184 } 1251 }
1185 1252
1186 public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) 1253 public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID)
@@ -1275,6 +1342,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1275 1342
1276 #region Client/Update Tools 1343 #region Client/Update Tools
1277 1344
1345 private IClientAPI GetActiveRootClient(UUID agentID)
1346 {
1347 foreach (Scene scene in m_sceneList)
1348 {
1349 ScenePresence sp = scene.GetScenePresence(agentID);
1350 if (sp != null && !sp.IsChildAgent && !sp.IsDeleted)
1351 {
1352 return sp.ControllingClient;
1353 }
1354 }
1355 return null;
1356 }
1357
1278 /// <summary> 1358 /// <summary>
1279 /// Try to find an active IClientAPI reference for agentID giving preference to root connections 1359 /// Try to find an active IClientAPI reference for agentID giving preference to root connections
1280 /// </summary> 1360 /// </summary>
@@ -1286,7 +1366,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1286 foreach (Scene scene in m_sceneList) 1366 foreach (Scene scene in m_sceneList)
1287 { 1367 {
1288 ScenePresence sp = scene.GetScenePresence(agentID); 1368 ScenePresence sp = scene.GetScenePresence(agentID);
1289 if (sp != null) 1369 if (sp != null && !sp.IsDeleted)
1290 { 1370 {
1291 if (!sp.IsChildAgent) 1371 if (!sp.IsChildAgent)
1292 { 1372 {
@@ -1303,67 +1383,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1303 return child; 1383 return child;
1304 } 1384 }
1305 1385
1306 /// <summary>
1307 /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'.
1308 /// </summary>
1309 private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data)
1310 {
1311 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1312
1313 OSDArray AgentData = new OSDArray(1);
1314 OSDMap AgentDataMap = new OSDMap(1);
1315 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1316 AgentData.Add(AgentDataMap);
1317
1318 OSDArray GroupData = new OSDArray(data.Length);
1319 OSDArray NewGroupData = new OSDArray(data.Length);
1320
1321 foreach (GroupMembershipData membership in data)
1322 {
1323 if (GetRequestingAgentID(remoteClient) != dataForAgentID)
1324 {
1325 if (!membership.ListInProfile)
1326 {
1327 // If we're sending group info to remoteclient about another agent,
1328 // filter out groups the other agent doesn't want to share.
1329 continue;
1330 }
1331 }
1332
1333 OSDMap GroupDataMap = new OSDMap(6);
1334 OSDMap NewGroupDataMap = new OSDMap(1);
1335
1336 GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID));
1337 GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers));
1338 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices));
1339 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture));
1340 GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution));
1341 GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName));
1342 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile));
1343
1344 GroupData.Add(GroupDataMap);
1345 NewGroupData.Add(NewGroupDataMap);
1346 }
1347
1348 OSDMap llDataStruct = new OSDMap(3);
1349 llDataStruct.Add("AgentData", AgentData);
1350 llDataStruct.Add("GroupData", GroupData);
1351 llDataStruct.Add("NewGroupData", NewGroupData);
1352
1353 if (m_debugEnabled)
1354 {
1355 m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct));
1356 }
1357
1358 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
1359
1360 if (queue != null)
1361 {
1362 queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient));
1363 }
1364
1365 }
1366
1367 private void SendScenePresenceUpdate(UUID AgentID, string Title) 1386 private void SendScenePresenceUpdate(UUID AgentID, string Title)
1368 { 1387 {
1369 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); 1388 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title);
@@ -1380,54 +1399,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1380 presence.Grouptitle = Title; 1399 presence.Grouptitle = Title;
1381 1400
1382 if (! presence.IsChildAgent) 1401 if (! presence.IsChildAgent)
1383 presence.SendAvatarDataToAllClients(); 1402 presence.SendAvatarDataToAllAgents();
1384 } 1403 }
1385 } 1404 }
1386 } 1405 }
1387 } 1406 }
1388 1407
1389 /// <summary> 1408 public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
1390 /// Send updates to all clients who might be interested in groups data for dataForClientID
1391 /// </summary>
1392 private void UpdateAllClientsWithGroupInfo(UUID dataForClientID)
1393 { 1409 {
1394 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1410 SendAgentGroupDataUpdate(remoteClient, true);
1395
1396 // TODO: Probably isn't nessesary to update every client in every scene.
1397 // Need to examine client updates and do only what's nessesary.
1398 lock (m_sceneList)
1399 {
1400 foreach (Scene scene in m_sceneList)
1401 {
1402 scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); });
1403 }
1404 }
1405 } 1411 }
1406 1412
1407 /// <summary> 1413 /// <summary>
1408 /// Update remoteClient with group information about dataForAgentID 1414 /// Tell remoteClient about its agent groups, and optionally send title to others
1409 /// </summary> 1415 /// </summary>
1410 private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) 1416 private void SendAgentGroupDataUpdate(IClientAPI remoteClient, bool tellOthers)
1411 { 1417 {
1412 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); 1418 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name);
1413 1419
1420 // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information
1421 // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything.
1422 if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc)
1423 return;
1424
1414 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff 1425 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
1415 1426
1416 OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); 1427 UUID agentID = GetRequestingAgentID(remoteClient);
1417 1428
1418 // Need to send a group membership update to the client 1429 SendDataUpdate(remoteClient, tellOthers);
1419 // UDP version doesn't seem to behave nicely. But we're going to send it out here
1420 // with an empty group membership to hopefully remove groups being displayed due
1421 // to the core Groups Stub
1422 remoteClient.SendGroupMembership(new GroupMembershipData[0]);
1423 1430
1424 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); 1431 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, agentID);
1425 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); 1432 remoteClient.UpdateGroupMembership(membershipArray);
1426 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
1427 1433
1428 if (remoteClient.AgentId == dataForAgentID) 1434 remoteClient.SendAgentGroupDataUpdate(agentID, membershipArray);
1429 remoteClient.RefreshGroupMembership(); 1435 }
1430 }
1431 1436
1432 /// <summary> 1437 /// <summary>
1433 /// Get a list of groups memberships for the agent that are marked "ListInProfile" 1438 /// Get a list of groups memberships for the agent that are marked "ListInProfile"
@@ -1465,7 +1470,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1465 membershipArray = membershipData.ToArray(); 1470 membershipArray = membershipData.ToArray();
1466 } 1471 }
1467 } 1472 }
1468 1473
1469 if (m_debugEnabled) 1474 if (m_debugEnabled)
1470 { 1475 {
1471 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); 1476 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
@@ -1478,13 +1483,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1478 return membershipArray; 1483 return membershipArray;
1479 } 1484 }
1480 1485
1481 1486 //tell remoteClient about its agent group info, and optionally send title to others
1482 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) 1487 private void SendDataUpdate(IClientAPI remoteClient, bool tellOthers)
1483 { 1488 {
1484 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1489 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1485 1490
1486 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff 1491 UUID activeGroupID = UUID.Zero;
1487 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); 1492 string activeGroupTitle = string.Empty;
1493 string activeGroupName = string.Empty;
1494 ulong activeGroupPowers = (ulong)GroupPowers.None;
1495
1496 UUID agentID = GetRequestingAgentID(remoteClient);
1497 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID, agentID);
1498 if (membership != null)
1499 {
1500 activeGroupID = membership.GroupID;
1501 activeGroupTitle = membership.GroupTitle;
1502 activeGroupPowers = membership.GroupPowers;
1503 activeGroupName = membership.GroupName;
1504 }
1505
1506 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, agentID);
1488 string firstname, lastname; 1507 string firstname, lastname;
1489 if (account != null) 1508 if (account != null)
1490 { 1509 {
@@ -1497,9 +1516,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1497 lastname = "Unknown"; 1516 lastname = "Unknown";
1498 } 1517 }
1499 1518
1500 remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, 1519 remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname,
1501 lastname, activeGroupPowers, activeGroupName, 1520 lastname, activeGroupPowers, activeGroupName,
1502 activeGroupTitle); 1521 activeGroupTitle);
1522
1523
1524 if (tellOthers)
1525 SendScenePresenceUpdate(agentID, activeGroupTitle);
1526
1527 ScenePresence sp = (ScenePresence)remoteClient.SceneAgent;
1528 if (sp != null)
1529 sp.Grouptitle = activeGroupTitle;
1503 } 1530 }
1504 1531
1505 #endregion 1532 #endregion
@@ -1510,7 +1537,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1510 { 1537 {
1511 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1538 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1512 1539
1513 IClientAPI localClient = GetActiveClient(msgTo); 1540 IClientAPI localClient = GetActiveRootClient(msgTo);
1514 if (localClient != null) 1541 if (localClient != null)
1515 { 1542 {
1516 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); 1543 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name);