aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs59
1 files changed, 31 insertions, 28 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6f26176..b70e9df 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -150,12 +150,27 @@ namespace OpenSim.Region.Framework.Scenes
150 150
151 get { return m_hasGroupChanged; } 151 get { return m_hasGroupChanged; }
152 } 152 }
153
154 private bool m_groupContainsForeignPrims = false;
153 155
154 /// <summary> 156 /// <summary>
155 /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since 157 /// Whether the group contains prims that came from a different group. This happens when
156 /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation. 158 /// linking or delinking groups. The implication is that until the group is persisted,
159 /// the prims in the database still use the old SceneGroupID. That's a problem if the group
160 /// is deleted, because we delete groups by searching for prims by their SceneGroupID.
157 /// </summary> 161 /// </summary>
158 public bool HasGroupChangedDueToDelink { get; private set; } 162 public bool GroupContainsForeignPrims
163 {
164 private set
165 {
166 m_groupContainsForeignPrims = value;
167 if (m_groupContainsForeignPrims)
168 HasGroupChanged = true;
169 }
170
171 get { return m_groupContainsForeignPrims; }
172 }
173
159 174
160 private bool isTimeToPersist() 175 private bool isTimeToPersist()
161 { 176 {
@@ -1624,7 +1639,7 @@ namespace OpenSim.Region.Framework.Scenes
1624 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; 1639 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
1625 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; 1640 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
1626 HasGroupChanged = false; 1641 HasGroupChanged = false;
1627 HasGroupChangedDueToDelink = false; 1642 GroupContainsForeignPrims = false;
1628 1643
1629 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); 1644 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
1630 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); 1645 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
@@ -1686,28 +1701,7 @@ namespace OpenSim.Region.Framework.Scenes
1686 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); 1701 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
1687 dupe.Backup = false; 1702 dupe.Backup = false;
1688 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); 1703 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
1689
1690 // Warning, The following code related to previousAttachmentStatus is needed so that clones of
1691 // attachments do not bordercross while they're being duplicated. This is hacktastic!
1692 // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region!
1693 // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state
1694 // (which should be false anyway) set it as an Attachment and then set it's Absolute Position,
1695 // then restore it's attachment state
1696
1697 // This is only necessary when userExposed is false!
1698
1699 bool previousAttachmentStatus = dupe.IsAttachment;
1700
1701 if (!userExposed)
1702 dupe.IsAttachment = true;
1703
1704 dupe.m_sittingAvatars = new List<UUID>(); 1704 dupe.m_sittingAvatars = new List<UUID>();
1705
1706 if (!userExposed)
1707 {
1708 dupe.IsAttachment = previousAttachmentStatus;
1709 }
1710
1711 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 1705 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
1712 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; 1706 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
1713 1707
@@ -2388,6 +2382,8 @@ namespace OpenSim.Region.Framework.Scenes
2388 // If linking prims with different permissions, fix them 2382 // If linking prims with different permissions, fix them
2389 AdjustChildPrimPermissions(); 2383 AdjustChildPrimPermissions();
2390 2384
2385 GroupContainsForeignPrims = true;
2386
2391 AttachToBackup(); 2387 AttachToBackup();
2392 2388
2393 // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the 2389 // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
@@ -2531,9 +2527,16 @@ namespace OpenSim.Region.Framework.Scenes
2531 2527
2532 linkPart.Rezzed = RootPart.Rezzed; 2528 linkPart.Rezzed = RootPart.Rezzed;
2533 2529
2534 // When we delete a group, we currently have to force persist to the database if the object id has changed 2530 // We must persist the delinked group to the database immediately, for safety. The problem
2535 // (since delete works by deleting all rows which have a given object id) 2531 // is that although in memory the new group has a new SceneGroupID, in the database it
2536 objectGroup.HasGroupChangedDueToDelink = true; 2532 // still has the parent group's SceneGroupID (until the next backup). This means that if the
2533 // parent group is deleted then the delinked group will also be deleted from the database.
2534 // This problem will disappear if the region remains alive long enough for another backup,
2535 // since at that time the delinked group's new SceneGroupID will be written to the database.
2536 // But if the region crashes before that then the prims will be permanently gone, and this must
2537 // not happen. (We can't use a just-in-time trick like GroupContainsForeignPrims in this case
2538 // because the delinked group doesn't know when the source group is deleted.)
2539 m_scene.ForceSceneObjectBackup(objectGroup);
2537 2540
2538 return objectGroup; 2541 return objectGroup;
2539 } 2542 }