diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 59 |
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 | } |