aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
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
parentMore keys for automated ini processing (diff)
downloadopensim-SC-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.zip
opensim-SC-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.tar.gz
opensim-SC-2eaa6d5ace738cf1848f82ce7a0b435928b6846f.tar.bz2
opensim-SC-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')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs98
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs18
3 files changed, 122 insertions, 8 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4e0e183..fc04761 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3401,6 +3401,20 @@ namespace OpenSim.Region.Framework.Scenes
3401 return count; 3401 return count;
3402 } 3402 }
3403 3403
3404 /// <summary>
3405 /// Gets the number of sitting avatars.
3406 /// </summary>
3407 /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
3408 /// <returns></returns>
3409 public int GetSittingAvatarsCount()
3410 {
3411 int count = 0;
3412
3413 Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount());
3414
3415 return count;
3416 }
3417
3404 public override string ToString() 3418 public override string ToString()
3405 { 3419 {
3406 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 3420 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
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}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c7a670f..c6a2a03 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -578,6 +578,12 @@ namespace OpenSim.Region.Framework.Scenes
578 public uint ParentID { get; set; } 578 public uint ParentID { get; set; }
579 579
580 /// <summary> 580 /// <summary>
581 /// Are we sitting on an object?
582 /// </summary>
583 /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
584 public bool IsSatOnObject { get { return ParentID != 0; } }
585
586 /// <summary>
581 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. 587 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
582 /// </summary> 588 /// </summary>
583 /// <remarks> 589 /// <remarks>
@@ -1808,6 +1814,8 @@ namespace OpenSim.Region.Framework.Scenes
1808 SendAvatarDataToAllAgents(); 1814 SendAvatarDataToAllAgents();
1809 m_requestedSitTargetID = 0; 1815 m_requestedSitTargetID = 0;
1810 1816
1817 part.RemoveSittingAvatar(UUID);
1818
1811 if (part != null) 1819 if (part != null)
1812 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1820 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1813 } 1821 }
@@ -1887,7 +1895,7 @@ namespace OpenSim.Region.Framework.Scenes
1887 ) 1895 )
1888 )); 1896 ));
1889 1897
1890// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); 1898 m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
1891 1899
1892 if (PhysicsActor != null) 1900 if (PhysicsActor != null)
1893 m_sitAvatarHeight = PhysicsActor.Size.Z; 1901 m_sitAvatarHeight = PhysicsActor.Size.Z;
@@ -1920,6 +1928,12 @@ namespace OpenSim.Region.Framework.Scenes
1920 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1928 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1921 canSit = true; 1929 canSit = true;
1922 } 1930 }
1931// else
1932// {
1933// m_log.DebugFormat(
1934// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
1935// Name, part.Name, part.LocalId);
1936// }
1923 } 1937 }
1924 1938
1925 if (canSit) 1939 if (canSit)
@@ -1930,6 +1944,8 @@ namespace OpenSim.Region.Framework.Scenes
1930 RemoveFromPhysicalScene(); 1944 RemoveFromPhysicalScene();
1931 } 1945 }
1932 1946
1947 part.AddSittingAvatar(UUID);
1948
1933 cameraAtOffset = part.GetCameraAtOffset(); 1949 cameraAtOffset = part.GetCameraAtOffset();
1934 cameraEyeOffset = part.GetCameraEyeOffset(); 1950 cameraEyeOffset = part.GetCameraEyeOffset();
1935 forceMouselook = part.GetForceMouselook(); 1951 forceMouselook = part.GetForceMouselook();