From 19837ff4dd8b01cf1f0a458cafc02c56be48bf66 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:30:02 +0200 Subject: [PATCH] Two new scripting functions osInviteToGroup(userID) and osEjectFromGroup(userID) that invite/eject users to/from groups the object containing the script is set to. These functions also work for closed groups. --- .../Framework/Interfaces/IGroupsModule.cs | 2 + .../Avatar/XmlRpcGroups/GroupsModule.cs | 122 ++++++++++++++---- .../Shared/Api/Implementation/OSSL_Api.cs | 69 ++++++++++ .../Shared/Api/Interface/IOSSL_Api.cs | 3 + .../Shared/Api/Runtime/OSSL_Stub.cs | 10 ++ 5 files changed, 183 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs index 4c501f669b..6885327ec7 100644 --- a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs @@ -93,7 +93,9 @@ namespace OpenSim.Region.Framework.Interfaces void JoinGroupRequest(IClientAPI remoteClient, UUID GroupID); void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID); void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID); + void EjectGroupMember(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID EjecteeID); void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID); + void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID); void NotifyChange(UUID GroupID); } } \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index ea5d80568a..2a15e5d6f6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -956,18 +956,56 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) + { + EjectGroupMember(remoteClient, GetRequestingAgentID(remoteClient), groupID, ejecteeID); + } + + public void EjectGroupMember(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Todo: Security check? - m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(agentID, ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); + string agentName; + RegionInfo regionInfo; - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); + // remoteClient provided or just agentID? + if (remoteClient != null) + { + agentName = remoteClient.Name; + regionInfo = remoteClient.Scene.RegionInfo; + remoteClient.SendEjectGroupMemberReply(agentID, groupID, true); + } + else + { + IClientAPI client = GetActiveClient(agentID); - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); + if (client != null) + { + agentName = client.Name; + regionInfo = client.Scene.RegionInfo; + client.SendEjectGroupMemberReply(agentID, groupID, true); + } + else + { + regionInfo = m_sceneList[0].RegionInfo; + UserAccount acc = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, agentID); + + if (acc != null) + { + agentName = acc.FirstName + " " + acc.LastName; + } + else + { + agentName = "Unknown member"; + } + } + } + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); + + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID); if ((groupInfo == null) || (account == null)) { return; @@ -977,23 +1015,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = agentID.Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); + msg.fromAgentName = agentName; + msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; OutgoingInstantMessage(msg, ejecteeID); - // Message to ejector // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid @@ -1003,26 +1040,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = agentID.Guid; + msg.toAgentID = agentID.Guid; msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; + msg.fromAgentName = agentName; if (account != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, account.FirstName + " " + account.LastName); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, account.FirstName + " " + account.LastName); } else { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member"); } msg.dialog = (byte)210; //interop msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); + OutgoingInstantMessage(msg, agentID); // SL sends out messages to everyone in the group @@ -1031,17 +1068,56 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) + { + InviteGroup(remoteClient, GetRequestingAgentID(remoteClient), groupID, invitedAgentID, roleID); + } + + public void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID invitedAgentID, UUID roleID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + string agentName; + RegionInfo regionInfo; + + // remoteClient provided or just agentID? + if (remoteClient != null) + { + agentName = remoteClient.Name; + regionInfo = remoteClient.Scene.RegionInfo; + } + else + { + IClientAPI client = GetActiveClient(agentID); + + if (client != null) + { + agentName = client.Name; + regionInfo = client.Scene.RegionInfo; + } + else + { + regionInfo = m_sceneList[0].RegionInfo; + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, agentID); + + if (account != null) + { + agentName = account.FirstName + " " + account.LastName; + } + else + { + agentName = "Unknown member"; + } + } + } + // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(agentID, 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(GetRequestingAgentID(remoteClient), InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(agentID, InviteID); if (inviteInfo != null) { @@ -1053,19 +1129,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + // msg.fromAgentID = agentID.Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; - msg.fromAgentName = remoteClient.Name; - msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); + msg.fromAgentName = agentName; + msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", agentName); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; msg.fromGroup = true; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; - msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; + msg.RegionID = regionInfo.RegionID.Guid; msg.binaryBucket = new byte[20]; OutgoingInstantMessage(msg, invitedAgentID); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 2ecd890e9c..a5dcba47c8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2980,5 +2980,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return String.Empty; } + + /// + /// Invite user to the group this object is set to + /// + /// + /// + public LSL_Integer osInviteToGroup(LSL_Key agentId) + { + CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup"); + m_host.AddScriptLPS(1); + + UUID agent = new UUID(agentId); + + // groups module is required + IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface(); + if (groupsModule == null) return ScriptBaseClass.FALSE; + + // object has to be set to a group, but not group owned + if (m_host.GroupID == UUID.Zero || m_host.GroupID == m_host.OwnerID) return ScriptBaseClass.FALSE; + + // object owner has to be in that group and required permissions + GroupMembershipData member = groupsModule.GetMembershipData(m_host.GroupID, m_host.OwnerID); + if (member == null || (member.GroupPowers & (ulong)GroupPowers.Invite) == 0) return ScriptBaseClass.FALSE; + + // check if agent is in that group already + //member = groupsModule.GetMembershipData(agent, m_host.GroupID, agent); + //if (member != null) return ScriptBaseClass.FALSE; + + // invited agent has to be present in this scene + if (World.GetScenePresence(agent) == null) return ScriptBaseClass.FALSE; + + groupsModule.InviteGroup(null, m_host.OwnerID, m_host.GroupID, agent, UUID.Zero); + + return ScriptBaseClass.TRUE; + } + + /// + /// Eject user from the group this object is set to + /// + /// + /// + public LSL_Integer osEjectFromGroup(LSL_Key agentId) + { + CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup"); + m_host.AddScriptLPS(1); + + UUID agent = new UUID(agentId); + + // groups module is required + IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface(); + if (groupsModule == null) return ScriptBaseClass.FALSE; + + // object has to be set to a group, but not group owned + if (m_host.GroupID == UUID.Zero || m_host.GroupID == m_host.OwnerID) return ScriptBaseClass.FALSE; + + // object owner has to be in that group and required permissions + GroupMembershipData member = groupsModule.GetMembershipData(m_host.GroupID, m_host.OwnerID); + if (member == null || (member.GroupPowers & (ulong)GroupPowers.Eject) == 0) return ScriptBaseClass.FALSE; + + // agent has to be in that group + //member = groupsModule.GetMembershipData(agent, m_host.GroupID, agent); + //if (member == null) return ScriptBaseClass.FALSE; + + // ejectee can be offline + + groupsModule.EjectGroupMember(null, m_host.OwnerID, m_host.GroupID, agent); + + return ScriptBaseClass.TRUE; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 8f9efc04d9..30bd3ef9eb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -231,5 +231,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osUnixTimeToTimestamp(long time); LSL_String osGetInventoryDesc(string item); + + LSL_Integer osInviteToGroup(LSL_Key agentId); + LSL_Integer osEjectFromGroup(LSL_Key agentId); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 09e5992393..680cefb4e0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -868,5 +868,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetInventoryDesc(item); } + + public LSL_Integer osInviteToGroup(LSL_Key agentId) + { + return m_OSSL_Functions.osInviteToGroup(agentId); + } + + public LSL_Integer osEjectFromGroup(LSL_Key agentId) + { + return m_OSSL_Functions.osEjectFromGroup(agentId); + } } }