From 844ae7720e02d01b839986e0ba8fab93f9c93c05 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 7 Sep 2013 17:58:32 +0200 Subject: [PATCH] Bring Core Groups up to current version --- OpenSim/Addons/Groups/GroupsExtendedData.cs | 24 + .../Addons/Groups/GroupsMessagingModule.cs | 432 +++++++++++++----- OpenSim/Addons/Groups/GroupsModule.cs | 109 ++--- .../GroupsServiceHGConnectorModule.cs | 42 +- .../HGGroupsServiceRobustConnector.cs | 2 - .../Addons/Groups/IGroupsServicesConnector.cs | 6 - .../GroupsServiceLocalConnectorModule.cs | 22 - .../Remote/GroupsServiceRemoteConnector.cs | 31 ++ .../GroupsServiceRemoteConnectorModule.cs | 24 +- .../Remote/GroupsServiceRobustConnector.cs | 45 +- .../Groups/RemoteConnectorCacheWrapper.cs | 13 +- .../Addons/Groups/Service/GroupsService.cs | 40 +- 12 files changed, 505 insertions(+), 285 deletions(-) diff --git a/OpenSim/Addons/Groups/GroupsExtendedData.cs b/OpenSim/Addons/Groups/GroupsExtendedData.cs index 6f4db286f4..1632aee706 100644 --- a/OpenSim/Addons/Groups/GroupsExtendedData.cs +++ b/OpenSim/Addons/Groups/GroupsExtendedData.cs @@ -504,6 +504,30 @@ namespace OpenSim.Groups return notice; } + + public static Dictionary DirGroupsReplyData(DirGroupsReplyData g) + { + Dictionary dict = new Dictionary(); + + dict["GroupID"] = g.groupID; + dict["Name"] = g.groupName; + dict["NMembers"] = g.members; + dict["SearchOrder"] = g.searchOrder; + + return dict; + } + + public static DirGroupsReplyData DirGroupsReplyData(Dictionary dict) + { + DirGroupsReplyData g; + + g.groupID = new UUID(dict["GroupID"].ToString()); + g.groupName = dict["Name"].ToString(); + Int32.TryParse(dict["NMembers"].ToString(), out g.members); + float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder); + + return g; + } } } diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index d172d48c6c..be59c6258c 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Groups { @@ -51,7 +52,7 @@ namespace OpenSim.Groups private IPresenceService m_presenceService; private IMessageTransferModule m_msgTransferModule = null; - + private IUserManagement m_UserManagement = null; private IGroupsServicesConnector m_groupData = null; // Config Options @@ -79,6 +80,10 @@ namespace OpenSim.Groups private int m_usersOnlineCacheExpirySeconds = 20; + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + + #region Region Module interfaceBase Members public void Initialise(IConfigSource config) @@ -124,10 +129,12 @@ namespace OpenSim.Groups m_sceneList.Add(scene); scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; scene.EventManager.OnClientLogin += OnClientLogin; } - + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -155,6 +162,17 @@ namespace OpenSim.Groups return; } + m_UserManagement = scene.RequestModuleInterface(); + + // No groups module, no groups messaging + if (m_UserManagement == null) + { + m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled."); + RemoveRegion(scene); + return; + } + + if (m_presenceService == null) m_presenceService = scene.PresenceService; @@ -227,87 +245,107 @@ namespace OpenSim.Groups public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { - List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID); + UUID fromAgentID = new UUID(im.fromAgentID); + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID); int groupMembersCount = groupMembers.Count; + PresenceInfo[] onlineAgents = null; - if (m_messageOnlineAgentsOnly) + // In V2 we always only send to online members. + // Sending to offline members is not an option. + string[] t1 = groupMembers.ConvertAll(gmd => gmd.AgentID.ToString()).ToArray(); + + // We cache in order not to overwhlem the presence service on large grids with many groups. This does + // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. + // (assuming this is the same across all grid simulators). + if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) { - string[] t1 = groupMembers.ConvertAll(gmd => gmd.AgentID.ToString()).ToArray(); + onlineAgents = m_presenceService.GetAgents(t1); + m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); + } - // We cache in order not to overwhlem the presence service on large grids with many groups. This does - // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. - // (assuming this is the same across all grid simulators). - PresenceInfo[] onlineAgents; - if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) - { - onlineAgents = m_presenceService.GetAgents(t1); - m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); - } + HashSet onlineAgentsUuidSet = new HashSet(); + Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); - HashSet onlineAgentsUuidSet = new HashSet(); - Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); + groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); - groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); - - // if (m_debugEnabled) +// if (m_debugEnabled) // m_log.DebugFormat( // "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", // groupID, groupMembersCount, groupMembers.Count()); - } - else - { - if (m_debugEnabled) - m_log.DebugFormat( - "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members", - groupID, groupMembers.Count); - } int requestStartTick = Environment.TickCount; + im.imSessionID = groupID.Guid; + im.fromGroup = true; + IClientAPI thisClient = GetActiveClient(fromAgentID); + if (thisClient != null) + { + im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid; + } + + // Send to self first of all + im.toAgentID = im.fromAgentID; + im.fromGroup = true; + ProcessMessageFromGroupSession(im); + + List regions = new List(); + List clientsAlreadySent = new List(); + + // Then send to everybody else foreach (GroupMembersData member in groupMembers) { - if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) + if (member.AgentID.Guid == im.fromAgentID) + continue; + + if (clientsAlreadySent.Contains(member.AgentID)) + continue; + clientsAlreadySent.Add(member.AgentID); + + if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); continue; } - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = groupID.Guid; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - msg.fromAgentID = im.fromAgentID; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; + im.toAgentID = member.AgentID.Guid; IClientAPI client = GetActiveClient(member.AgentID); if (client == null) { // If they're not local, forward across the grid + // BUT do it only once per region, please! Sim would be even better! if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + + bool reallySend = true; + if (onlineAgents != null) + { + PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString()); + if (regions.Contains(presence.RegionID)) + reallySend = false; + else + regions.Add(presence.RegionID); + } + + if (reallySend) + { + // We have to create a new IM structure because the transfer module + // uses async send + GridInstantMessage msg = new GridInstantMessage(im, true); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } } else { // Deliver locally, directly if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); + + ProcessMessageFromGroupSession(im); } + } - // Temporary for assessing how long it still takes to send messages to large online groups. - if (m_messageOnlineAgentsOnly) + if (m_debugEnabled) m_log.DebugFormat( "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); @@ -324,9 +362,20 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name); - client.OnInstantMessage += OnInstantMessage; + ResetAgentGroupChatSessions(client.AgentId.ToString()); } + void OnMakeRootAgent(ScenePresence sp) + { + sp.ControllingClient.OnInstantMessage += OnInstantMessage; + } + + void OnMakeChildAgent(ScenePresence sp) + { + sp.ControllingClient.OnInstantMessage -= OnInstantMessage; + } + + private void OnGridInstantMessage(GridInstantMessage msg) { // The instant message module will only deliver messages of dialog types: @@ -335,21 +384,91 @@ namespace OpenSim.Groups // Any other message type will not be delivered to a client by the // Instant Message Module - + UUID regionID = new UUID(msg.RegionID); if (m_debugEnabled) { - m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}", + System.Reflection.MethodBase.GetCurrentMethod().Name, regionID); DebugGridInstantMessage(msg); } // Incoming message from a group - if ((msg.fromGroup == true) && - ((msg.dialog == (byte)InstantMessageDialog.SessionSend) - || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) - || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) + if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend)) { - ProcessMessageFromGroupSession(msg); + // We have to redistribute the message across all members of the group who are here + // on this sim + + UUID GroupID = new UUID(msg.imSessionID); + + Scene aScene = m_sceneList[0]; + GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID); + + List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID); + + //if (m_debugEnabled) + // foreach (GroupMembersData m in groupMembers) + // m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID); + + foreach (Scene s in m_sceneList) + { + s.ForEachScenePresence(sp => + { + // If we got this via grid messaging, it's because the caller thinks + // that the root agent is here. We should only send the IM to root agents. + if (sp.IsChildAgent) + return; + + GroupMembersData m = groupMembers.Find(gmd => + { + return gmd.AgentID == sp.UUID; + }); + if (m.AgentID == UUID.Zero) + { + if (m_debugEnabled) + m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID); + return; + } + + // Check if the user has an agent in the region where + // the IM came from, and if so, skip it, because the IM + // was already sent via that agent + if (regionOfOrigin != null) + { + AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID); + if (aCircuit != null) + { + if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle)) + { + if (m_debugEnabled) + m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID); + return; + } + else + { + if (m_debugEnabled) + m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID); + } + } + } + + UUID AgentID = sp.UUID; + msg.toAgentID = AgentID.Guid; + + if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) + { + if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID)) + AddAgentToSession(AgentID, GroupID, msg); + else + { + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name); + + ProcessMessageFromGroupSession(msg); + } + } + }); + + } } } @@ -359,82 +478,40 @@ namespace OpenSim.Groups UUID AgentID = new UUID(msg.fromAgentID); UUID GroupID = new UUID(msg.imSessionID); + UUID toAgentID = new UUID(msg.toAgentID); switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); + AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); break; case (byte)InstantMessageDialog.SessionDrop: - m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); + AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID) - && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID) - ) + // User hasn't dropped, so they're in the session, + // maybe we should deliver it. + IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); + if (client != null) { - // Agent not in session and hasn't dropped from session - // Add them to the session for now, and Invite them - m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name); - UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI activeClient = GetActiveClient(toAgentID); - if (activeClient != null) + if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID)) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); - - // Force? open the group session dialog??? - // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); - IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - GroupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message - , new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName) - ); - - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } + if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID)) + // This actually sends the message too, so no need to resend it + // with client.SendInstantMessage + AddAgentToSession(toAgentID, GroupID, msg); + else + client.SendInstantMessage(msg); } } - else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) + else { - // User hasn't dropped, so they're in the session, - // maybe we should deliver it. - IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); - if (client != null) - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name); - client.SendInstantMessage(msg); - } - else - { - m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - } + m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); } break; @@ -444,6 +521,53 @@ namespace OpenSim.Groups } } + private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg) + { + // Agent not in session and hasn't dropped from session + // Add them to the session for now, and Invite them + AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); + + IClientAPI activeClient = GetActiveClient(AgentID); + if (activeClient != null) + { + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); + if (groupInfo != null) + { + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); + + // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); + IEventQueue eq = activeClient.Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + GroupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message + , AgentID + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName) + ); + + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , AgentID + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); + } + } + } + #endregion @@ -469,7 +593,7 @@ namespace OpenSim.Groups if (groupInfo != null) { - m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); + AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); @@ -495,7 +619,7 @@ namespace OpenSim.Groups m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); //If this agent is sending a message, then they want to be in the session - m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); + AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); SendMessageToGroup(im, GroupID); } @@ -566,12 +690,12 @@ namespace OpenSim.Groups { if (!sp.IsChildAgent) { - if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name); + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name); return sp.ControllingClient; } else { - if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name); + if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name); child = sp.ControllingClient; } } @@ -590,5 +714,71 @@ namespace OpenSim.Groups } #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(string agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + agentList.Remove(agentID); + + foreach (List agentList in m_groupsAgentsInvitedToChatSession.Values) + agentList.Remove(agentID); + } + + public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(string agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + + // Add to invited + if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID)) + m_groupsAgentsInvitedToChatSession[groupID].Add(agentID); + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + + } + #endregion + } } diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index f805d69f58..b0493faaf5 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -141,6 +141,8 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnMakeRootAgent += OnMakeRoot; + scene.EventManager.OnMakeChildAgent += OnMakeChild; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it @@ -194,6 +196,8 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnMakeRootAgent -= OnMakeRoot; + scene.EventManager.OnMakeChildAgent -= OnMakeChild; scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; lock (m_sceneList) @@ -232,16 +236,29 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; - client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; + } + private void OnMakeRoot(ScenePresence sp) + { + if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; // Used for Notices and Group Invites/Accept/Reject - client.OnInstantMessage += OnInstantMessage; + sp.ControllingClient.OnInstantMessage += OnInstantMessage; // Send client their groups information. - SendAgentGroupDataUpdate(client, client.AgentId); + SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID); + } + + private void OnMakeChild(ScenePresence sp) + { + if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; + // Used for Notices and Group Invites/Accept/Reject + sp.ControllingClient.OnInstantMessage -= OnInstantMessage; } private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) @@ -287,21 +304,6 @@ namespace OpenSim.Groups } */ - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) - { - if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) - { - if (m_debugEnabled) - m_log.DebugFormat( - "[Groups]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", - System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); - - // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), queryText).ToArray()); - } - - } - private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -347,7 +349,7 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog); + //m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog); // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { @@ -465,12 +467,12 @@ namespace OpenSim.Groups } // Send notice out to everyone that wants notices - // Build notice IIM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) { if (member.AcceptNotices) { + // Build notice IIM, one of reach, because the sending may be async + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); msg.toAgentID = member.AgentID.Guid; OutgoingInstantMessage(msg, member.AgentID); } @@ -485,7 +487,7 @@ namespace OpenSim.Groups return; //// 16 bytes are the UUID. Maybe. - UUID folderID = new UUID(im.binaryBucket, 0); +// UUID folderID = new UUID(im.binaryBucket, 0); UUID noticeID = new UUID(im.imSessionID); GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); @@ -766,14 +768,17 @@ namespace OpenSim.Groups remoteClient.SendCreateGroupReply(UUID.Zero, false, "Insufficient funds to create a group."); return UUID.Zero; } - money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate); } + string reason = string.Empty; UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId, out reason); if (groupID != UUID.Zero) { + if (money != null) + money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate); + remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. @@ -904,23 +909,7 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID); - //GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); - GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); - //GridInstantMessage msg = new GridInstantMessage(); - //msg.imSessionID = UUID.Zero.Guid; - //msg.fromAgentID = data.GroupID.Guid; - //msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; - //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - //msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; - //msg.message = data.noticeData.Subject + "|" + data.Message; - //msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - //msg.fromGroup = true; - //msg.offline = (byte)0; - //msg.ParentEstateID = 0; - //msg.Position = Vector3.Zero; - //msg.RegionID = UUID.Zero.Guid; - //msg.binaryBucket = data.BinaryBucket; OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } @@ -1002,6 +991,10 @@ namespace OpenSim.Groups // Should this send updates to everyone in the group? SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + + if (reason != string.Empty) + // A warning + remoteClient.SendAlertMessage("Warning: " + reason); } else remoteClient.SendJoinGroupReply(groupID, false); @@ -1186,6 +1179,11 @@ namespace OpenSim.Groups } } + public List FindGroups(IClientAPI remoteClient, string query) + { + return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query); + } + #endregion #region Client/Update Tools @@ -1225,12 +1223,16 @@ namespace OpenSim.Groups { if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information + // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything. + if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc) + return; + OSDArray AgentData = new OSDArray(1); OSDMap AgentDataMap = new OSDMap(1); AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); AgentData.Add(AgentDataMap); - OSDArray GroupData = new OSDArray(data.Length); OSDArray NewGroupData = new OSDArray(data.Length); @@ -1276,8 +1278,7 @@ namespace OpenSim.Groups if (queue != null) { queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); - } - + } } private void SendScenePresenceUpdate(UUID AgentID, string Title) @@ -1339,6 +1340,7 @@ namespace OpenSim.Groups GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); + //remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); if (remoteClient.AgentId == dataForAgentID) remoteClient.RefreshGroupMembership(); @@ -1399,19 +1401,18 @@ namespace OpenSim.Groups if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); - string firstname, lastname; - if (account != null) + string firstname = "Unknown", lastname = "Unknown"; + string name = m_UserManagement.GetUserName(dataForAgentID); + if (!string.IsNullOrEmpty(name)) { - firstname = account.FirstName; - lastname = account.LastName; + string[] parts = name.Split(new char[] { ' ' }); + if (parts.Length >= 2) + { + firstname = parts[0]; + lastname = parts[1]; + } } - else - { - firstname = "Unknown"; - lastname = "Unknown"; - } - + remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, lastname, activeGroupPowers, activeGroupName, activeGroupTitle); diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index f670272662..4642b2adaf 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -186,7 +186,6 @@ namespace OpenSim.Groups public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason) { - m_log.DebugFormat("[Groups]: Creating group {0}", name); reason = string.Empty; if (m_UserManagement.IsLocalGridUser(RequestingAgentID)) return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID, @@ -255,7 +254,10 @@ namespace OpenSim.Groups { string url = string.Empty, gname = string.Empty; if (IsLocal(GroupID, out url, out gname)) - return m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), GroupID); + { + string agentID = AgentUUI(RequestingAgentID); + return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID); + } else if (!string.IsNullOrEmpty(url)) { ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID); @@ -397,17 +399,21 @@ namespace OpenSim.Groups if (success) { + // Here we always return true. The user has been added to the local group, + // independent of whether the remote operation succeeds or not url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI"); if (url == string.Empty) { - reason = "User doesn't have a groups server"; - return false; + reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid."; + return true; } GroupsServiceHGConnector c = GetConnector(url); if (c != null) - return c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason); + c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason); + return true; } + return false; } } else if (m_UserManagement.IsLocalGridUser(uid)) // local user @@ -544,7 +550,6 @@ namespace OpenSim.Groups List urls = new List(); foreach (GroupMembersData m in members) { - UUID userID = UUID.Zero; if (!m_UserManagement.IsLocalGridUser(m.AgentID)) { string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI"); @@ -592,28 +597,6 @@ namespace OpenSim.Groups return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID); } - public void ResetAgentGroupChatSessions(string agentID) - { - } - - public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID) - { - } - - public void AgentInvitedToGroupChatSession(string agentID, UUID groupID) - { - } - #endregion #region hypergrid groups @@ -685,6 +668,9 @@ namespace OpenSim.Groups { serviceLocation = string.Empty; name = string.Empty; + if (groupID.Equals(UUID.Zero)) + return true; + ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty); if (group == null) { diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs index 3584f78c52..6f589226f2 100644 --- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs @@ -47,7 +47,6 @@ namespace OpenSim.Groups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HGGroupsService m_GroupsService; - private string m_HomeURI = string.Empty; private string m_ConfigName = "Groups"; // Called by Robust shell @@ -209,7 +208,6 @@ namespace OpenSim.Groups UUID groupID = new UUID(request["GroupID"].ToString()); string agentID = request["AgentID"].ToString(); string token = request["AccessToken"].ToString(); - string reason = string.Empty; m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token); } diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs index 73deb7a7b4..a09b59e238 100644 --- a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs +++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs @@ -92,12 +92,6 @@ namespace OpenSim.Groups GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID); List GetGroupNotices(string RequestingAgentID, UUID GroupID); - void ResetAgentGroupChatSessions(string agentID); - bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID); - bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID); - void AgentDroppedFromGroupChatSession(string agentID, UUID groupID); - void AgentInvitedToGroupChatSession(string agentID, UUID groupID); - } public class GroupInviteInfo diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs index 905bc913ff..564dec4543 100644 --- a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs +++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs @@ -320,28 +320,6 @@ namespace OpenSim.Groups return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID); } - public void ResetAgentGroupChatSessions(string agentID) - { - } - - public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID) - { - } - - public void AgentInvitedToGroupChatSession(string agentID, UUID groupID) - { - } - #endregion } } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index 04328c9c3a..161ca0c4cc 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -133,6 +133,36 @@ namespace OpenSim.Groups return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]); } + public List FindGroups(string RequestingAgentID, string query) + { + List hits = new List(); + if (string.IsNullOrEmpty(query)) + return hits; + + Dictionary sendData = new Dictionary(); + sendData["Query"] = query; + sendData["RequestingAgentID"] = RequestingAgentID; + + Dictionary ret = MakeRequest("FINDGROUPS", sendData); + + if (ret == null) + return hits; + + if (!ret.ContainsKey("RESULT")) + return hits; + + if (ret["RESULT"].ToString() == "NULL") + return hits; + + foreach (object v in ((Dictionary)ret["RESULT"]).Values) + { + DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary)v); + hits.Add(m); + } + + return hits; + } + public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) { reason = string.Empty; @@ -226,6 +256,7 @@ namespace OpenSim.Groups Dictionary sendData = new Dictionary(); sendData["GroupID"] = GroupID.ToString(); sendData["RequestingAgentID"] = RequestingAgentID; + Dictionary ret = MakeRequest("GETGROUPMEMBERS", sendData); if (ret == null) diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs index f1cf66c5ba..d3de0e8975 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs @@ -199,7 +199,7 @@ namespace OpenSim.Groups public List FindGroups(string RequestingAgentID, string search) { // TODO! - return new List(); + return m_GroupsService.FindGroups(RequestingAgentID, search); } public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) @@ -406,28 +406,6 @@ namespace OpenSim.Groups }); } - public void ResetAgentGroupChatSessions(string agentID) - { - } - - public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID) - { - return false; - } - - public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID) - { - } - - public void AgentInvitedToGroupChatSession(string agentID, UUID groupID) - { - } - #endregion } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index f991d016f0..7e55d3ce8a 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -133,6 +133,8 @@ namespace OpenSim.Groups return HandleAddNotice(request); case "GETNOTICES": return HandleGetNotices(request); + case "FINDGROUPS": + return HandleFindGroups(request); } m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method); } @@ -170,11 +172,16 @@ namespace OpenSim.Groups } - grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID); - if (grec == null) - NullResult(result, "Internal Error"); + if (grec.GroupID != UUID.Zero) + { + grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID); + if (grec == null) + NullResult(result, "Internal Error"); + else + result["RESULT"] = GroupsDataUtils.GroupRecord(grec); + } else - result["RESULT"] = GroupsDataUtils.GroupRecord(grec); + NullResult(result, reason); } string xmlString = ServerUtils.BuildXmlResponse(result); @@ -264,7 +271,6 @@ namespace OpenSim.Groups UUID groupID = new UUID(request["GroupID"].ToString()); string agentID = request["AgentID"].ToString(); string requestingAgentID = request["RequestingAgentID"].ToString(); - string reason = string.Empty; m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID); } @@ -495,7 +501,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; bool success = false; if (op == "ADD") @@ -563,7 +568,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; if (op == "GROUP") { @@ -626,7 +630,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) { @@ -739,6 +742,32 @@ namespace OpenSim.Groups return Util.UTF8NoBomEncoding.GetBytes(xmlString); } + byte[] HandleFindGroups(Dictionary request) + { + Dictionary result = new Dictionary(); + + if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query")) + NullResult(result, "Bad network data"); + + List hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString()); + + if (hits == null || (hits != null && hits.Count == 0)) + NullResult(result, "No hits"); + else + { + Dictionary dict = new Dictionary(); + int i = 0; + foreach (DirGroupsReplyData n in hits) + dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n); + + result["RESULT"] = dict; + } + + + string xmlString = ServerUtils.BuildXmlResponse(result); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); + } + #region Helpers diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs index e7d38c2020..3ac74fceb2 100644 --- a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs +++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs @@ -53,7 +53,7 @@ namespace OpenSim.Groups private ForeignImporter m_ForeignImporter; private Dictionary m_ActiveRequests = new Dictionary(); - private const int GROUPS_CACHE_TIMEOUT = 5 * 60; // 5 minutes + private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes // This all important cache cahces objects of different types: // group- or group- => ExtendedGroupRecord @@ -209,13 +209,10 @@ namespace OpenSim.Groups public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d) { GroupMembershipData activeGroup = d(); - if (activeGroup != null) - { - string cacheKey = "active-" + AgentID.ToString(); - lock (m_Cache) - if (m_Cache.Contains(cacheKey)) - m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT); - } + string cacheKey = "active-" + AgentID.ToString(); + lock (m_Cache) + if (m_Cache.Contains(cacheKey)) + m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT); } public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d) diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs index 0668870ef1..037ef59b9e 100644 --- a/OpenSim/Addons/Groups/Service/GroupsService.cs +++ b/OpenSim/Addons/Groups/Service/GroupsService.cs @@ -130,6 +130,13 @@ namespace OpenSim.Groups { reason = string.Empty; + // Check if the group already exists + if (m_Database.RetrieveGroup(name) != null) + { + reason = "A group with that name already exists"; + return UUID.Zero; + } + // Create the group GroupData data = new GroupData(); data.GroupID = UUID.Random(); @@ -248,13 +255,20 @@ namespace OpenSim.Groups return members; List rolesList = new List(roles); - // Is the requester a member of the group? - bool isInGroup = false; - if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null) - isInGroup = true; + // Check visibility? + // When we don't want to check visibility, we pass it "all" as the requestingAgentID + bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString()); - if (!isInGroup) // reduce the roles to the visible ones - rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0); + if (checkVisibility) + { + // Is the requester a member of the group? + bool isInGroup = false; + if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null) + isInGroup = true; + + if (!isInGroup) // reduce the roles to the visible ones + rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0); + } MembershipData[] datas = m_Database.RetrieveMembers(GroupID); if (datas == null || (datas != null && datas.Length == 0)) @@ -723,12 +737,12 @@ namespace OpenSim.Groups #region Actions without permission checks - private void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) + protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) { _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty); } - public void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) + protected void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) { // 1. Delete membership m_Database.DeleteMember(GroupID, AgentID); @@ -780,7 +794,7 @@ namespace OpenSim.Groups } - private bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add) + protected bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add) { RoleData data = m_Database.RetrieveRole(groupID, roleID); @@ -810,12 +824,12 @@ namespace OpenSim.Groups return m_Database.StoreRole(data); } - private void _RemoveGroupRole(UUID groupID, UUID roleID) + protected void _RemoveGroupRole(UUID groupID, UUID roleID) { m_Database.DeleteRole(groupID, roleID); } - private void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) + protected void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) { RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); if (data != null) @@ -840,7 +854,7 @@ namespace OpenSim.Groups } - private List _GetGroupRoles(UUID groupID) + protected List _GetGroupRoles(UUID groupID) { List roles = new List(); @@ -865,7 +879,7 @@ namespace OpenSim.Groups return roles; } - private List _GetGroupRoleMembers(UUID GroupID, bool isInGroup) + protected List _GetGroupRoleMembers(UUID GroupID, bool isInGroup) { List rmembers = new List();