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
This commit is contained in:
Justin Clark-Casey (justincc)
2013-01-04 20:34:39 +00:00
parent a75f24bb79
commit 9503383887
3 changed files with 103 additions and 67 deletions

View File

@@ -647,6 +647,18 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks>
public UUID FromFolderID { get; set; }
/// <summary>
/// IDs of all avatars sat on this scene object.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
protected internal List<UUID> m_sittingAvatars = new List<UUID>();
#endregion
// ~SceneObjectGroup()
@@ -3563,6 +3575,20 @@ namespace OpenSim.Region.Framework.Scenes
return count;
}
/// <summary>
/// Get a copy of the list of sitting avatars on all prims of this object.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
/// <returns>A list of the sitting avatars. Returns an empty list if there are no sitting avatars.</returns>
public List<UUID> GetSittingAvatars()
{
lock (m_sittingAvatars)
return new List<UUID>(m_sittingAvatars);
}
/// <summary>
/// Gets the number of sitting avatars.
/// </summary>
@@ -3570,11 +3596,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns>
public int GetSittingAvatarsCount()
{
int count = 0;
Array.ForEach<SceneObjectPart>(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);