From 2743565f7e66920906b9a3f81051fc75fff28728 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 17 Jan 2013 02:43:29 +0000 Subject: [PATCH 1/8] *TEST TEST TEST* don't send AvatarAppearance to self --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a9195f72fe..a5c19c3f42 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2707,7 +2707,7 @@ namespace OpenSim.Region.Framework.Scenes // again here... this comes after the cached appearance check because the avatars // appearance goes into the avatar update packet SendAvatarDataToAllAgents(); - SendAppearanceToAgent(this); +// SendAppearanceToAgent(this); // If we are using the the cached appearance then send it out to everyone if (cachedappearance) From 755e452342fe1c5a15552d2dcb903bdb1639081f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 17 Jan 2013 03:29:38 +0000 Subject: [PATCH 2/8] revert the test, sending again appearance to self in ValidateAndSendAppearanceAndAgentData() --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a5c19c3f42..a9195f72fe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2707,7 +2707,7 @@ namespace OpenSim.Region.Framework.Scenes // again here... this comes after the cached appearance check because the avatars // appearance goes into the avatar update packet SendAvatarDataToAllAgents(); -// SendAppearanceToAgent(this); + SendAppearanceToAgent(this); // If we are using the the cached appearance then send it out to everyone if (cachedappearance) From 9d1989e64fa460646f9a3d52d4024c3b56888617 Mon Sep 17 00:00:00 2001 From: teravus Date: Tue, 22 Jan 2013 18:49:50 -0500 Subject: [PATCH 3/8] * Handle a NRE with Baked Textures that may result in a failed appearance. This may be an issue, or it may be a symptom. --- .../Linden/Caps/UploadBakedTextureModule.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 6bed95f369..eca576dd76 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -190,8 +190,15 @@ namespace OpenSim.Region.ClientStack.Linden { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { - cacheItems[i].TextureID = - textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; + Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; + if (face == null) + { + textureEntry.CreateFace(cacheItems[i].TextureIndex); + textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = + AppearanceManager.DEFAULT_AVATAR_TEXTURE; + continue; + } + cacheItems[i].TextureID =face.TextureID; if (m_scene.AssetService != null) cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); @@ -213,8 +220,16 @@ namespace OpenSim.Region.ClientStack.Linden { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { + Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; + if (face == null) + { + textureEntry.CreateFace(cacheItems[i].TextureIndex); + textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = + AppearanceManager.DEFAULT_AVATAR_TEXTURE; + continue; + } cacheItems[i].TextureID = - textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID; + face.TextureID; } else { From bfac09849ff4b14f5df4bab4fffdbaea0d3b6a9e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 26 Jan 2013 06:12:26 +0000 Subject: [PATCH 4/8] bug fix: crash when too many collisions on a ode step --- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 82 ++++++++++--------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 510cbe90af..754bc86978 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -995,63 +995,67 @@ namespace OpenSim.Region.Physics.OdePlugin d.ContactGeom maxContact = curContact; -// if (IgnoreNegSides && curContact.side1 < 0) -// maxContact.depth = float.MinValue; + // if (IgnoreNegSides && curContact.side1 < 0) + // maxContact.depth = float.MinValue; d.ContactGeom minContact = curContact; -// if (IgnoreNegSides && curContact.side1 < 0) -// minContact.depth = float.MaxValue; + // if (IgnoreNegSides && curContact.side1 < 0) + // minContact.depth = float.MaxValue; IntPtr Joint; bool FeetCollision = false; int ncontacts = 0; - int i = 0; + int i = 0; - while (true) - { - if (m_global_contactcount >= maxContactsbeforedeath) - break; + while (true) + { // if (!(IgnoreNegSides && curContact.side1 < 0)) + { + bool noskip = true; + if (dop1ava) { - bool noskip = true; - if (dop1ava) - { - if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact, ref FeetCollision))) + if (!(((OdeCharacter)p1).Collide(g1, false, ref curContact, ref FeetCollision))) - noskip = false; - } - else if (dop2ava) - { - if (!(((OdeCharacter)p2).Collide(g2,true, ref curContact, ref FeetCollision))) - noskip = false; - } - - if (noskip) - { - m_global_contactcount++; - ncontacts++; - - Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); - d.JointAttach(Joint, b1, b2); - - if (curContact.depth > maxContact.depth) - maxContact = curContact; - - if (curContact.depth < minContact.depth) - minContact = curContact; - } + noskip = false; + } + else if (dop2ava) + { + if (!(((OdeCharacter)p2).Collide(g2, true, ref curContact, ref FeetCollision))) + noskip = false; } - if (++i >= count) - break; + if (noskip) + { + m_global_contactcount++; + if (m_global_contactcount >= maxContactsbeforedeath) + break; - if (!GetCurContactGeom(i, ref curContact)) - break; + ncontacts++; + + Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); + if (Joint == IntPtr.Zero) + break; + + d.JointAttach(Joint, b1, b2); + + if (curContact.depth > maxContact.depth) + maxContact = curContact; + + if (curContact.depth < minContact.depth) + minContact = curContact; + } } + if (++i >= count) + break; + + if (!GetCurContactGeom(i, ref curContact)) + break; + } + if (ncontacts > 0) { ContactPoint maxDepthContact = new ContactPoint( From 564b513963bd35e072b0a1f760cfc5ac8675f776 Mon Sep 17 00:00:00 2001 From: teravus Date: Sat, 26 Jan 2013 07:31:54 -0500 Subject: [PATCH 5/8] * This update is ugly as sin, but it 'fills in the blanks' of your appearance when your inventory items go missing. This repairs appearance from missing wearables immediately on the V1 appearance pipeline, the second login on Firestorm. It only replaces the essential body parts that are missing.. hair, skin, eyes, shape... so if you delete all your wearables, you will rez naked. Anyway, this is still experimental.. I need another day of playing with this to handle all of the situations. One thing that I still need to do is try and get the assets.. and if we can't get the assets for some reason, skip and replace that part of the outfit. --- .../AvatarFactory/AvatarFactoryModule.cs | 265 +++++++++++++++++- 1 file changed, 260 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 7ec28605c1..fd442dcd14 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -674,20 +674,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) { IInventoryService invService = m_scene.InventoryService; - + bool resetwearable = false; if (invService.GetRootFolder(userID) != null) { for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) { for (int j = 0; j < appearance.Wearables[i].Count; j++) { + // Check if the default wearables are not set if (appearance.Wearables[i][j].ItemID == UUID.Zero) - continue; + { + switch ((WearableType) i) + { + case WearableType.Eyes: + case WearableType.Hair: + case WearableType.Shape: + case WearableType.Skin: + //case WearableType.Underpants: + TryAndRepair((WearableType)i, invService, userID, appearance); + resetwearable = true; + m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values."); + resetwearable = true; + break; - // Ignore ruth's assets + } + continue; + } + + // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) - continue; + { + switch ((WearableType)i) + { + case WearableType.Eyes: + case WearableType.Hair: + case WearableType.Shape: + case WearableType.Skin: + //case WearableType.Underpants: + TryAndRepair((WearableType)i, invService, userID, appearance); + + m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); + resetwearable = true; + break; + } + continue; + } + InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); baseItem = invService.GetItem(baseItem); @@ -701,17 +734,239 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", appearance.Wearables[i][j].ItemID, (WearableType)i); - appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); + TryAndRepair((WearableType)i, invService, userID, appearance); + resetwearable = true; + } } } + + // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... + if (appearance.Wearables[(int) WearableType.Eyes] == null) + { + m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); + + TryAndRepair(WearableType.Eyes, invService, userID, appearance); + resetwearable = true; + } + else + { + if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero) + { + m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}", + appearance.Wearables[(int) WearableType.Eyes][0].ItemID, + appearance.Wearables[(int) WearableType.Eyes][0].AssetID); + TryAndRepair(WearableType.Eyes, invService, userID, appearance); + resetwearable = true; + + } + + } + // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... + if (appearance.Wearables[(int)WearableType.Shape] == null) + { + m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape)); + + TryAndRepair(WearableType.Shape, invService, userID, appearance); + resetwearable = true; + } + else + { + if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero) + { + m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}", + appearance.Wearables[(int)WearableType.Shape][0].ItemID, + appearance.Wearables[(int)WearableType.Shape][0].AssetID); + TryAndRepair(WearableType.Shape, invService, userID, appearance); + resetwearable = true; + + } + + } + // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... + if (appearance.Wearables[(int)WearableType.Hair] == null) + { + m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair)); + + TryAndRepair(WearableType.Hair, invService, userID, appearance); + resetwearable = true; + } + else + { + if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero) + { + m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}", + appearance.Wearables[(int)WearableType.Hair][0].ItemID, + appearance.Wearables[(int)WearableType.Hair][0].AssetID); + TryAndRepair(WearableType.Hair, invService, userID, appearance); + resetwearable = true; + + } + + } + // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... + if (appearance.Wearables[(int)WearableType.Skin] == null) + { + m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin)); + + TryAndRepair(WearableType.Skin, invService, userID, appearance); + resetwearable = true; + } + else + { + if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero) + { + m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}", + appearance.Wearables[(int)WearableType.Skin][0].ItemID, + appearance.Wearables[(int)WearableType.Skin][0].AssetID); + TryAndRepair(WearableType.Skin, invService, userID, appearance); + resetwearable = true; + + } + + } + if (resetwearable) + { + ScenePresence presence = null; + if (m_scene.TryGetScenePresence(userID, out presence)) + { + presence.ControllingClient.SendWearables(presence.Appearance.Wearables, + presence.Appearance.Serial++); + } + } + } else { m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); } } + private void TryAndRepair(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) + { + UUID defaultwearable = GetDefaultItem(type); + if (defaultwearable != UUID.Zero) + { + UUID newInvItem = UUID.Random(); + InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID) + { + AssetID = + defaultwearable, + AssetType + = + (int) + AssetType + .Bodypart, + CreatorId + = + userID + .ToString + (), + //InvType = (int)InventoryType.Wearable, + Description + = + "Failed Wearable Replacement", + Folder = + invService + .GetFolderForType + (userID, + AssetType + .Bodypart) + .ID, + Flags = (uint) type, + Name = Enum.GetName(typeof (WearableType), type), + BasePermissions = (uint) PermissionMask.Copy, + CurrentPermissions = (uint) PermissionMask.Copy, + EveryOnePermissions = (uint) PermissionMask.Copy, + GroupPermissions = (uint) PermissionMask.Copy, + NextPermissions = (uint) PermissionMask.Copy + }; + invService.AddItem(itembase); + UUID LinkInvItem = UUID.Random(); + itembase = new InventoryItemBase(LinkInvItem, userID) + { + AssetID = + newInvItem, + AssetType + = + (int) + AssetType + .Link, + CreatorId + = + userID + .ToString + (), + InvType = (int) InventoryType.Wearable, + + Description + = + "Failed Wearable Replacement", + Folder = + invService + .GetFolderForType + (userID, + AssetType + .CurrentOutfitFolder) + .ID, + Flags = (uint) type, + Name = Enum.GetName(typeof (WearableType), type), + BasePermissions = (uint) PermissionMask.Copy, + CurrentPermissions = (uint) PermissionMask.Copy, + EveryOnePermissions = (uint) PermissionMask.Copy, + GroupPermissions = (uint) PermissionMask.Copy, + NextPermissions = (uint) PermissionMask.Copy + }; + invService.AddItem(itembase); + appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type)); + ScenePresence presence = null; + if (m_scene.TryGetScenePresence(userID, out presence)) + { + m_scene.SendInventoryUpdate(presence.ControllingClient, + invService.GetFolderForType(userID, + AssetType + .CurrentOutfitFolder), + false, true); + } + } + } + private UUID GetDefaultItem(WearableType wearable) + { + // These are Urban male.. but it doesn't matter as long as the assets exist. + UUID ret = UUID.Zero; + switch (wearable) + { + case WearableType.Eyes: + ret = new UUID("46d7f979-c060-0ad6-5d3c-8de38c941c8d"); + break; + case WearableType.Hair: + ret = new UUID("21ae002d-57af-441a-81ff-86f5f674b9b9"); + break; + case WearableType.Pants: + ret = new UUID("e3440698-48fd-41ac-af9b-f680547cbef2"); + break; + case WearableType.Shape: + ret = new UUID("7c1f1354-2aba-4e55-8357-1545c2c003ce"); + break; + case WearableType.Shirt: + ret = new UUID("f8fefa00-b019-4072-9c04-ff79c65348b9"); + break; + case WearableType.Shoes: + ret = new UUID("6455d2cf-0ee1-4c9a-9812-da03371bf719"); + break; + case WearableType.Skin: + ret = new UUID("29c99e80-cf59-4fa0-9f8e-e4a1ccaf2fa3"); + break; + case WearableType.Socks: + ret = new UUID("96472ac3-1e18-49e5-b2e4-17c03791ea96"); + break; + case WearableType.Underpants: + ret = new UUID("d6c7b174-8a2d-473f-a80f-3b7d7b7b3a96"); + break; + } + + return ret; + } #endregion #region Client Event Handlers From 1b5d5d70401ef69bf3e9da0bb1e668d4ccd520ce Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 26 Jan 2013 18:03:18 +0100 Subject: [PATCH 6/8] Stop temp-on-rez object from being deleted while an avatar sits on them --- 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 ed1bbd8827..41f04e29c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2023,7 +2023,7 @@ namespace OpenSim.Region.Framework.Scenes (parcel.LandData.GroupID != GroupID || parcel.LandData.GroupID == UUID.Zero)) { - if ((DateTime.UtcNow - RootPart.Rezzed).TotalMinutes > + if (GetSittingAvatarsCount() == 0 && (DateTime.UtcNow - RootPart.Rezzed).TotalMinutes > parcel.LandData.OtherCleanTime) { DetachFromBackup(); From f1fbb774b6f08acde0c88618911dd4dc311217ad Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 26 Jan 2013 20:39:17 +0100 Subject: [PATCH 7/8] Reinstate cleaning objects from parcel when avatars sit on them. Instead do it properly for temp-on-rez. Auto-return overrides sitting. Temp does not. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e3bc8c7b36..c7a38f7f8a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5122,7 +5122,7 @@ namespace OpenSim.Region.Framework.Scenes { if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) { - if (grp.RootPart.Expires <= DateTime.Now) + if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now) DeleteSceneObject(grp, false); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 41f04e29c4..ed1bbd8827 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2023,7 +2023,7 @@ namespace OpenSim.Region.Framework.Scenes (parcel.LandData.GroupID != GroupID || parcel.LandData.GroupID == UUID.Zero)) { - if (GetSittingAvatarsCount() == 0 && (DateTime.UtcNow - RootPart.Rezzed).TotalMinutes > + if ((DateTime.UtcNow - RootPart.Rezzed).TotalMinutes > parcel.LandData.OtherCleanTime) { DetachFromBackup(); From 380b017e3295eaf30a4a96c23faed5be78495256 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Jan 2013 00:20:34 +0100 Subject: [PATCH 8/8] Prevent items being destroyed by rename operations. Renaming of a wearable also sends an asset transaciton but it is empty. So we can't ignore name data when a transaction is present and can't treat every transaction as valid. --- .../Agent/AssetTransaction/AssetXferUploader.cs | 3 ++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index 0aa46931fb..43b8b4462f 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -339,7 +339,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction // to avoid a race condition when the appearance module retrieves the item to set the asset id in // the AvatarAppearance structure. item.AssetID = m_asset.FullID; - m_Scene.InventoryService.UpdateItem(item); + if (item.AssetID != UUID.Zero) + m_Scene.InventoryService.UpdateItem(item); if (m_uploadState == UploadState.Complete) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index c9d1205484..4130029b33 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -401,17 +401,17 @@ namespace OpenSim.Region.Framework.Scenes if (item.Owner != remoteClient.AgentId) return; - if (UUID.Zero == transactionID) - { - item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255); - item.Name = itemUpd.Name; - item.Description = itemUpd.Description; + item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255); + item.Name = itemUpd.Name; + item.Description = itemUpd.Description; // m_log.DebugFormat( // "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}", // itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags, // item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions); + if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid + { if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; @@ -446,7 +446,8 @@ namespace OpenSim.Region.Framework.Scenes InventoryService.UpdateItem(item); } - else + + if (UUID.Zero != transactionID) { if (AgentTransactionsModule != null) {