From ae355720abb70f0f27b3dcc7b711c76483ac0d07 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 4 Jan 2013 20:34:39 +0000
Subject: Fix llGetLinkKey() to return the last sat avatar as the last link
number.
As per http://wiki.secondlife.com/wiki/LlGetLinkKey
This is done by keeping a scene-object wide list of sitters.
This also fixes bugs in this function where linknums 0 and 1 weren't treated properly if there were sitting avatars on a single prim.
This also fixes a minor race condition for multiple concurrent sitters on a prim with no current sitters by locking on the object-wide list rather than individual sop lists
Addresses http://opensimulator.org/mantis/view.php?id=6477
---
.../Region/Framework/Scenes/SceneObjectGroup.cs | 35 ++++++++++++++++++----
1 file changed, 29 insertions(+), 6 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 35e7c45..15795e5 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -647,6 +647,18 @@ namespace OpenSim.Region.Framework.Scenes
///
public UUID FromFolderID { get; set; }
+ ///
+ /// IDs of all avatars sat on this scene object.
+ ///
+ ///
+ /// We need this so that we can maintain a linkset wide ordering of avatars sat on different parts.
+ /// This must be locked before it is read or written.
+ /// SceneObjectPart sitting avatar add/remove code also locks on this object to avoid race conditions.
+ /// No avatar should appear more than once in this list.
+ /// Do not manipulate this list directly - use the Add/Remove sitting avatar methods on SceneObjectPart.
+ ///
+ protected internal List m_sittingAvatars = new List();
+
#endregion
// ~SceneObjectGroup()
@@ -3564,17 +3576,28 @@ namespace OpenSim.Region.Framework.Scenes
}
///
+ /// Get a copy of the list of sitting avatars on all prims of this object.
+ ///
+ ///
+ /// This is sorted by the order in which avatars sat down. If an avatar stands up then all avatars that sat
+ /// down after it move one place down the list.
+ ///
+ /// A list of the sitting avatars. Returns an empty list if there are no sitting avatars.
+ public List GetSittingAvatars()
+ {
+ lock (m_sittingAvatars)
+ return new List(m_sittingAvatars);
+ }
+
+ ///
/// Gets the number of sitting avatars.
///
/// This applies to all sitting avatars whether there is a sit target set or not.
///
public int GetSittingAvatarsCount()
{
- int count = 0;
-
- Array.ForEach(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount());
-
- return count;
+ lock (m_sittingAvatars)
+ return m_sittingAvatars.Count;
}
public override string ToString()
@@ -3583,7 +3606,7 @@ namespace OpenSim.Region.Framework.Scenes
}
#region ISceneObject
-
+
public virtual ISceneObject CloneForNewScene()
{
SceneObjectGroup sog = Copy(false);
--
cgit v1.1