From 0247d738e2cc4ad9ca6a8631c49cdd700f567190 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 27 Mar 2012 12:50:58 -0700 Subject: [PATCH 1/3] When loading objects from DB, first add to scene, then call TriggerOnSceneObjectLoaded. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9bca654d12..292c81f4a2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1685,8 +1685,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectGroup group in PrimsFromDB) { - EventManager.TriggerOnSceneObjectLoaded(group); AddRestoredSceneObject(group, true, true); + EventManager.TriggerOnSceneObjectLoaded(group); SceneObjectPart rootPart = group.GetChildPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; rootPart.TrimPermissions(); From 7223b63563f28f6fe8044bdabcd1b9900d28c54a Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:09:58 +0200 Subject: [PATCH 2/3] User level based restrictions for HyperGrid teleports, asset uploads, group creations and getting contacted from other grids. Incoming HyperGrid teleports can also be restricted to local users. --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 36 ++++++++++++---- ...ewFileAgentInventoryVariablePriceModule.cs | 42 +++++++++++++------ .../AssetTransactionModule.cs | 22 +++++++++- .../EntityTransfer/EntityTransferModule.cs | 15 +++++++ .../Avatar/XmlRpcGroups/GroupsModule.cs | 22 +++++++++- .../Shared/Api/Implementation/LSL_Api.cs | 3 ++ .../HypergridService/GatekeeperService.cs | 13 ++++++ .../HypergridService/UserAgentService.cs | 14 ++++++- bin/OpenSimDefaults.ini | 12 ++++++ bin/Robust.HG.ini.example | 3 ++ .../StandaloneCommon.ini.example | 7 ++++ 11 files changed, 164 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index ed3430a319..8ec2f200bb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -111,6 +111,7 @@ namespace OpenSim.Region.ClientStack.Linden private IAssetService m_assetService; private bool m_dumpAssetsToFile = false; private string m_regionName; + private int m_levelUpload = 0; public BunchOfCaps(Scene scene, Caps caps) { @@ -121,7 +122,10 @@ namespace OpenSim.Region.ClientStack.Linden { IConfig sconfig = config.Configs["Startup"]; if (sconfig != null) + { m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); + m_levelUpload = sconfig.GetInt("LevelUpload", 0); + } } m_assetService = m_Scene.AssetService; @@ -357,21 +361,37 @@ namespace OpenSim.Region.ClientStack.Linden llsdRequest.asset_type == "animation" || llsdRequest.asset_type == "sound") { + ScenePresence avatar = null; IClientAPI client = null; - IScene scene = null; - if (GetClient != null) - { - client = GetClient(m_HostCapsObj.AgentID); - scene = client.Scene; + m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar); - IMoneyModule mm = scene.RequestModuleInterface(); + // check user level + if (avatar != null) + { + client = avatar.ControllingClient; + + if (avatar.UserLevel < m_levelUpload) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + + LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); + errorResponse.uploader = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + + // check funds + if (client != null) + { + IMoneyModule mm = m_Scene.RequestModuleInterface(); if (mm != null) { if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); errorResponse.uploader = ""; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 1117f2a8a6..91872c5a34 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden // private IAssetService m_assetService; private bool m_dumpAssetsToFile = false; private bool m_enabled = true; + private int m_levelUpload = 0; #region IRegionModuleBase Members @@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden return; m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); + m_levelUpload = meshConfig.GetInt("LevelUpload", 0); } public void AddRegion(Scene pScene) @@ -137,25 +139,41 @@ namespace OpenSim.Region.ClientStack.Linden // llsdRequest.asset_type == "animation" || // llsdRequest.asset_type == "sound") // { + // check user level + ScenePresence avatar = null; IClientAPI client = null; + m_scene.TryGetScenePresence(agentID, out avatar); - + if (avatar != null) + { + client = avatar.ControllingClient; + + if (avatar.UserLevel < m_levelUpload) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + + // check funds IMoneyModule mm = m_scene.RequestModuleInterface(); - + if (mm != null) { - if (m_scene.TryGetClient(agentID, out client)) + if (!mm.UploadCovered(agentID, mm.UploadCharge)) { - if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - errorResponse.rsvp = ""; - errorResponse.state = "error"; - return errorResponse; - } + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; } } // } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 95e3aeceb1..874693e8ea 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction protected Scene m_Scene; private bool m_dumpAssetsToFile = false; + private int m_levelUpload = 0; /// /// Each agent has its own singleton collection of transactions @@ -56,8 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(IConfigSource source) { + IConfig sconfig = source.Configs["Startup"]; + if (sconfig != null) + { + m_levelUpload = sconfig.GetInt("LevelUpload", 0); + } } public void AddRegion(Scene scene) @@ -241,7 +247,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction (AssetType)type == AssetType.Animation) && tempFile == false) { + ScenePresence avatar = null; Scene scene = (Scene)remoteClient.Scene; + scene.TryGetScenePresence(remoteClient.AgentId, out avatar); + + // check user level + if (avatar != null) + { + if (avatar.UserLevel < m_levelUpload) + { + remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); + return; + } + } + + // check funds IMoneyModule mm = scene.RequestModuleInterface(); if (mm != null) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 2d73594189..427a49d248 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -60,6 +60,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer set { m_MaxTransferDistance = value; } } + private int m_levelHGTeleport = 0; + protected bool m_Enabled = false; protected Scene m_aScene; protected List m_Scenes = new List(); @@ -101,7 +103,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) + { MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); + m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); + } m_agentsInTransit = new List(); m_Enabled = true; @@ -227,6 +232,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + // check if HyperGrid teleport is allowed, based on user level + int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID); + + if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport)) + { + m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); + sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted"); + return; + } + uint curX = 0, curY = 0; Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); int curCellX = (int)(curX / Constants.RegionSize); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b60cd4206f..ea5d80568a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; private bool m_debugEnabled = false; + private int m_levelGroupCreate = 0; #region IRegionModuleBase Members @@ -115,6 +116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); + m_levelGroupCreate = groupsConfig.GetInt("LevelGroupCreate", 0); } } @@ -708,13 +710,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } + + // check user level + ScenePresence avatar = null; + Scene scene = (Scene)remoteClient.Scene; + scene.TryGetScenePresence(remoteClient.AgentId, out avatar); + + if (avatar != null) + { + if (avatar.UserLevel < m_levelGroupCreate) + { + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); + return UUID.Zero; + } + } + + // check funds // is there is a money module present ? - IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money = scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { - remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); + remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); return UUID.Zero; } money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d7a629bf8b..745592940d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4151,6 +4151,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case 4: // DATA_RATING (0,0,0,0,0,0) reply = "0,0,0,0,0,0"; break; + case 7: // DATA_USERLEVEL (integer) + reply = account.UserLevel.ToString(); + break; case 8: // DATA_PAYINFO (0|1|2|3) reply = "0"; break; diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 4e386879cc..149a0abb4f 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -60,6 +60,7 @@ namespace OpenSim.Services.HypergridService protected string m_AllowedClients = string.Empty; protected string m_DeniedClients = string.Empty; + private static bool m_ForeignAgentsAllowed = true; private static UUID m_ScopeID; private static bool m_AllowTeleportsToAnyRegion; @@ -110,6 +111,7 @@ namespace OpenSim.Services.HypergridService m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty); m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty); + m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true); if (m_GridService == null || m_PresenceService == null || m_SimulationService == null) throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); @@ -257,6 +259,17 @@ namespace OpenSim.Services.HypergridService } m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok"); + // + // Foreign agents allowed + // + if (account == null && !m_ForeignAgentsAllowed) + { + reason = "Unauthorized"; + m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1}. Refusing service.", + aCircuit.firstname, aCircuit.lastname); + return false; + } + // May want to authorize bool isFirstLogin = false; diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 6a5007ff26..49c7f89598 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -73,6 +73,8 @@ namespace OpenSim.Services.HypergridService protected static string m_GridName; + protected static int m_LevelOutsideContacts; + protected static bool m_BypassClientVerification; public UserAgentService(IConfigSource config) : this(config, null) @@ -127,6 +129,8 @@ namespace OpenSim.Services.HypergridService } if (!m_GridName.EndsWith("/")) m_GridName = m_GridName + "/"; + + m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0); } } @@ -571,10 +575,16 @@ namespace OpenSim.Services.HypergridService public UUID GetUUID(String first, String last) { - // Let's see if it's a local user + // Let's see if it's a local user UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last); if (account != null) - return account.PrincipalID; + { + // check user level + if (account.UserLevel < m_LevelOutsideContacts) + return UUID.Zero; + else + return account.PrincipalID; + } else return UUID.Zero; } diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 28c5587ad7..45d604f829 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -272,6 +272,8 @@ ; Disabled by default ; simple_build_permissions = False + ; Minimum user level required to upload assets + ;LevelUpload = 0 ; ## ; ## SCRIPT ENGINE @@ -620,6 +622,10 @@ ; This is set to 4095 because current viewers can't handle teleports that are greater than this distance max_distance = 4095 + ; Minimum user level required for HyperGrid teleports + LevelHGTeleport = 0 + + [Messaging] ; Control which region module is used for instant messaging. ; Default is InstantMessageModule (this is the name of the core IM module as well as the setting) @@ -657,6 +663,9 @@ ; mesh, and use it for collisions. UseMeshiesPhysicsMesh = true + ; Minimum user level required to upload meshes + ;LevelUpload = 0 + [ODEPhysicsSettings] ;## @@ -1497,6 +1506,9 @@ ; System.Net.WebException: The request was aborted: The request was canceled. ; XmlRpcDisableKeepAlive = false + ; Minimum user level required to create groups + ;LevelGroupCreate = 0 + [PacketPool] ; Enables the experimental packet pool. Yes, we've been here before. diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index e0242abbef..2fd9f11ba6 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -373,6 +373,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;; the IP address of the machine where your LoginService is ;LoginServerIP = "127.0.0.1" + ; User level required to be contacted from other grids + ;LevelOutsideContacts = 0 + ; * The interface that local users get when they are in other grids. ; * This restricts the inventory operations while in other grids. ; * Still not completely safe, especially if users perform inventory operations diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 3dfbed7fdc..8d9842cc5a 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -147,6 +147,9 @@ ;AllowedClients = "" ;DeniedClients = "" + ;; Are foreign visitors allowed + ;ForeignAgentsAllowed = true + [FreeswitchService] ;; If FreeSWITCH is not being used then you don't need to set any of these parameters ;; @@ -241,3 +244,7 @@ ; DisallowResidents -- only Admins and Managers allowed ; Example: ; Region_Test_1 = "DisallowForeigners" + +[UserAgentService] + ; User level required to be contacted from other grids + ;LevelOutsideContacts = 0 From 19837ff4dd8b01cf1f0a458cafc02c56be48bf66 Mon Sep 17 00:00:00 2001 From: Snoopy Pfeffer Date: Tue, 27 Mar 2012 22:30:02 +0200 Subject: [PATCH 3/3] 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); + } } }