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
iar_mods
Justin Clark-Casey (justincc) 2012-02-08 21:58:59 +00:00
parent bef2a368f4
commit dfa19e23f0
4 changed files with 54 additions and 10 deletions

View File

@ -2170,7 +2170,24 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.DelinkObjects(parts); m_sceneGraph.DelinkObjects(parts);
} }
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="client"></param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds) public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
{
LinkObjects(client.AgentId, parentPrimId, childPrimIds);
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="agentId">The ID of the user linking.</param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(UUID agentId, uint parentPrimId, List<uint> childPrimIds)
{ {
List<UUID> owners = new List<UUID>(); List<UUID> owners = new List<UUID>();
@ -2183,7 +2200,7 @@ namespace OpenSim.Region.Framework.Scenes
return; 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"); m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
return; return;
@ -2199,7 +2216,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!owners.Contains(part.OwnerID)) if (!owners.Contains(part.OwnerID))
owners.Add(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); children.Add(part);
} }

View File

@ -1662,6 +1662,10 @@ namespace OpenSim.Region.Framework.Scenes
{ {
SceneObjectGroup child = children[i].ParentGroup; 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 // Make sure no child prim is set for sale
// So that, on delink, no prims are unwittingly // So that, on delink, no prims are unwittingly
// left for sale and sold off // left for sale and sold off
@ -1684,11 +1688,13 @@ namespace OpenSim.Region.Framework.Scenes
// We need to explicitly resend the newly link prim's object properties since no other actions // 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) // occur on link to invoke this elsewhere (such as object selection)
parentGroup.RootPart.CreateSelected = true; if (childGroups.Count > 0)
parentGroup.TriggerScriptChangedEvent(Changed.LINK); {
parentGroup.HasGroupChanged = true; parentGroup.RootPart.CreateSelected = true;
parentGroup.ScheduleGroupForFullUpdate(); parentGroup.TriggerScriptChangedEvent(Changed.LINK);
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
}
} }
finally finally
{ {

View File

@ -1961,6 +1961,10 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", // "[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); // 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; SceneObjectPart linkPart = objectGroup.m_rootPart;
Vector3 oldGroupPosition = linkPart.GroupPosition; Vector3 oldGroupPosition = linkPart.GroupPosition;

View File

@ -39,14 +39,31 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes.Tests namespace OpenSim.Region.Framework.Scenes.Tests
{ {
/// <summary>
/// Linking tests
/// </summary>
[TestFixture] [TestFixture]
public class SceneObjectLinkingTests public class SceneObjectLinkingTests
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Links to self should be ignored.
/// </summary>
[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<uint>() { sog1.Parts[1].LocalId });
// sog1.LinkToGroup(sog1);
Assert.That(sog1.Parts.Length, Is.EqualTo(nParts));
}
[Test] [Test]
public void TestLinkDelink2SceneObjects() public void TestLinkDelink2SceneObjects()
{ {