aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Addons/Groups
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Addons/Groups')
-rw-r--r--OpenSim/Addons/Groups/GroupsExtendedData.cs24
-rw-r--r--OpenSim/Addons/Groups/GroupsMessagingModule.cs430
-rw-r--r--OpenSim/Addons/Groups/GroupsModule.cs109
-rw-r--r--OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs42
-rw-r--r--OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs2
-rw-r--r--OpenSim/Addons/Groups/IGroupsServicesConnector.cs6
-rw-r--r--OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs22
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs31
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs24
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs45
-rw-r--r--OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs13
-rw-r--r--OpenSim/Addons/Groups/Service/GroupsService.cs40
12 files changed, 504 insertions, 284 deletions
diff --git a/OpenSim/Addons/Groups/GroupsExtendedData.cs b/OpenSim/Addons/Groups/GroupsExtendedData.cs
index 6f4db28..1632aee 100644
--- a/OpenSim/Addons/Groups/GroupsExtendedData.cs
+++ b/OpenSim/Addons/Groups/GroupsExtendedData.cs
@@ -504,6 +504,30 @@ namespace OpenSim.Groups
504 504
505 return notice; 505 return notice;
506 } 506 }
507
508 public static Dictionary<string, object> DirGroupsReplyData(DirGroupsReplyData g)
509 {
510 Dictionary<string, object> dict = new Dictionary<string, object>();
511
512 dict["GroupID"] = g.groupID;
513 dict["Name"] = g.groupName;
514 dict["NMembers"] = g.members;
515 dict["SearchOrder"] = g.searchOrder;
516
517 return dict;
518 }
519
520 public static DirGroupsReplyData DirGroupsReplyData(Dictionary<string, object> dict)
521 {
522 DirGroupsReplyData g;
523
524 g.groupID = new UUID(dict["GroupID"].ToString());
525 g.groupName = dict["Name"].ToString();
526 Int32.TryParse(dict["NMembers"].ToString(), out g.members);
527 float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
528
529 return g;
530 }
507 } 531 }
508 532
509} 533}
diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
index d172d48..be59c62 100644
--- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs
+++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
@@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 43
43namespace OpenSim.Groups 44namespace OpenSim.Groups
44{ 45{
@@ -51,7 +52,7 @@ namespace OpenSim.Groups
51 private IPresenceService m_presenceService; 52 private IPresenceService m_presenceService;
52 53
53 private IMessageTransferModule m_msgTransferModule = null; 54 private IMessageTransferModule m_msgTransferModule = null;
54 55 private IUserManagement m_UserManagement = null;
55 private IGroupsServicesConnector m_groupData = null; 56 private IGroupsServicesConnector m_groupData = null;
56 57
57 // Config Options 58 // Config Options
@@ -79,6 +80,10 @@ namespace OpenSim.Groups
79 80
80 private int m_usersOnlineCacheExpirySeconds = 20; 81 private int m_usersOnlineCacheExpirySeconds = 20;
81 82
83 private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
84 private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
85
86
82 #region Region Module interfaceBase Members 87 #region Region Module interfaceBase Members
83 88
84 public void Initialise(IConfigSource config) 89 public void Initialise(IConfigSource config)
@@ -124,10 +129,12 @@ namespace OpenSim.Groups
124 m_sceneList.Add(scene); 129 m_sceneList.Add(scene);
125 130
126 scene.EventManager.OnNewClient += OnNewClient; 131 scene.EventManager.OnNewClient += OnNewClient;
132 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
133 scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
127 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 134 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
128 scene.EventManager.OnClientLogin += OnClientLogin; 135 scene.EventManager.OnClientLogin += OnClientLogin;
129 } 136 }
130 137
131 public void RegionLoaded(Scene scene) 138 public void RegionLoaded(Scene scene)
132 { 139 {
133 if (!m_groupMessagingEnabled) 140 if (!m_groupMessagingEnabled)
@@ -155,6 +162,17 @@ namespace OpenSim.Groups
155 return; 162 return;
156 } 163 }
157 164
165 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
166
167 // No groups module, no groups messaging
168 if (m_UserManagement == null)
169 {
170 m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
171 RemoveRegion(scene);
172 return;
173 }
174
175
158 if (m_presenceService == null) 176 if (m_presenceService == null)
159 m_presenceService = scene.PresenceService; 177 m_presenceService = scene.PresenceService;
160 178
@@ -227,87 +245,107 @@ namespace OpenSim.Groups
227 245
228 public void SendMessageToGroup(GridInstantMessage im, UUID groupID) 246 public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
229 { 247 {
230 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID); 248 UUID fromAgentID = new UUID(im.fromAgentID);
249 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
231 int groupMembersCount = groupMembers.Count; 250 int groupMembersCount = groupMembers.Count;
251 PresenceInfo[] onlineAgents = null;
232 252
233 if (m_messageOnlineAgentsOnly) 253 // In V2 we always only send to online members.
234 { 254 // Sending to offline members is not an option.
235 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray(); 255 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
236 256
237 // We cache in order not to overwhlem the presence service on large grids with many groups. This does 257 // We cache in order not to overwhlem the presence service on large grids with many groups. This does
238 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. 258 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
239 // (assuming this is the same across all grid simulators). 259 // (assuming this is the same across all grid simulators).
240 PresenceInfo[] onlineAgents; 260 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
241 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) 261 {
242 { 262 onlineAgents = m_presenceService.GetAgents(t1);
243 onlineAgents = m_presenceService.GetAgents(t1); 263 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
244 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); 264 }
245 }
246 265
247 HashSet<string> onlineAgentsUuidSet = new HashSet<string>(); 266 HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
248 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); 267 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
249 268
250 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); 269 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
251 270
252 // if (m_debugEnabled) 271// if (m_debugEnabled)
253// m_log.DebugFormat( 272// m_log.DebugFormat(
254// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", 273// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
255// groupID, groupMembersCount, groupMembers.Count()); 274// groupID, groupMembersCount, groupMembers.Count());
256 } 275
257 else 276 int requestStartTick = Environment.TickCount;
277
278 im.imSessionID = groupID.Guid;
279 im.fromGroup = true;
280 IClientAPI thisClient = GetActiveClient(fromAgentID);
281 if (thisClient != null)
258 { 282 {
259 if (m_debugEnabled) 283 im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
260 m_log.DebugFormat(
261 "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members",
262 groupID, groupMembers.Count);
263 } 284 }
264 285
265 int requestStartTick = Environment.TickCount; 286 // Send to self first of all
287 im.toAgentID = im.fromAgentID;
288 im.fromGroup = true;
289 ProcessMessageFromGroupSession(im);
266 290
291 List<UUID> regions = new List<UUID>();
292 List<UUID> clientsAlreadySent = new List<UUID>();
293
294 // Then send to everybody else
267 foreach (GroupMembersData member in groupMembers) 295 foreach (GroupMembersData member in groupMembers)
268 { 296 {
269 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) 297 if (member.AgentID.Guid == im.fromAgentID)
298 continue;
299
300 if (clientsAlreadySent.Contains(member.AgentID))
301 continue;
302 clientsAlreadySent.Add(member.AgentID);
303
304 if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
270 { 305 {
271 // Don't deliver messages to people who have dropped this session 306 // Don't deliver messages to people who have dropped this session
272 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); 307 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
273 continue; 308 continue;
274 } 309 }
275 310
276 // Copy Message 311 im.toAgentID = member.AgentID.Guid;
277 GridInstantMessage msg = new GridInstantMessage();
278 msg.imSessionID = groupID.Guid;
279 msg.fromAgentName = im.fromAgentName;
280 msg.message = im.message;
281 msg.dialog = im.dialog;
282 msg.offline = im.offline;
283 msg.ParentEstateID = im.ParentEstateID;
284 msg.Position = im.Position;
285 msg.RegionID = im.RegionID;
286 msg.binaryBucket = im.binaryBucket;
287 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
288
289 msg.fromAgentID = im.fromAgentID;
290 msg.fromGroup = true;
291
292 msg.toAgentID = member.AgentID.Guid;
293 312
294 IClientAPI client = GetActiveClient(member.AgentID); 313 IClientAPI client = GetActiveClient(member.AgentID);
295 if (client == null) 314 if (client == null)
296 { 315 {
297 // If they're not local, forward across the grid 316 // If they're not local, forward across the grid
317 // BUT do it only once per region, please! Sim would be even better!
298 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); 318 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
299 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); 319
320 bool reallySend = true;
321 if (onlineAgents != null)
322 {
323 PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
324 if (regions.Contains(presence.RegionID))
325 reallySend = false;
326 else
327 regions.Add(presence.RegionID);
328 }
329
330 if (reallySend)
331 {
332 // We have to create a new IM structure because the transfer module
333 // uses async send
334 GridInstantMessage msg = new GridInstantMessage(im, true);
335 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
336 }
300 } 337 }
301 else 338 else
302 { 339 {
303 // Deliver locally, directly 340 // Deliver locally, directly
304 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); 341 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
305 ProcessMessageFromGroupSession(msg); 342
343 ProcessMessageFromGroupSession(im);
306 } 344 }
345
307 } 346 }
308 347
309 // Temporary for assessing how long it still takes to send messages to large online groups. 348 if (m_debugEnabled)
310 if (m_messageOnlineAgentsOnly)
311 m_log.DebugFormat( 349 m_log.DebugFormat(
312 "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", 350 "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
313 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); 351 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
@@ -324,9 +362,20 @@ namespace OpenSim.Groups
324 { 362 {
325 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name); 363 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
326 364
327 client.OnInstantMessage += OnInstantMessage; 365 ResetAgentGroupChatSessions(client.AgentId.ToString());
366 }
367
368 void OnMakeRootAgent(ScenePresence sp)
369 {
370 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
371 }
372
373 void OnMakeChildAgent(ScenePresence sp)
374 {
375 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
328 } 376 }
329 377
378
330 private void OnGridInstantMessage(GridInstantMessage msg) 379 private void OnGridInstantMessage(GridInstantMessage msg)
331 { 380 {
332 // The instant message module will only deliver messages of dialog types: 381 // The instant message module will only deliver messages of dialog types:
@@ -335,21 +384,91 @@ namespace OpenSim.Groups
335 // Any other message type will not be delivered to a client by the 384 // Any other message type will not be delivered to a client by the
336 // Instant Message Module 385 // Instant Message Module
337 386
338 387 UUID regionID = new UUID(msg.RegionID);
339 if (m_debugEnabled) 388 if (m_debugEnabled)
340 { 389 {
341 m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 390 m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
391 System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
342 392
343 DebugGridInstantMessage(msg); 393 DebugGridInstantMessage(msg);
344 } 394 }
345 395
346 // Incoming message from a group 396 // Incoming message from a group
347 if ((msg.fromGroup == true) && 397 if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
348 ((msg.dialog == (byte)InstantMessageDialog.SessionSend)
349 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
350 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
351 { 398 {
352 ProcessMessageFromGroupSession(msg); 399 // We have to redistribute the message across all members of the group who are here
400 // on this sim
401
402 UUID GroupID = new UUID(msg.imSessionID);
403
404 Scene aScene = m_sceneList[0];
405 GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
406
407 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID);
408
409 //if (m_debugEnabled)
410 // foreach (GroupMembersData m in groupMembers)
411 // m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
412
413 foreach (Scene s in m_sceneList)
414 {
415 s.ForEachScenePresence(sp =>
416 {
417 // If we got this via grid messaging, it's because the caller thinks
418 // that the root agent is here. We should only send the IM to root agents.
419 if (sp.IsChildAgent)
420 return;
421
422 GroupMembersData m = groupMembers.Find(gmd =>
423 {
424 return gmd.AgentID == sp.UUID;
425 });
426 if (m.AgentID == UUID.Zero)
427 {
428 if (m_debugEnabled)
429 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
430 return;
431 }
432
433 // Check if the user has an agent in the region where
434 // the IM came from, and if so, skip it, because the IM
435 // was already sent via that agent
436 if (regionOfOrigin != null)
437 {
438 AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
439 if (aCircuit != null)
440 {
441 if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
442 {
443 if (m_debugEnabled)
444 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
445 return;
446 }
447 else
448 {
449 if (m_debugEnabled)
450 m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
451 }
452 }
453 }
454
455 UUID AgentID = sp.UUID;
456 msg.toAgentID = AgentID.Guid;
457
458 if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
459 {
460 if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
461 AddAgentToSession(AgentID, GroupID, msg);
462 else
463 {
464 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
465
466 ProcessMessageFromGroupSession(msg);
467 }
468 }
469 });
470
471 }
353 } 472 }
354 } 473 }
355 474
@@ -359,82 +478,40 @@ namespace OpenSim.Groups
359 478
360 UUID AgentID = new UUID(msg.fromAgentID); 479 UUID AgentID = new UUID(msg.fromAgentID);
361 UUID GroupID = new UUID(msg.imSessionID); 480 UUID GroupID = new UUID(msg.imSessionID);
481 UUID toAgentID = new UUID(msg.toAgentID);
362 482
363 switch (msg.dialog) 483 switch (msg.dialog)
364 { 484 {
365 case (byte)InstantMessageDialog.SessionAdd: 485 case (byte)InstantMessageDialog.SessionAdd:
366 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 486 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
367 break; 487 break;
368 488
369 case (byte)InstantMessageDialog.SessionDrop: 489 case (byte)InstantMessageDialog.SessionDrop:
370 m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); 490 AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
371 break; 491 break;
372 492
373 case (byte)InstantMessageDialog.SessionSend: 493 case (byte)InstantMessageDialog.SessionSend:
374 if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID) 494 // User hasn't dropped, so they're in the session,
375 && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID) 495 // maybe we should deliver it.
376 ) 496 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
497 if (client != null)
377 { 498 {
378 // Agent not in session and hasn't dropped from session 499 // Deliver locally, directly
379 // Add them to the session for now, and Invite them 500 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
380 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
381 501
382 UUID toAgentID = new UUID(msg.toAgentID); 502 if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
383 IClientAPI activeClient = GetActiveClient(toAgentID);
384 if (activeClient != null)
385 { 503 {
386 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); 504 if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
387 if (groupInfo != null) 505 // This actually sends the message too, so no need to resend it
388 { 506 // with client.SendInstantMessage
389 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); 507 AddAgentToSession(toAgentID, GroupID, msg);
390 508 else
391 // Force? open the group session dialog??? 509 client.SendInstantMessage(msg);
392 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
393 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
394 eq.ChatterboxInvitation(
395 GroupID
396 , groupInfo.GroupName
397 , new UUID(msg.fromAgentID)
398 , msg.message
399 , new UUID(msg.toAgentID)
400 , msg.fromAgentName
401 , msg.dialog
402 , msg.timestamp
403 , msg.offline == 1
404 , (int)msg.ParentEstateID
405 , msg.Position
406 , 1
407 , new UUID(msg.imSessionID)
408 , msg.fromGroup
409 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
410 );
411
412 eq.ChatterBoxSessionAgentListUpdates(
413 new UUID(GroupID)
414 , new UUID(msg.fromAgentID)
415 , new UUID(msg.toAgentID)
416 , false //canVoiceChat
417 , false //isModerator
418 , false //text mute
419 );
420 }
421 } 510 }
422 } 511 }
423 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) 512 else
424 { 513 {
425 // User hasn't dropped, so they're in the session, 514 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
426 // maybe we should deliver it.
427 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
428 if (client != null)
429 {
430 // Deliver locally, directly
431 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
432 client.SendInstantMessage(msg);
433 }
434 else
435 {
436 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
437 }
438 } 515 }
439 break; 516 break;
440 517
@@ -444,6 +521,53 @@ namespace OpenSim.Groups
444 } 521 }
445 } 522 }
446 523
524 private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
525 {
526 // Agent not in session and hasn't dropped from session
527 // Add them to the session for now, and Invite them
528 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
529
530 IClientAPI activeClient = GetActiveClient(AgentID);
531 if (activeClient != null)
532 {
533 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
534 if (groupInfo != null)
535 {
536 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
537
538 // Force? open the group session dialog???
539 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
540 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
541 eq.ChatterboxInvitation(
542 GroupID
543 , groupInfo.GroupName
544 , new UUID(msg.fromAgentID)
545 , msg.message
546 , AgentID
547 , msg.fromAgentName
548 , msg.dialog
549 , msg.timestamp
550 , msg.offline == 1
551 , (int)msg.ParentEstateID
552 , msg.Position
553 , 1
554 , new UUID(msg.imSessionID)
555 , msg.fromGroup
556 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
557 );
558
559 eq.ChatterBoxSessionAgentListUpdates(
560 new UUID(GroupID)
561 , AgentID
562 , new UUID(msg.toAgentID)
563 , false //canVoiceChat
564 , false //isModerator
565 , false //text mute
566 );
567 }
568 }
569 }
570
447 #endregion 571 #endregion
448 572
449 573
@@ -469,7 +593,7 @@ namespace OpenSim.Groups
469 593
470 if (groupInfo != null) 594 if (groupInfo != null)
471 { 595 {
472 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 596 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
473 597
474 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); 598 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
475 599
@@ -495,7 +619,7 @@ namespace OpenSim.Groups
495 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); 619 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
496 620
497 //If this agent is sending a message, then they want to be in the session 621 //If this agent is sending a message, then they want to be in the session
498 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 622 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
499 623
500 SendMessageToGroup(im, GroupID); 624 SendMessageToGroup(im, GroupID);
501 } 625 }
@@ -566,12 +690,12 @@ namespace OpenSim.Groups
566 { 690 {
567 if (!sp.IsChildAgent) 691 if (!sp.IsChildAgent)
568 { 692 {
569 if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name); 693 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
570 return sp.ControllingClient; 694 return sp.ControllingClient;
571 } 695 }
572 else 696 else
573 { 697 {
574 if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name); 698 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
575 child = sp.ControllingClient; 699 child = sp.ControllingClient;
576 } 700 }
577 } 701 }
@@ -590,5 +714,71 @@ namespace OpenSim.Groups
590 } 714 }
591 715
592 #endregion 716 #endregion
717
718 #region GroupSessionTracking
719
720 public void ResetAgentGroupChatSessions(string agentID)
721 {
722 foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
723 agentList.Remove(agentID);
724
725 foreach (List<string> agentList in m_groupsAgentsInvitedToChatSession.Values)
726 agentList.Remove(agentID);
727 }
728
729 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
730 {
731 // If we're tracking this group, and we can find them in the tracking, then they've been invited
732 return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
733 && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
734 }
735
736 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
737 {
738 // If we're tracking drops for this group,
739 // and we find them, well... then they've dropped
740 return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
741 && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
742 }
743
744 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
745 {
746 if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
747 {
748 // If not in dropped list, add
749 if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
750 {
751 m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
752 }
753 }
754 }
755
756 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
757 {
758 // Add Session Status if it doesn't exist for this session
759 CreateGroupChatSessionTracking(groupID);
760
761 // If nessesary, remove from dropped list
762 if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
763 {
764 m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
765 }
766
767 // Add to invited
768 if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
769 m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
770 }
771
772 private void CreateGroupChatSessionTracking(UUID groupID)
773 {
774 if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
775 {
776 m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
777 m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
778 }
779
780 }
781 #endregion
782
593 } 783 }
594} 784}
diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs
index 10bfa8f..b0493fa 100644
--- a/OpenSim/Addons/Groups/GroupsModule.cs
+++ b/OpenSim/Addons/Groups/GroupsModule.cs
@@ -141,6 +141,8 @@ namespace OpenSim.Groups
141 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 141 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
142 142
143 scene.EventManager.OnNewClient += OnNewClient; 143 scene.EventManager.OnNewClient += OnNewClient;
144 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
145 scene.EventManager.OnMakeChildAgent += OnMakeChild;
144 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 146 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
145 // The InstantMessageModule itself doesn't do this, 147 // The InstantMessageModule itself doesn't do this,
146 // so lets see if things explode if we don't do it 148 // so lets see if things explode if we don't do it
@@ -194,6 +196,8 @@ namespace OpenSim.Groups
194 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 196 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
195 197
196 scene.EventManager.OnNewClient -= OnNewClient; 198 scene.EventManager.OnNewClient -= OnNewClient;
199 scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
200 scene.EventManager.OnMakeChildAgent -= OnMakeChild;
197 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; 201 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
198 202
199 lock (m_sceneList) 203 lock (m_sceneList)
@@ -232,16 +236,29 @@ namespace OpenSim.Groups
232 { 236 {
233 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 237 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
234 238
235 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
236 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 239 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
237 client.OnDirFindQuery += OnDirFindQuery;
238 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 240 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
241 }
239 242
243 private void OnMakeRoot(ScenePresence sp)
244 {
245 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
246
247 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
240 // Used for Notices and Group Invites/Accept/Reject 248 // Used for Notices and Group Invites/Accept/Reject
241 client.OnInstantMessage += OnInstantMessage; 249 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
242 250
243 // Send client their groups information. 251 // Send client their groups information.
244 SendAgentGroupDataUpdate(client, client.AgentId); 252 SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
253 }
254
255 private void OnMakeChild(ScenePresence sp)
256 {
257 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
258
259 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
260 // Used for Notices and Group Invites/Accept/Reject
261 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
245 } 262 }
246 263
247 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 264 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@@ -287,21 +304,6 @@ namespace OpenSim.Groups
287 } 304 }
288 */ 305 */
289 306
290 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
291 {
292 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
293 {
294 if (m_debugEnabled)
295 m_log.DebugFormat(
296 "[Groups]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
297 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
298
299 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
300 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), queryText).ToArray());
301 }
302
303 }
304
305 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 307 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
306 { 308 {
307 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 309 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -347,7 +349,7 @@ namespace OpenSim.Groups
347 { 349 {
348 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 350 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
349 351
350 m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog); 352 //m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog);
351 // Group invitations 353 // Group invitations
352 if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) 354 if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
353 { 355 {
@@ -465,12 +467,12 @@ namespace OpenSim.Groups
465 } 467 }
466 468
467 // Send notice out to everyone that wants notices 469 // Send notice out to everyone that wants notices
468 // Build notice IIM
469 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
470 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) 470 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
471 { 471 {
472 if (member.AcceptNotices) 472 if (member.AcceptNotices)
473 { 473 {
474 // Build notice IIM, one of reach, because the sending may be async
475 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
474 msg.toAgentID = member.AgentID.Guid; 476 msg.toAgentID = member.AgentID.Guid;
475 OutgoingInstantMessage(msg, member.AgentID); 477 OutgoingInstantMessage(msg, member.AgentID);
476 } 478 }
@@ -485,7 +487,7 @@ namespace OpenSim.Groups
485 return; 487 return;
486 488
487 //// 16 bytes are the UUID. Maybe. 489 //// 16 bytes are the UUID. Maybe.
488 UUID folderID = new UUID(im.binaryBucket, 0); 490// UUID folderID = new UUID(im.binaryBucket, 0);
489 UUID noticeID = new UUID(im.imSessionID); 491 UUID noticeID = new UUID(im.imSessionID);
490 492
491 GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); 493 GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID);
@@ -766,14 +768,17 @@ namespace OpenSim.Groups
766 remoteClient.SendCreateGroupReply(UUID.Zero, false, "Insufficient funds to create a group."); 768 remoteClient.SendCreateGroupReply(UUID.Zero, false, "Insufficient funds to create a group.");
767 return UUID.Zero; 769 return UUID.Zero;
768 } 770 }
769 money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, "Group Creation");
770 } 771 }
772
771 string reason = string.Empty; 773 string reason = string.Empty;
772 UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment, 774 UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment,
773 allowPublish, maturePublish, remoteClient.AgentId, out reason); 775 allowPublish, maturePublish, remoteClient.AgentId, out reason);
774 776
775 if (groupID != UUID.Zero) 777 if (groupID != UUID.Zero)
776 { 778 {
779 if (money != null)
780 money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
781
777 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); 782 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly");
778 783
779 // Update the founder with new group information. 784 // Update the founder with new group information.
@@ -904,23 +909,7 @@ namespace OpenSim.Groups
904 { 909 {
905 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID); 910 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID);
906 911
907 //GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null);
908
909 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); 912 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
910 //GridInstantMessage msg = new GridInstantMessage();
911 //msg.imSessionID = UUID.Zero.Guid;
912 //msg.fromAgentID = data.GroupID.Guid;
913 //msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
914 //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
915 //msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
916 //msg.message = data.noticeData.Subject + "|" + data.Message;
917 //msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
918 //msg.fromGroup = true;
919 //msg.offline = (byte)0;
920 //msg.ParentEstateID = 0;
921 //msg.Position = Vector3.Zero;
922 //msg.RegionID = UUID.Zero.Guid;
923 //msg.binaryBucket = data.BinaryBucket;
924 913
925 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); 914 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
926 } 915 }
@@ -1002,6 +991,10 @@ namespace OpenSim.Groups
1002 991
1003 // Should this send updates to everyone in the group? 992 // Should this send updates to everyone in the group?
1004 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 993 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
994
995 if (reason != string.Empty)
996 // A warning
997 remoteClient.SendAlertMessage("Warning: " + reason);
1005 } 998 }
1006 else 999 else
1007 remoteClient.SendJoinGroupReply(groupID, false); 1000 remoteClient.SendJoinGroupReply(groupID, false);
@@ -1186,6 +1179,11 @@ namespace OpenSim.Groups
1186 } 1179 }
1187 } 1180 }
1188 1181
1182 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1183 {
1184 return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
1185 }
1186
1189 #endregion 1187 #endregion
1190 1188
1191 #region Client/Update Tools 1189 #region Client/Update Tools
@@ -1225,12 +1223,16 @@ namespace OpenSim.Groups
1225 { 1223 {
1226 if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1224 if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1227 1225
1226 // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information
1227 // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything.
1228 if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc)
1229 return;
1230
1228 OSDArray AgentData = new OSDArray(1); 1231 OSDArray AgentData = new OSDArray(1);
1229 OSDMap AgentDataMap = new OSDMap(1); 1232 OSDMap AgentDataMap = new OSDMap(1);
1230 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); 1233 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1231 AgentData.Add(AgentDataMap); 1234 AgentData.Add(AgentDataMap);
1232 1235
1233
1234 OSDArray GroupData = new OSDArray(data.Length); 1236 OSDArray GroupData = new OSDArray(data.Length);
1235 OSDArray NewGroupData = new OSDArray(data.Length); 1237 OSDArray NewGroupData = new OSDArray(data.Length);
1236 1238
@@ -1276,8 +1278,7 @@ namespace OpenSim.Groups
1276 if (queue != null) 1278 if (queue != null)
1277 { 1279 {
1278 queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); 1280 queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient));
1279 } 1281 }
1280
1281 } 1282 }
1282 1283
1283 private void SendScenePresenceUpdate(UUID AgentID, string Title) 1284 private void SendScenePresenceUpdate(UUID AgentID, string Title)
@@ -1339,6 +1340,7 @@ namespace OpenSim.Groups
1339 1340
1340 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); 1341 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
1341 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); 1342 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
1343
1342 //remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); 1344 //remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
1343 if (remoteClient.AgentId == dataForAgentID) 1345 if (remoteClient.AgentId == dataForAgentID)
1344 remoteClient.RefreshGroupMembership(); 1346 remoteClient.RefreshGroupMembership();
@@ -1399,19 +1401,18 @@ namespace OpenSim.Groups
1399 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1401 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1400 1402
1401 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff 1403 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
1402 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); 1404 string firstname = "Unknown", lastname = "Unknown";
1403 string firstname, lastname; 1405 string name = m_UserManagement.GetUserName(dataForAgentID);
1404 if (account != null) 1406 if (!string.IsNullOrEmpty(name))
1405 {
1406 firstname = account.FirstName;
1407 lastname = account.LastName;
1408 }
1409 else
1410 { 1407 {
1411 firstname = "Unknown"; 1408 string[] parts = name.Split(new char[] { ' ' });
1412 lastname = "Unknown"; 1409 if (parts.Length >= 2)
1410 {
1411 firstname = parts[0];
1412 lastname = parts[1];
1413 }
1413 } 1414 }
1414 1415
1415 remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, 1416 remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname,
1416 lastname, activeGroupPowers, activeGroupName, 1417 lastname, activeGroupPowers, activeGroupName,
1417 activeGroupTitle); 1418 activeGroupTitle);
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
index f670272..4642b2a 100644
--- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
@@ -186,7 +186,6 @@ namespace OpenSim.Groups
186 public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, 186 public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
187 bool allowPublish, bool maturePublish, UUID founderID, out string reason) 187 bool allowPublish, bool maturePublish, UUID founderID, out string reason)
188 { 188 {
189 m_log.DebugFormat("[Groups]: Creating group {0}", name);
190 reason = string.Empty; 189 reason = string.Empty;
191 if (m_UserManagement.IsLocalGridUser(RequestingAgentID)) 190 if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
192 return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID, 191 return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
@@ -255,7 +254,10 @@ namespace OpenSim.Groups
255 { 254 {
256 string url = string.Empty, gname = string.Empty; 255 string url = string.Empty, gname = string.Empty;
257 if (IsLocal(GroupID, out url, out gname)) 256 if (IsLocal(GroupID, out url, out gname))
258 return m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), GroupID); 257 {
258 string agentID = AgentUUI(RequestingAgentID);
259 return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID);
260 }
259 else if (!string.IsNullOrEmpty(url)) 261 else if (!string.IsNullOrEmpty(url))
260 { 262 {
261 ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID); 263 ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
@@ -397,17 +399,21 @@ namespace OpenSim.Groups
397 399
398 if (success) 400 if (success)
399 { 401 {
402 // Here we always return true. The user has been added to the local group,
403 // independent of whether the remote operation succeeds or not
400 url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI"); 404 url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
401 if (url == string.Empty) 405 if (url == string.Empty)
402 { 406 {
403 reason = "User doesn't have a groups server"; 407 reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid.";
404 return false; 408 return true;
405 } 409 }
406 410
407 GroupsServiceHGConnector c = GetConnector(url); 411 GroupsServiceHGConnector c = GetConnector(url);
408 if (c != null) 412 if (c != null)
409 return c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason); 413 c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
414 return true;
410 } 415 }
416 return false;
411 } 417 }
412 } 418 }
413 else if (m_UserManagement.IsLocalGridUser(uid)) // local user 419 else if (m_UserManagement.IsLocalGridUser(uid)) // local user
@@ -544,7 +550,6 @@ namespace OpenSim.Groups
544 List<string> urls = new List<string>(); 550 List<string> urls = new List<string>();
545 foreach (GroupMembersData m in members) 551 foreach (GroupMembersData m in members)
546 { 552 {
547 UUID userID = UUID.Zero;
548 if (!m_UserManagement.IsLocalGridUser(m.AgentID)) 553 if (!m_UserManagement.IsLocalGridUser(m.AgentID))
549 { 554 {
550 string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI"); 555 string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI");
@@ -592,28 +597,6 @@ namespace OpenSim.Groups
592 return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID); 597 return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
593 } 598 }
594 599
595 public void ResetAgentGroupChatSessions(string agentID)
596 {
597 }
598
599 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
600 {
601 return false;
602 }
603
604 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
605 {
606 return false;
607 }
608
609 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
610 {
611 }
612
613 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
614 {
615 }
616
617 #endregion 600 #endregion
618 601
619 #region hypergrid groups 602 #region hypergrid groups
@@ -685,6 +668,9 @@ namespace OpenSim.Groups
685 { 668 {
686 serviceLocation = string.Empty; 669 serviceLocation = string.Empty;
687 name = string.Empty; 670 name = string.Empty;
671 if (groupID.Equals(UUID.Zero))
672 return true;
673
688 ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty); 674 ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty);
689 if (group == null) 675 if (group == null)
690 { 676 {
diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs
index 3584f78..6f58922 100644
--- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs
+++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs
@@ -47,7 +47,6 @@ namespace OpenSim.Groups
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private HGGroupsService m_GroupsService; 49 private HGGroupsService m_GroupsService;
50 private string m_HomeURI = string.Empty;
51 private string m_ConfigName = "Groups"; 50 private string m_ConfigName = "Groups";
52 51
53 // Called by Robust shell 52 // Called by Robust shell
@@ -209,7 +208,6 @@ namespace OpenSim.Groups
209 UUID groupID = new UUID(request["GroupID"].ToString()); 208 UUID groupID = new UUID(request["GroupID"].ToString());
210 string agentID = request["AgentID"].ToString(); 209 string agentID = request["AgentID"].ToString();
211 string token = request["AccessToken"].ToString(); 210 string token = request["AccessToken"].ToString();
212 string reason = string.Empty;
213 211
214 m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token); 212 m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
215 } 213 }
diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
index 73deb7a..a09b59e 100644
--- a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
+++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
@@ -92,12 +92,6 @@ namespace OpenSim.Groups
92 GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID); 92 GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
93 List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID); 93 List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
94 94
95 void ResetAgentGroupChatSessions(string agentID);
96 bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID);
97 bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID);
98 void AgentDroppedFromGroupChatSession(string agentID, UUID groupID);
99 void AgentInvitedToGroupChatSession(string agentID, UUID groupID);
100
101 } 95 }
102 96
103 public class GroupInviteInfo 97 public class GroupInviteInfo
diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
index 905bc91..564dec4 100644
--- a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
@@ -320,28 +320,6 @@ namespace OpenSim.Groups
320 return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID); 320 return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
321 } 321 }
322 322
323 public void ResetAgentGroupChatSessions(string agentID)
324 {
325 }
326
327 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
328 {
329 return false;
330 }
331
332 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
333 {
334 return false;
335 }
336
337 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
338 {
339 }
340
341 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
342 {
343 }
344
345 #endregion 323 #endregion
346 } 324 }
347} 325}
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
index 04328c9..161ca0c 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
@@ -133,6 +133,36 @@ namespace OpenSim.Groups
133 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); 133 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
134 } 134 }
135 135
136 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
137 {
138 List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
139 if (string.IsNullOrEmpty(query))
140 return hits;
141
142 Dictionary<string, object> sendData = new Dictionary<string, object>();
143 sendData["Query"] = query;
144 sendData["RequestingAgentID"] = RequestingAgentID;
145
146 Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
147
148 if (ret == null)
149 return hits;
150
151 if (!ret.ContainsKey("RESULT"))
152 return hits;
153
154 if (ret["RESULT"].ToString() == "NULL")
155 return hits;
156
157 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
158 {
159 DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
160 hits.Add(m);
161 }
162
163 return hits;
164 }
165
136 public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) 166 public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
137 { 167 {
138 reason = string.Empty; 168 reason = string.Empty;
@@ -226,6 +256,7 @@ namespace OpenSim.Groups
226 Dictionary<string, object> sendData = new Dictionary<string, object>(); 256 Dictionary<string, object> sendData = new Dictionary<string, object>();
227 sendData["GroupID"] = GroupID.ToString(); 257 sendData["GroupID"] = GroupID.ToString();
228 sendData["RequestingAgentID"] = RequestingAgentID; 258 sendData["RequestingAgentID"] = RequestingAgentID;
259
229 Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData); 260 Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
230 261
231 if (ret == null) 262 if (ret == null)
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
index f1cf66c..d3de0e8 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Groups
199 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search) 199 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
200 { 200 {
201 // TODO! 201 // TODO!
202 return new List<DirGroupsReplyData>(); 202 return m_GroupsService.FindGroups(RequestingAgentID, search);
203 } 203 }
204 204
205 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) 205 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
@@ -406,28 +406,6 @@ namespace OpenSim.Groups
406 }); 406 });
407 } 407 }
408 408
409 public void ResetAgentGroupChatSessions(string agentID)
410 {
411 }
412
413 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
414 {
415 return false;
416 }
417
418 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
419 {
420 return false;
421 }
422
423 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
424 {
425 }
426
427 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
428 {
429 }
430
431 #endregion 409 #endregion
432 } 410 }
433 411
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
index f991d01..7e55d3c 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
@@ -133,6 +133,8 @@ namespace OpenSim.Groups
133 return HandleAddNotice(request); 133 return HandleAddNotice(request);
134 case "GETNOTICES": 134 case "GETNOTICES":
135 return HandleGetNotices(request); 135 return HandleGetNotices(request);
136 case "FINDGROUPS":
137 return HandleFindGroups(request);
136 } 138 }
137 m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method); 139 m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
138 } 140 }
@@ -170,11 +172,16 @@ namespace OpenSim.Groups
170 172
171 } 173 }
172 174
173 grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID); 175 if (grec.GroupID != UUID.Zero)
174 if (grec == null) 176 {
175 NullResult(result, "Internal Error"); 177 grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID);
178 if (grec == null)
179 NullResult(result, "Internal Error");
180 else
181 result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
182 }
176 else 183 else
177 result["RESULT"] = GroupsDataUtils.GroupRecord(grec); 184 NullResult(result, reason);
178 } 185 }
179 186
180 string xmlString = ServerUtils.BuildXmlResponse(result); 187 string xmlString = ServerUtils.BuildXmlResponse(result);
@@ -264,7 +271,6 @@ namespace OpenSim.Groups
264 UUID groupID = new UUID(request["GroupID"].ToString()); 271 UUID groupID = new UUID(request["GroupID"].ToString());
265 string agentID = request["AgentID"].ToString(); 272 string agentID = request["AgentID"].ToString();
266 string requestingAgentID = request["RequestingAgentID"].ToString(); 273 string requestingAgentID = request["RequestingAgentID"].ToString();
267 string reason = string.Empty;
268 274
269 m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID); 275 m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
270 } 276 }
@@ -495,7 +501,6 @@ namespace OpenSim.Groups
495 else 501 else
496 { 502 {
497 string op = request["OP"].ToString(); 503 string op = request["OP"].ToString();
498 string reason = string.Empty;
499 504
500 bool success = false; 505 bool success = false;
501 if (op == "ADD") 506 if (op == "ADD")
@@ -563,7 +568,6 @@ namespace OpenSim.Groups
563 else 568 else
564 { 569 {
565 string op = request["OP"].ToString(); 570 string op = request["OP"].ToString();
566 string reason = string.Empty;
567 571
568 if (op == "GROUP") 572 if (op == "GROUP")
569 { 573 {
@@ -626,7 +630,6 @@ namespace OpenSim.Groups
626 else 630 else
627 { 631 {
628 string op = request["OP"].ToString(); 632 string op = request["OP"].ToString();
629 string reason = string.Empty;
630 633
631 if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) 634 if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
632 { 635 {
@@ -739,6 +742,32 @@ namespace OpenSim.Groups
739 return Util.UTF8NoBomEncoding.GetBytes(xmlString); 742 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
740 } 743 }
741 744
745 byte[] HandleFindGroups(Dictionary<string, object> request)
746 {
747 Dictionary<string, object> result = new Dictionary<string, object>();
748
749 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
750 NullResult(result, "Bad network data");
751
752 List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
753
754 if (hits == null || (hits != null && hits.Count == 0))
755 NullResult(result, "No hits");
756 else
757 {
758 Dictionary<string, object> dict = new Dictionary<string, object>();
759 int i = 0;
760 foreach (DirGroupsReplyData n in hits)
761 dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
762
763 result["RESULT"] = dict;
764 }
765
766
767 string xmlString = ServerUtils.BuildXmlResponse(result);
768 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
769 }
770
742 771
743 #region Helpers 772 #region Helpers
744 773
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
index e7d38c2..3ac74fc 100644
--- a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
+++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Groups
53 private ForeignImporter m_ForeignImporter; 53 private ForeignImporter m_ForeignImporter;
54 54
55 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>(); 55 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
56 private const int GROUPS_CACHE_TIMEOUT = 5 * 60; // 5 minutes 56 private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
57 57
58 // This all important cache cahces objects of different types: 58 // This all important cache cahces objects of different types:
59 // group-<GroupID> or group-<Name> => ExtendedGroupRecord 59 // group-<GroupID> or group-<Name> => ExtendedGroupRecord
@@ -209,13 +209,10 @@ namespace OpenSim.Groups
209 public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d) 209 public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
210 { 210 {
211 GroupMembershipData activeGroup = d(); 211 GroupMembershipData activeGroup = d();
212 if (activeGroup != null) 212 string cacheKey = "active-" + AgentID.ToString();
213 { 213 lock (m_Cache)
214 string cacheKey = "active-" + AgentID.ToString(); 214 if (m_Cache.Contains(cacheKey))
215 lock (m_Cache) 215 m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
216 if (m_Cache.Contains(cacheKey))
217 m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
218 }
219 } 216 }
220 217
221 public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d) 218 public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs
index 0668870..037ef59 100644
--- a/OpenSim/Addons/Groups/Service/GroupsService.cs
+++ b/OpenSim/Addons/Groups/Service/GroupsService.cs
@@ -130,6 +130,13 @@ namespace OpenSim.Groups
130 { 130 {
131 reason = string.Empty; 131 reason = string.Empty;
132 132
133 // Check if the group already exists
134 if (m_Database.RetrieveGroup(name) != null)
135 {
136 reason = "A group with that name already exists";
137 return UUID.Zero;
138 }
139
133 // Create the group 140 // Create the group
134 GroupData data = new GroupData(); 141 GroupData data = new GroupData();
135 data.GroupID = UUID.Random(); 142 data.GroupID = UUID.Random();
@@ -248,13 +255,20 @@ namespace OpenSim.Groups
248 return members; 255 return members;
249 List<RoleData> rolesList = new List<RoleData>(roles); 256 List<RoleData> rolesList = new List<RoleData>(roles);
250 257
251 // Is the requester a member of the group? 258 // Check visibility?
252 bool isInGroup = false; 259 // When we don't want to check visibility, we pass it "all" as the requestingAgentID
253 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null) 260 bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
254 isInGroup = true;
255 261
256 if (!isInGroup) // reduce the roles to the visible ones 262 if (checkVisibility)
257 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0); 263 {
264 // Is the requester a member of the group?
265 bool isInGroup = false;
266 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
267 isInGroup = true;
268
269 if (!isInGroup) // reduce the roles to the visible ones
270 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
271 }
258 272
259 MembershipData[] datas = m_Database.RetrieveMembers(GroupID); 273 MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
260 if (datas == null || (datas != null && datas.Length == 0)) 274 if (datas == null || (datas != null && datas.Length == 0))
@@ -723,12 +737,12 @@ namespace OpenSim.Groups
723 737
724 #region Actions without permission checks 738 #region Actions without permission checks
725 739
726 private void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) 740 protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
727 { 741 {
728 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty); 742 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty);
729 } 743 }
730 744
731 public void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) 745 protected void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
732 { 746 {
733 // 1. Delete membership 747 // 1. Delete membership
734 m_Database.DeleteMember(GroupID, AgentID); 748 m_Database.DeleteMember(GroupID, AgentID);
@@ -780,7 +794,7 @@ namespace OpenSim.Groups
780 794
781 } 795 }
782 796
783 private bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add) 797 protected bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add)
784 { 798 {
785 RoleData data = m_Database.RetrieveRole(groupID, roleID); 799 RoleData data = m_Database.RetrieveRole(groupID, roleID);
786 800
@@ -810,12 +824,12 @@ namespace OpenSim.Groups
810 return m_Database.StoreRole(data); 824 return m_Database.StoreRole(data);
811 } 825 }
812 826
813 private void _RemoveGroupRole(UUID groupID, UUID roleID) 827 protected void _RemoveGroupRole(UUID groupID, UUID roleID)
814 { 828 {
815 m_Database.DeleteRole(groupID, roleID); 829 m_Database.DeleteRole(groupID, roleID);
816 } 830 }
817 831
818 private void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) 832 protected void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
819 { 833 {
820 RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); 834 RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
821 if (data != null) 835 if (data != null)
@@ -840,7 +854,7 @@ namespace OpenSim.Groups
840 854
841 } 855 }
842 856
843 private List<GroupRolesData> _GetGroupRoles(UUID groupID) 857 protected List<GroupRolesData> _GetGroupRoles(UUID groupID)
844 { 858 {
845 List<GroupRolesData> roles = new List<GroupRolesData>(); 859 List<GroupRolesData> roles = new List<GroupRolesData>();
846 860
@@ -865,7 +879,7 @@ namespace OpenSim.Groups
865 return roles; 879 return roles;
866 } 880 }
867 881
868 private List<ExtendedGroupRoleMembersData> _GetGroupRoleMembers(UUID GroupID, bool isInGroup) 882 protected List<ExtendedGroupRoleMembersData> _GetGroupRoleMembers(UUID GroupID, bool isInGroup)
869 { 883 {
870 List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>(); 884 List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
871 885