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