aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs255
1 files changed, 180 insertions, 75 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 8528edc..42644dc 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -37,11 +37,13 @@ using System.Xml.Serialization;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData;
40using OpenSim.Framework; 41using OpenSim.Framework;
41using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes.Scripting; 43using OpenSim.Region.Framework.Scenes.Scripting;
43using OpenSim.Region.Framework.Scenes.Serialization; 44using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Region.Physics.Manager; 45using OpenSim.Region.Physics.Manager;
46using PermissionMask = OpenSim.Framework.PermissionMask;
45 47
46namespace OpenSim.Region.Framework.Scenes 48namespace OpenSim.Region.Framework.Scenes
47{ 49{
@@ -116,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes
116 118
117 #endregion Enumerations 119 #endregion Enumerations
118 120
119 public class SceneObjectPart : IScriptHost, ISceneEntity 121 public class SceneObjectPart : ISceneEntity
120 { 122 {
121 /// <value> 123 /// <value>
122 /// Denote all sides of the prim 124 /// Denote all sides of the prim
@@ -136,6 +138,32 @@ namespace OpenSim.Region.Framework.Scenes
136 138
137 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 139 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
138 140
141 /// <summary>
142 /// Dynamic attributes can be created and deleted as required.
143 /// </summary>
144 public DAMap DynAttrs { get; set; }
145
146 private DOMap m_dynObjs;
147
148 /// <summary>
149 /// Dynamic objects that can be created and deleted as required.
150 /// </summary>
151 public DOMap DynObjs
152 {
153 get
154 {
155 if (m_dynObjs == null)
156 m_dynObjs = new DOMap();
157
158 return m_dynObjs;
159 }
160
161 set
162 {
163 m_dynObjs = value;
164 }
165 }
166
139 /// <value> 167 /// <value>
140 /// Is this a root part? 168 /// Is this a root part?
141 /// </value> 169 /// </value>
@@ -386,6 +414,7 @@ namespace OpenSim.Region.Framework.Scenes
386 m_particleSystem = Utils.EmptyBytes; 414 m_particleSystem = Utils.EmptyBytes;
387 Rezzed = DateTime.UtcNow; 415 Rezzed = DateTime.UtcNow;
388 Description = String.Empty; 416 Description = String.Empty;
417 DynAttrs = new DAMap();
389 418
390 // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, 419 // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
391 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 420 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
@@ -441,8 +470,8 @@ namespace OpenSim.Region.Framework.Scenes
441 private uint _category; 470 private uint _category;
442 private Int32 _creationDate; 471 private Int32 _creationDate;
443 private uint _parentID = 0; 472 private uint _parentID = 0;
444 private uint _baseMask = (uint)PermissionMask.All; 473 private uint _baseMask = (uint)(PermissionMask.All | PermissionMask.Export);
445 private uint _ownerMask = (uint)PermissionMask.All; 474 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
446 private uint _groupMask = (uint)PermissionMask.None; 475 private uint _groupMask = (uint)PermissionMask.None;
447 private uint _everyoneMask = (uint)PermissionMask.None; 476 private uint _everyoneMask = (uint)PermissionMask.None;
448 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); 477 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
@@ -1342,7 +1371,7 @@ namespace OpenSim.Region.Framework.Scenes
1342 public UUID SitTargetAvatar { get; set; } 1371 public UUID SitTargetAvatar { get; set; }
1343 1372
1344 /// <summary> 1373 /// <summary>
1345 /// IDs of all avatars start on this object part. 1374 /// IDs of all avatars sat on this part.
1346 /// </summary> 1375 /// </summary>
1347 /// <remarks> 1376 /// <remarks>
1348 /// We need to track this so that we can stop sat upon prims from being attached. 1377 /// We need to track this so that we can stop sat upon prims from being attached.
@@ -1689,6 +1718,10 @@ namespace OpenSim.Region.Framework.Scenes
1689 1718
1690 if (ParentGroup != null) 1719 if (ParentGroup != null)
1691 ParentGroup.HasGroupChanged = true; 1720 ParentGroup.HasGroupChanged = true;
1721
1722 PhysicsActor pa = PhysActor;
1723 if (pa != null)
1724 pa.Density = Density;
1692 } 1725 }
1693 } 1726 }
1694 1727
@@ -1708,6 +1741,9 @@ namespace OpenSim.Region.Framework.Scenes
1708 if (ParentGroup != null) 1741 if (ParentGroup != null)
1709 ParentGroup.HasGroupChanged = true; 1742 ParentGroup.HasGroupChanged = true;
1710 1743
1744 PhysicsActor pa = PhysActor;
1745 if (pa != null)
1746 pa.GravModifier = GravityModifier;
1711 } 1747 }
1712 } 1748 }
1713 1749
@@ -1726,10 +1762,14 @@ namespace OpenSim.Region.Framework.Scenes
1726 1762
1727 if (ParentGroup != null) 1763 if (ParentGroup != null)
1728 ParentGroup.HasGroupChanged = true; 1764 ParentGroup.HasGroupChanged = true;
1765
1766 PhysicsActor pa = PhysActor;
1767 if (pa != null)
1768 pa.Friction = Friction;
1729 } 1769 }
1730 } 1770 }
1731 1771
1732 public float Bounciness 1772 public float Restitution
1733 { 1773 {
1734 get { return m_bounce; } 1774 get { return m_bounce; }
1735 set 1775 set
@@ -1744,6 +1784,10 @@ namespace OpenSim.Region.Framework.Scenes
1744 1784
1745 if (ParentGroup != null) 1785 if (ParentGroup != null)
1746 ParentGroup.HasGroupChanged = true; 1786 ParentGroup.HasGroupChanged = true;
1787
1788 PhysicsActor pa = PhysActor;
1789 if (pa != null)
1790 pa.Restitution = Restitution;
1747 } 1791 }
1748 } 1792 }
1749 1793
@@ -2118,6 +2162,8 @@ namespace OpenSim.Region.Framework.Scenes
2118 // safeguard actual copy is done in sog.copy 2162 // safeguard actual copy is done in sog.copy
2119 dupe.KeyframeMotion = null; 2163 dupe.KeyframeMotion = null;
2120 2164
2165 dupe.DynAttrs.CopyFrom(DynAttrs);
2166
2121 if (userExposed) 2167 if (userExposed)
2122 { 2168 {
2123/* 2169/*
@@ -2431,11 +2477,11 @@ namespace OpenSim.Region.Framework.Scenes
2431 public int GetAxisRotation(int axis) 2477 public int GetAxisRotation(int axis)
2432 { 2478 {
2433 //Cannot use ScriptBaseClass constants as no referance to it currently. 2479 //Cannot use ScriptBaseClass constants as no referance to it currently.
2434 if (axis == 2)//STATUS_ROTATE_X 2480 if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X)
2435 return STATUS_ROTATE_X; 2481 return STATUS_ROTATE_X;
2436 if (axis == 4)//STATUS_ROTATE_Y 2482 if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y)
2437 return STATUS_ROTATE_Y; 2483 return STATUS_ROTATE_Y;
2438 if (axis == 8)//STATUS_ROTATE_Z 2484 if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z)
2439 return STATUS_ROTATE_Z; 2485 return STATUS_ROTATE_Z;
2440 2486
2441 return 0; 2487 return 0;
@@ -2470,18 +2516,6 @@ namespace OpenSim.Region.Framework.Scenes
2470 return new Vector3(0, 0, 0); 2516 return new Vector3(0, 0, 0);
2471 2517
2472 return ParentGroup.GetGeometricCenter(); 2518 return ParentGroup.GetGeometricCenter();
2473
2474 /*
2475 PhysicsActor pa = PhysActor;
2476
2477 if (pa != null)
2478 {
2479 Vector3 vtmp = pa.CenterOfMass;
2480 return vtmp;
2481 }
2482 else
2483 return new Vector3(0, 0, 0);
2484 */
2485 } 2519 }
2486 2520
2487 public float GetMass() 2521 public float GetMass()
@@ -2895,11 +2929,14 @@ namespace OpenSim.Region.Framework.Scenes
2895 2929
2896 public void PhysicsOutOfBounds(Vector3 pos) 2930 public void PhysicsOutOfBounds(Vector3 pos)
2897 { 2931 {
2898 m_log.Error("[PHYSICS]: Physical Object went out of bounds."); 2932 // Note: This is only being called on the root prim at this time.
2933
2934 m_log.ErrorFormat(
2935 "[SCENE OBJECT PART]: Physical object {0}, localID {1} went out of bounds at {2} in {3}. Stopping at {4} and making non-physical.",
2936 Name, LocalId, pos, ParentGroup.Scene.Name, AbsolutePosition);
2899 2937
2900 RemFlag(PrimFlags.Physics); 2938 RemFlag(PrimFlags.Physics);
2901 DoPhysicsPropertyUpdate(false, true); 2939 DoPhysicsPropertyUpdate(false, true);
2902 //ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
2903 } 2940 }
2904 2941
2905 public void PhysicsRequestingTerseUpdate() 2942 public void PhysicsRequestingTerseUpdate()
@@ -3322,13 +3359,13 @@ namespace OpenSim.Region.Framework.Scenes
3322 ParentGroup.SetAxisRotation(axis, rotate); 3359 ParentGroup.SetAxisRotation(axis, rotate);
3323 3360
3324 //Cannot use ScriptBaseClass constants as no referance to it currently. 3361 //Cannot use ScriptBaseClass constants as no referance to it currently.
3325 if (axis == 2)//STATUS_ROTATE_X 3362 if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0)
3326 STATUS_ROTATE_X = rotate; 3363 STATUS_ROTATE_X = rotate;
3327 3364
3328 if (axis == 4)//STATUS_ROTATE_Y 3365 if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0)
3329 STATUS_ROTATE_Y = rotate; 3366 STATUS_ROTATE_Y = rotate;
3330 3367
3331 if (axis == 8)//STATUS_ROTATE_Z 3368 if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0)
3332 STATUS_ROTATE_Z = rotate; 3369 STATUS_ROTATE_Z = rotate;
3333 } 3370 }
3334 3371
@@ -3706,6 +3743,10 @@ namespace OpenSim.Region.Framework.Scenes
3706 /// <param name="events"></param> 3743 /// <param name="events"></param>
3707 public void SetScriptEvents(UUID scriptid, int events) 3744 public void SetScriptEvents(UUID scriptid, int events)
3708 { 3745 {
3746// m_log.DebugFormat(
3747// "[SCENE OBJECT PART]: Set script events for script with id {0} on {1}/{2} to {3} in {4}",
3748// scriptid, Name, ParentGroup.Name, events, ParentGroup.Scene.Name);
3749
3709 // scriptEvents oldparts; 3750 // scriptEvents oldparts;
3710 lock (m_scriptEvents) 3751 lock (m_scriptEvents)
3711 { 3752 {
@@ -4235,6 +4276,7 @@ namespace OpenSim.Region.Framework.Scenes
4235 result.distance = distance2; 4276 result.distance = distance2;
4236 result.HitTF = true; 4277 result.HitTF = true;
4237 result.ipoint = q; 4278 result.ipoint = q;
4279 result.face = i;
4238 //m_log.Info("[FACE]:" + i.ToString()); 4280 //m_log.Info("[FACE]:" + i.ToString());
4239 //m_log.Info("[POINT]: " + q.ToString()); 4281 //m_log.Info("[POINT]: " + q.ToString());
4240 //m_log.Info("[DIST]: " + distance2.ToString()); 4282 //m_log.Info("[DIST]: " + distance2.ToString());
@@ -4281,10 +4323,10 @@ namespace OpenSim.Region.Framework.Scenes
4281 4323
4282 public void TrimPermissions() 4324 public void TrimPermissions()
4283 { 4325 {
4284 BaseMask &= (uint)PermissionMask.All; 4326 BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export);
4285 OwnerMask &= (uint)PermissionMask.All; 4327 OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export);
4286 GroupMask &= (uint)PermissionMask.All; 4328 GroupMask &= (uint)PermissionMask.All;
4287 EveryoneMask &= (uint)PermissionMask.All; 4329 EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export);
4288 NextOwnerMask &= (uint)PermissionMask.All; 4330 NextOwnerMask &= (uint)PermissionMask.All;
4289 } 4331 }
4290 4332
@@ -4387,10 +4429,22 @@ namespace OpenSim.Region.Framework.Scenes
4387 baseMask; 4429 baseMask;
4388 break; 4430 break;
4389 case 8: 4431 case 8:
4432 // Trying to set export permissions - extra checks
4433 if (set && (mask & (uint)PermissionMask.Export) != 0)
4434 {
4435 if ((OwnerMask & (uint)PermissionMask.Export) == 0 || (BaseMask & (uint)PermissionMask.Export) == 0 || (NextOwnerMask & (uint)PermissionMask.All) != (uint)PermissionMask.All)
4436 mask &= ~(uint)PermissionMask.Export;
4437 }
4390 EveryoneMask = ApplyMask(EveryoneMask, set, mask) & 4438 EveryoneMask = ApplyMask(EveryoneMask, set, mask) &
4391 baseMask; 4439 baseMask;
4392 break; 4440 break;
4393 case 16: 4441 case 16:
4442 // Force full perm if export
4443 if ((EveryoneMask & (uint)PermissionMask.Export) != 0)
4444 {
4445 NextOwnerMask = (uint)PermissionMask.All;
4446 break;
4447 }
4394 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4448 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4395 baseMask; 4449 baseMask;
4396 // Prevent the client from creating no copy, no transfer 4450 // Prevent the client from creating no copy, no transfer
@@ -4493,8 +4547,8 @@ namespace OpenSim.Region.Framework.Scenes
4493 GravityModifier = physdata.GravitationModifier; 4547 GravityModifier = physdata.GravitationModifier;
4494 if(Friction != physdata.Friction) 4548 if(Friction != physdata.Friction)
4495 Friction = physdata.Friction; 4549 Friction = physdata.Friction;
4496 if(Bounciness != physdata.Bounce) 4550 if(Restitution != physdata.Bounce)
4497 Bounciness = physdata.Bounce; 4551 Restitution = physdata.Bounce;
4498 } 4552 }
4499 /// <summary> 4553 /// <summary>
4500 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4554 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
@@ -4558,7 +4612,8 @@ namespace OpenSim.Region.Framework.Scenes
4558 if (ParentGroup.RootPart == this) 4612 if (ParentGroup.RootPart == this)
4559 AngularVelocity = new Vector3(0, 0, 0); 4613 AngularVelocity = new Vector3(0, 0, 0);
4560 } 4614 }
4561 else 4615
4616 else
4562 { 4617 {
4563 if (ParentGroup.Scene.CollidablePrims) 4618 if (ParentGroup.Scene.CollidablePrims)
4564 { 4619 {
@@ -4604,9 +4659,31 @@ namespace OpenSim.Region.Framework.Scenes
4604 UpdatePhysicsSubscribedEvents(); 4659 UpdatePhysicsSubscribedEvents();
4605 } 4660 }
4606 } 4661 }
4607 4662 if (SetVD)
4663 {
4664 // If the above logic worked (this is urgent candidate to unit tests!)
4665 // we now have a physicsactor.
4666 // Defensive programming calls for a check here.
4667 // Better would be throwing an exception that could be catched by a unit test as the internal
4668 // logic should make sure, this Physactor is always here.
4669 if (pa != null)
4670 {
4671 pa.SetVolumeDetect(1);
4672 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4673 VolumeDetectActive = true;
4674 }
4608 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4675 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4676 }
4677 else if (SetVD != wasVD)
4678 {
4679 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4680 // (mumbles, well, at least if you have infinte CPU powers :-))
4681 if (pa != null)
4682 pa.SetVolumeDetect(0);
4609 4683
4684 RemFlag(PrimFlags.Phantom);
4685 VolumeDetectActive = false;
4686 }
4610 // and last in case we have a new actor and not building 4687 // and last in case we have a new actor and not building
4611 4688
4612 if (ParentGroup != null) 4689 if (ParentGroup != null)
@@ -4646,9 +4723,9 @@ namespace OpenSim.Region.Framework.Scenes
4646 PhysicsShapeType, 4723 PhysicsShapeType,
4647 m_localId); 4724 m_localId);
4648 } 4725 }
4649 catch (Exception ex) 4726 catch (Exception e)
4650 { 4727 {
4651 m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message); 4728 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4652 pa = null; 4729 pa = null;
4653 } 4730 }
4654 4731
@@ -4657,6 +4734,11 @@ namespace OpenSim.Region.Framework.Scenes
4657 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4734 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4658 pa.SetMaterial(Material); 4735 pa.SetMaterial(Material);
4659 4736
4737 pa.Density = Density;
4738 pa.GravModifier = GravityModifier;
4739 pa.Friction = Friction;
4740 pa.Restitution = Restitution;
4741
4660 if (VolumeDetectActive) // change if not the default only 4742 if (VolumeDetectActive) // change if not the default only
4661 pa.SetVolumeDetect(1); 4743 pa.SetVolumeDetect(1);
4662 4744
@@ -4717,7 +4799,9 @@ namespace OpenSim.Region.Framework.Scenes
4717 } 4799 }
4718 4800
4719 PhysActor = pa; 4801 PhysActor = pa;
4720 } 4802
4803 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4804 }
4721 4805
4722 /// <summary> 4806 /// <summary>
4723 /// This removes the part from the physics scene. 4807 /// This removes the part from the physics scene.
@@ -4736,6 +4820,8 @@ namespace OpenSim.Region.Framework.Scenes
4736 pa.OnOutOfBounds -= PhysicsOutOfBounds; 4820 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4737 4821
4738 ParentGroup.Scene.PhysicsScene.RemovePrim(pa); 4822 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4823
4824 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4739 } 4825 }
4740 PhysActor = null; 4826 PhysActor = null;
4741 } 4827 }
@@ -4911,8 +4997,25 @@ namespace OpenSim.Region.Framework.Scenes
4911 4997
4912 Changed changeFlags = 0; 4998 Changed changeFlags = 0;
4913 4999
5000 Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture;
5001 Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture;
5002
5003 // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all
5004 // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point.
5005 if (fallbackNewFace == null)
5006 {
5007 fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
5008 newTex.DefaultTexture = fallbackNewFace;
5009 }
5010 if (fallbackOldFace == null)
5011 {
5012 fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
5013 oldTex.DefaultTexture = fallbackOldFace;
5014 }
5015
4914 for (int i = 0 ; i < GetNumberOfSides(); i++) 5016 for (int i = 0 ; i < GetNumberOfSides(); i++)
4915 { 5017 {
5018
4916 Primitive.TextureEntryFace newFace = newTex.DefaultTexture; 5019 Primitive.TextureEntryFace newFace = newTex.DefaultTexture;
4917 Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; 5020 Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture;
4918 5021
@@ -5138,9 +5241,12 @@ namespace OpenSim.Region.Framework.Scenes
5138 5241
5139 public void ApplyNextOwnerPermissions() 5242 public void ApplyNextOwnerPermissions()
5140 { 5243 {
5141 BaseMask &= NextOwnerMask; 5244 // Export needs to be preserved in the base and everyone
5245 // mask, but removed in the owner mask as a next owner
5246 // can never change the export status
5247 BaseMask &= NextOwnerMask | (uint)PermissionMask.Export;
5142 OwnerMask &= NextOwnerMask; 5248 OwnerMask &= NextOwnerMask;
5143 EveryoneMask &= NextOwnerMask; 5249 EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export;
5144 5250
5145 Inventory.ApplyNextOwnerPermissions(); 5251 Inventory.ApplyNextOwnerPermissions();
5146 } 5252 }
@@ -5202,18 +5308,22 @@ namespace OpenSim.Region.Framework.Scenes
5202 /// <param name='avatarId'></param> 5308 /// <param name='avatarId'></param>
5203 protected internal bool AddSittingAvatar(UUID avatarId) 5309 protected internal bool AddSittingAvatar(UUID avatarId)
5204 { 5310 {
5205 if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) 5311 lock (ParentGroup.m_sittingAvatars)
5206 SitTargetAvatar = avatarId; 5312 {
5313 if (IsSitTargetSet && SitTargetAvatar == UUID.Zero)
5314 SitTargetAvatar = avatarId;
5207 5315
5208 HashSet<UUID> sittingAvatars = m_sittingAvatars; 5316 if (m_sittingAvatars == null)
5317 m_sittingAvatars = new HashSet<UUID>();
5209 5318
5210 if (sittingAvatars == null) 5319 if (m_sittingAvatars.Add(avatarId))
5211 sittingAvatars = new HashSet<UUID>(); 5320 {
5321 ParentGroup.m_sittingAvatars.Add(avatarId);
5212 5322
5213 lock (sittingAvatars) 5323 return true;
5214 { 5324 }
5215 m_sittingAvatars = sittingAvatars; 5325
5216 return m_sittingAvatars.Add(avatarId); 5326 return false;
5217 } 5327 }
5218 } 5328 }
5219 5329
@@ -5227,27 +5337,26 @@ namespace OpenSim.Region.Framework.Scenes
5227 /// <param name='avatarId'></param> 5337 /// <param name='avatarId'></param>
5228 protected internal bool RemoveSittingAvatar(UUID avatarId) 5338 protected internal bool RemoveSittingAvatar(UUID avatarId)
5229 { 5339 {
5230 if (SitTargetAvatar == avatarId) 5340 lock (ParentGroup.m_sittingAvatars)
5231 SitTargetAvatar = UUID.Zero; 5341 {
5232 5342 if (SitTargetAvatar == avatarId)
5233 HashSet<UUID> sittingAvatars = m_sittingAvatars; 5343 SitTargetAvatar = UUID.Zero;
5234 5344
5235 // This can occur under a race condition where another thread 5345 if (m_sittingAvatars == null)
5236 if (sittingAvatars == null) 5346 return false;
5237 return false;
5238 5347
5239 lock (sittingAvatars) 5348 if (m_sittingAvatars.Remove(avatarId))
5240 {
5241 if (sittingAvatars.Remove(avatarId))
5242 { 5349 {
5243 if (sittingAvatars.Count == 0) 5350 if (m_sittingAvatars.Count == 0)
5244 m_sittingAvatars = null; 5351 m_sittingAvatars = null;
5245 5352
5353 ParentGroup.m_sittingAvatars.Remove(avatarId);
5354
5246 return true; 5355 return true;
5247 } 5356 }
5248 }
5249 5357
5250 return false; 5358 return false;
5359 }
5251 } 5360 }
5252 5361
5253 /// <summary> 5362 /// <summary>
@@ -5257,16 +5366,12 @@ namespace OpenSim.Region.Framework.Scenes
5257 /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> 5366 /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns>
5258 public HashSet<UUID> GetSittingAvatars() 5367 public HashSet<UUID> GetSittingAvatars()
5259 { 5368 {
5260 HashSet<UUID> sittingAvatars = m_sittingAvatars; 5369 lock (ParentGroup.m_sittingAvatars)
5261
5262 if (sittingAvatars == null)
5263 {
5264 return null;
5265 }
5266 else
5267 { 5370 {
5268 lock (sittingAvatars) 5371 if (m_sittingAvatars == null)
5269 return new HashSet<UUID>(sittingAvatars); 5372 return null;
5373 else
5374 return new HashSet<UUID>(m_sittingAvatars);
5270 } 5375 }
5271 } 5376 }
5272 5377
@@ -5277,13 +5382,13 @@ namespace OpenSim.Region.Framework.Scenes
5277 /// <returns></returns> 5382 /// <returns></returns>
5278 public int GetSittingAvatarsCount() 5383 public int GetSittingAvatarsCount()
5279 { 5384 {
5280 HashSet<UUID> sittingAvatars = m_sittingAvatars; 5385 lock (ParentGroup.m_sittingAvatars)
5281 5386 {
5282 if (sittingAvatars == null) 5387 if (m_sittingAvatars == null)
5283 return 0; 5388 return 0;
5284 5389 else
5285 lock (sittingAvatars) 5390 return m_sittingAvatars.Count;
5286 return sittingAvatars.Count; 5391 }
5287 } 5392 }
5288 } 5393 }
5289} 5394}