diff options
author | onefang | 2019-09-11 16:36:50 +1000 |
---|---|---|
committer | onefang | 2019-09-11 16:36:50 +1000 |
commit | 50cd1ffd32f69228e566f2b0b89f86ea0d9fe489 (patch) | |
tree | 52f2ab0c04f1a5d7d6ac5dc872981b4b156447e7 /OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |
parent | Renamed branch to SledjChisl. (diff) | |
parent | Bump to release flavour, build 0. (diff) | |
download | opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.zip opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.gz opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.bz2 opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.xz |
Merge branch 'SledjChisl'
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 524 |
1 files changed, 279 insertions, 245 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 1565da9..20b7c5e 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,30 @@ 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)); | 1114 | } |
1115 | |||
1116 | public void JoinGroup(string agentID, UUID groupID) | ||
1117 | { | ||
1118 | // Should check to see if OpenEnrollment, or if there's an outstanding invitation | ||
1119 | UUID u = new UUID(agentID); | ||
1120 | m_groupData.AddAgentToGroup(u, u, groupID, UUID.Zero); | ||
1057 | } | 1121 | } |
1058 | 1122 | ||
1059 | public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) | 1123 | public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) |
@@ -1068,7 +1132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1068 | 1132 | ||
1069 | // SL sends out notifcations to the group messaging session that the person has left | 1133 | // 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? | 1134 | // Should this also update everyone who is in the group? |
1071 | SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); | 1135 | SendAgentGroupDataUpdate(remoteClient, true); |
1072 | } | 1136 | } |
1073 | 1137 | ||
1074 | public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) | 1138 | public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) |
@@ -1120,17 +1184,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1120 | } | 1184 | } |
1121 | 1185 | ||
1122 | GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); | 1186 | GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); |
1123 | 1187 | if (groupInfo == null) | |
1124 | UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID); | ||
1125 | if ((groupInfo == null) || (account == null)) | ||
1126 | { | ||
1127 | return; | 1188 | return; |
1128 | } | 1189 | |
1190 | |||
1191 | IClientAPI ejecteeClient = GetActiveRootClient(ejecteeID); | ||
1129 | 1192 | ||
1130 | // Send Message to Ejectee | 1193 | // Send Message to Ejectee |
1131 | GridInstantMessage msg = new GridInstantMessage(); | 1194 | GridInstantMessage msg = new GridInstantMessage(); |
1132 | 1195 | ||
1133 | msg.imSessionID = UUID.Zero.Guid; | 1196 | string ejecteeName = "Unknown member"; |
1197 | // if local send a normal message | ||
1198 | if(ejecteeClient != null) | ||
1199 | { | ||
1200 | msg.imSessionID = UUID.Zero.Guid; | ||
1201 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; | ||
1202 | // also execute and send update | ||
1203 | ejecteeClient.SendAgentDropGroup(groupID); | ||
1204 | SendAgentGroupDataUpdate(ejecteeClient,true); | ||
1205 | ejecteeName = ejecteeClient.Name; | ||
1206 | } | ||
1207 | else // send | ||
1208 | { | ||
1209 | // Interop, received special 210 code for ejecting a group member | ||
1210 | // this only works within the comms servers domain, and won't work hypergrid | ||
1211 | // TODO:FIXME: Use a presence server of some kind to find out where the | ||
1212 | // client actually is, and try contacting that region directly to notify them, | ||
1213 | // or provide the notification via xmlrpc update queue | ||
1214 | |||
1215 | msg.imSessionID = groupInfo.GroupID.Guid; | ||
1216 | msg.dialog = (byte)210; //interop | ||
1217 | UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID); | ||
1218 | if (account != null) | ||
1219 | ejecteeName = account.FirstName + " " + account.LastName; | ||
1220 | } | ||
1221 | |||
1134 | msg.fromAgentID = agentID.Guid; | 1222 | msg.fromAgentID = agentID.Guid; |
1135 | // msg.fromAgentID = info.GroupID; | 1223 | // msg.fromAgentID = info.GroupID; |
1136 | msg.toAgentID = ejecteeID.Guid; | 1224 | msg.toAgentID = ejecteeID.Guid; |
@@ -1138,7 +1226,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1138 | msg.timestamp = 0; | 1226 | msg.timestamp = 0; |
1139 | msg.fromAgentName = agentName; | 1227 | msg.fromAgentName = agentName; |
1140 | msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); | 1228 | msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); |
1141 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; | 1229 | // |
1142 | msg.fromGroup = false; | 1230 | msg.fromGroup = false; |
1143 | msg.offline = (byte)0; | 1231 | msg.offline = (byte)0; |
1144 | msg.ParentEstateID = 0; | 1232 | msg.ParentEstateID = 0; |
@@ -1148,11 +1236,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1148 | OutgoingInstantMessage(msg, ejecteeID); | 1236 | OutgoingInstantMessage(msg, ejecteeID); |
1149 | 1237 | ||
1150 | // Message to ejector | 1238 | // 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 | 1239 | ||
1157 | msg = new GridInstantMessage(); | 1240 | msg = new GridInstantMessage(); |
1158 | msg.imSessionID = UUID.Zero.Guid; | 1241 | msg.imSessionID = UUID.Zero.Guid; |
@@ -1160,15 +1243,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1160 | msg.toAgentID = agentID.Guid; | 1243 | msg.toAgentID = agentID.Guid; |
1161 | msg.timestamp = 0; | 1244 | msg.timestamp = 0; |
1162 | msg.fromAgentName = agentName; | 1245 | msg.fromAgentName = agentName; |
1163 | if (account != null) | 1246 | |
1164 | { | 1247 | 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); | 1248 | |
1166 | } | 1249 | // msg.dialog = (byte)210; //interop |
1167 | else | 1250 | 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; | 1251 | msg.fromGroup = false; |
1173 | msg.offline = (byte)0; | 1252 | msg.offline = (byte)0; |
1174 | msg.ParentEstateID = 0; | 1253 | msg.ParentEstateID = 0; |
@@ -1176,11 +1255,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1176 | msg.RegionID = regionInfo.RegionID.Guid; | 1255 | msg.RegionID = regionInfo.RegionID.Guid; |
1177 | msg.binaryBucket = new byte[0]; | 1256 | msg.binaryBucket = new byte[0]; |
1178 | OutgoingInstantMessage(msg, agentID); | 1257 | 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 | } | 1258 | } |
1185 | 1259 | ||
1186 | public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) | 1260 | public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) |
@@ -1275,6 +1349,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1275 | 1349 | ||
1276 | #region Client/Update Tools | 1350 | #region Client/Update Tools |
1277 | 1351 | ||
1352 | private IClientAPI GetActiveRootClient(UUID agentID) | ||
1353 | { | ||
1354 | foreach (Scene scene in m_sceneList) | ||
1355 | { | ||
1356 | ScenePresence sp = scene.GetScenePresence(agentID); | ||
1357 | if (sp != null && !sp.IsChildAgent && !sp.IsDeleted) | ||
1358 | { | ||
1359 | return sp.ControllingClient; | ||
1360 | } | ||
1361 | } | ||
1362 | return null; | ||
1363 | } | ||
1364 | |||
1278 | /// <summary> | 1365 | /// <summary> |
1279 | /// Try to find an active IClientAPI reference for agentID giving preference to root connections | 1366 | /// Try to find an active IClientAPI reference for agentID giving preference to root connections |
1280 | /// </summary> | 1367 | /// </summary> |
@@ -1286,7 +1373,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1286 | foreach (Scene scene in m_sceneList) | 1373 | foreach (Scene scene in m_sceneList) |
1287 | { | 1374 | { |
1288 | ScenePresence sp = scene.GetScenePresence(agentID); | 1375 | ScenePresence sp = scene.GetScenePresence(agentID); |
1289 | if (sp != null) | 1376 | if (sp != null && !sp.IsDeleted) |
1290 | { | 1377 | { |
1291 | if (!sp.IsChildAgent) | 1378 | if (!sp.IsChildAgent) |
1292 | { | 1379 | { |
@@ -1303,67 +1390,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1303 | return child; | 1390 | return child; |
1304 | } | 1391 | } |
1305 | 1392 | ||
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) | 1393 | private void SendScenePresenceUpdate(UUID AgentID, string Title) |
1368 | { | 1394 | { |
1369 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); | 1395 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); |
@@ -1380,54 +1406,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1380 | presence.Grouptitle = Title; | 1406 | presence.Grouptitle = Title; |
1381 | 1407 | ||
1382 | if (! presence.IsChildAgent) | 1408 | if (! presence.IsChildAgent) |
1383 | presence.SendAvatarDataToAllClients(); | 1409 | presence.SendAvatarDataToAllAgents(); |
1384 | } | 1410 | } |
1385 | } | 1411 | } |
1386 | } | 1412 | } |
1387 | } | 1413 | } |
1388 | 1414 | ||
1389 | /// <summary> | 1415 | 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 | { | 1416 | { |
1394 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 1417 | 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 | } | 1418 | } |
1406 | 1419 | ||
1407 | /// <summary> | 1420 | /// <summary> |
1408 | /// Update remoteClient with group information about dataForAgentID | 1421 | /// Tell remoteClient about its agent groups, and optionally send title to others |
1409 | /// </summary> | 1422 | /// </summary> |
1410 | private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) | 1423 | private void SendAgentGroupDataUpdate(IClientAPI remoteClient, bool tellOthers) |
1411 | { | 1424 | { |
1412 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); | 1425 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); |
1413 | 1426 | ||
1427 | // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information | ||
1428 | // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything. | ||
1429 | if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc) | ||
1430 | return; | ||
1431 | |||
1414 | // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff | 1432 | // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff |
1415 | 1433 | ||
1416 | OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); | 1434 | UUID agentID = GetRequestingAgentID(remoteClient); |
1417 | 1435 | ||
1418 | // Need to send a group membership update to the client | 1436 | 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 | 1437 | ||
1424 | GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); | 1438 | GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, agentID); |
1425 | SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); | 1439 | remoteClient.UpdateGroupMembership(membershipArray); |
1426 | remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); | ||
1427 | 1440 | ||
1428 | if (remoteClient.AgentId == dataForAgentID) | 1441 | remoteClient.SendAgentGroupDataUpdate(agentID, membershipArray); |
1429 | remoteClient.RefreshGroupMembership(); | 1442 | } |
1430 | } | ||
1431 | 1443 | ||
1432 | /// <summary> | 1444 | /// <summary> |
1433 | /// Get a list of groups memberships for the agent that are marked "ListInProfile" | 1445 | /// Get a list of groups memberships for the agent that are marked "ListInProfile" |
@@ -1465,7 +1477,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1465 | membershipArray = membershipData.ToArray(); | 1477 | membershipArray = membershipData.ToArray(); |
1466 | } | 1478 | } |
1467 | } | 1479 | } |
1468 | 1480 | ||
1469 | if (m_debugEnabled) | 1481 | if (m_debugEnabled) |
1470 | { | 1482 | { |
1471 | m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); | 1483 | m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); |
@@ -1478,13 +1490,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1478 | return membershipArray; | 1490 | return membershipArray; |
1479 | } | 1491 | } |
1480 | 1492 | ||
1481 | 1493 | //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) | 1494 | private void SendDataUpdate(IClientAPI remoteClient, bool tellOthers) |
1483 | { | 1495 | { |
1484 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 1496 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
1485 | 1497 | ||
1486 | // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff | 1498 | UUID activeGroupID = UUID.Zero; |
1487 | UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); | 1499 | string activeGroupTitle = string.Empty; |
1500 | string activeGroupName = string.Empty; | ||
1501 | ulong activeGroupPowers = (ulong)GroupPowers.None; | ||
1502 | |||
1503 | UUID agentID = GetRequestingAgentID(remoteClient); | ||
1504 | GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID, agentID); | ||
1505 | if (membership != null) | ||
1506 | { | ||
1507 | activeGroupID = membership.GroupID; | ||
1508 | activeGroupTitle = membership.GroupTitle; | ||
1509 | activeGroupPowers = membership.GroupPowers; | ||
1510 | activeGroupName = membership.GroupName; | ||
1511 | } | ||
1512 | |||
1513 | UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, agentID); | ||
1488 | string firstname, lastname; | 1514 | string firstname, lastname; |
1489 | if (account != null) | 1515 | if (account != null) |
1490 | { | 1516 | { |
@@ -1497,9 +1523,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1497 | lastname = "Unknown"; | 1523 | lastname = "Unknown"; |
1498 | } | 1524 | } |
1499 | 1525 | ||
1500 | remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, | 1526 | remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname, |
1501 | lastname, activeGroupPowers, activeGroupName, | 1527 | lastname, activeGroupPowers, activeGroupName, |
1502 | activeGroupTitle); | 1528 | activeGroupTitle); |
1529 | |||
1530 | |||
1531 | if (tellOthers) | ||
1532 | SendScenePresenceUpdate(agentID, activeGroupTitle); | ||
1533 | |||
1534 | ScenePresence sp = (ScenePresence)remoteClient.SceneAgent; | ||
1535 | if (sp != null) | ||
1536 | sp.Grouptitle = activeGroupTitle; | ||
1503 | } | 1537 | } |
1504 | 1538 | ||
1505 | #endregion | 1539 | #endregion |
@@ -1510,7 +1544,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1510 | { | 1544 | { |
1511 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 1545 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
1512 | 1546 | ||
1513 | IClientAPI localClient = GetActiveClient(msgTo); | 1547 | IClientAPI localClient = GetActiveRootClient(msgTo); |
1514 | if (localClient != null) | 1548 | if (localClient != null) |
1515 | { | 1549 | { |
1516 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); | 1550 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); |