From 62b3bdf0fc7a64dd9b845eb27fa8e1a2a1866c2b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Oct 2013 11:18:15 +0300 Subject: When linking two groups, and then deleting the combined group: delete *all* of the combined group's prims, including those that came from the second subgroup This fixes http://opensimulator.org/mantis/view.php?id=6175 --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 38 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6f26176..a78a0cb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -150,12 +150,27 @@ namespace OpenSim.Region.Framework.Scenes get { return m_hasGroupChanged; } } + + private bool m_groupContainsForeignPrims = false; /// - /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since - /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation. + /// Whether the group contains prims that came from a different group. This happens when + /// linking or delinking groups. The implication is that until the group is persisted, + /// the prims in the database still use the old SceneGroupID. That's a problem if the group + /// is deleted, because we delete groups by searching for prims by their SceneGroupID. /// - public bool HasGroupChangedDueToDelink { get; private set; } + public bool GroupContainsForeignPrims + { + private set + { + m_groupContainsForeignPrims = value; + if (m_groupContainsForeignPrims) + HasGroupChanged = true; + } + + get { return m_groupContainsForeignPrims; } + } + private bool isTimeToPersist() { @@ -1624,7 +1639,7 @@ namespace OpenSim.Region.Framework.Scenes backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; HasGroupChanged = false; - HasGroupChangedDueToDelink = false; + GroupContainsForeignPrims = false; m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); @@ -2388,6 +2403,8 @@ namespace OpenSim.Region.Framework.Scenes // If linking prims with different permissions, fix them AdjustChildPrimPermissions(); + GroupContainsForeignPrims = true; + AttachToBackup(); // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the @@ -2531,9 +2548,16 @@ namespace OpenSim.Region.Framework.Scenes linkPart.Rezzed = RootPart.Rezzed; - // When we delete a group, we currently have to force persist to the database if the object id has changed - // (since delete works by deleting all rows which have a given object id) - objectGroup.HasGroupChangedDueToDelink = true; + // We must persist the delinked group to the database immediately, for safety. The problem + // is that although in memory the new group has a new SceneGroupID, in the database it + // still has the parent group's SceneGroupID (until the next backup). This means that if the + // parent group is deleted then the delinked group will also be deleted from the database. + // This problem will disappear if the region remains alive long enough for another backup, + // since at that time the delinked group's new SceneGroupID will be written to the database. + // But if the region crashes before that then the prims will be permanently gone, and this must + // not happen. (We can't use a just-in-time trick like GroupContainsForeignPrims in this case + // because the delinked group doesn't know when the source group is deleted.) + m_scene.ForceSceneObjectBackup(objectGroup); return objectGroup; } -- cgit v1.1 From 773ffcafc3dbbda29534b26d0a4813e1cf422a79 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Oct 2013 12:21:20 +0300 Subject: Removed "hacktastic" code that is no longer needed. We no longer set the object's AbsolutePosition in this place, so the IsAttachment hack doesn't do anything anymore. This resolves http://opensimulator.org/mantis/view.php?id=6936 --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a78a0cb..b70e9df 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1701,28 +1701,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); dupe.Backup = false; dupe.m_parts = new MapAndArray(); - - // Warning, The following code related to previousAttachmentStatus is needed so that clones of - // attachments do not bordercross while they're being duplicated. This is hacktastic! - // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! - // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state - // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, - // then restore it's attachment state - - // This is only necessary when userExposed is false! - - bool previousAttachmentStatus = dupe.IsAttachment; - - if (!userExposed) - dupe.IsAttachment = true; - dupe.m_sittingAvatars = new List(); - - if (!userExposed) - { - dupe.IsAttachment = previousAttachmentStatus; - } - dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; -- cgit v1.1