From 7c977f9e276b6469e108970d205238d89ccc5b83 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 20 Feb 2020 08:27:42 +0000 Subject: [PATCH] fix release controls on deattach --- .../Avatar/Attachments/AttachmentsModule.cs | 6 +- .../Framework/Interfaces/IEntityInventory.cs | 3 + .../Scenes/SceneObjectGroup.Inventory.cs | 26 +++++-- .../Scenes/SceneObjectPartInventory.cs | 71 +++++++++++++++++++ 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e53ca479a2..28079fda05 100755 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -839,6 +839,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); // Attach (NULL) stops scripts. We don't want that. Resume them. + so.RemoveScriptsPermissions(4 | 2048); // take controls and camera control so.ResumeScripts(); so.HasGroupChanged = true; so.RootPart.ScheduleFullUpdate(); @@ -856,11 +857,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } + so.RemoveScriptsPermissions(4 | 2048); // take controls and camera control + // If this didn't come from inventory, it also shouldn't go there // on detach. It's likely a temp attachment. if (so.FromItemID == UUID.Zero) { - // Retirn value is ignored PrepareScriptInstanceForSave(so, true); lock (sp.AttachmentsSyncLock) @@ -889,6 +891,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // clobber the run flag // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from // scripts performing attachment operations at the same time. Getting object states stops the scripts. + string scriptedState = PrepareScriptInstanceForSave(so, true); lock (sp.AttachmentsSyncLock) @@ -1194,6 +1197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.DeleteSceneObject(so, false, false); // Prepare sog for storage + so.AttachedAvatar = UUID.Zero; so.RootPart.SetParentLocalId(0); so.IsAttachment = false; diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index e7c2428708..5f1bd15311 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -105,6 +105,9 @@ namespace OpenSim.Region.Framework.Interfaces /// void StopScriptInstances(); + void RemoveScriptsPermissions(int permissions); + void RemoveScriptsPermissions(ScenePresence sp, int permissions); + /// /// Start a script which is in this entity's inventory. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 8899e96dba..0da2c2e5a1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -103,6 +103,20 @@ namespace OpenSim.Region.Framework.Scenes Array.ForEach(m_parts.GetArray(), p => p.Inventory.StopScriptInstances()); } + public void RemoveScriptsPermissions(int permissions) + { + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].Inventory.RemoveScriptsPermissions(permissions); + } + + public void RemoveScriptsPermissions(ScenePresence sp, int permissions) + { + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].Inventory.RemoveScriptsPermissions(sp, permissions); + } + /// /// Add an inventory item from a user's inventory to a prim in this scene object. /// @@ -139,6 +153,7 @@ namespace OpenSim.Region.Framework.Scenes taskItem.CreatorID = item.CreatorIdAsUuid; taskItem.Type = item.AssetType; taskItem.InvType = item.InvType; + taskItem.Flags = item.Flags; if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions()) { @@ -165,15 +180,14 @@ namespace OpenSim.Region.Framework.Scenes taskItem.NextPermissions = item.NextPermissions; } - taskItem.Flags = item.Flags; -// m_log.DebugFormat( -// "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}", -// taskItem.Flags, taskItem.Name, localID, remoteClient.Name); + // m_log.DebugFormat( + // "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}", + // taskItem.Flags, taskItem.Name, localID, remoteClient.Name); // TODO: These are pending addition of those fields to TaskInventoryItem -// taskItem.SalePrice = item.SalePrice; -// taskItem.SaleType = item.SaleType; + // taskItem.SalePrice = item.SalePrice; + // taskItem.SaleType = item.SaleType; taskItem.CreationDate = (uint)item.CreationDate; bool addFromAllowedDrop; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8c880fc179..437fbcf743 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -714,6 +714,77 @@ namespace OpenSim.Region.Framework.Scenes // m_part.ParentGroup.AddActiveScriptCount(-1); } + public void RemoveScriptsPermissions(int permissions) + { + bool removeControl = ((permissions & 4) != 0); //takecontrol + List grants = new List(); + List items = new List(); + + permissions = ~permissions; + m_items.LockItemsForWrite(true); + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.InvType != (int)InventoryType.LSL) + continue; + int curmask = item.PermsMask; + UUID curGrant = item.PermsGranter; + if (removeControl && ((curmask & 4) != 0)) + { + grants.Add(curGrant); + items.Add(item.ItemID); + } + curmask &= permissions; + item.PermsMask = curmask; + if(curmask == 0) + item.PermsGranter = UUID.Zero; + } + m_items.LockItemsForWrite(false); + + if(grants.Count > 0) + { + for(int i = 0; i< grants.Count;++i) + { + ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(grants[i]); + if (presence != null && !presence.IsDeleted) + presence.UnRegisterControlEventsToScript(m_part.LocalId, items[i]); + } + } + } + + public void RemoveScriptsPermissions(ScenePresence sp, int permissions) + { + bool removeControl = ((permissions & 4) != 0); //takecontrol + UUID grant = sp.UUID; + List items = new List(); + + permissions = ~permissions; + m_items.LockItemsForWrite(true); + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.InvType != (int) InventoryType.LSL) + continue; + if(grant != item.PermsGranter) + continue; + int curmask = item.PermsMask; + if (removeControl && ((curmask & 4) != 0)) + items.Add(item.ItemID); + curmask &= permissions; + item.PermsMask = curmask; + if(curmask == 0) + item.PermsGranter = UUID.Zero; + } + m_items.LockItemsForWrite(false); + + if(items.Count > 0) + { + for(int i = 0; i < items.Count; ++i) + { + if (!sp.IsDeleted) + sp.UnRegisterControlEventsToScript(m_part.LocalId, items[i]); + } + } + } + /// /// Check if the inventory holds an item with a given name. ///