From cd77648f489a08b52093513e0ad3d7965104755d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 29 May 2010 05:14:18 +0200 Subject: [PATCH 01/11] Get the user's DOB back from the server response properly. --- OpenSim/Services/Interfaces/IUserAccountService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs index e316731a52..09d1d874f0 100644 --- a/OpenSim/Services/Interfaces/IUserAccountService.cs +++ b/OpenSim/Services/Interfaces/IUserAccountService.cs @@ -91,7 +91,7 @@ namespace OpenSim.Services.Interfaces UserTitle = kvp["UserTitle"].ToString(); if (kvp.ContainsKey("Created")) - Convert.ToInt32(kvp["Created"].ToString()); + Created = Convert.ToInt32(kvp["Created"].ToString()); if (kvp.ContainsKey("ServiceURLs") && kvp["ServiceURLs"] != null) { ServiceURLs = new Dictionary(); From bfcac0ede824ead5b6809f03eab73450f48075db Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 30 May 2010 13:46:05 +0200 Subject: [PATCH 02/11] Changes OSSL Api permissions for the case of UUID list. In 0.6.9, the UUIDs would be the IDs of the prim owners in whose prims these functions would run. This changes it so the UUID is the SCRIPT CREATOR instead. Further, osfunctions limited by uuid will not run if the creator and owner differ and the owner has mod rights on the script. There is still a danger in passing moodifiable scripts to others, as they can insert a harmful function, then remove the mod rights to make it runnable. As before, care needs to be taken, but where it was modable prims that were the risk before, modable scripts are the weak spot now. In cases where prim owner == script creator == script owner, nothing will change. --- .../Shared/Api/Implementation/OSSL_Api.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 15469db94f..5b634e0269 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -278,10 +278,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (!m_FunctionPerms[function].Contains(UUID.Zero)) { - if (!m_FunctionPerms[function].Contains(m_host.OwnerID)) + TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); + if (ti == null) + { OSSLError( - String.Format("{0} permission denied. Prim owner is not in the list of users allowed to execute this function.", + String.Format("{0} permission error. Can't find script in prim inventory.", function)); + } + if (!m_FunctionPerms[function].Contains(ti.CreatorID)) + OSSLError( + String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function.", + function)); + if (ti.CreatorID != ti.OwnerID) + { + if ((ti.CurrentPermissions & (uint)PermissionMask.Modify) != 0) + OSSLError( + String.Format("{0} permission denied. Script permissions error.", + function)); + + } } } } @@ -2137,4 +2152,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } -} \ No newline at end of file +} From f1a1d7a5211a250aeb4ed540562be0c79f051e4b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 30 May 2010 15:46:54 +0200 Subject: [PATCH 03/11] Changes osFunction permissions again. Allow_ with a list of UUIDs now again refers to prim OWNERS. A new option set, Creators_, is added to allow selection by script creator. For existing installs, this means no functional change. The warning from my prior commit doesn't apply anymore. --- .../Shared/Api/Implementation/OSSL_Api.cs | 69 ++++++++++++++----- bin/OpenSim.ini.example | 6 ++ 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 5b634e0269..7ada738084 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -105,6 +105,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // modification of user data, or allows the compromise of // sensitive data by design. + class FunctionPerms + { + public List AllowedCreators; + public List AllowedOwners; + + public FunctionPerms() + { + AllowedCreators = new List(); + AllowedOwners = new List(); + } + } + [Serializable] public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi { @@ -117,7 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; internal float m_ScriptDelayFactor = 1.0f; internal float m_ScriptDistanceFactor = 1.0f; - internal Dictionary > m_FunctionPerms = new Dictionary >(); + internal Dictionary m_FunctionPerms = new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { @@ -217,31 +229,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_FunctionPerms.ContainsKey(function)) { - string perm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); - if (perm == "") + FunctionPerms perms = new FunctionPerms(); + m_FunctionPerms[function] = perms; + + string ownerPerm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); + string creatorPerm = m_ScriptEngine.Config.GetString("Creators_" + function, ""); + if (ownerPerm == "" && creatorPerm == "") { - m_FunctionPerms[function] = null; // a null value is default + // Default behavior + perms.AllowedOwners = null; + perms.AllowedCreators = null; } else { bool allowed; - if (bool.TryParse(perm, out allowed)) + if (bool.TryParse(ownerPerm, out allowed)) { // Boolean given if (allowed) { - m_FunctionPerms[function] = new List(); - m_FunctionPerms[function].Add(UUID.Zero); + // Allow globally + perms.AllowedOwners.Add(UUID.Zero); } - else - m_FunctionPerms[function] = new List(); // Empty list = none } else { - m_FunctionPerms[function] = new List(); - - string[] ids = perm.Split(new char[] {','}); + string[] ids = ownerPerm.Split(new char[] {','}); foreach (string id in ids) { string current = id.Trim(); @@ -250,7 +264,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (UUID.TryParse(current, out uuid)) { if (uuid != UUID.Zero) - m_FunctionPerms[function].Add(uuid); + perms.AllowedOwners.Add(uuid); + } + } + + ids = creatorPerm.Split(new char[] {','}); + foreach (string id in ids) + { + string current = id.Trim(); + UUID uuid; + + if (UUID.TryParse(current, out uuid)) + { + if (uuid != UUID.Zero) + perms.AllowedCreators.Add(uuid); } } } @@ -266,8 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // // To allow use by anyone, the list contains UUID.Zero // - if (m_FunctionPerms[function] == null) // No list = true + if (m_FunctionPerms[function].AllowedOwners == null) { + // Allow / disallow by threat level if (level > m_MaxThreatLevel) OSSLError( String.Format( @@ -276,8 +304,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (!m_FunctionPerms[function].Contains(UUID.Zero)) + if (!m_FunctionPerms[function].AllowedOwners.Contains(UUID.Zero)) { + // Not anyone. Do detailed checks + if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) + { + // prim owner is in the list of allowed owners + return; + } + TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); if (ti == null) { @@ -285,9 +320,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api String.Format("{0} permission error. Can't find script in prim inventory.", function)); } - if (!m_FunctionPerms[function].Contains(ti.CreatorID)) + if (!m_FunctionPerms[function].AllowedCreators.Contains(ti.CreatorID)) OSSLError( - String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function.", + String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", function)); if (ti.CreatorID != ti.OwnerID) { diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 7b427a5fd2..2a70e9668e 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -979,6 +979,12 @@ ; Comma separated list of UUIDS allows the function for that list of UUIDS ; Allow_osSetRegionWaterHeight = 888760cb-a3cf-43ac-8ea4-8732fd3ee2bb + ; You can also use script creators as the uuid + ; Creators_osSetRegionWaterHeight = , ... + + ; If both Allow_ and Creators_ are given, effective permissions + ; are the union of the two. + ; Allow for llCreateLink and llBreakLink to work without asking for permission ; only enable this in a trusted environment otherwise you may be subject to hijacking ; AutomaticLinkPermission = false From 8df9f272eb0bd25c8965453ef8a88e3c998eeec8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 31 May 2010 01:02:04 +0200 Subject: [PATCH 04/11] Fix a nullref in EventManager caused by RegionReady not setting the scene --- .../Scripting/RegionReadyModule/RegionReadyModule.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c653e98401..672109b773 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -146,6 +146,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); c.Sender = null; c.SenderUUID = UUID.Zero; + c.Scene = m_scene; m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); From e515467c5e9a03de8d0df8e24d1ca70636f6e099 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 31 May 2010 19:00:02 +0200 Subject: [PATCH 05/11] Fix create selection getting overwritten by multiple updates for the same prim. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 ++++++++- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 0945bce5ae..a516a54ca4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4558,11 +4558,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (recipientID == data.OwnerID) { - if ((data.Flags & PrimFlags.CreateSelected) != 0) + if (data.CreateSelected) { // Only send this flag once, then unset it flags |= PrimFlags.CreateSelected; - data.Flags &= ~PrimFlags.CreateSelected; + data.CreateSelected = false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e923a92566..a02f614387 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1500,7 +1500,7 @@ namespace OpenSim.Region.Framework.Scenes // We need to explicitly resend the newly link prim's object properties since no other actions // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); + parentGroup.RootPart.CreateSelected = true; parentGroup.TriggerScriptChangedEvent(Changed.LINK); parentGroup.HasGroupChanged = true; parentGroup.ScheduleGroupForFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4453bebec8..ab7e3e99f6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2254,7 +2254,7 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = 2; linkPart.SetParent(this); - linkPart.AddFlag(PrimFlags.CreateSelected); + linkPart.CreateSelected = true; //if (linkPart.PhysActor != null) //{ diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b36b9bfff2..ce1972fd91 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -387,7 +387,6 @@ namespace OpenSim.Region.Framework.Scenes // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log _flags = 0; - _flags |= PrimFlags.CreateSelected; TrimPermissions(); //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); @@ -417,6 +416,7 @@ namespace OpenSim.Region.Framework.Scenes private PrimFlags _flags = 0; private DateTime m_expires; private DateTime m_rezzed; + private bool m_createSelected = true; public UUID CreatorID { @@ -967,6 +967,13 @@ namespace OpenSim.Region.Framework.Scenes set { m_updateFlag = value; } } + [XmlIgnore] + public bool CreateSelected + { + get { return m_createSelected; } + set { m_createSelected = value; } + } + #endregion //--------------- diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7a9a92d175..6e9a823c87 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3506,7 +3506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } parentPrim.TriggerScriptChangedEvent(Changed.LINK); - parentPrim.RootPart.AddFlag(PrimFlags.CreateSelected); + parentPrim.RootPart.CreateSelected = true; parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); From be69259981f0452f1f7fe7d084fde0f4bc2789cf Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 02:45:14 +0200 Subject: [PATCH 06/11] Change the handling of CreateSelected. Only send it on real creation, not for each prim coming into view. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ce1972fd91..38b2dc2f68 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -387,6 +387,7 @@ namespace OpenSim.Region.Framework.Scenes // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log _flags = 0; + CreateSelected = true; TrimPermissions(); //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); @@ -416,7 +417,7 @@ namespace OpenSim.Region.Framework.Scenes private PrimFlags _flags = 0; private DateTime m_expires; private DateTime m_rezzed; - private bool m_createSelected = true; + private bool m_createSelected = false; public UUID CreatorID { From 2fce7d9bcf001094e3d88516e7ea44e9a077da1b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 01:07:46 +0200 Subject: [PATCH 07/11] Split GetAxisAlignedBoundingBox into two methods to allow calculation of combined bounding boxes and offsets --- .../Framework/Scenes/SceneObjectGroup.cs | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ab7e3e99f6..0ad05e77b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -652,10 +652,16 @@ namespace OpenSim.Region.Framework.Scenes /// offsetHeight is the offset in the Z axis from the centre of the bounding box to the centre of the root prim /// /// - public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) + public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) { - float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; - lock (m_parts) + maxX = -256f; + maxY = -256f; + maxZ = -256f; + minX = 256f; + minY = 256f; + minZ = 256f; + + lock(m_parts); { foreach (SceneObjectPart part in m_parts.Values) { @@ -888,7 +894,18 @@ namespace OpenSim.Region.Framework.Scenes minZ = backBottomLeft.Z; } } + } + public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) + { + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; + + GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); offsetHeight = 0; From bde01e26e159e3e10fd606e316ab68a199af5934 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 01:25:24 +0200 Subject: [PATCH 08/11] Add a method to get the bounding box and root prim offsets within it for a group of prims. --- OpenSim/Region/Framework/Scenes/Scene.cs | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6d4de90f20..6300665b29 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5189,5 +5189,49 @@ namespace OpenSim.Region.Framework.Scenes ReloadEstateData(); } } + + public Vector3[] GetCombinedBoundingBox(List objects, out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) + { + minX = 256; + maxX = -256; + minY = 256; + maxY = -256; + minZ = 8192; + maxZ = -256; + + List offsets = new List(); + + foreach (SceneObjectGroup g in objects) + { + float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; + + g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); + + if (minX > ominX) + minX = ominX; + if (minY > ominY) + minY = ominY; + if (minZ > ominZ) + minZ = ominZ; + if (maxX < omaxX) + maxX = omaxX; + if (maxY < omaxY) + maxY = omaxY; + if (maxZ < omaxZ) + maxZ = omaxZ; + } + + foreach (SceneObjectGroup g in objects) + { + Vector3 vec = g.AbsolutePosition; + vec.X -= minX; + vec.Y -= minY; + vec.Z -= minZ; + + offsets.Add(vec); + } + + return offsets.ToArray(); + } } } From f29cb57bf183c0530ead35890163f39903c8f410 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 02:27:30 +0200 Subject: [PATCH 09/11] Continuing refactor. Refactor DeRezObject to deal with multiple objects --- .../HGInventoryAccessModule.cs | 17 +- .../InventoryAccess/InventoryAccessModule.cs | 14 ++ .../Interfaces/IInventoryAccessModule.cs | 2 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 18 ++- .../Framework/Scenes/Scene.Inventory.cs | 146 ++++++++++-------- 5 files changed, 122 insertions(+), 75 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 93aeb9440f..2ab46aa33f 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -119,9 +119,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// DeleteToInventory /// - public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) + public override UUID DeleteToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient) { - UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient); + UUID ret = UUID.Zero; + + // HACK: Only works for lists of length one. + // Intermediate version, just to make things compile + foreach (SceneObjectGroup g in objectGroups) + ret = DeleteToInventory(action, folderID, g, remoteClient); + + return ret; + } + + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + SceneObjectGroup objectGroup, IClientAPI remoteClient) + { + UUID assetID = base.DeleteToInventory(action, folderID, new List() {objectGroup}, remoteClient); if (!assetID.Equals(UUID.Zero)) { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 901dcba707..3035d889e7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -188,6 +188,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// /// + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + List objectGroups, IClientAPI remoteClient) + { + // HACK: This is only working for lists containing a single item! + // It's just a hack to make this WIP compile and run. Nothing + // currently calls this with multiple items. + UUID ret = UUID.Zero; + + foreach (SceneObjectGroup g in objectGroups) + ret = DeleteToInventory(action, folderID, g, remoteClient); + + return ret; + } + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) { diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 81852583c6..97f4188751 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IInventoryAccessModule { UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data); - UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient); + UUID DeleteToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient); SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index c08b961373..241cac0f11 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes { public DeRezAction action; public IClientAPI remoteClient; - public SceneObjectGroup objectGroup; + public List objectGroups; public UUID folderID; public bool permissionToDelete; } @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes /// Delete the given object from the scene /// public void DeleteToInventory(DeRezAction action, UUID folderID, - SceneObjectGroup objectGroup, IClientAPI remoteClient, + List objectGroups, IClientAPI remoteClient, bool permissionToDelete) { if (Enabled) @@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes DeleteToInventoryHolder dtis = new DeleteToInventoryHolder(); dtis.action = action; dtis.folderID = folderID; - dtis.objectGroup = objectGroup; + dtis.objectGroups = objectGroups; dtis.remoteClient = remoteClient; dtis.permissionToDelete = permissionToDelete; @@ -103,7 +103,10 @@ namespace OpenSim.Region.Framework.Scenes // This is not ideal since the object will still be available for manipulation when it should be, but it's // better than losing the object for now. if (permissionToDelete) - objectGroup.DeleteGroup(false); + { + foreach (SceneObjectGroup g in objectGroups) + g.DeleteGroup(false); + } } private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) @@ -140,9 +143,12 @@ namespace OpenSim.Region.Framework.Scenes { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) - invAccess.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); + invAccess.DeleteToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); if (x.permissionToDelete) - m_scene.DeleteSceneObject(x.objectGroup, false); + { + foreach (SceneObjectGroup g in x.objectGroups) + m_scene.DeleteSceneObject(g, false); + } } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 96f22a4255..bad92a00cd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1531,79 +1531,98 @@ namespace OpenSim.Region.Framework.Scenes public virtual void DeRezObject(IClientAPI remoteClient, uint localID, UUID groupID, DeRezAction action, UUID destinationID) { - SceneObjectPart part = GetSceneObjectPart(localID); - if (part == null) - return; + DeRezObjects(remoteClient, new List() { localID} , groupID, action, destinationID); + } - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) - return; + public virtual void DeRezObjects(IClientAPI remoteClient, List localIDs, + UUID groupID, DeRezAction action, UUID destinationID) + { + // First, see of we can perform the requested action and + // build a list of eligible objects + List deleteIDs = new List(); + List deleteGroups = new List(); - // Can't delete child prims - if (part != part.ParentGroup.RootPart) - return; + // Start with true for both, then remove the flags if objects + // that we can't derez are part of the selection + bool permissionToTake = true; + bool permissionToTakeCopy = true; + bool permissionToDelete = true; - SceneObjectGroup grp = part.ParentGroup; - - //force a database backup/update on this SceneObjectGroup - //So that we know the database is upto date, for when deleting the object from it - ForceSceneObjectBackup(grp); - - bool permissionToTake = false; - bool permissionToDelete = false; - - if (action == DeRezAction.SaveToExistingUserInventoryItem) + foreach (uint localID in localIDs) { - if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero) - { - permissionToTake = true; + // Invalid id + SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; + + // Already deleted by someone else + if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + continue; + + // Can't delete child prims + if (part != part.ParentGroup.RootPart) + continue; + + SceneObjectGroup grp = part.ParentGroup; + + deleteIDs.Add(localID); + deleteGroups.Add(grp); + + // Force a database backup/update on this SceneObjectGroup + // So that we know the database is upto date, + // for when deleting the object from it + ForceSceneObjectBackup(grp); + + if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + permissionToTakeCopy = false; + if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) + permissionToTake = false; + + if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) permissionToDelete = false; - } - } - else if (action == DeRezAction.TakeCopy) - { - permissionToTake = - Permissions.CanTakeCopyObject( - grp.UUID, - remoteClient.AgentId); - } - else if (action == DeRezAction.GodTakeCopy) - { - permissionToTake = - Permissions.IsGod( - remoteClient.AgentId); - } - else if (action == DeRezAction.Take) - { - permissionToTake = - Permissions.CanTakeObject( - grp.UUID, - remoteClient.AgentId); - //If they can take, they can delete! - permissionToDelete = permissionToTake; } - else if (action == DeRezAction.Delete) + + // Handle god perms + if (Permissions.IsGod(remoteClient.AgentId)) { - permissionToTake = - Permissions.CanDeleteObject( - grp.UUID, - remoteClient.AgentId); - permissionToDelete = permissionToTake; + permissionToTake = true; + permissionToTakeCopy = true; + permissionToDelete = true; } - else if (action == DeRezAction.Return) + + // If we're re-saving, we don't even want to delete + if (action == DeRezAction.SaveToExistingUserInventoryItem) + permissionToDelete = false; + + // if we want to take a copy,, we also don't want to delete + // Note: after this point, the permissionToTakeCopy flag + // becomes irrelevant. It already includes the permissionToTake + // permission and after excluding no copy items here, we can + // just use that. + if (action == DeRezAction.TakeCopy) + { + // If we don't have permission, stop right here + if (!permissionToTakeCopy) + return; + + // Don't delete + permissionToDelete = false; + } + + if (action == DeRezAction.Return) { if (remoteClient != null) { - permissionToTake = - Permissions.CanReturnObjects( + if (Permissions.CanReturnObjects( null, remoteClient.AgentId, - new List() {grp}); - permissionToDelete = permissionToTake; - - if (permissionToDelete) + deleteGroups)) + foreach (SceneObjectGroup g in deleteGroups) { - AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); + DeleteSceneObject(g, false); + return; } } else // Auto return passes through here with null agent @@ -1612,22 +1631,17 @@ namespace OpenSim.Region.Framework.Scenes permissionToDelete = true; } } - else - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name); - return; - } if (permissionToTake) { m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, grp, remoteClient, + action, destinationID, deleteGroups, remoteClient, permissionToDelete); } else if (permissionToDelete) { - DeleteSceneObject(grp, false); + foreach (SceneObjectGroup g in deleteGroups) + DeleteSceneObject(g, false); } } From a5728cc91c6737e6abef75c4b1da2f78a8317d84 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 03:04:49 +0200 Subject: [PATCH 10/11] Fix prim returns I broke earlier --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index bad92a00cd..cc7b6485f7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1618,11 +1618,14 @@ namespace OpenSim.Region.Framework.Scenes null, remoteClient.AgentId, deleteGroups)) - foreach (SceneObjectGroup g in deleteGroups) { - AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); - DeleteSceneObject(g, false); - return; + permissionToTake = true; + permissionToDelete = true; + + foreach (SceneObjectGroup g in deleteGroups) + { + AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); + } } } else // Auto return passes through here with null agent From 4867dd135dcdfece6af653906cb3bb088412110c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 03:04:49 +0200 Subject: [PATCH 11/11] Fix prim returns I broke earlier --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0ad05e77b8..837d3a2142 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -659,7 +659,7 @@ namespace OpenSim.Region.Framework.Scenes maxZ = -256f; minX = 256f; minY = 256f; - minZ = 256f; + minZ = 8192f; lock(m_parts); {