From 083587eb3222905869e02a392da588d982837ec3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 8 Feb 2012 21:58:59 +0000 Subject: [PATCH] Stop a scene object from attempting to link with itself (which results in an exception and constant complaints in v3 viewers). Aims to address http://opensimulator.org/mantis/view.php?id=5878 --- .../Framework/Scenes/Scene.Inventory.cs | 21 +++++++++++++++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 16 +++++++++---- .../Framework/Scenes/SceneObjectGroup.cs | 4 ++++ .../Scenes/Tests/SceneObjectLinkingTests.cs | 23 ++++++++++++++++--- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4019a80a36..646ee78585 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2110,7 +2110,24 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.DelinkObjects(parts); } + /// + /// Link the scene objects containing the indicated parts to a root object. + /// + /// + /// A root prim id of the object which will be the root prim of the resulting linkset. + /// A list of child prims for the objects that should be linked in. public void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) + { + LinkObjects(client.AgentId, parentPrimId, childPrimIds); + } + + /// + /// Link the scene objects containing the indicated parts to a root object. + /// + /// The ID of the user linking. + /// A root prim id of the object which will be the root prim of the resulting linkset. + /// A list of child prims for the objects that should be linked in. + public void LinkObjects(UUID agentId, uint parentPrimId, List childPrimIds) { List owners = new List(); @@ -2123,7 +2140,7 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + if (!Permissions.CanLinkObject(agentId, root.ParentGroup.RootPart.UUID)) { m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); return; @@ -2139,7 +2156,7 @@ namespace OpenSim.Region.Framework.Scenes if (!owners.Contains(part.OwnerID)) owners.Add(part.OwnerID); - if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID)) + if (Permissions.CanLinkObject(agentId, part.ParentGroup.RootPart.UUID)) children.Add(part); } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 0c22937f16..e05cf70b20 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1660,6 +1660,10 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup child = children[i].ParentGroup; + // Don't try and add a group to itself - this will only cause severe problems later on. + if (child == parentGroup) + continue; + // Make sure no child prim is set for sale // So that, on delink, no prims are unwittingly // left for sale and sold off @@ -1679,11 +1683,13 @@ namespace OpenSim.Region.Framework.Scenes // We need to explicitly resend the newly link prim's object properties since no other actions // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.CreateSelected = true; - parentGroup.TriggerScriptChangedEvent(Changed.LINK); - parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); - + if (childGroups.Count > 0) + { + parentGroup.RootPart.CreateSelected = true; + parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); + } } finally { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 41daaad13d..f3b7d4220f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2004,6 +2004,10 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); + // Linking to ourselves is not a valid operation. + if (objectGroup == this) + return; + SceneObjectPart linkPart = objectGroup.m_rootPart; Vector3 oldGroupPosition = linkPart.GroupPosition; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 2912a46d7d..8be025e3a1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -39,14 +39,31 @@ using log4net; namespace OpenSim.Region.Framework.Scenes.Tests { - /// - /// Linking tests - /// [TestFixture] public class SceneObjectLinkingTests { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Links to self should be ignored. + /// + [Test] + public void TestLinkToSelf() + { + TestHelpers.InMethod(); + + UUID ownerId = TestHelpers.ParseTail(0x1); + int nParts = 3; + + TestScene scene = SceneHelpers.SetupScene(); + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10); + scene.AddSceneObject(sog1); + scene.LinkObjects(ownerId, sog1.LocalId, new List() { sog1.Parts[1].LocalId }); +// sog1.LinkToGroup(sog1); + + Assert.That(sog1.Parts.Length, Is.EqualTo(nParts)); + } + [Test] public void TestLinkDelink2SceneObjects() {