diff options
author | Justin Clark-Casey (justincc) | 2012-07-09 21:24:32 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-07-09 21:24:32 +0100 |
commit | 2eaa6d5ace738cf1848f82ce7a0b435928b6846f (patch) | |
tree | 091add9a2885fbb702cf908e1b2f70f5d1730131 /OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |
parent | More keys for automated ini processing (diff) | |
download | opensim-SC_OLD-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.zip opensim-SC_OLD-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.tar.gz opensim-SC_OLD-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.tar.bz2 opensim-SC_OLD-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.tar.xz |
Do not allow a script to attach a prim if its being sat upon.
This prevents a stack overflow where a get position on the avatar will refer to the attachment which will in turn refer back to the avatar.
This required recording of all sitting avatars on a prim which is done separately from recording the sit target avatar.
Recording HashSet is null if there are no sitting avatars in order to save memory.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 98 |
1 files changed, 91 insertions, 7 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3d81358..6518b84 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -374,7 +374,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
374 | private uint _category; | 374 | private uint _category; |
375 | private Int32 _creationDate; | 375 | private Int32 _creationDate; |
376 | private uint _parentID = 0; | 376 | private uint _parentID = 0; |
377 | private UUID m_sitTargetAvatar = UUID.Zero; | ||
378 | private uint _baseMask = (uint)PermissionMask.All; | 377 | private uint _baseMask = (uint)PermissionMask.All; |
379 | private uint _ownerMask = (uint)PermissionMask.All; | 378 | private uint _ownerMask = (uint)PermissionMask.All; |
380 | private uint _groupMask = (uint)PermissionMask.None; | 379 | private uint _groupMask = (uint)PermissionMask.None; |
@@ -1233,13 +1232,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1233 | } | 1232 | } |
1234 | 1233 | ||
1235 | /// <summary> | 1234 | /// <summary> |
1236 | /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero | 1235 | /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero |
1237 | /// </summary> | 1236 | /// </summary> |
1238 | public UUID SitTargetAvatar | 1237 | public UUID SitTargetAvatar { get; set; } |
1239 | { | 1238 | |
1240 | get { return m_sitTargetAvatar; } | 1239 | /// <summary> |
1241 | set { m_sitTargetAvatar = value; } | 1240 | /// IDs of all avatars start on this object part. |
1242 | } | 1241 | /// </summary> |
1242 | /// <remarks> | ||
1243 | /// We need to track this so that we can stop sat upon prims from being attached. | ||
1244 | /// </remarks> | ||
1245 | /// <value> | ||
1246 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. | ||
1247 | /// </value> | ||
1248 | private HashSet<UUID> m_sittingAvatars; | ||
1243 | 1249 | ||
1244 | public virtual UUID RegionID | 1250 | public virtual UUID RegionID |
1245 | { | 1251 | { |
@@ -4493,5 +4499,83 @@ namespace OpenSim.Region.Framework.Scenes | |||
4493 | Color color = Color; | 4499 | Color color = Color; |
4494 | return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); | 4500 | return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); |
4495 | } | 4501 | } |
4502 | |||
4503 | /// <summary> | ||
4504 | /// Record an avatar sitting on this part. | ||
4505 | /// </summary> | ||
4506 | /// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks> | ||
4507 | /// <returns> | ||
4508 | /// true if the avatar was not already recorded, false otherwise. | ||
4509 | /// </returns> | ||
4510 | /// <param name='avatarId'></param> | ||
4511 | protected internal bool AddSittingAvatar(UUID avatarId) | ||
4512 | { | ||
4513 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
4514 | |||
4515 | if (sittingAvatars == null) | ||
4516 | sittingAvatars = new HashSet<UUID>(); | ||
4517 | |||
4518 | lock (sittingAvatars) | ||
4519 | { | ||
4520 | m_sittingAvatars = sittingAvatars; | ||
4521 | return m_sittingAvatars.Add(avatarId); | ||
4522 | } | ||
4523 | } | ||
4524 | |||
4525 | /// <summary> | ||
4526 | /// Remove an avatar recorded as sitting on this part. | ||
4527 | /// </summary> | ||
4528 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
4529 | /// <returns> | ||
4530 | /// true if the avatar was present and removed, false if it was not present. | ||
4531 | /// </returns> | ||
4532 | /// <param name='avatarId'></param> | ||
4533 | protected internal bool RemoveSittingAvatar(UUID avatarId) | ||
4534 | { | ||
4535 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
4536 | |||
4537 | // This can occur under a race condition where another thread | ||
4538 | if (sittingAvatars == null) | ||
4539 | return false; | ||
4540 | |||
4541 | lock (sittingAvatars) | ||
4542 | { | ||
4543 | if (sittingAvatars.Remove(avatarId)) | ||
4544 | { | ||
4545 | if (sittingAvatars.Count == 0) | ||
4546 | m_sittingAvatars = null; | ||
4547 | |||
4548 | return true; | ||
4549 | } | ||
4550 | } | ||
4551 | |||
4552 | return false; | ||
4553 | } | ||
4554 | |||
4555 | /// <summary> | ||
4556 | /// Get a copy of the list of sitting avatars. | ||
4557 | /// </summary> | ||
4558 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
4559 | /// <returns></returns> | ||
4560 | public HashSet<UUID> GetSittingAvatars() | ||
4561 | { | ||
4562 | return new HashSet<UUID>(m_sittingAvatars); | ||
4563 | } | ||
4564 | |||
4565 | /// <summary> | ||
4566 | /// Gets the number of sitting avatars. | ||
4567 | /// </summary> | ||
4568 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
4569 | /// <returns></returns> | ||
4570 | public int GetSittingAvatarsCount() | ||
4571 | { | ||
4572 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
4573 | |||
4574 | if (sittingAvatars == null) | ||
4575 | return 0; | ||
4576 | |||
4577 | lock (sittingAvatars) | ||
4578 | return sittingAvatars.Count; | ||
4579 | } | ||
4496 | } | 4580 | } |
4497 | } | 4581 | } |