aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs78
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs38
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs35
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs119
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs144
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs69
6 files changed, 288 insertions, 195 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 01be491..379128a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1969,60 +1969,13 @@ namespace OpenSim.Region.Framework.Scenes
1969 if (null == item) 1969 if (null == item)
1970 return null; 1970 return null;
1971 1971
1972 UUID ownerID = item.OwnerID; 1972 SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item);
1973 AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); 1973
1974 1974 if (null == group)
1975 if (null == rezAsset)
1976 return null;
1977
1978 string xmlData = Utils.BytesToString(rezAsset.Data);
1979 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
1980
1981 if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos))
1982 return null; 1975 return null;
1983
1984 group.ResetIDs();
1985
1986 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
1987
1988 // Since renaming the item in the inventory does not affect the name stored
1989 // in the serialization, transfer the correct name from the inventory to the
1990 // object itself before we rez.
1991 rootPart.Name = item.Name;
1992 rootPart.Description = item.Description;
1993
1994 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
1995
1996 group.SetGroup(sourcePart.GroupID, null);
1997
1998 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
1999 {
2000 if (Permissions.PropagatePermissions())
2001 {
2002 foreach (SceneObjectPart part in partList)
2003 {
2004 part.EveryoneMask = item.EveryonePermissions;
2005 part.NextOwnerMask = item.NextPermissions;
2006 }
2007
2008 group.ApplyNextOwnerPermissions();
2009 }
2010 }
2011
2012 foreach (SceneObjectPart part in partList)
2013 {
2014 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
2015 {
2016 part.LastOwnerID = part.OwnerID;
2017 part.OwnerID = item.OwnerID;
2018 part.Inventory.ChangeInventoryOwner(item.OwnerID);
2019 }
2020
2021 part.EveryoneMask = item.EveryonePermissions;
2022 part.NextOwnerMask = item.NextPermissions;
2023 }
2024 1976
2025 rootPart.TrimPermissions(); 1977 if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
1978 return null;
2026 1979
2027 if (!Permissions.BypassPermissions()) 1980 if (!Permissions.BypassPermissions())
2028 { 1981 {
@@ -2038,7 +1991,7 @@ namespace OpenSim.Region.Framework.Scenes
2038 1991
2039 group.ScheduleGroupForFullUpdate(); 1992 group.ScheduleGroupForFullUpdate();
2040 1993
2041 return rootPart.ParentGroup; 1994 return group;
2042 } 1995 }
2043 1996
2044 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) 1997 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId)
@@ -2098,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes
2098 sog.SetGroup(groupID, remoteClient); 2051 sog.SetGroup(groupID, remoteClient);
2099 sog.ScheduleGroupForFullUpdate(); 2052 sog.ScheduleGroupForFullUpdate();
2100 2053
2101 foreach (SceneObjectPart child in sog.Children.Values) 2054 lock (sog.Children)
2102 child.Inventory.ChangeInventoryOwner(ownerID); 2055 {
2056 foreach (SceneObjectPart child in sog.Children.Values)
2057 child.Inventory.ChangeInventoryOwner(ownerID);
2058 }
2103 } 2059 }
2104 else 2060 else
2105 { 2061 {
@@ -2109,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 if (sog.GroupID != groupID) 2065 if (sog.GroupID != groupID)
2110 continue; 2066 continue;
2111 2067
2112 foreach (SceneObjectPart child in sog.Children.Values) 2068 lock (sog.Children)
2113 { 2069 {
2114 child.LastOwnerID = child.OwnerID; 2070 foreach (SceneObjectPart child in sog.Children.Values)
2115 child.Inventory.ChangeInventoryOwner(groupID); 2071 {
2072 child.LastOwnerID = child.OwnerID;
2073 child.Inventory.ChangeInventoryOwner(groupID);
2074 }
2116 } 2075 }
2117 2076
2118 sog.SetOwnerId(groupID); 2077 sog.SetOwnerId(groupID);
2119 sog.ApplyNextOwnerPermissions(); 2078 sog.ApplyNextOwnerPermissions();
2120 } 2079 }
2121
2122 } 2080 }
2123 2081
2124 foreach (uint localID in localIDs) 2082 foreach (uint localID in localIDs)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index e25b1f1..9f1575d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes
156 } 156 }
157 break; 157 break;
158 } 158 }
159 else 159 else
160 { 160 {
161 // We also need to check the children of this prim as they 161 // We also need to check the children of this prim as they
162 // can be selected as well and send property information 162 // can be selected as well and send property information
163 bool foundPrim = false; 163 bool foundPrim = false;
164 foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) 164
165 { 165 SceneObjectGroup sog = ent as SceneObjectGroup;
166 if (child.Value.LocalId == primLocalID) 166
167 { 167 lock (sog.Children)
168 child.Value.GetProperties(remoteClient); 168 {
169 foundPrim = true; 169 foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children))
170 break; 170 {
171 } 171 if (child.Value.LocalId == primLocalID)
172 } 172 {
173 if (foundPrim) break; 173 child.Value.GetProperties(remoteClient);
174 foundPrim = true;
175 break;
176 }
177 }
178 }
179
180 if (foundPrim)
181 break;
174 } 182 }
175 } 183 }
176 } 184 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f4cbe1f..1f4d022 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes
1756 1756
1757 if (group.RootPart == null) 1757 if (group.RootPart == null)
1758 { 1758 {
1759 m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", 1759 m_log.ErrorFormat(
1760 group.Children == null ? 0 : group.Children.Count); 1760 "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
1761 group.Children == null ? 0 : group.PrimCount);
1761 } 1762 }
1762 1763
1763 AddRestoredSceneObject(group, true, true); 1764 AddRestoredSceneObject(group, true, true);
@@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes
2064 group.RemoveScriptInstances(true); 2065 group.RemoveScriptInstances(true);
2065 } 2066 }
2066 2067
2067 foreach (SceneObjectPart part in group.Children.Values) 2068 lock (group.Children)
2068 { 2069 {
2069 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) 2070 foreach (SceneObjectPart part in group.Children.Values)
2070 { 2071 {
2071 PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? 2072 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
2072 } 2073 {
2073 else if (part.PhysActor != null) 2074 PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
2074 { 2075 }
2075 PhysicsScene.RemovePrim(part.PhysActor); 2076 else if (part.PhysActor != null)
2076 part.PhysActor = null; 2077 {
2078 PhysicsScene.RemovePrim(part.PhysActor);
2079 part.PhysActor = null;
2080 }
2077 } 2081 }
2078 } 2082 }
2083
2079// if (rootPart.PhysActor != null) 2084// if (rootPart.PhysActor != null)
2080// { 2085// {
2081// PhysicsScene.RemovePrim(rootPart.PhysActor); 2086// PhysicsScene.RemovePrim(rootPart.PhysActor);
@@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes
2426 2431
2427 // Force allocation of new LocalId 2432 // Force allocation of new LocalId
2428 // 2433 //
2429 foreach (SceneObjectPart p in sceneObject.Children.Values) 2434 lock (sceneObject.Children)
2430 p.LocalId = 0; 2435 {
2436 foreach (SceneObjectPart p in sceneObject.Children.Values)
2437 p.LocalId = 0;
2438 }
2431 2439
2432 if (sceneObject.IsAttachmentCheckFull()) // Attachment 2440 if (sceneObject.IsAttachmentCheckFull()) // Attachment
2433 { 2441 {
2434 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); 2442 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
2435 sceneObject.RootPart.AddFlag(PrimFlags.Phantom); 2443 sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
2436
2437 2444
2438 // Don't sent a full update here because this will cause full updates to be sent twice for 2445 // Don't sent a full update here because this will cause full updates to be sent twice for
2439 // attachments on region crossings, resulting in viewer glitches. 2446 // attachments on region crossings, resulting in viewer glitches.
@@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes
2447 2454
2448 if (sp != null) 2455 if (sp != null)
2449 { 2456 {
2450
2451 SceneObjectGroup grp = sceneObject; 2457 SceneObjectGroup grp = sceneObject;
2452 2458
2453 m_log.DebugFormat( 2459 m_log.DebugFormat(
@@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes
2459 2465
2460 if (AttachmentsModule != null) 2466 if (AttachmentsModule != null)
2461 AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); 2467 AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
2462
2463 } 2468 }
2464 else 2469 else
2465 { 2470 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 58a7661..1da4287 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -362,48 +362,52 @@ namespace OpenSim.Region.Framework.Scenes
362// "[SCENE GRAPH]: Adding object {0} {1} to region {2}", 362// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
363// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); 363// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
364 364
365 if (m_parentScene.m_clampPrimSize) 365 lock (sceneObject.Children)
366 { 366 {
367 foreach (SceneObjectPart part in sceneObject.Children.Values) 367 if (m_parentScene.m_clampPrimSize)
368 { 368 {
369 Vector3 scale = part.Shape.Scale; 369 foreach (SceneObjectPart part in sceneObject.Children.Values)
370 370 {
371 if (scale.X > m_parentScene.m_maxNonphys) 371 Vector3 scale = part.Shape.Scale;
372 scale.X = m_parentScene.m_maxNonphys; 372
373 if (scale.Y > m_parentScene.m_maxNonphys) 373 if (scale.X > m_parentScene.m_maxNonphys)
374 scale.Y = m_parentScene.m_maxNonphys; 374 scale.X = m_parentScene.m_maxNonphys;
375 if (scale.Z > m_parentScene.m_maxNonphys) 375 if (scale.Y > m_parentScene.m_maxNonphys)
376 scale.Z = m_parentScene.m_maxNonphys; 376 scale.Y = m_parentScene.m_maxNonphys;
377 377 if (scale.Z > m_parentScene.m_maxNonphys)
378 part.Shape.Scale = scale; 378 scale.Z = m_parentScene.m_maxNonphys;
379
380 part.Shape.Scale = scale;
381 }
379 } 382 }
380 } 383
384 sceneObject.AttachToScene(m_parentScene);
385
386 if (sendClientUpdates)
387 sceneObject.ScheduleGroupForFullUpdate();
388
389 Entities.Add(sceneObject);
390 m_numPrim += sceneObject.Children.Count;
381 391
382 sceneObject.AttachToScene(m_parentScene); 392 if (attachToBackup)
393 sceneObject.AttachToBackup();
383 394
384 if (sendClientUpdates) 395 if (OnObjectCreate != null)
385 sceneObject.ScheduleGroupForFullUpdate(); 396 OnObjectCreate(sceneObject);
386 397
387 Entities.Add(sceneObject); 398 lock (SceneObjectGroupsByFullID)
388 m_numPrim += sceneObject.Children.Count; 399 {
389 400 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
390 if (attachToBackup) 401 foreach (SceneObjectPart part in sceneObject.Children.Values)
391 sceneObject.AttachToBackup(); 402 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
392 403 }
393 if (OnObjectCreate != null) 404
394 OnObjectCreate(sceneObject); 405 lock (SceneObjectGroupsByLocalID)
395 406 {
396 lock (SceneObjectGroupsByFullID) 407 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
397 { 408 foreach (SceneObjectPart part in sceneObject.Children.Values)
398 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 409 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
399 foreach (SceneObjectPart part in sceneObject.Children.Values) 410 }
400 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
401 }
402 lock (SceneObjectGroupsByLocalID)
403 {
404 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
405 foreach (SceneObjectPart part in sceneObject.Children.Values)
406 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
407 } 411 }
408 } 412 }
409 413
@@ -422,10 +426,10 @@ namespace OpenSim.Region.Framework.Scenes
422 426
423 if (!resultOfObjectLinked) 427 if (!resultOfObjectLinked)
424 { 428 {
425 m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; 429 m_numPrim -= grp.PrimCount;
426 430
427 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 431 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
428 RemovePhysicalPrim(grp.Children.Count); 432 RemovePhysicalPrim(grp.PrimCount);
429 } 433 }
430 434
431 if (OnObjectRemove != null) 435 if (OnObjectRemove != null)
@@ -906,8 +910,12 @@ namespace OpenSim.Region.Framework.Scenes
906 { 910 {
907 if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) 911 if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog))
908 { 912 {
909 if (sog.Children.ContainsKey(fullID)) 913 lock (sog.Children)
910 return sog; 914 {
915 if (sog.Children.ContainsKey(fullID))
916 return sog;
917 }
918
911 SceneObjectGroupsByFullID.Remove(fullID); 919 SceneObjectGroupsByFullID.Remove(fullID);
912 } 920 }
913 } 921 }
@@ -1615,7 +1623,7 @@ namespace OpenSim.Region.Framework.Scenes
1615 { 1623 {
1616 if (part != null) 1624 if (part != null)
1617 { 1625 {
1618 if (part.ParentGroup.Children.Count != 1) // Skip single 1626 if (part.ParentGroup.PrimCount != 1) // Skip single
1619 { 1627 {
1620 if (part.LinkNum < 2) // Root 1628 if (part.LinkNum < 2) // Root
1621 rootParts.Add(part); 1629 rootParts.Add(part);
@@ -1643,8 +1651,15 @@ namespace OpenSim.Region.Framework.Scenes
1643 // However, editing linked parts and unlinking may be different 1651 // However, editing linked parts and unlinking may be different
1644 // 1652 //
1645 SceneObjectGroup group = root.ParentGroup; 1653 SceneObjectGroup group = root.ParentGroup;
1646 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); 1654
1647 int numChildren = group.Children.Count; 1655 List<SceneObjectPart> newSet = null;
1656 int numChildren = -1;
1657
1658 lock (group.Children)
1659 {
1660 newSet = new List<SceneObjectPart>(group.Children.Values);
1661 numChildren = group.PrimCount;
1662 }
1648 1663
1649 // If there are prims left in a link set, but the root is 1664 // If there are prims left in a link set, but the root is
1650 // slated for unlink, we need to do this 1665 // slated for unlink, we need to do this
@@ -1723,12 +1738,17 @@ namespace OpenSim.Region.Framework.Scenes
1723 { 1738 {
1724 if (ent is SceneObjectGroup) 1739 if (ent is SceneObjectGroup)
1725 { 1740 {
1726 foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) 1741 SceneObjectGroup sog = ent as SceneObjectGroup;
1742
1743 lock (sog.Children)
1727 { 1744 {
1728 if (subent.Value.LocalId == localID) 1745 foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children)
1729 { 1746 {
1730 objid = subent.Key; 1747 if (subent.Value.LocalId == localID)
1731 obj = subent.Value; 1748 {
1749 objid = subent.Key;
1750 obj = subent.Value;
1751 }
1732 } 1752 }
1733 } 1753 }
1734 } 1754 }
@@ -1793,7 +1813,8 @@ namespace OpenSim.Region.Framework.Scenes
1793 SceneObjectGroup original = GetGroupByPrim(originalPrimID); 1813 SceneObjectGroup original = GetGroupByPrim(originalPrimID);
1794 if (original != null) 1814 if (original != null)
1795 { 1815 {
1796 if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) 1816 if (m_parentScene.Permissions.CanDuplicateObject(
1817 original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
1797 { 1818 {
1798 SceneObjectGroup copy = original.Copy(true); 1819 SceneObjectGroup copy = original.Copy(true);
1799 copy.AbsolutePosition = copy.AbsolutePosition + offset; 1820 copy.AbsolutePosition = copy.AbsolutePosition + offset;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 117f869..fc5eeed 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
213 /// </summary> 213 /// </summary>
214 public int PrimCount 214 public int PrimCount
215 { 215 {
216 get { return m_parts.Count; } 216 get { lock (m_parts) { return m_parts.Count; } }
217 } 217 }
218 218
219 protected Quaternion m_rotation = Quaternion.Identity; 219 protected Quaternion m_rotation = Quaternion.Identity;
@@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes
237 237
238 /// <value> 238 /// <value>
239 /// The parts of this scene object group. You must lock this property before using it. 239 /// The parts of this scene object group. You must lock this property before using it.
240 /// If you want to know the number of children, consider using the PrimCount property instead
240 /// </value> 241 /// </value>
241 public Dictionary<UUID, SceneObjectPart> Children 242 public Dictionary<UUID, SceneObjectPart> Children
242 { 243 {
@@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes
298 { 299 {
299 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 300 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
300 } 301 }
302
301 if (RootPart.GetStatusSandbox()) 303 if (RootPart.GetStatusSandbox())
302 { 304 {
303 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 305 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
308 return; 310 return;
309 } 311 }
310 } 312 }
313
311 lock (m_parts) 314 lock (m_parts)
312 { 315 {
313 foreach (SceneObjectPart part in m_parts.Values) 316 foreach (SceneObjectPart part in m_parts.Values)
@@ -335,7 +338,16 @@ namespace OpenSim.Region.Framework.Scenes
335 public override UUID UUID 338 public override UUID UUID
336 { 339 {
337 get { return m_rootPart.UUID; } 340 get { return m_rootPart.UUID; }
338 set { m_rootPart.UUID = value; } 341 set
342 {
343 m_rootPart.UUID = value;
344
345 lock (m_parts)
346 {
347 m_parts.Remove(m_rootPart.UUID);
348 m_parts.Add(m_rootPart.UUID, m_rootPart);
349 }
350 }
339 } 351 }
340 352
341 public UUID OwnerID 353 public UUID OwnerID
@@ -549,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes
549 if (m_rootPart.LocalId == 0) 561 if (m_rootPart.LocalId == 0)
550 m_rootPart.LocalId = m_scene.AllocateLocalId(); 562 m_rootPart.LocalId = m_scene.AllocateLocalId();
551 563
552 // No need to lock here since the object isn't yet in a scene 564 lock (m_parts)
553 foreach (SceneObjectPart part in m_parts.Values)
554 { 565 {
555 if (Object.ReferenceEquals(part, m_rootPart)) 566 foreach (SceneObjectPart part in m_parts.Values)
556 {
557 continue;
558 }
559
560 if (part.LocalId == 0)
561 { 567 {
562 part.LocalId = m_scene.AllocateLocalId(); 568 if (Object.ReferenceEquals(part, m_rootPart))
569 {
570 continue;
571 }
572
573 if (part.LocalId == 0)
574 {
575 part.LocalId = m_scene.AllocateLocalId();
576 }
577
578 part.ParentID = m_rootPart.LocalId;
579 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
563 } 580 }
564
565 part.ParentID = m_rootPart.LocalId;
566 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
567 } 581 }
568 582
569 ApplyPhysics(m_scene.m_physicalPrim); 583 ApplyPhysics(m_scene.m_physicalPrim);
@@ -661,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
661 minY = 256f; 675 minY = 256f;
662 minZ = 8192f; 676 minZ = 8192f;
663 677
664 lock(m_parts); 678 lock(m_parts)
665 { 679 {
666 foreach (SceneObjectPart part in m_parts.Values) 680 foreach (SceneObjectPart part in m_parts.Values)
667 { 681 {
@@ -986,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes
986 m_rootPart.AttachedAvatar = agentID; 1000 m_rootPart.AttachedAvatar = agentID;
987 1001
988 //Anakin Lohner bug #3839 1002 //Anakin Lohner bug #3839
989 foreach (SceneObjectPart p in m_parts.Values) 1003 lock (m_parts)
990 { 1004 {
991 p.AttachedAvatar = agentID; 1005 foreach (SceneObjectPart p in m_parts.Values)
1006 {
1007 p.AttachedAvatar = agentID;
1008 }
992 } 1009 }
993 1010
994 if (m_rootPart.PhysActor != null) 1011 if (m_rootPart.PhysActor != null)
@@ -1056,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes
1056 1073
1057 AbsolutePosition = detachedpos; 1074 AbsolutePosition = detachedpos;
1058 m_rootPart.AttachedAvatar = UUID.Zero; 1075 m_rootPart.AttachedAvatar = UUID.Zero;
1059 //Anakin Lohner bug #3839 1076
1060 foreach (SceneObjectPart p in m_parts.Values) 1077 //Anakin Lohner bug #3839
1078 lock (m_parts)
1061 { 1079 {
1062 p.AttachedAvatar = UUID.Zero; 1080 foreach (SceneObjectPart p in m_parts.Values)
1081 {
1082 p.AttachedAvatar = UUID.Zero;
1083 }
1063 } 1084 }
1064 1085
1065 m_rootPart.SetParentLocalId(0); 1086 m_rootPart.SetParentLocalId(0);
@@ -1085,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes
1085 } 1106 }
1086 1107
1087 m_rootPart.AttachedAvatar = UUID.Zero; 1108 m_rootPart.AttachedAvatar = UUID.Zero;
1109
1088 //Anakin Lohner bug #3839 1110 //Anakin Lohner bug #3839
1089 foreach (SceneObjectPart p in m_parts.Values) 1111 lock (m_parts)
1090 { 1112 {
1091 p.AttachedAvatar = UUID.Zero; 1113 foreach (SceneObjectPart p in m_parts.Values)
1114 {
1115 p.AttachedAvatar = UUID.Zero;
1116 }
1092 } 1117 }
1093 1118
1094 m_rootPart.SetParentLocalId(0); 1119 m_rootPart.SetParentLocalId(0);
@@ -1151,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes
1151 part.ParentID = 0; 1176 part.ParentID = 0;
1152 part.LinkNum = 0; 1177 part.LinkNum = 0;
1153 1178
1154 // No locking required since the SOG should not be in the scene yet - one can't change root parts after 1179 lock (m_parts)
1155 // the scene object has been attached to the scene 1180 m_parts.Add(m_rootPart.UUID, m_rootPart);
1156 m_parts.Add(m_rootPart.UUID, m_rootPart);
1157 } 1181 }
1158 1182
1159 /// <summary> 1183 /// <summary>
@@ -1616,14 +1640,14 @@ namespace OpenSim.Region.Framework.Scenes
1616 } 1640 }
1617 1641
1618 /// <summary> 1642 /// <summary>
1619 /// 1643 /// Copy the given part as the root part of this scene object.
1620 /// </summary> 1644 /// </summary>
1621 /// <param name="part"></param> 1645 /// <param name="part"></param>
1622 /// <param name="cAgentID"></param> 1646 /// <param name="cAgentID"></param>
1623 /// <param name="cGroupID"></param> 1647 /// <param name="cGroupID"></param>
1624 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1648 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1625 { 1649 {
1626 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); 1650 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1627 } 1651 }
1628 1652
1629 public void ScriptSetPhysicsStatus(bool UsePhysics) 1653 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -1873,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes
1873 /// <param name="cGroupID"></param> 1897 /// <param name="cGroupID"></param>
1874 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1898 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1875 { 1899 {
1876 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1900 SceneObjectPart newPart = null;
1877 newPart.SetParent(this); 1901
1878
1879 lock (m_parts) 1902 lock (m_parts)
1880 { 1903 {
1904 newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1905 newPart.SetParent(this);
1881 m_parts.Add(newPart.UUID, newPart); 1906 m_parts.Add(newPart.UUID, newPart);
1882 } 1907 }
1883 1908
@@ -1894,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes
1894 /// </summary> 1919 /// </summary>
1895 public void ResetIDs() 1920 public void ResetIDs()
1896 { 1921 {
1897 // As this is only ever called for prims which are not currently part of the scene (and hence 1922 lock (m_parts)
1898 // not accessible by clients), there should be no need to lock
1899 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
1900 m_parts.Clear();
1901 foreach (SceneObjectPart part in partsList)
1902 { 1923 {
1903 part.ResetIDs(part.LinkNum); // Don't change link nums 1924 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
1904 m_parts.Add(part.UUID, part); 1925 m_parts.Clear();
1926 foreach (SceneObjectPart part in partsList)
1927 {
1928 part.ResetIDs(part.LinkNum); // Don't change link nums
1929 m_parts.Add(part.UUID, part);
1930 }
1905 } 1931 }
1906 } 1932 }
1907 1933
@@ -2127,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes
2127 public SceneObjectPart GetChildPart(UUID primID) 2153 public SceneObjectPart GetChildPart(UUID primID)
2128 { 2154 {
2129 SceneObjectPart childPart = null; 2155 SceneObjectPart childPart = null;
2130 if (m_parts.ContainsKey(primID)) 2156
2157 lock (m_parts)
2131 { 2158 {
2132 childPart = m_parts[primID]; 2159 if (m_parts.ContainsKey(primID))
2160 {
2161 childPart = m_parts[primID];
2162 }
2133 } 2163 }
2164
2134 return childPart; 2165 return childPart;
2135 } 2166 }
2136 2167
@@ -2165,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
2165 /// <returns></returns> 2196 /// <returns></returns>
2166 public bool HasChildPrim(UUID primID) 2197 public bool HasChildPrim(UUID primID)
2167 { 2198 {
2168 if (m_parts.ContainsKey(primID)) 2199 lock (m_parts)
2169 { 2200 {
2170 return true; 2201 if (m_parts.ContainsKey(primID))
2202 return true;
2171 } 2203 }
2172 2204
2173 return false; 2205 return false;
@@ -2361,17 +2393,19 @@ namespace OpenSim.Region.Framework.Scenes
2361 lock (m_parts) 2393 lock (m_parts)
2362 { 2394 {
2363 m_parts.Remove(linkPart.UUID); 2395 m_parts.Remove(linkPart.UUID);
2364 } 2396
2365 2397 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2366 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2367 RootPart.LinkNum = 0;
2368 else
2369 {
2370 foreach (SceneObjectPart p in m_parts.Values)
2371 { 2398 {
2372 if (p.LinkNum > linkPart.LinkNum) 2399 RootPart.LinkNum = 0;
2373 p.LinkNum--;
2374 } 2400 }
2401 else
2402 {
2403 foreach (SceneObjectPart p in m_parts.Values)
2404 {
2405 if (p.LinkNum > linkPart.LinkNum)
2406 p.LinkNum--;
2407 }
2408 }
2375 } 2409 }
2376 2410
2377 linkPart.ParentID = 0; 2411 linkPart.ParentID = 0;
@@ -2753,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes
2753 public void UpdatePermissions(UUID AgentID, byte field, uint localID, 2787 public void UpdatePermissions(UUID AgentID, byte field, uint localID,
2754 uint mask, byte addRemTF) 2788 uint mask, byte addRemTF)
2755 { 2789 {
2756 foreach (SceneObjectPart part in m_parts.Values) 2790 lock (m_parts)
2757 part.UpdatePermissions(AgentID, field, localID, mask, 2791 {
2758 addRemTF); 2792 foreach (SceneObjectPart part in m_parts.Values)
2793 part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
2794 }
2759 2795
2760 HasGroupChanged = true; 2796 HasGroupChanged = true;
2761 } 2797 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 4ae53a2..e08fa77 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -37,6 +37,7 @@ using log4net;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes.Scripting; 39using OpenSim.Region.Framework.Scenes.Scripting;
40using OpenSim.Region.Framework.Scenes.Serialization;
40 41
41namespace OpenSim.Region.Framework.Scenes 42namespace OpenSim.Region.Framework.Scenes
42{ 43{
@@ -574,6 +575,71 @@ namespace OpenSim.Region.Framework.Scenes
574 return items; 575 return items;
575 } 576 }
576 577
578 public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item)
579 {
580 UUID ownerID = item.OwnerID;
581 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
582
583 if (null == rezAsset)
584 {
585 m_log.WarnFormat(
586 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
587 item.AssetID, item.Name, m_part.Name);
588 return null;
589 }
590
591 string xmlData = Utils.BytesToString(rezAsset.Data);
592 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
593
594 group.ResetIDs();
595
596 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
597
598 // Since renaming the item in the inventory does not affect the name stored
599 // in the serialization, transfer the correct name from the inventory to the
600 // object itself before we rez.
601 rootPart.Name = item.Name;
602 rootPart.Description = item.Description;
603
604 List<SceneObjectPart> partList = null;
605
606 lock (group.Children)
607 partList = new List<SceneObjectPart>(group.Children.Values);
608
609 group.SetGroup(m_part.GroupID, null);
610
611 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
612 {
613 if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
614 {
615 foreach (SceneObjectPart part in partList)
616 {
617 part.EveryoneMask = item.EveryonePermissions;
618 part.NextOwnerMask = item.NextPermissions;
619 }
620
621 group.ApplyNextOwnerPermissions();
622 }
623 }
624
625 foreach (SceneObjectPart part in partList)
626 {
627 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
628 {
629 part.LastOwnerID = part.OwnerID;
630 part.OwnerID = item.OwnerID;
631 part.Inventory.ChangeInventoryOwner(item.OwnerID);
632 }
633
634 part.EveryoneMask = item.EveryonePermissions;
635 part.NextOwnerMask = item.NextPermissions;
636 }
637
638 rootPart.TrimPermissions();
639
640 return group;
641 }
642
577 /// <summary> 643 /// <summary>
578 /// Update an existing inventory item. 644 /// Update an existing inventory item.
579 /// </summary> 645 /// </summary>
@@ -1029,6 +1095,5 @@ namespace OpenSim.Region.Framework.Scenes
1029 } 1095 }
1030 } 1096 }
1031 } 1097 }
1032
1033 } 1098 }
1034} 1099} \ No newline at end of file