From 06617ffd06c743cebffa768bc56a979f473b5b5b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 00:18:30 +0100 Subject: Add regression test for updating attachment position --- .../Attachments/Tests/AttachmentsModuleTests.cs | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 5e89eec..94c0030 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -303,6 +303,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); } + [Test] + public void TestUpdateAttachmentPosition() + { + TestHelpers.InMethod(); + + UUID userId = TestHelpers.ParseTail(0x1); + UUID attItemId = TestHelpers.ParseTail(0x2); + UUID attAssetId = TestHelpers.ParseTail(0x3); + string attName = "att"; + + UserAccountHelpers.CreateUserWithInventory(scene, userId); + InventoryItemBase attItem + = UserInventoryHelpers.CreateInventoryItem( + scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + acd.Appearance = new AvatarAppearance(); + acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); + + SceneObjectGroup attSo = sp.GetAttachments()[0]; + + Vector3 newPosition = new Vector3(1, 2, 4); + + scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); + + Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); + Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); + } + // I'm commenting this test because scene setup NEEDS InventoryService to // be non-null //[Test] -- cgit v1.1 From 798846c5b6c05f37c661dde70fb9aaf51306e407 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 00:39:41 +0100 Subject: refactor AttachmentsModule tests to use a common method for standard attachment item setup --- .../Attachments/Tests/AttachmentsModuleTests.cs | 139 ++++++++++----------- 1 file changed, 69 insertions(+), 70 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 94c0030..8f4a807 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -58,6 +58,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests private AttachmentsModule m_attMod; private ScenePresence m_presence; + /// + /// Standard user ID + /// + private UUID m_userId = TestHelpers.ParseTail(0x1); + +// /// +// /// Standard attachment item ID +// /// +// private UUID m_attItemId = TestHelpers.ParseTail(0x10); +// +// /// +// /// Standard attachment asset ID +// /// +// private UUID m_attAssetId = TestHelpers.ParseTail(0x11); + [TestFixtureSetUp] public void FixtureInit() { @@ -86,13 +101,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } /// - /// Add the standard presence for a test. + /// Creates an attachment item in the given user's inventory. Does not attach. /// - private void AddPresence() + /// + /// A user with the given ID and an inventory must already exist. + /// + /// + /// The attachment item. + /// + /// + /// + /// + /// + private InventoryItemBase CreateAttachmentItem(UUID userId, string attName, int rawItemId, int rawAssetId) { - UUID userId = TestHelpers.ParseTail(0x1); - UserAccountHelpers.CreateUserWithInventory(scene, userId); - m_presence = SceneHelpers.AddScenePresence(scene, userId); + return UserInventoryHelpers.CreateInventoryItem( + scene, + attName, + TestHelpers.ParseTail(rawItemId), + TestHelpers.ParseTail(rawAssetId), + userId, + InventoryType.Object); } [Test] @@ -101,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - AddPresence(); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); + string attName = "att"; SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup; @@ -140,24 +171,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); List attachments = m_presence.GetAttachments(); Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; - Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -165,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check appearance status Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); - Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -174,17 +201,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); + ISceneEntity so + = m_attMod.RezSingleAttachmentFromInventory( + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); // Check scene presence status @@ -196,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); // Check item status - Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); + Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); // Check object in scene Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); @@ -208,18 +232,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - AddPresence(); - - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + m_presence = SceneHelpers.AddScenePresence(scene, m_userId); - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); m_attMod.RezSingleAttachmentFromInventory( - m_presence, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId); + m_presence, attItem.ID, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToInv(m_presence, attItem.ID); // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.False); @@ -227,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(0)); // Check item status - Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); + Assert.That(m_presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); } /// @@ -239,17 +259,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -268,17 +281,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); @@ -288,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attachments.Count, Is.EqualTo(1)); SceneObjectGroup attSo = attachments[0]; - Assert.That(attSo.Name, Is.EqualTo(attName)); + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); Assert.That(attSo.IsAttachment); Assert.That(attSo.UsesPhysics, Is.False); @@ -298,9 +304,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests List retreivedAttachments = presence.Appearance.GetAttachments(); Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); - Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId)); - Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId)); - Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID)); + Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); + Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] @@ -308,17 +314,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests { TestHelpers.InMethod(); - UUID userId = TestHelpers.ParseTail(0x1); - UUID attItemId = TestHelpers.ParseTail(0x2); - UUID attAssetId = TestHelpers.ParseTail(0x3); - string attName = "att"; - - UserAccountHelpers.CreateUserWithInventory(scene, userId); - InventoryItemBase attItem - = UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, userId, InventoryType.Object); + UserAccountHelpers.CreateUserWithInventory(scene, m_userId); + InventoryItemBase attItem = CreateAttachmentItem(m_userId, "att", 0x10, 0x20); - AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(m_userId); acd.Appearance = new AvatarAppearance(); acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); -- cgit v1.1 From 4cf49369b51c21a0eadd719eb46f53d207e1e5f7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Jun 2012 01:39:39 +0100 Subject: Stop flicking IsAttachment false and then true in AttachmentsModule.UpdateAttachmentPosition() in order to avoid a hud update race condition. Previously, setting IsAttachment to false then true was necessary to serialize the updated attachment object information. However, UpdateAttachmentPosition no longer does this update. Whilst IsAttachment is set to false there is a race condition where the update thread can wrongly send hud object updates to clients that do not own the hud, resulting in screen artifacts. --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b74c0ba..a2b95eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -408,17 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; - // First we save the - // attachment point information, then we update the relative - // positioning. Then we have to mark the object as NOT an - // attachment. This is necessary in order to correctly save - // and retrieve GroupPosition information for the attachment. - // Finally, we restore the object's attachment status. - uint attachmentPoint = sog.AttachmentPoint; sog.UpdateGroupPosition(pos); - sog.IsAttachment = false; - sog.AbsolutePosition = sog.RootPart.AttachedPos; - sog.AttachmentPoint = attachmentPoint; sog.HasGroupChanged = true; } -- cgit v1.1 From 5301648cff6b451fef4cca0baf8cda1bdb1455a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 21:08:19 +0100 Subject: In AttachmentsModule.DetachSingleAttachmentToInvInternal(), remove attachment before changing properties for correct inventory serialization. Serialization of attachments requires IsAttachment = false so that correct positions are serialized instead of avatar position. However, doing this when a hud is still attached allows race conditions with update threads, resulting in hud artifacts on other viewers. This change sets SOG.IsDeleted before serialization changes take place (IsDeleted itself is not a serialized property). LLClientView then screens out any deleted SOGs before sending updates to viewers. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a2b95eb..99e0153 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -628,6 +628,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); sp.RemoveAttachment(group); + m_scene.DeleteSceneObject(group, false); // Prepare sog for storage group.AttachedAvatar = UUID.Zero; @@ -636,7 +637,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.AbsolutePosition = group.RootPart.AttachedPos; UpdateKnownItem(sp, group, true); - m_scene.DeleteSceneObject(group, false); return; } -- cgit v1.1 From e5b739aaebace6b028f3f6bf05d21ff7a7c5affe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Jun 2012 22:48:13 +0100 Subject: When attachments are being saved and deleted for a closing root agent, delete first to avoid a hud race condition with update threads. If delete doesn't occur first then the update thread can outrace the IsAttachment = false necessary to save attachments and send hud artifacts to other viewers. --- .../Avatar/Attachments/AttachmentsModule.cs | 33 ++++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 99e0153..2b0e4ab 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -152,31 +152,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted) + public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) { -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); - if (!Enabled) return; - foreach (SceneObjectGroup grp in sp.GetAttachments()) +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); + + lock (sp.AttachmentsSyncLock) { - grp.IsAttachment = false; - grp.AbsolutePosition = grp.RootPart.AttachedPos; - UpdateKnownItem(sp, grp, saveAllScripted); - grp.IsAttachment = true; + foreach (SceneObjectGroup grp in sp.GetAttachments()) + { + grp.Scene.DeleteSceneObject(grp, false); + + if (saveChanged || saveAllScripted) + { + grp.IsAttachment = false; + grp.AbsolutePosition = grp.RootPart.AttachedPos; + UpdateKnownItem(sp, grp, saveAllScripted); + } + } + + sp.ClearAttachments(); } } public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", -// m_scene.RegionInfo.RegionName, sp.Name, silent); - if (!Enabled) return; +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", +// m_scene.RegionInfo.RegionName, sp.Name, silent); + foreach (SceneObjectGroup sop in sp.GetAttachments()) { sop.Scene.DeleteSceneObject(sop, silent); -- cgit v1.1