diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 229 |
1 files changed, 157 insertions, 72 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 20a6626..42644dc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -37,11 +37,13 @@ using System.Xml.Serialization; | |||
37 | using log4net; | 37 | using log4net; |
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenMetaverse.Packets; | 39 | using OpenMetaverse.Packets; |
40 | using OpenMetaverse.StructuredData; | ||
40 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
41 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
42 | using OpenSim.Region.Framework.Scenes.Scripting; | 43 | using OpenSim.Region.Framework.Scenes.Scripting; |
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Region.Physics.Manager; | 45 | using OpenSim.Region.Physics.Manager; |
46 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
45 | 47 | ||
46 | namespace OpenSim.Region.Framework.Scenes | 48 | namespace 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. |
@@ -2133,6 +2162,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2133 | // safeguard actual copy is done in sog.copy | 2162 | // safeguard actual copy is done in sog.copy |
2134 | dupe.KeyframeMotion = null; | 2163 | dupe.KeyframeMotion = null; |
2135 | 2164 | ||
2165 | dupe.DynAttrs.CopyFrom(DynAttrs); | ||
2166 | |||
2136 | if (userExposed) | 2167 | if (userExposed) |
2137 | { | 2168 | { |
2138 | /* | 2169 | /* |
@@ -2446,11 +2477,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2446 | public int GetAxisRotation(int axis) | 2477 | public int GetAxisRotation(int axis) |
2447 | { | 2478 | { |
2448 | //Cannot use ScriptBaseClass constants as no referance to it currently. | 2479 | //Cannot use ScriptBaseClass constants as no referance to it currently. |
2449 | if (axis == 2)//STATUS_ROTATE_X | 2480 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) |
2450 | return STATUS_ROTATE_X; | 2481 | return STATUS_ROTATE_X; |
2451 | if (axis == 4)//STATUS_ROTATE_Y | 2482 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) |
2452 | return STATUS_ROTATE_Y; | 2483 | return STATUS_ROTATE_Y; |
2453 | if (axis == 8)//STATUS_ROTATE_Z | 2484 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) |
2454 | return STATUS_ROTATE_Z; | 2485 | return STATUS_ROTATE_Z; |
2455 | 2486 | ||
2456 | return 0; | 2487 | return 0; |
@@ -2485,18 +2516,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2485 | return new Vector3(0, 0, 0); | 2516 | return new Vector3(0, 0, 0); |
2486 | 2517 | ||
2487 | return ParentGroup.GetGeometricCenter(); | 2518 | return ParentGroup.GetGeometricCenter(); |
2488 | |||
2489 | /* | ||
2490 | PhysicsActor pa = PhysActor; | ||
2491 | |||
2492 | if (pa != null) | ||
2493 | { | ||
2494 | Vector3 vtmp = pa.CenterOfMass; | ||
2495 | return vtmp; | ||
2496 | } | ||
2497 | else | ||
2498 | return new Vector3(0, 0, 0); | ||
2499 | */ | ||
2500 | } | 2519 | } |
2501 | 2520 | ||
2502 | public float GetMass() | 2521 | public float GetMass() |
@@ -2910,11 +2929,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2910 | 2929 | ||
2911 | public void PhysicsOutOfBounds(Vector3 pos) | 2930 | public void PhysicsOutOfBounds(Vector3 pos) |
2912 | { | 2931 | { |
2913 | 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); | ||
2914 | 2937 | ||
2915 | RemFlag(PrimFlags.Physics); | 2938 | RemFlag(PrimFlags.Physics); |
2916 | DoPhysicsPropertyUpdate(false, true); | 2939 | DoPhysicsPropertyUpdate(false, true); |
2917 | //ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
2918 | } | 2940 | } |
2919 | 2941 | ||
2920 | public void PhysicsRequestingTerseUpdate() | 2942 | public void PhysicsRequestingTerseUpdate() |
@@ -3337,13 +3359,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3337 | ParentGroup.SetAxisRotation(axis, rotate); | 3359 | ParentGroup.SetAxisRotation(axis, rotate); |
3338 | 3360 | ||
3339 | //Cannot use ScriptBaseClass constants as no referance to it currently. | 3361 | //Cannot use ScriptBaseClass constants as no referance to it currently. |
3340 | if (axis == 2)//STATUS_ROTATE_X | 3362 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) |
3341 | STATUS_ROTATE_X = rotate; | 3363 | STATUS_ROTATE_X = rotate; |
3342 | 3364 | ||
3343 | if (axis == 4)//STATUS_ROTATE_Y | 3365 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) |
3344 | STATUS_ROTATE_Y = rotate; | 3366 | STATUS_ROTATE_Y = rotate; |
3345 | 3367 | ||
3346 | if (axis == 8)//STATUS_ROTATE_Z | 3368 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) |
3347 | STATUS_ROTATE_Z = rotate; | 3369 | STATUS_ROTATE_Z = rotate; |
3348 | } | 3370 | } |
3349 | 3371 | ||
@@ -3721,6 +3743,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3721 | /// <param name="events"></param> | 3743 | /// <param name="events"></param> |
3722 | public void SetScriptEvents(UUID scriptid, int events) | 3744 | public void SetScriptEvents(UUID scriptid, int events) |
3723 | { | 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 | |||
3724 | // scriptEvents oldparts; | 3750 | // scriptEvents oldparts; |
3725 | lock (m_scriptEvents) | 3751 | lock (m_scriptEvents) |
3726 | { | 3752 | { |
@@ -4250,6 +4276,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4250 | result.distance = distance2; | 4276 | result.distance = distance2; |
4251 | result.HitTF = true; | 4277 | result.HitTF = true; |
4252 | result.ipoint = q; | 4278 | result.ipoint = q; |
4279 | result.face = i; | ||
4253 | //m_log.Info("[FACE]:" + i.ToString()); | 4280 | //m_log.Info("[FACE]:" + i.ToString()); |
4254 | //m_log.Info("[POINT]: " + q.ToString()); | 4281 | //m_log.Info("[POINT]: " + q.ToString()); |
4255 | //m_log.Info("[DIST]: " + distance2.ToString()); | 4282 | //m_log.Info("[DIST]: " + distance2.ToString()); |
@@ -4296,10 +4323,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4296 | 4323 | ||
4297 | public void TrimPermissions() | 4324 | public void TrimPermissions() |
4298 | { | 4325 | { |
4299 | BaseMask &= (uint)PermissionMask.All; | 4326 | BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
4300 | OwnerMask &= (uint)PermissionMask.All; | 4327 | OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
4301 | GroupMask &= (uint)PermissionMask.All; | 4328 | GroupMask &= (uint)PermissionMask.All; |
4302 | EveryoneMask &= (uint)PermissionMask.All; | 4329 | EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
4303 | NextOwnerMask &= (uint)PermissionMask.All; | 4330 | NextOwnerMask &= (uint)PermissionMask.All; |
4304 | } | 4331 | } |
4305 | 4332 | ||
@@ -4402,10 +4429,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
4402 | baseMask; | 4429 | baseMask; |
4403 | break; | 4430 | break; |
4404 | 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 | } | ||
4405 | EveryoneMask = ApplyMask(EveryoneMask, set, mask) & | 4438 | EveryoneMask = ApplyMask(EveryoneMask, set, mask) & |
4406 | baseMask; | 4439 | baseMask; |
4407 | break; | 4440 | break; |
4408 | 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 | } | ||
4409 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & | 4448 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & |
4410 | baseMask; | 4449 | baseMask; |
4411 | // Prevent the client from creating no copy, no transfer | 4450 | // Prevent the client from creating no copy, no transfer |
@@ -4573,7 +4612,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4573 | if (ParentGroup.RootPart == this) | 4612 | if (ParentGroup.RootPart == this) |
4574 | AngularVelocity = new Vector3(0, 0, 0); | 4613 | AngularVelocity = new Vector3(0, 0, 0); |
4575 | } | 4614 | } |
4576 | else | 4615 | |
4616 | else | ||
4577 | { | 4617 | { |
4578 | if (ParentGroup.Scene.CollidablePrims) | 4618 | if (ParentGroup.Scene.CollidablePrims) |
4579 | { | 4619 | { |
@@ -4619,9 +4659,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
4619 | UpdatePhysicsSubscribedEvents(); | 4659 | UpdatePhysicsSubscribedEvents(); |
4620 | } | 4660 | } |
4621 | } | 4661 | } |
4622 | 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 | } | ||
4623 | // 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); | ||
4624 | 4683 | ||
4684 | RemFlag(PrimFlags.Phantom); | ||
4685 | VolumeDetectActive = false; | ||
4686 | } | ||
4625 | // 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 |
4626 | 4688 | ||
4627 | if (ParentGroup != null) | 4689 | if (ParentGroup != null) |
@@ -4661,9 +4723,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4661 | PhysicsShapeType, | 4723 | PhysicsShapeType, |
4662 | m_localId); | 4724 | m_localId); |
4663 | } | 4725 | } |
4664 | catch (Exception ex) | 4726 | catch (Exception e) |
4665 | { | 4727 | { |
4666 | 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); |
4667 | pa = null; | 4729 | pa = null; |
4668 | } | 4730 | } |
4669 | 4731 | ||
@@ -4737,7 +4799,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4737 | } | 4799 | } |
4738 | 4800 | ||
4739 | PhysActor = pa; | 4801 | PhysActor = pa; |
4740 | } | 4802 | |
4803 | ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); | ||
4804 | } | ||
4741 | 4805 | ||
4742 | /// <summary> | 4806 | /// <summary> |
4743 | /// This removes the part from the physics scene. | 4807 | /// This removes the part from the physics scene. |
@@ -4756,6 +4820,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4756 | pa.OnOutOfBounds -= PhysicsOutOfBounds; | 4820 | pa.OnOutOfBounds -= PhysicsOutOfBounds; |
4757 | 4821 | ||
4758 | ParentGroup.Scene.PhysicsScene.RemovePrim(pa); | 4822 | ParentGroup.Scene.PhysicsScene.RemovePrim(pa); |
4823 | |||
4824 | ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); | ||
4759 | } | 4825 | } |
4760 | PhysActor = null; | 4826 | PhysActor = null; |
4761 | } | 4827 | } |
@@ -4931,8 +4997,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
4931 | 4997 | ||
4932 | Changed changeFlags = 0; | 4998 | Changed changeFlags = 0; |
4933 | 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 | |||
4934 | for (int i = 0 ; i < GetNumberOfSides(); i++) | 5016 | for (int i = 0 ; i < GetNumberOfSides(); i++) |
4935 | { | 5017 | { |
5018 | |||
4936 | Primitive.TextureEntryFace newFace = newTex.DefaultTexture; | 5019 | Primitive.TextureEntryFace newFace = newTex.DefaultTexture; |
4937 | Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; | 5020 | Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; |
4938 | 5021 | ||
@@ -5158,9 +5241,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
5158 | 5241 | ||
5159 | public void ApplyNextOwnerPermissions() | 5242 | public void ApplyNextOwnerPermissions() |
5160 | { | 5243 | { |
5161 | 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; | ||
5162 | OwnerMask &= NextOwnerMask; | 5248 | OwnerMask &= NextOwnerMask; |
5163 | EveryoneMask &= NextOwnerMask; | 5249 | EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export; |
5164 | 5250 | ||
5165 | Inventory.ApplyNextOwnerPermissions(); | 5251 | Inventory.ApplyNextOwnerPermissions(); |
5166 | } | 5252 | } |
@@ -5222,18 +5308,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
5222 | /// <param name='avatarId'></param> | 5308 | /// <param name='avatarId'></param> |
5223 | protected internal bool AddSittingAvatar(UUID avatarId) | 5309 | protected internal bool AddSittingAvatar(UUID avatarId) |
5224 | { | 5310 | { |
5225 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | 5311 | lock (ParentGroup.m_sittingAvatars) |
5226 | SitTargetAvatar = avatarId; | 5312 | { |
5313 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | ||
5314 | SitTargetAvatar = avatarId; | ||
5227 | 5315 | ||
5228 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | 5316 | if (m_sittingAvatars == null) |
5317 | m_sittingAvatars = new HashSet<UUID>(); | ||
5229 | 5318 | ||
5230 | if (sittingAvatars == null) | 5319 | if (m_sittingAvatars.Add(avatarId)) |
5231 | sittingAvatars = new HashSet<UUID>(); | 5320 | { |
5321 | ParentGroup.m_sittingAvatars.Add(avatarId); | ||
5232 | 5322 | ||
5233 | lock (sittingAvatars) | 5323 | return true; |
5234 | { | 5324 | } |
5235 | m_sittingAvatars = sittingAvatars; | 5325 | |
5236 | return m_sittingAvatars.Add(avatarId); | 5326 | return false; |
5237 | } | 5327 | } |
5238 | } | 5328 | } |
5239 | 5329 | ||
@@ -5247,27 +5337,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
5247 | /// <param name='avatarId'></param> | 5337 | /// <param name='avatarId'></param> |
5248 | protected internal bool RemoveSittingAvatar(UUID avatarId) | 5338 | protected internal bool RemoveSittingAvatar(UUID avatarId) |
5249 | { | 5339 | { |
5250 | if (SitTargetAvatar == avatarId) | 5340 | lock (ParentGroup.m_sittingAvatars) |
5251 | SitTargetAvatar = UUID.Zero; | 5341 | { |
5252 | 5342 | if (SitTargetAvatar == avatarId) | |
5253 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | 5343 | SitTargetAvatar = UUID.Zero; |
5254 | 5344 | ||
5255 | // This can occur under a race condition where another thread | 5345 | if (m_sittingAvatars == null) |
5256 | if (sittingAvatars == null) | 5346 | return false; |
5257 | return false; | ||
5258 | 5347 | ||
5259 | lock (sittingAvatars) | 5348 | if (m_sittingAvatars.Remove(avatarId)) |
5260 | { | ||
5261 | if (sittingAvatars.Remove(avatarId)) | ||
5262 | { | 5349 | { |
5263 | if (sittingAvatars.Count == 0) | 5350 | if (m_sittingAvatars.Count == 0) |
5264 | m_sittingAvatars = null; | 5351 | m_sittingAvatars = null; |
5265 | 5352 | ||
5353 | ParentGroup.m_sittingAvatars.Remove(avatarId); | ||
5354 | |||
5266 | return true; | 5355 | return true; |
5267 | } | 5356 | } |
5268 | } | ||
5269 | 5357 | ||
5270 | return false; | 5358 | return false; |
5359 | } | ||
5271 | } | 5360 | } |
5272 | 5361 | ||
5273 | /// <summary> | 5362 | /// <summary> |
@@ -5277,16 +5366,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
5277 | /// <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> |
5278 | public HashSet<UUID> GetSittingAvatars() | 5367 | public HashSet<UUID> GetSittingAvatars() |
5279 | { | 5368 | { |
5280 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | 5369 | lock (ParentGroup.m_sittingAvatars) |
5281 | |||
5282 | if (sittingAvatars == null) | ||
5283 | { | 5370 | { |
5284 | return null; | 5371 | if (m_sittingAvatars == null) |
5285 | } | 5372 | return null; |
5286 | else | 5373 | else |
5287 | { | 5374 | return new HashSet<UUID>(m_sittingAvatars); |
5288 | lock (sittingAvatars) | ||
5289 | return new HashSet<UUID>(sittingAvatars); | ||
5290 | } | 5375 | } |
5291 | } | 5376 | } |
5292 | 5377 | ||
@@ -5297,13 +5382,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
5297 | /// <returns></returns> | 5382 | /// <returns></returns> |
5298 | public int GetSittingAvatarsCount() | 5383 | public int GetSittingAvatarsCount() |
5299 | { | 5384 | { |
5300 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | 5385 | lock (ParentGroup.m_sittingAvatars) |
5301 | 5386 | { | |
5302 | if (sittingAvatars == null) | 5387 | if (m_sittingAvatars == null) |
5303 | return 0; | 5388 | return 0; |
5304 | 5389 | else | |
5305 | lock (sittingAvatars) | 5390 | return m_sittingAvatars.Count; |
5306 | return sittingAvatars.Count; | 5391 | } |
5307 | } | 5392 | } |
5308 | } | 5393 | } |
5309 | } | 5394 | } |