Inconsistent locking of ScenePresence array in SceneGraph. Fixed by eliminating option to return the actual list. Callers can now either request a copy of the array as a new List or ask the SceneGraph to call a delegate function on every ScenePresence. Iteration and locking of the ScenePresences now takes place only within the SceneGraph class.

This patch also applies a fix to Combat/CombatModule.cs which had unlocked iteration of the ScenePresences and inconsistent try/catch around the use of those ScenePresences.
slimupdates
Dan Lake 2010-03-17 06:40:00 -07:00 committed by John Hurliman
parent a647f50087
commit 73e9b0be72
10 changed files with 262 additions and 237 deletions

View File

@ -89,60 +89,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
get { return true; } get { return true; }
} }
private void KillAvatar(uint killerObjectLocalID, ScenePresence DeadAvatar) private void KillAvatar(uint killerObjectLocalID, ScenePresence deadAvatar)
{ {
string deadAvatarMessage;
ScenePresence killingAvatar = null;
string killingAvatarMessage;
if (killerObjectLocalID == 0) if (killerObjectLocalID == 0)
DeadAvatar.ControllingClient.SendAgentAlertMessage("You committed suicide!", true); deadAvatarMessage = "You committed suicide!";
else else
{ {
bool foundResult = false; // Try to get the avatar responsible for the killing
string resultstring = String.Empty; killingAvatar = deadAvatar.Scene.GetScenePresence(killerObjectLocalID);
ScenePresence[] allav = DeadAvatar.Scene.GetScenePresences(); if (killingAvatar == null)
try
{ {
for (int i = 0; i < allav.Length; i++) // Try to get the object which was responsible for the killing
SceneObjectPart part = deadAvatar.Scene.GetSceneObjectPart(killerObjectLocalID);
if (part == null)
{ {
ScenePresence av = allav[i]; // Cause of death: Unknown
deadAvatarMessage = "You died!";
if (av.LocalId == killerObjectLocalID)
{
av.ControllingClient.SendAlertMessage("You fragged " + DeadAvatar.Firstname + " " + DeadAvatar.Lastname);
resultstring = av.Firstname + " " + av.Lastname;
foundResult = true;
}
}
} catch (InvalidOperationException)
{
}
if (!foundResult)
{
SceneObjectPart part = DeadAvatar.Scene.GetSceneObjectPart(killerObjectLocalID);
if (part != null)
{
ScenePresence av = DeadAvatar.Scene.GetScenePresence(part.OwnerID);
if (av != null)
{
av.ControllingClient.SendAlertMessage("You fragged " + DeadAvatar.Firstname + " " + DeadAvatar.Lastname);
resultstring = av.Firstname + " " + av.Lastname;
DeadAvatar.ControllingClient.SendAgentAlertMessage("You got killed by " + resultstring + "!", true);
}
else
{
string killer = DeadAvatar.Scene.GetUserName(part.OwnerID);
DeadAvatar.ControllingClient.SendAgentAlertMessage("You impaled yourself on " + part.Name + " owned by " + killer +"!", true);
}
//DeadAvatar.Scene. part.ObjectOwner
} }
else else
{ {
DeadAvatar.ControllingClient.SendAgentAlertMessage("You died!", true); // Try to find the avatar wielding the killing object
killingAvatar = deadAvatar.Scene.GetScenePresence(part.OwnerID);
if (killingAvatar == null)
deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, deadAvatar.Scene.GetUserName(part.OwnerID));
else
{
killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name);
deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name);
}
} }
} }
else
{
killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name);
deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name);
}
} }
DeadAvatar.Health = 100; try
DeadAvatar.Scene.TeleportClientHome(DeadAvatar.UUID, DeadAvatar.ControllingClient); {
deadAvatar.ControllingClient.SendAgentAlertMessage(deadAvatarMessage, true);
if(killingAvatar != null)
killingAvatar.ControllingClient.SendAlertMessage("You fragged " + deadAvatar.Firstname + " " + deadAvatar.Lastname);
}
catch (InvalidOperationException)
{ }
deadAvatar.Health = 100;
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
} }
private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)

View File

@ -87,31 +87,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
public void SendAlertToUser(string firstName, string lastName, string message, bool modal) public void SendAlertToUser(string firstName, string lastName, string message, bool modal)
{ {
ScenePresence[] presenceList = m_scene.GetScenePresences(); ScenePresence presence = m_scene.GetScenePresence(firstName, lastName);
if(presence != null)
for (int i = 0; i < presenceList.Length; i++) presence.ControllingClient.SendAgentAlertMessage(message, modal);
{
ScenePresence presence = presenceList[i];
if (presence.Firstname == firstName && presence.Lastname == lastName)
{
presence.ControllingClient.SendAgentAlertMessage(message, modal);
break;
}
}
} }
public void SendGeneralAlert(string message) public void SendGeneralAlert(string message)
{ {
ScenePresence[] presenceList = m_scene.GetScenePresences(); m_scene.ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < presenceList.Length; i++)
{ {
ScenePresence presence = presenceList[i];
if (!presence.IsChildAgent) if (!presence.IsChildAgent)
presence.ControllingClient.SendAlertMessage(message); presence.ControllingClient.SendAlertMessage(message);
} });
} }
public void SendDialogToUser( public void SendDialogToUser(
@ -179,14 +166,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
public void SendNotificationToUsersInRegion( public void SendNotificationToUsersInRegion(
UUID fromAvatarID, string fromAvatarName, string message) UUID fromAvatarID, string fromAvatarName, string message)
{ {
ScenePresence[] presences = m_scene.GetScenePresences(); m_scene.ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < presences.Length; i++)
{ {
ScenePresence presence = presences[i];
if (!presence.IsChildAgent) if (!presence.IsChildAgent)
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message); presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
} });
} }
/// <summary> /// <summary>

View File

@ -469,12 +469,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID) private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID)
{ {
// Get a fresh list that will not change as people get teleported away // Get a fresh list that will not change as people get teleported away
ScenePresence[] presences = m_scene.GetScenePresences(); List<ScenePresence> presences = m_scene.GetScenePresences();
for (int i = 0; i < presences.Length; i++) foreach(ScenePresence p in presences)
{ {
ScenePresence p = presences[i];
if (p.UUID != senderID) if (p.UUID != senderID)
{ {
// make sure they are still there, we could be working down a long list // make sure they are still there, we could be working down a long list

View File

@ -3599,9 +3599,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
{ {
ScenePresence presence; ScenePresence presence;
m_sceneGraph.TryGetAvatar(agentID, out presence); if(m_sceneGraph.TryGetAvatar(agentID, out presence))
if (presence != null)
{ {
try try
{ {
@ -3776,9 +3774,7 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 lookAt, uint teleportFlags) Vector3 lookAt, uint teleportFlags)
{ {
ScenePresence sp; ScenePresence sp;
m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp); if(m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp))
if (sp != null)
{ {
uint regionX = m_regInfo.RegionLocX; uint regionX = m_regInfo.RegionLocX;
uint regionY = m_regInfo.RegionLocY; uint regionY = m_regInfo.RegionLocY;
@ -4134,6 +4130,11 @@ namespace OpenSim.Region.Framework.Scenes
//The idea is to have a group of method that return a list of avatars meeting some requirement //The idea is to have a group of method that return a list of avatars meeting some requirement
// ie it could be all m_scenePresences within a certain range of the calling prim/avatar. // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
//
// GetAvatars returns a new list of all root agent presences in the scene
// GetScenePresences returns a new list of all presences in the scene or a filter may be passed.
// GetScenePresence returns the presence with matching UUID or first/last name.
// ForEachScenePresence requests the Scene to run a delegate function against all presences.
/// <summary> /// <summary>
/// Return a list of all avatars in this region. /// Return a list of all avatars in this region.
@ -4150,7 +4151,7 @@ namespace OpenSim.Region.Framework.Scenes
/// This list is a new object, so it can be iterated over without locking. /// This list is a new object, so it can be iterated over without locking.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ScenePresence[] GetScenePresences() public List<ScenePresence> GetScenePresences()
{ {
return m_sceneGraph.GetScenePresences(); return m_sceneGraph.GetScenePresences();
} }
@ -4176,6 +4177,28 @@ namespace OpenSim.Region.Framework.Scenes
return m_sceneGraph.GetScenePresence(avatarID); return m_sceneGraph.GetScenePresence(avatarID);
} }
/// <summary>
/// Request the ScenePresence in this region by first/last name.
/// Should normally only be a single match, but first is always returned
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <returns></returns>
public ScenePresence GetScenePresence(string firstName, string lastName)
{
return m_sceneGraph.GetScenePresence(firstName, lastName);
}
/// <summary>
/// Request the ScenePresence in this region by localID.
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
public ScenePresence GetScenePresence(uint localID)
{
return m_sceneGraph.GetScenePresence(localID);
}
public override bool PresenceChildStatus(UUID avatarID) public override bool PresenceChildStatus(UUID avatarID)
{ {
ScenePresence cp = GetScenePresence(avatarID); ScenePresence cp = GetScenePresence(avatarID);
@ -4191,25 +4214,14 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// /// Performs action on all scene presences.
/// </summary> /// </summary>
/// <param name="action"></param> /// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action) public void ForEachScenePresence(Action<ScenePresence> action)
{ {
// We don't want to try to send messages if there are no avatars.
if (m_sceneGraph != null) if (m_sceneGraph != null)
{ {
try m_sceneGraph.ForEachScenePresence(action);
{
ScenePresence[] presences = GetScenePresences();
for (int i = 0; i < presences.Length; i++)
action(presences[i]);
}
catch (Exception e)
{
m_log.Info("[BUG] in " + RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
}
} }
} }

View File

@ -165,9 +165,10 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void UpdatePresences() protected internal void UpdatePresences()
{ {
ScenePresence[] updateScenePresences = GetScenePresences(); ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < updateScenePresences.Length; i++) {
updateScenePresences[i].Update(); presence.Update();
});
} }
protected internal float UpdatePhysics(double elapsed) protected internal float UpdatePhysics(double elapsed)
@ -196,9 +197,10 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void UpdateScenePresenceMovement() protected internal void UpdateScenePresenceMovement()
{ {
ScenePresence[] moveEntities = GetScenePresences(); ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < moveEntities.Length; i++) {
moveEntities[i].UpdateMovement(); presence.UpdateMovement();
});
} }
#endregion #endregion
@ -616,18 +618,16 @@ namespace OpenSim.Region.Framework.Scenes
public void RecalculateStats() public void RecalculateStats()
{ {
ScenePresence[] presences = GetScenePresences();
int rootcount = 0; int rootcount = 0;
int childcount = 0; int childcount = 0;
for (int i = 0; i < presences.Length; i++) ForEachScenePresence(delegate(ScenePresence presence)
{ {
ScenePresence user = presences[i]; if (presence.IsChildAgent)
if (user.IsChildAgent)
++childcount; ++childcount;
else else
++rootcount; ++rootcount;
} });
m_numRootAgents = rootcount; m_numRootAgents = rootcount;
m_numChildAgents = childcount; m_numChildAgents = childcount;
@ -674,25 +674,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
#region Get Methods #region Get Methods
/// <summary>
/// Request a List of all scene presences in this scene. This is a new list, so no
/// locking is required to iterate over it.
/// </summary>
/// <returns></returns>
protected internal ScenePresence[] GetScenePresences()
{
return m_scenePresenceArray;
}
protected internal List<ScenePresence> GetAvatars()
{
List<ScenePresence> result =
GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; });
return result;
}
/// <summary> /// <summary>
/// Get the controlling client for the given avatar, if there is one. /// Get the controlling client for the given avatar, if there is one.
/// ///
@ -718,44 +699,118 @@ namespace OpenSim.Region.Framework.Scenes
return null; return null;
} }
// The idea is to have a group of method that return a list of avatars meeting some requirement
// ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
//
// GetAvatars returns a new list of all root agent presences in the scene
// GetScenePresences returns a new list of all presences in the scene or a filter may be passed.
// GetScenePresence returns the presence with matching UUID or the first presence matching the passed filter.
// ForEachScenePresence requests the Scene to run a delegate function against all presences.
/// <summary>
/// Request a list of all avatars in this region (no child agents)
/// This list is a new object, so it can be iterated over without locking.
/// </summary>
/// <returns></returns>
public List<ScenePresence> GetAvatars()
{
return GetScenePresences(delegate(ScenePresence scenePresence)
{
return !scenePresence.IsChildAgent;
});
}
/// <summary>
/// Request a list of m_scenePresences in this World
/// Returns a copy so it can be iterated without a lock.
/// There is no guarantee that presences will remain in the scene after the list is returned.
/// </summary>
/// <returns></returns>
protected internal List<ScenePresence> GetScenePresences()
{
List<ScenePresence> result;
lock (m_scenePresences)
{
result = new List<ScenePresence>(m_scenePresenceArray.Length);
result.AddRange(m_scenePresenceArray);
}
return result;
}
/// <summary> /// <summary>
/// Request a filtered list of m_scenePresences in this World /// Request a filtered list of m_scenePresences in this World
/// Returns a copy so it can be iterated without a lock.
/// There is no guarantee that presences will remain in the scene after the list is returned.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter) protected internal List<ScenePresence> GetScenePresences(FilterAvatarList filter)
{ {
// No locking of scene presences here since we're passing back a list...
List<ScenePresence> result = new List<ScenePresence>(); List<ScenePresence> result = new List<ScenePresence>();
ScenePresence[] scenePresences = GetScenePresences(); // Check each ScenePresence against the filter
ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < scenePresences.Length; i++)
{ {
ScenePresence avatar = scenePresences[i]; if (filter(presence))
if (filter(avatar)) result.Add(presence);
result.Add(avatar); });
}
return result; return result;
} }
/// <summary>
/// Request the ScenePresence in this region matching filter.
/// Only the first match is returned.
///
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
protected internal ScenePresence GetScenePresence(FilterAvatarList filter)
{
ScenePresence result = null;
// Get all of the ScenePresences
List<ScenePresence> presences = GetScenePresences();
foreach (ScenePresence presence in presences)
{
if (filter(presence))
{
result = presence;
break;
}
}
return result;
}
protected internal ScenePresence GetScenePresence(string firstName, string lastName)
{
return GetScenePresence(delegate(ScenePresence presence)
{
return(presence.Firstname == firstName && presence.Lastname == lastName);
});
}
/// <summary> /// <summary>
/// Request a scene presence by UUID /// Request a scene presence by UUID
/// </summary> /// </summary>
/// <param name="avatarID"></param> /// <param name="agentID"></param>
/// <returns>null if the agent was not found</returns> /// <returns>null if the agent was not found</returns>
protected internal ScenePresence GetScenePresence(UUID agentID) protected internal ScenePresence GetScenePresence(UUID agentID)
{ {
ScenePresence sp; ScenePresence sp;
TryGetAvatar(agentID, out sp);
lock (m_scenePresences)
{
m_scenePresences.TryGetValue(agentID, out sp);
}
return sp; return sp;
} }
/// <summary>
/// Request the ScenePresence in this region by localID.
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
protected internal ScenePresence GetScenePresence(uint localID)
{
return GetScenePresence(delegate(ScenePresence presence)
{
return (presence.LocalId == localID);
});
}
/// <summary> /// <summary>
/// Get a scene object group that contains the prim with the given local id /// Get a scene object group that contains the prim with the given local id
/// </summary> /// </summary>
@ -910,29 +965,19 @@ namespace OpenSim.Region.Framework.Scenes
protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
{ {
lock (m_scenePresences) lock (m_scenePresences)
return m_scenePresences.TryGetValue(avatarId, out avatar); {
m_scenePresences.TryGetValue(avatarId, out avatar);
}
return (avatar != null);
} }
protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{ {
ScenePresence[] presences = GetScenePresences(); avatar = GetScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < presences.Length; i++)
{ {
ScenePresence presence = presences[i]; return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0);
});
if (!presence.IsChildAgent) return (avatar != null);
{
if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
{
avatar = presence;
return true;
}
}
}
avatar = null;
return false;
} }
/// <summary> /// <summary>
@ -1014,6 +1059,28 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Performs action on all scene presences.
/// </summary>
/// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action)
{
List<ScenePresence> presences = GetScenePresences();
try
{
foreach(ScenePresence presence in presences)
{
action(presence);
}
}
catch (Exception e)
{
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
}
}
#endregion #endregion
#region Client Event handlers #region Client Event handlers

View File

@ -414,12 +414,8 @@ namespace OpenSim.Region.Framework.Scenes
ForEachCurrentScene( ForEachCurrentScene(
delegate(Scene scene) delegate(Scene scene)
{ {
ScenePresence[] scenePresences = scene.GetScenePresences(); scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
for (int i = 0; i < scenePresences.Length; i++)
{ {
ScenePresence scenePresence = scenePresences[i];
if (!scenePresence.IsChildAgent) if (!scenePresence.IsChildAgent)
{ {
m_log.DebugFormat("Packet debug for {0} {1} set to {2}", m_log.DebugFormat("Packet debug for {0} {1} set to {2}",
@ -429,7 +425,7 @@ namespace OpenSim.Region.Framework.Scenes
scenePresence.ControllingClient.SetDebugPacketLevel(newDebug); scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
} }
} });
} }
); );
} }
@ -441,14 +437,11 @@ namespace OpenSim.Region.Framework.Scenes
ForEachCurrentScene( ForEachCurrentScene(
delegate(Scene scene) delegate(Scene scene)
{ {
ScenePresence[] scenePresences = scene.GetScenePresences(); scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
for (int i = 0; i < scenePresences.Length; i++)
{ {
ScenePresence scenePresence = scenePresences[i];
if (!scenePresence.IsChildAgent) if (!scenePresence.IsChildAgent)
avatars.Add(scenePresence); avatars.Add(scenePresence);
} });
} }
); );
@ -461,7 +454,7 @@ namespace OpenSim.Region.Framework.Scenes
ForEachCurrentScene(delegate(Scene scene) ForEachCurrentScene(delegate(Scene scene)
{ {
ScenePresence[] scenePresences = scene.GetScenePresences(); List<ScenePresence> scenePresences = scene.GetScenePresences();
presences.AddRange(scenePresences); presences.AddRange(scenePresences);
}); });

View File

@ -1268,22 +1268,20 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart part in m_parts.Values) foreach (SceneObjectPart part in m_parts.Values)
{ {
// part.Inventory.RemoveScriptInstances(); // part.Inventory.RemoveScriptInstances();
Scene.ForEachScenePresence(delegate(ScenePresence avatar)
ScenePresence[] avatars = Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
{ {
if (avatars[i].ParentID == LocalId) if (avatar.ParentID == LocalId)
{ {
avatars[i].StandUp(); avatar.StandUp();
} }
if (!silent) if (!silent)
{ {
part.UpdateFlag = 0; part.UpdateFlag = 0;
if (part == m_rootPart) if (part == m_rootPart)
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
} }
} });
} }
} }
} }

View File

@ -1197,15 +1197,14 @@ namespace OpenSim.Region.Framework.Scenes
private void SendObjectPropertiesToClient(UUID AgentID) private void SendObjectPropertiesToClient(UUID AgentID)
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
// Ugly reference :( // Ugly reference :(
if (avatars[i].UUID == AgentID) if (avatar.UUID == AgentID)
{ {
m_parentGroup.GetProperties(avatars[i].ControllingClient); m_parentGroup.GetProperties(avatar.ControllingClient);
} }
} });
} }
// TODO: unused: // TODO: unused:
@ -1260,11 +1259,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void AddFullUpdateToAllAvatars() public void AddFullUpdateToAllAvatars()
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
avatars[i].SceneViewer.QueuePartForUpdate(this); avatar.SceneViewer.QueuePartForUpdate(this);
} });
} }
public void AddFullUpdateToAvatar(ScenePresence presence) public void AddFullUpdateToAvatar(ScenePresence presence)
@ -1285,11 +1283,10 @@ namespace OpenSim.Region.Framework.Scenes
/// Terse updates /// Terse updates
public void AddTerseUpdateToAllAvatars() public void AddTerseUpdateToAllAvatars()
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
avatars[i].SceneViewer.QueuePartForUpdate(this); avatar.SceneViewer.QueuePartForUpdate(this);
} });
} }
public void AddTerseUpdateToAvatar(ScenePresence presence) public void AddTerseUpdateToAvatar(ScenePresence presence)
@ -2121,17 +2118,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
for (int i = 0; i < avlist.Length; i++)
{ {
ScenePresence av = avlist[i];
if (av.LocalId == localId) if (av.LocalId == localId)
{ {
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar //If it is 1, it is to accept ONLY collisions from this avatar
if (found) if (found)
{ {
@ -2153,7 +2146,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
if (!found) if (!found)
{ {
@ -2171,7 +2164,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} });
} }
} }
if (colliding.Count > 0) if (colliding.Count > 0)
@ -2257,17 +2250,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
for (int i = 0; i < avlist.Length; i++)
{ {
ScenePresence av = avlist[i];
if (av.LocalId == localId) if (av.LocalId == localId)
{ {
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar //If it is 1, it is to accept ONLY collisions from this avatar
if (found) if (found)
{ {
@ -2289,7 +2278,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
if (!found) if (!found)
{ {
@ -2307,7 +2296,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} });
} }
} }
if (colliding.Count > 0) if (colliding.Count > 0)
@ -2388,17 +2377,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
for (int i = 0; i < avlist.Length; i++)
{ {
ScenePresence av = avlist[i];
if (av.LocalId == localId) if (av.LocalId == localId)
{ {
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar //If it is 1, it is to accept ONLY collisions from this avatar
if (found) if (found)
{ {
@ -2420,7 +2405,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
if (!found) if (!found)
{ {
@ -2438,7 +2423,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} });
} }
} }
@ -2877,11 +2862,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void SendFullUpdateToAllClients() public void SendFullUpdateToAllClients()
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID)); SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
} });
} }
/// <summary> /// <summary>
@ -2890,13 +2874,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="agentID"></param> /// <param name="agentID"></param>
public void SendFullUpdateToAllClientsExcept(UUID agentID) public void SendFullUpdateToAllClientsExcept(UUID agentID)
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
// Ugly reference :( // Ugly reference :(
if (avatars[i].UUID != agentID) if (avatar.UUID != agentID)
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID)); SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
} });
} }
/// <summary> /// <summary>
@ -3096,11 +3079,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void SendTerseUpdateToAllClients() public void SendTerseUpdateToAllClients()
{ {
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
SendTerseUpdateToClient(avatars[i].ControllingClient); SendTerseUpdateToClient(avatar.ControllingClient);
} });
} }
public void SetAttachmentPoint(uint AttachmentPoint) public void SetAttachmentPoint(uint AttachmentPoint)

View File

@ -912,14 +912,11 @@ namespace OpenSim.Region.Framework.Scenes
m_isChildAgent = false; m_isChildAgent = false;
ScenePresence[] animAgents = m_scene.GetScenePresences(); m_scene.ForEachScenePresence(delegate(ScenePresence presence)
for (int i = 0; i < animAgents.Length; i++)
{ {
ScenePresence presence = animAgents[i];
if (presence != this) if (presence != this)
presence.Animator.SendAnimPackToClient(ControllingClient); presence.Animator.SendAnimPackToClient(ControllingClient);
} });
m_scene.EventManager.TriggerOnMakeRootAgent(this); m_scene.EventManager.TriggerOnMakeRootAgent(this);
} }
@ -2469,13 +2466,10 @@ namespace OpenSim.Region.Framework.Scenes
public void SendInitialFullUpdateToAllClients() public void SendInitialFullUpdateToAllClients()
{ {
m_perfMonMS = Util.EnvironmentTickCount(); m_perfMonMS = Util.EnvironmentTickCount();
int avUpdates = 0;
ScenePresence[] avatars = m_scene.GetScenePresences(); m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
for (int i = 0; i < avatars.Length; i++)
{ {
ScenePresence avatar = avatars[i]; ++avUpdates;
// only send if this is the root (children are only "listening posts" in a foreign region) // only send if this is the root (children are only "listening posts" in a foreign region)
if (!IsChildAgent) if (!IsChildAgent)
{ {
@ -2491,9 +2485,9 @@ namespace OpenSim.Region.Framework.Scenes
avatar.Animator.SendAnimPackToClient(ControllingClient); avatar.Animator.SendAnimPackToClient(ControllingClient);
} }
} }
} });
m_scene.StatsReporter.AddAgentUpdates(avatars.Length); m_scene.StatsReporter.AddAgentUpdates(avUpdates);
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
//Animator.SendAnimPack(); //Animator.SendAnimPack();

View File

@ -68,7 +68,7 @@ namespace OpenSim.Region.UserStatistics
HTMLUtil.OL_O(ref output, ""); HTMLUtil.OL_O(ref output, "");
foreach (Scene scene in all_scenes) foreach (Scene scene in all_scenes)
{ {
ScenePresence[] avatarInScene = scene.GetScenePresences(); List<ScenePresence> avatarInScene = scene.GetScenePresences();
HTMLUtil.LI_O(ref output, String.Empty); HTMLUtil.LI_O(ref output, String.Empty);
output.Append(scene.RegionInfo.RegionName); output.Append(scene.RegionInfo.RegionName);