diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2c65e7398a..98c4f1d26a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3932,8 +3932,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_scene is null || IsDeleted) return; - HasGroupChanged = true; - if (SetTemporary) { DetachFromBackup(); @@ -3998,6 +3996,7 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false); m_scene.EventManager.TriggerParcelPrimCountTainted(); + HasGroupChanged = true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -4508,17 +4507,6 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateGroupRotationR(Quaternion rot) { m_rootPart.UpdateRotation(rot); - - /* this is done by rootpart RotationOffset set called by UpdateRotation - PhysicsActor actor = m_rootPart.PhysActor; - if (actor is not null) - { - actor.Orientation = m_rootPart.RotationOffset; - m_scene.PhysicsScene.AddPhysicsActorTaint(actor); - } - */ - HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); } /// @@ -4530,13 +4518,6 @@ namespace OpenSim.Region.Framework.Scenes { m_rootPart.UpdateRotation(rot); - //already done above - //PhysicsActor actor = m_rootPart.PhysActor; - //if (actor is not null) - //{ - // actor.Orientation = m_rootPart.RotationOffset; - //} - if (IsAttachment) { m_rootPart.AttachedPos = pos; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 497bfd683d..fbb1d968e9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -5071,7 +5071,7 @@ namespace OpenSim.Region.Framework.Scenes if (newTex.FaceTextures[i] != null) newFace = newTex.FaceTextures[i]; - if (oldFace.TextureID != newFace.TextureID) + if (oldFace.TextureID.NotEqual(newFace.TextureID)) changeFlags |= Changed.TEXTURE; Color4 oldRGBA = oldFace.RGBA; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 906886b300..ea9cb125e4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Holds in memory prim inventory /// - protected TaskInventoryDictionary m_items = new TaskInventoryDictionary(); + protected TaskInventoryDictionary m_items = []; protected Dictionary m_scripts = null; /// /// Tracks whether inventory has changed since the last persistent backup @@ -973,7 +973,7 @@ namespace OpenSim.Region.Framework.Scenes public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) { m_items.LockItemsForRead(true); - List il = new List(m_items.Values); + List il = [.. m_items.Values]; m_items.LockItemsForRead(false); foreach (TaskInventoryItem i in il) { @@ -1014,15 +1014,21 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(true); - m_items.Add(item.ItemID, item); - if (item.InvType == (int)InventoryType.LSL) - { - if (m_scripts == null) - m_scripts = new Dictionary(); - m_scripts.Add(item.ItemID, item); - } + bool added = m_items.TryAdd(item.ItemID, item); + if(added) + { + if (item.InvType == (int)InventoryType.LSL) + { + m_scripts ??= new Dictionary(); + m_scripts[item.ItemID] = item; + } + m_inventorySerial++; + HasInventoryChanged = true; + } m_items.LockItemsForWrite(false); + if(!added) + return; if (allowedDrop) m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP, item.ItemID); @@ -1030,8 +1036,6 @@ namespace OpenSim.Region.Framework.Scenes m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_part.AggregateInnerPerms(); - m_inventorySerial++; - HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } @@ -1044,21 +1048,29 @@ namespace OpenSim.Region.Framework.Scenes /// public void RestoreInventoryItems(ICollection items) { - m_items.LockItemsForWrite(true); + if (items == null || items.Count == 0) + return; + m_items.LockItemsForWrite(true); + int nchanges = 0; foreach (TaskInventoryItem item in items) { - m_items.Add(item.ItemID, item); - if (item.InvType == (int)InventoryType.LSL) - { - if (m_scripts == null) - m_scripts = new Dictionary(); - m_scripts.Add(item.ItemID, item); + if(m_items.TryAdd(item.ItemID, item)) + { + if (item.InvType == (int)InventoryType.LSL) + { + m_scripts ??= new Dictionary(); + m_scripts[item.ItemID] = item; + } + nchanges++; } } m_items.LockItemsForWrite(false); - m_part.AggregateInnerPerms(); - m_inventorySerial++; + if(nchanges > 0) + { + m_part.AggregateInnerPerms(); + m_inventorySerial++; + } } /// @@ -1331,7 +1343,7 @@ namespace OpenSim.Region.Framework.Scenes { m_items.LockItemsForWrite(true); - if (m_items.ContainsKey(item.ItemID)) + if (m_items.TryGetValue(item.ItemID, out TaskInventoryItem olditem)) { //m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); @@ -1347,7 +1359,7 @@ namespace OpenSim.Region.Framework.Scenes item.OwnerID = item.GroupID; if (item.AssetID.IsZero()) - item.AssetID = m_items[item.ItemID].AssetID; + item.AssetID = olditem.AssetID; m_items[item.ItemID] = item; if(item.InvType == (int)InventoryType.LSL) @@ -1391,50 +1403,45 @@ namespace OpenSim.Region.Framework.Scenes /// in this prim's inventory. public int RemoveInventoryItem(UUID itemID) { - m_items.LockItemsForRead(true); - - if (m_items.ContainsKey(itemID)) + m_items.LockItemsForWrite(true); + try { - int type = m_items[itemID].InvType; - m_items.LockItemsForRead(false); - if (type == (int)InventoryType.LSL) // Script + if (m_items.Remove(itemID, out TaskInventoryItem olditem)) { - m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); - } - m_items.LockItemsForWrite(true); - m_items.Remove(itemID); - if(m_scripts != null) - { - m_scripts.Remove(itemID); - if(m_scripts.Count == 0) - m_scripts = null; - } - if (m_scripts == null) - { - m_part.RemFlag(PrimFlags.Scripted); - } + int type = olditem.InvType; + if(m_scripts != null) + { + m_scripts.Remove(itemID); + if(m_scripts.Count == 0) + m_scripts = null; + } + if (m_scripts == null) + m_part.RemFlag(PrimFlags.Scripted); - m_part.ParentGroup.InvalidateDeepEffectivePerms(); - m_inventorySerial++; - HasInventoryChanged = true; + m_part.ParentGroup.InvalidateDeepEffectivePerms(); + m_inventorySerial++; + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + m_part.ScheduleFullUpdate(); + + if (type == (int)InventoryType.LSL) // Script + m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); + if (m_scripts != null) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + return type; + } + else + { + m_log.Error( + "[PRIM INVENTORY]: Tried to remove item ID " + + $"{itemID} from prim {m_part.Name}, {m_part.UUID} but the item does not exist in this inventory"); + } + } + finally + { m_items.LockItemsForWrite(false); - - m_part.ParentGroup.HasGroupChanged = true; - m_part.ScheduleFullUpdate(); - - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - return type; } - else - { - m_items.LockItemsForRead(false); - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", - itemID, m_part.Name, m_part.UUID); - } - return -1; }