From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001 From: onefang Date: Sun, 19 May 2019 21:24:15 +1000 Subject: Dump OpenSim 0.9.0.1 into it's own branch. --- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 337 ++++++++++++++++----- 1 file changed, 256 insertions(+), 81 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 81cef5b..c20c81d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -88,10 +88,6 @@ namespace OpenSim.Region.Framework.Scenes /// /// Stop and remove the scripts contained in all the prims in this group /// - /// - /// Should be true if these scripts are being removed because the scene - /// object is being deleted. This will prevent spurious updates to the client. - /// public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { SceneObjectPart[] parts = m_parts.GetArray(); @@ -115,78 +111,81 @@ namespace OpenSim.Region.Framework.Scenes /// The user inventory item being added. /// The item UUID that should be used by the new item. /// - public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID) + public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID, bool withModRights = true) { // m_log.DebugFormat( -// "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}", +// "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}", // item.Name, remoteClient.Name, localID); - + UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; SceneObjectPart part = GetPart(localID); - if (part != null) + if (part == null) { - TaskInventoryItem taskItem = new TaskInventoryItem(); - - taskItem.ItemID = newItemId; - taskItem.AssetID = item.AssetID; - taskItem.Name = item.Name; - taskItem.Description = item.Description; - taskItem.OwnerID = part.OwnerID; // Transfer ownership - taskItem.CreatorID = item.CreatorIdAsUuid; - taskItem.Type = item.AssetType; - taskItem.InvType = item.InvType; - - if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions()) - { - taskItem.BasePermissions = item.BasePermissions & - item.NextPermissions; - taskItem.CurrentPermissions = item.CurrentPermissions & - item.NextPermissions; - taskItem.EveryonePermissions = item.EveryOnePermissions & - item.NextPermissions; - taskItem.GroupPermissions = item.GroupPermissions & - item.NextPermissions; - taskItem.NextPermissions = item.NextPermissions; - // We're adding this to a prim we don't own. Force - // owner change - taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - } - else - { - taskItem.BasePermissions = item.BasePermissions; - taskItem.CurrentPermissions = item.CurrentPermissions; - taskItem.EveryonePermissions = item.EveryOnePermissions; - taskItem.GroupPermissions = item.GroupPermissions; - taskItem.NextPermissions = item.NextPermissions; - } - - taskItem.Flags = item.Flags; + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't find prim local ID {0} in group {1}, {2} to add inventory item ID {3}", + localID, Name, UUID, newItemId); + return false; + } -// 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.CreationDate = (uint)item.CreationDate; + TaskInventoryItem taskItem = new TaskInventoryItem(); - bool addFromAllowedDrop = agentID != part.OwnerID; + taskItem.ItemID = newItemId; + taskItem.AssetID = item.AssetID; + taskItem.Name = item.Name; + taskItem.Description = item.Description; + taskItem.OwnerID = part.OwnerID; // Transfer ownership + taskItem.CreatorID = item.CreatorIdAsUuid; + taskItem.Type = item.AssetType; + taskItem.InvType = item.InvType; - part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); + if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions()) + { + taskItem.BasePermissions = item.BasePermissions & + item.NextPermissions; + taskItem.CurrentPermissions = item.CurrentPermissions & + item.NextPermissions; + taskItem.EveryonePermissions = item.EveryOnePermissions & + item.NextPermissions; + taskItem.GroupPermissions = item.GroupPermissions & + item.NextPermissions; + taskItem.NextPermissions = item.NextPermissions; + // We're adding this to a prim we don't own. Force + // owner change + taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - return true; } else { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't find prim local ID {0} in group {1}, {2} to add inventory item ID {3}", - localID, Name, UUID, newItemId); + taskItem.BasePermissions = item.BasePermissions; + taskItem.CurrentPermissions = item.CurrentPermissions; + taskItem.EveryonePermissions = item.EveryOnePermissions; + taskItem.GroupPermissions = item.GroupPermissions; + taskItem.NextPermissions = item.NextPermissions; } - return false; + 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); + + // TODO: These are pending addition of those fields to TaskInventoryItem +// taskItem.SalePrice = item.SalePrice; +// taskItem.SaleType = item.SaleType; + taskItem.CreationDate = (uint)item.CreationDate; + + bool addFromAllowedDrop; + if(withModRights) + addFromAllowedDrop = false; + else + addFromAllowedDrop = (part.ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0; + + part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); + part.ParentGroup.InvalidateEffectivePerms(); + return true; + } /// @@ -252,21 +251,201 @@ namespace OpenSim.Region.Framework.Scenes return -1; } - public uint GetEffectivePermissions() + // new test code, to place in better place later + private object m_PermissionsLock = new object(); + private bool m_EffectivePermsInvalid = true; + private bool m_DeepEffectivePermsInvalid = true; + + // should called when parts chanced by their contents did not, so we know their cacche is valid + // in case of doubt call InvalidateDeepEffectivePerms(), it only costs a bit more cpu time + public void InvalidateEffectivePerms() + { + lock(m_PermissionsLock) + m_EffectivePermsInvalid = true; + } + + // should called when parts chanced and their contents where accounted for + public void InvalidateDeepEffectivePerms() + { + lock(m_PermissionsLock) + { + m_DeepEffectivePermsInvalid = true; + m_EffectivePermsInvalid = true; + } + } + + private uint m_EffectiveEveryOnePerms; + public uint EffectiveEveryOnePerms + { + get + { + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveEveryOnePerms; + } + } + } + + private uint m_EffectiveGroupPerms; + public uint EffectiveGroupPerms + { + get + { + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveGroupPerms; + } + } + } + + private uint m_EffectiveGroupOrEveryOnePerms; + public uint EffectiveGroupOrEveryOnePerms + { + get + { + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveGroupOrEveryOnePerms; + } + } + } + + private uint m_EffectiveOwnerPerms; + public uint EffectiveOwnerPerms + { + get + { + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveOwnerPerms; + } + } + } + + public void AggregatePerms() + { + lock(m_PermissionsLock) + { + // aux + const uint allmask = (uint)PermissionMask.AllEffective; + const uint movemodmask = (uint)(PermissionMask.Move | PermissionMask.Modify); + const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); + + uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; + bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; + + uint rootOwnerPerms = RootPart.OwnerMask; + uint owner = rootOwnerPerms; + uint rootGroupPerms = RootPart.GroupMask; + uint group = rootGroupPerms; + uint rootEveryonePerms = RootPart.EveryoneMask; + uint everyone = rootEveryonePerms; + + bool needUpdate = false; + // date is time of writing april 30th 2017 + bool newobj = (RootPart.CreationDate == 0 || RootPart.CreationDate > 1493574994); + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + + if(m_DeepEffectivePermsInvalid) + part.AggregatedInnerPermsForGroup(); + + owner &= part.AggregatedInnerOwnerPerms; + group &= part.AggregatedInnerGroupPerms; + if(newobj) + group &= part.AggregatedInnerGroupPerms; + if(newobj) + everyone &= part.AggregatedInnerEveryonePerms; + } + // recover modify and move + rootOwnerPerms &= movemodmask; + owner |= rootOwnerPerms; + if((owner & copytransfermast) == 0) + owner |= (uint)PermissionMask.Transfer; + + owner &= basePerms; + if(owner != m_EffectiveOwnerPerms) + { + needUpdate = true; + m_EffectiveOwnerPerms = owner; + } + + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; + + // recover modify and move + rootGroupPerms &= movemodmask; + group |= rootGroupPerms; + if(noBaseTransfer) + group &=~(uint)PermissionMask.Copy; + else + group |= ownertransfermask; + + uint groupOrEveryone = group; + uint tmpPerms = group & owner; + if(tmpPerms != m_EffectiveGroupPerms) + { + needUpdate = true; + m_EffectiveGroupPerms = tmpPerms; + } + + // recover move + rootEveryonePerms &= (uint)PermissionMask.Move; + everyone |= rootEveryonePerms; + everyone &= ~(uint)PermissionMask.Modify; + if(noBaseTransfer) + everyone &=~(uint)PermissionMask.Copy; + else + everyone |= ownertransfermask; + + groupOrEveryone |= everyone; + + tmpPerms = everyone & owner; + if(tmpPerms != m_EffectiveEveryOnePerms) + { + needUpdate = true; + m_EffectiveEveryOnePerms = tmpPerms; + } + + tmpPerms = groupOrEveryone & owner; + if(tmpPerms != m_EffectiveGroupOrEveryOnePerms) + { + needUpdate = true; + m_EffectiveGroupOrEveryOnePerms = tmpPerms; + } + + m_DeepEffectivePermsInvalid = false; + m_EffectivePermsInvalid = false; + + if(needUpdate) + RootPart.ScheduleFullUpdate(); + } + } + + public uint CurrentAndFoldedNextPermissions() { uint perms=(uint)(PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Move | - PermissionMask.Transfer) | 7; + PermissionMask.Transfer | + PermissionMask.FoldedMask); - uint ownerMask = 0x7fffffff; + uint ownerMask = RootPart.OwnerMask; SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; -// m_log.DebugFormat("[SCENE OBJECT GROUP INVENTORY]: Effective perms of {0} are {1}", part.Name, (OpenMetaverse.PermissionMask)part.OwnerMask); - ownerMask &= part.OwnerMask; + ownerMask &= part.BaseMask; perms &= part.Inventory.MaskEffectivePermissions(); } @@ -276,17 +455,8 @@ namespace OpenSim.Region.Framework.Scenes perms &= ~(uint)PermissionMask.Copy; if ((ownerMask & (uint)PermissionMask.Transfer) == 0) perms &= ~(uint)PermissionMask.Transfer; - - // If root prim permissions are applied here, this would screw - // with in-inventory manipulation of the next owner perms - // in a major way. So, let's move this to the give itself. - // Yes. I know. Evil. -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) -// perms &= ~((uint)PermissionMask.Modify >> 13); -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) -// perms &= ~((uint)PermissionMask.Copy >> 13); -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) -// perms &= ~((uint)PermissionMask.Transfer >> 13); + if ((ownerMask & (uint)PermissionMask.Export) == 0) + perms &= ~(uint)PermissionMask.Export; return perms; } @@ -323,18 +493,19 @@ namespace OpenSim.Region.Framework.Scenes xmldoc.AppendChild(xmlnode); XmlElement rootElement = xmldoc.CreateElement("", "ScriptData", String.Empty); - + xmldoc.AppendChild(rootElement); - + XmlElement wrapper = xmldoc.CreateElement("", "ScriptStates", String.Empty); - + rootElement.AppendChild(wrapper); foreach (KeyValuePair state in states) { XmlDocument sdoc = new XmlDocument(); + sdoc.XmlResolver=null; sdoc.LoadXml(state.Value); XmlNodeList rootL = sdoc.GetElementsByTagName("State"); XmlNode rootNode = rootL[0]; @@ -357,7 +528,7 @@ namespace OpenSim.Region.Framework.Scenes return; IScriptModule scriptModule = null; - + foreach (IScriptModule sm in s.RequestModuleInterfaces()) { if (sm.ScriptEngineName == s.DefaultScriptEngine) @@ -370,6 +541,7 @@ namespace OpenSim.Region.Framework.Scenes return; XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; try { doc.LoadXml(objXMLData); @@ -396,7 +568,7 @@ namespace OpenSim.Region.Framework.Scenes return; XmlElement dataE = (XmlElement)dataL[0]; - + foreach (XmlNode n in dataE.ChildNodes) { XmlElement stateE = (XmlElement)n; @@ -408,6 +580,9 @@ namespace OpenSim.Region.Framework.Scenes public void ResumeScripts() { + if (m_scene.RegionInfo.RegionSettings.DisableScripts) + return; + SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) parts[i].Inventory.ResumeScripts(); -- cgit v1.1