diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 00fe5df046..06aad91f4b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,41 +28,30 @@ using System; using System.Collections.Generic; using System.Reflection; - - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule + public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the Groups Server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -108,8 +97,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - // NoOp + if (!m_groupMessagingEnabled) + return; + + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -117,12 +110,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupsModule = scene.RequestModuleInterface(); + m_groupData = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_groupsModule == null) + if (m_groupData == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -144,7 +137,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - } public void RemoveRegion(Scene scene) @@ -172,7 +164,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupsModule = null; + m_groupData = null; m_msgTransferModule = null; } @@ -197,6 +189,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + /// + /// Not really needed, but does confirm that the group exists. + /// + public bool StartGroupChatSession(UUID agentID, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); + + if (groupInfo != null) + { + return true; + } + else + { + return false; + } + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) + { + if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, 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; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + 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); + } + } + } + #region SimGridEventHandlers private void OnNewClient(IClientAPI client) @@ -236,42 +297,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + UUID AgentID = new UUID(msg.fromAgentID); + UUID GroupID = new UUID(msg.imSessionID); + switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) + ) { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, 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 + GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) + , msg.message + , new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -285,7 +350,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) + new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -295,7 +360,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -321,56 +386,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -383,21 +400,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - UUID groupID = new UUID(im.toAgentID); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); - - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) + GroupID + , AgentID , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -409,64 +428,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID groupID = new UUID(im.toAgentID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - SendMessageToGroup(im, groupID); + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + + SendMessageToGroup(im, GroupID); } } #endregion - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // 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 = im.imSessionID; - 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(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - 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); - } - } - } - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -518,6 +494,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + IClientAPI child = null; // Try root avatar first @@ -529,16 +507,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8d32e668a0..edd5af79a3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -87,16 +87,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; - class GroupRequestIDInfo - { - public GroupRequestID RequestID = new GroupRequestID(); - public DateTime LastUsedTMStamp = DateTime.MinValue; - } - private Dictionary m_clientRequestIDInfo = new Dictionary(); - private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer; - - // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; @@ -133,30 +123,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - m_clientRequestIDFlushTimer = new Timer(); - m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; - m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; - m_clientRequestIDFlushTimer.AutoReset = true; - m_clientRequestIDFlushTimer.Start(); - } - } - - void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) - { - lock (m_clientRequestIDInfo) - { - TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); - UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; - foreach (UUID key in CurrentKeys) - { - if (m_clientRequestIDInfo.ContainsKey(key)) - { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) - { - m_clientRequestIDInfo.Remove(key); - } - } - } } } @@ -234,8 +200,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); - - m_clientRequestIDFlushTimer.Stop(); } public Type ReplaceableInterface @@ -272,14 +236,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - lock (m_clientRequestIDInfo) - { - if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - // flush any old RequestID information - m_clientRequestIDInfo.Remove(client.AgentId); - } - } + // Send client thier groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -287,7 +244,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -331,10 +288,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { 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); + 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(GetClientGroupRequestID(remoteClient), queryText).ToArray()); + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); } } @@ -348,7 +308,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -361,13 +321,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -388,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); if (inviteInfo == null) { @@ -407,7 +367,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -431,14 +391,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } } @@ -452,7 +412,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -496,14 +456,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { if (m_debugEnabled) { @@ -549,7 +509,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.fromAgentID); + UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } @@ -588,20 +548,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(null, GroupID, null); + return m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); } + public GroupRecord GetGroupRecord(string name) + { + return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); + } + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } /// @@ -611,10 +576,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -636,8 +600,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } + } return data; @@ -647,21 +618,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID); return data; - } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } + } return data; - - } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -670,17 +645,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -691,7 +665,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -705,40 +679,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(UUID.Zero, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with groupID={1}, agentID={2}", + System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); - return m_groupData.GetAgentGroupMembership(null, agentID, groupID); + return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Check? - - m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + // Note: Permissions checking for modification rights is handled by the Groups Server/Service + m_groupData.UpdateGroup(GetRequestingAgentID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { - // TODO: Security Check? + // Note: Permissions checking for modification rights is handled by the Groups Server/Service if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; @@ -754,12 +728,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } money.ApplyGroupCreationCharge(remoteClient.AgentId); } - UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); return groupID; } @@ -770,7 +744,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); + return m_groupData.GetGroupNotices(GetRequestingAgentID(remoteClient), groupID).ToArray(); } /// @@ -780,7 +754,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero, avatarID); if (membership != null) { return membership.GroupTitle; @@ -795,13 +769,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } @@ -811,16 +785,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Security Checks are handled in the Groups Service. - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(GetRequestingAgentID(remoteClient), groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(grID, groupID, roleID); + m_groupData.RemoveGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: @@ -831,7 +803,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } - m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -842,7 +814,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -850,18 +822,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; default: @@ -870,25 +840,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); + GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.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; @@ -900,7 +868,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } } @@ -920,7 +888,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -947,7 +915,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) @@ -955,19 +923,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -975,21 +943,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); + remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); if ((groupInfo == null) || (userProfile == null)) @@ -1002,7 +969,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1028,8 +995,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; if (userProfile != null) @@ -1047,7 +1014,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); // SL sends out messages to everyone in the group @@ -1061,13 +1028,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - GroupRequestID grid = GetClientGroupRequestID(remoteClient); - m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); if (inviteInfo != null) { @@ -1079,7 +1045,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1132,57 +1098,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } - private GroupRequestID GetClientGroupRequestID(IClientAPI client) - { - if (client == null) - { - return new GroupRequestID(); - } - - lock (m_clientRequestIDInfo) - { - if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - GroupRequestIDInfo info = new GroupRequestIDInfo(); - info.RequestID.AgentID = client.AgentId; - info.RequestID.SessionID = client.SessionId; - - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); - - // Default to local user service and hope for the best? - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - - } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - info.RequestID.UserServiceURL = fupd.UserServerURI; - } - else - { - // They're a local user, use this: - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - } - - m_clientRequestIDInfo.Add(client.AgentId, info); - } - - m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; - - return m_clientRequestIDInfo[client.AgentId].RequestID; - } -// Unreachable code! -// return new GroupRequestID(); - } - /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1231,6 +1146,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups llDataStruct.Add("GroupData", GroupData); llDataStruct.Add("NewGroupData", NewGroupData); + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + } + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) @@ -1308,7 +1228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) { - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; if (requestingClient.AgentId != dataForAgentID) @@ -1330,7 +1250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers); } } @@ -1389,6 +1309,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; + } } + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 9e0fa2de4a..a046e094cd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,42 +36,47 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupsServicesConnector { - UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); - List FindGroups(GroupRequestID requestID, string search); - List GetGroupMembers(GroupRequestID requestID, UUID GroupID); + UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); + List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); - void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); - List GetGroupRoles(GroupRequestID requestID, UUID GroupID); - List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); + void AddGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID); + List GetGroupRoles(UUID RequestingAgentID, UUID GroupID); + List GetGroupRoleMembers(UUID RequestingAgentID, UUID GroupID); - void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void AddAgentToGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void AddAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void RemoveAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void AddAgentToGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void SetAgentActiveGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID RequestingAgentID, UUID AgentID); - void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); + void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); - GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); + void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); - void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); - List GetGroupNotices(GroupRequestID requestID, UUID GroupID); + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo @@ -81,11 +86,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID AgentID = UUID.Zero; public UUID InviteID = UUID.Zero; } - - public class GroupRequestID - { - public UUID AgentID = UUID.Zero; - public string UserServiceURL = string.Empty; - public UUID SessionID = UUID.Zero; - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs new file mode 100644 index 0000000000..669373f125 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -0,0 +1,1329 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; + +using Nwc.XmlRpc; + +using log4net; +using Mono.Addins; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; + +/*************************************************************************** + * Simian Data Map + * =============== + * + * OwnerID -> Type -> Key + * ----------------------- + * + * UserID -> Group -> ActiveGroup + * + GroupID + * + * UserID -> GroupSessionDropped -> GroupID + * UserID -> GroupSessionInvited -> GroupID + * + * UserID -> GroupMember -> GroupID + * + SelectedRoleID [UUID] + * + AcceptNotices [bool] + * + ListInProfile [bool] + * + Contribution [int] + * + * UserID -> GroupRole[GroupID] -> RoleID + * + * + * GroupID -> Group -> GroupName + * + Charter + * + ShowInList + * + InsigniaID + * + MembershipFee + * + OpenEnrollment + * + AllowPublish + * + MaturePublish + * + FounderID + * + EveryonePowers + * + OwnerRoleID + * + OwnersPowers + * + * GroupID -> GroupRole -> RoleID + * + Name + * + Description + * + Title + * + Powers + * + * GroupID -> GroupMemberInvite -> InviteID + * + AgentID + * + RoleID + * + * GroupID -> GroupNotice -> NoticeID + * + TimeStamp [uint] + * + FromName [string] + * + Subject [string] + * + Message [string] + * + BinaryBucket [byte[]] + * + * */ + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + private bool m_connectorEnabled = false; + + private string m_groupsServerURI = string.Empty; + + private bool m_debugEnabled = false; + + // private IUserAccountService m_accountService = null; + + + #region IRegionModuleBase Members + + public string Name + { + get { return "SimianGroupsServicesConnector"; } + } + + // this module is not intended to be replaced, but there should only be 1 of them. + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + { + m_connectorEnabled = false; + return; + } + + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); + m_connectorEnabled = false; + return; + } + + // If we got all the config options we need, lets start'er'up + m_connectorEnabled = true; + + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + + } + } + + public void Close() + { + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + } + + public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (m_connectorEnabled) + { + scene.RegisterModuleInterface(this); + } + } + + public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (scene.RequestModuleInterface() == this) + { + scene.UnregisterModuleInterface(this); + } + } + + public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) + { + // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info + // scene.EventManager.OnNewClient += OnNewClient; + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + + + + #region IGroupsServicesConnector Members + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + OSDMap GroupInfoMap = new OSDMap(); + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); + GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); + GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); + GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); + + if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) + { + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + + AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); + + return GroupID; + } + else + { + return UUID.Zero; + } + } + + + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // TODO: Check to make sure requestingAgentID has permission to update group + + string GroupName; + OSDMap GroupInfoMap; + if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) + { + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + + SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); + } + + } + + + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupRoleInfo = new OSDMap(); + GroupRoleInfo["Name"] = OSD.FromString(name); + GroupRoleInfo["Description"] = OSD.FromString(description); + GroupRoleInfo["Title"] = OSD.FromString(title); + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + // TODO: Add security, make sure that requestingAgentID has permision to add roles + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Add security + + // Can't delete the Everyone Role + if (roleID != UUID.Zero) + { + // Remove all GroupRole Members from Role + Dictionary GroupRoleMembers; + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) + { + foreach(UUID UserID in GroupRoleMembers.Keys) + { + EnsureRoleNotSelectedByMember(groupID, roleID, UserID); + + SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); + } + } + + // Remove role + SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); + } + } + + + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security, check that requestingAgentID is allowed to update group roles + + OSDMap GroupRoleInfo; + if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) + { + if (name != null) + { + GroupRoleInfo["Name"] = OSD.FromString(name); + } + if (description != null) + { + GroupRoleInfo["Description"] = OSD.FromString(description); + } + if (title != null) + { + GroupRoleInfo["Title"] = OSD.FromString(title); + } + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + } + + + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupInfoMap = null; + if (groupID != UUID.Zero) + { + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) + { + return null; + } + } + else if ((groupName != null) && (groupName != string.Empty)) + { + if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) + { + return null; + } + } + + GroupRecord GroupInfo = new GroupRecord(); + + GroupInfo.GroupID = groupID; + GroupInfo.GroupName = groupName; + GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); + GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); + GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); + GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); + GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); + GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); + GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); + GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); + GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); + + return GroupInfo; + + } + + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap groupProfile; + string groupName; + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) + { + // GroupProfileData is not nullable + return new GroupProfileData(); + } + + GroupProfileData MemberGroupProfile = new GroupProfileData(); + MemberGroupProfile.GroupID = groupID; + MemberGroupProfile.Name = groupName; + + if (groupProfile["Charter"] != null) + { + MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); + } + + MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; + MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); + MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); + MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); + MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); + MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); + MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; + MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); + + Dictionary Members; + if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) + { + MemberGroupProfile.GroupMembershipCount = Members.Count; + } + + Dictionary Roles; + if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) + { + MemberGroupProfile.GroupRolesCount = Roles.Count; + } + + // TODO: Get Group Money balance from somewhere + // group.Money = 0; + + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + } + + public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap ActiveGroup = new OSDMap(); + ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); + SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); + } + + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); + GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); + GroupMemberInfo["Contribution"] = OSD.FromInteger(0); + GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Invite = new OSDMap(); + Invite["AgentID"] = OSD.FromUUID(agentID); + Invite["RoleID"] = OSD.FromUUID(roleID); + + SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInvite; + UUID GroupID; + if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) + { + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = GroupID; + inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); + inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); + SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); + } + + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Setup Agent/Group information + SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); + + // Add agent to Everyone Group + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); + + // Add agent to Specified Role + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + + // Set selected role in this group to specified role + SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + } + + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If current active group is the group the agent is being removed from, change their group to UUID.Zero + GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); + if (memberActiveMembership.GroupID == groupID) + { + SetAgentActiveGroup(agentID, agentID, UUID.Zero); + } + + // Remove Group Member information for this group + SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); + + // By using a Simian Generics Type consisting of a prefix and a groupID, + // combined with RoleID as key allows us to get a list of roles a particular member + // of a group is assigned to. + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + + // Take Agent out of all other group roles + Dictionary GroupRoles; + if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) + { + foreach (string roleID in GroupRoles.Keys) + { + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); + } + } + } + + public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); + } + + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Cannot remove members from the Everyone Role + if (roleID != UUID.Zero) + { + EnsureRoleNotSelectedByMember(groupID, roleID, agentID); + + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); + } + } + + public List FindGroups(UUID requestingAgentID, string search) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List findings = new List(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", "Group" }, + { "Key", search }, + { "Fuzzy", "1" } + }; + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = entryMap["OwnerID"].AsUUID(); + data.groupName = entryMap["Key"].AsString(); + + // TODO: is there a better way to do this? + Dictionary Members; + if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) + { + data.members = Members.Count; + } + else + { + data.members = 0; + } + + // TODO: sort results? + // data.searchOrder = order; + + findings.Add(data); + } + } + + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData data = new GroupMembershipData(); + + /////////////////////////////// + // Agent Specific Information: + // + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); + } + + OSDMap UserGroupMemberInfo; + if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) + { + data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); + data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); + data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); + data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + + /////////////////////////////// + // Role Specific Information: + // + + OSDMap GroupRoleInfo; + if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) + { + data.GroupTitle = GroupRoleInfo["Title"].AsString(); + data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); + } + } + + /////////////////////////////// + // Group Specific Information: + // + OSDMap GroupInfo; + string GroupName; + if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) + { + data.GroupID = groupID; + data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); + data.Charter = GroupInfo["Charter"].AsString(); + data.FounderID = GroupInfo["FounderID"].AsUUID(); + data.GroupName = GroupName; + data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); + data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); + data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); + data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); + data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Zero; + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + GroupID = UserActiveGroup["GroupID"].AsUUID(); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); + } + + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List memberships = new List(); + + Dictionary GroupMemberShips; + if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) + { + foreach (string key in GroupMemberShips.Keys) + { + memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); + } + } + + return memberships; + } + + public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } + } + return Roles; + } + + public List GetGroupRoles(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach (KeyValuePair role in GroupRoles) + { + GroupRolesData data = new GroupRolesData(); + + data.RoleID = UUID.Parse(role.Key); + + data.Name = role.Value["Name"].AsString(); + data.Description = role.Value["Description"].AsString(); + data.Title = role.Value["Title"].AsString(); + data.Powers = role.Value["Powers"].AsULong(); + + Dictionary GroupRoleMembers; + if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) + { + data.Members = GroupRoleMembers.Count; + } + else + { + data.Members = 0; + } + + Roles.Add(data); + } + } + + return Roles; + + } + + + + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + OSDMap GroupInfo; + string GroupName; + UUID GroupOwnerRoleID = UUID.Zero; + if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) + { + return members; + } + GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); + + // Locally cache group roles, since we'll be needing this data for each member + Dictionary GroupRoles; + SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); + + // Locally cache list of group owners + Dictionary GroupOwners; + SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); + + + Dictionary GroupMembers; + if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) + { + foreach (KeyValuePair member in GroupMembers) + { + GroupMembersData data = new GroupMembersData(); + + data.AgentID = member.Key; + + UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); + + data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); + data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); + data.Contribution = member.Value["Contribution"].AsInteger(); + + data.IsOwner = GroupOwners.ContainsKey(member.Key); + + OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; + data.Title = GroupRoleInfo["Title"].AsString(); + data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); + + members.Add(data); + } + } + + return members; + + } + + public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach( KeyValuePair Role in GroupRoles ) + { + Dictionary GroupRoleMembers; + if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) + { + foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = GroupRoleMember.Key; + data.RoleID = UUID.Parse(Role.Key); + + members.Add(data); + } + } + } + } + + return members; + } + + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List values = new List(); + + Dictionary Notices; + if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) + { + foreach (KeyValuePair Notice in Notices) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse(Notice.Key); + data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); + data.FromName = Notice.Value["FromName"].AsString(); + data.Subject = Notice.Value["Subject"].AsString(); + data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; + + //TODO: Figure out how to get this + data.AssetType = 0; + + values.Add(data); + } + } + + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupNotice; + UUID GroupID; + if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) + { + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = GroupID; + data.Message = GroupNotice["Message"].AsString(); + data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); + data.noticeData.NoticeID = noticeID; + data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); + data.noticeData.FromName = GroupNotice["FromName"].AsString(); + data.noticeData.Subject = GroupNotice["Subject"].AsString(); + data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + return null; + } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Notice = new OSDMap(); + Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); + Notice["FromName"] = OSD.FromString(fromName); + Notice["Subject"] = OSD.FromString(subject); + Notice["Message"] = OSD.FromString(message); + Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); + + SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); + + } + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + #endregion + + private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If member's SelectedRole is roleID, change their selected role to Everyone + // before removing them from the role + OSDMap UserGroupInfo; + if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) + { + if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) + { + UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); + } + SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); + } + } + + + #region Simian Util Methods + private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + string value = OSDParser.SerializeJsonString(map); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "AddGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key }, + { "Value", value} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); + return false; + } + } + + /// + /// Returns the first of possibly many entries for Owner/Type pair + /// + private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + key = null; + map = null; + return false; + } + private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + ownerID = UUID.Zero; + map = null; + return false; + } + + private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count == 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + map = null; + return false; + } + + private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key } + }; + + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + + private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key } + }; + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); + return false; + } + } + #endregion + + } + +} + diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 964d0bbbf1..2a60b00e19 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -47,9 +47,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | @@ -61,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_disableKeepAlive = false; @@ -69,6 +67,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupWriteKey = string.Empty; + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + + #region IRegionModuleBase Members public string Name @@ -104,11 +110,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -118,6 +124,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; } @@ -131,13 +140,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (m_connectorEnabled) + { scene.RegisterModuleInterface(this); + } } public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (scene.RequestModuleInterface() == this) + { scene.UnregisterModuleInterface(this); + } } public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) @@ -157,14 +170,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - - #region IGroupsServicesConnector Members /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -236,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -248,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -262,10 +273,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall(requestID, "groups.updateGroup", param); + XmlRpcCall(requestingAgentID, "groups.updateGroup", param); } - public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -276,19 +287,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.addRoleToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -308,10 +319,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.updateGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -323,7 +334,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -334,12 +345,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -347,38 +358,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } - - - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); + XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -386,11 +394,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -398,16 +406,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); } - public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -423,60 +431,59 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); } - - public List FindGroups(GroupRequestID requestID, string search) + public List FindGroups(UUID requestingAgentID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); List findings = new List(); @@ -498,13 +505,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -516,12 +523,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -531,13 +538,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -552,13 +558,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); List Roles = new List(); @@ -584,12 +590,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); List Roles = new List(); @@ -617,12 +623,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); List members = new List(); @@ -650,12 +656,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -674,12 +680,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return members; } - public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); List values = new List(); @@ -701,12 +707,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return values; } - public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -732,7 +738,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -745,7 +751,70 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall(requestID, "groups.addGroupNotice", param); + XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); + } + + + + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID 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(UUID 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(UUID 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(UUID 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); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + } #endregion @@ -778,7 +847,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { - GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -797,6 +865,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -829,6 +898,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; } @@ -837,15 +907,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Encapsulate the XmlRpc call to standardize security and error handling. /// - private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) + private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - if (requestID == null) - { - requestID = new GroupRequestID(); - } - param.Add("RequestingAgentID", requestID.AgentID.ToString()); - param.Add("RequestingAgentUserService", requestID.UserServiceURL); - param.Add("RequestingSessionID", requestID.SessionID.ToString()); + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); param.Add("ReadKey", m_groupReadKey); @@ -862,7 +931,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups try { - resp = req.Send(m_serviceURL, 10000); + resp = req.Send(m_groupsServerURI, 10000); } catch (Exception e) { @@ -936,15 +1005,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + + /// + /// Group Request Tokens are an attempt to allow the groups service to authenticate + /// requests. + /// TODO: This broke after the big grid refactor, either find a better way, or discard this + /// + /// + /// + private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) + { + UserServiceURL = ""; + SessionID = UUID.Zero; - } - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; + // Need to rework this based on changes to User Services + /* + UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); + if (userAccount == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + UserServiceURL = fupd.UserServerURI; + SessionID = fupd.CurrentAgent.SessionID; + + } + else + { + // They're a local user, use this: + UserServiceURL = m_commManager.NetworkServersInfo.UserURL; + SessionID = userProfile.CurrentAgent.SessionID; + } + */ + } + } } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 5214718ec9..4a8629f6f0 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1302,10 +1302,18 @@ ;MessagingModule = GroupsMessagingModule ;MessagingEnabled = true - ; Service connector to Groups Service [Select One] - ; XmlRpc Service Connector to the Flotsam XmlRpc Groups Service Implementation + ; Service connector to Groups Service [Select One] ServicesConnectorModule + + + ; Simian Grid Service for Groups + ;ServicesConnectorModule = SimianGroupsServicesConnector + ;GroupsServerURI = http://mygridserver.com:82/Grid/ + + ; XmlRpc Service Connector to the Flotsam XmlRpc Groups Service settings ;ServicesConnectorModule = XmlRpcGroupsServicesConnector - ;XmlRpcServiceURL = http://yourxmlrpcserver.com/xmlrpc.php + ;GroupsServerURI = http://yourxmlrpcserver.com/xmlrpc.php + + ; XmlRpc Service Settings ;XmlRpcServiceReadKey = 1234 ;XmlRpcServiceWriteKey = 1234 diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 6da0f1e8a1..8fc24256e9 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -20,6 +20,12 @@ ; change this to your grid-wide grid server ; GridServerURI = "http://mygridserver.com:8003" +[Groups] + ; + ; change this to your grid-wide groups server + ; + GroupsServerURI = "http://mygridserver.com:82/Grid/" + [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.