diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 58de44ea75..01df5750da 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2310,7 +2310,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(); @@ -2323,7 +2340,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; @@ -2339,7 +2356,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 17563bd537..6dd42ddd28 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1751,6 +1751,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 @@ -1777,8 +1781,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); + 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 46c4d7b2ea..683aafcf56 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2361,6 +2361,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 a2332bb4ec..be5b4a8986 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() { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 3ea7352159..a0ae55aa3f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -299,13 +299,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC NPCAvatar av; if (m_avatars.TryGetValue(agentID, out av)) { +// m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", agentID, av.Name); scene.RemoveClient(agentID, false); m_avatars.Remove(agentID); +// m_log.DebugFormat("[NPC MODULE]: Removed {0} {1}", agentID, av.Name); return true; } } +// m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", agentID); return false; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 34f2cc7aaa..da2ef7b2b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -538,6 +538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public bool Stop(int timeout) { +// m_log.DebugFormat( +// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); + IScriptWorkItem result; lock (m_EventQueue) @@ -772,7 +775,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } catch (Exception e) { - // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); +// m_log.DebugFormat( +// "[SCRIPT] Exception in script {0} {1}: {2}{3}", +// ScriptName, ItemID, e.Message, e.StackTrace); + m_InEvent = false; m_CurrentEvent = String.Empty; diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 24a94180db..f627e37d8f 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -301,7 +301,7 @@ namespace OpenSim.Region.UserStatistics public void OnRegisterCaps(UUID agentID, Caps caps) { - m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); string capsPath = "/CAPS/VS/" + UUID.Random(); caps.RegisterHandler("ViewerStats", new RestStreamHandler("POST", capsPath, @@ -462,7 +462,7 @@ namespace OpenSim.Region.UserStatistics if (!m_sessions.ContainsKey(agentID)) { - m_log.Warn("[VS]: no session for stat disclosure"); + m_log.Warn("[WEB STATS MODULE]: no session for stat disclosure"); return new UserSessionID(); } uid = m_sessions[agentID]; @@ -667,14 +667,13 @@ namespace OpenSim.Region.UserStatistics { updatecmd.ExecuteNonQuery(); } - catch - (SqliteExecutionException) + catch (SqliteExecutionException) { - m_log.Warn("[WEBSTATS]: failed to write stats to storage Execution Exception"); + m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage Execution Exception"); } catch (SqliteSyntaxException) { - m_log.Warn("[WEBSTATS]: failed to write stats to storage SQL Syntax Exception"); + m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage SQL Syntax Exception"); } } diff --git a/prebuild.xml b/prebuild.xml index 7f069bd11a..0454e246e6 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3320,6 +3320,7 @@ +