aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-07-09 21:24:32 +0100
committerJustin Clark-Casey (justincc)2012-07-09 21:24:32 +0100
commit2eaa6d5ace738cf1848f82ce7a0b435928b6846f (patch)
tree091add9a2885fbb702cf908e1b2f70f5d1730131 /OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
parentMore keys for automated ini processing (diff)
downloadopensim-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.cs98
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}