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