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; }
}
private void KillAvatar(uint killerObjectLocalID, ScenePresence DeadAvatar)
private void KillAvatar(uint killerObjectLocalID, ScenePresence deadAvatar)
{
string deadAvatarMessage;
ScenePresence killingAvatar = null;
string killingAvatarMessage;
if (killerObjectLocalID == 0)
DeadAvatar.ControllingClient.SendAgentAlertMessage("You committed suicide!", true);
deadAvatarMessage = "You committed suicide!";
else
{
bool foundResult = false;
string resultstring = String.Empty;
ScenePresence[] allav = DeadAvatar.Scene.GetScenePresences();
// Try to get the avatar responsible for the killing
killingAvatar = deadAvatar.Scene.GetScenePresence(killerObjectLocalID);
if (killingAvatar == null)
{
// Try to get the object which was responsible for the killing
SceneObjectPart part = deadAvatar.Scene.GetSceneObjectPart(killerObjectLocalID);
if (part == null)
{
// Cause of death: Unknown
deadAvatarMessage = "You died!";
}
else
{
// 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);
}
}
try
{
for (int i = 0; i < allav.Length; i++)
{
ScenePresence av = allav[i];
deadAvatar.ControllingClient.SendAgentAlertMessage(deadAvatarMessage, true);
if(killingAvatar != null)
killingAvatar.ControllingClient.SendAlertMessage("You fragged " + deadAvatar.Firstname + " " + deadAvatar.Lastname);
}
catch (InvalidOperationException)
{ }
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
{
DeadAvatar.ControllingClient.SendAgentAlertMessage("You died!", true);
}
}
}
DeadAvatar.Health = 100;
DeadAvatar.Scene.TeleportClientHome(DeadAvatar.UUID, DeadAvatar.ControllingClient);
deadAvatar.Health = 100;
deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
}
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)
{
ScenePresence[] presenceList = m_scene.GetScenePresences();
for (int i = 0; i < presenceList.Length; i++)
{
ScenePresence presence = presenceList[i];
if (presence.Firstname == firstName && presence.Lastname == lastName)
{
ScenePresence presence = m_scene.GetScenePresence(firstName, lastName);
if(presence != null)
presence.ControllingClient.SendAgentAlertMessage(message, modal);
break;
}
}
}
public void SendGeneralAlert(string message)
{
ScenePresence[] presenceList = m_scene.GetScenePresences();
for (int i = 0; i < presenceList.Length; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
{
ScenePresence presence = presenceList[i];
if (!presence.IsChildAgent)
presence.ControllingClient.SendAlertMessage(message);
}
});
}
public void SendDialogToUser(
@ -179,14 +166,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
public void SendNotificationToUsersInRegion(
UUID fromAvatarID, string fromAvatarName, string message)
{
ScenePresence[] presences = m_scene.GetScenePresences();
for (int i = 0; i < presences.Length; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
{
ScenePresence presence = presences[i];
if (!presence.IsChildAgent)
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
}
});
}
/// <summary>

View File

@ -469,12 +469,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID)
{
// 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)
{
// 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)
{
ScenePresence presence;
m_sceneGraph.TryGetAvatar(agentID, out presence);
if (presence != null)
if(m_sceneGraph.TryGetAvatar(agentID, out presence))
{
try
{
@ -3776,9 +3774,7 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 lookAt, uint teleportFlags)
{
ScenePresence sp;
m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp);
if (sp != null)
if(m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp))
{
uint regionX = m_regInfo.RegionLocX;
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
// 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>
/// 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.
/// </summary>
/// <returns></returns>
public ScenePresence[] GetScenePresences()
public List<ScenePresence> GetScenePresences()
{
return m_sceneGraph.GetScenePresences();
}
@ -4176,6 +4177,28 @@ namespace OpenSim.Region.Framework.Scenes
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)
{
ScenePresence cp = GetScenePresence(avatarID);
@ -4191,25 +4214,14 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <summary>
///
/// Performs action on all scene presences.
/// </summary>
/// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action)
{
// We don't want to try to send messages if there are no avatars.
if (m_sceneGraph != null)
{
try
{
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);
}
m_sceneGraph.ForEachScenePresence(action);
}
}

View File

@ -165,9 +165,10 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void UpdatePresences()
{
ScenePresence[] updateScenePresences = GetScenePresences();
for (int i = 0; i < updateScenePresences.Length; i++)
updateScenePresences[i].Update();
ForEachScenePresence(delegate(ScenePresence presence)
{
presence.Update();
});
}
protected internal float UpdatePhysics(double elapsed)
@ -196,9 +197,10 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void UpdateScenePresenceMovement()
{
ScenePresence[] moveEntities = GetScenePresences();
for (int i = 0; i < moveEntities.Length; i++)
moveEntities[i].UpdateMovement();
ForEachScenePresence(delegate(ScenePresence presence)
{
presence.UpdateMovement();
});
}
#endregion
@ -616,18 +618,16 @@ namespace OpenSim.Region.Framework.Scenes
public void RecalculateStats()
{
ScenePresence[] presences = GetScenePresences();
int rootcount = 0;
int childcount = 0;
for (int i = 0; i < presences.Length; i++)
ForEachScenePresence(delegate(ScenePresence presence)
{
ScenePresence user = presences[i];
if (user.IsChildAgent)
if (presence.IsChildAgent)
++childcount;
else
++rootcount;
}
});
m_numRootAgents = rootcount;
m_numChildAgents = childcount;
@ -674,25 +674,6 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
#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>
/// Get the controlling client for the given avatar, if there is one.
///
@ -718,42 +699,116 @@ namespace OpenSim.Region.Framework.Scenes
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>
/// 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>
/// <returns></returns>
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>();
ScenePresence[] scenePresences = GetScenePresences();
for (int i = 0; i < scenePresences.Length; i++)
// Check each ScenePresence against the filter
ForEachScenePresence(delegate(ScenePresence presence)
{
ScenePresence avatar = scenePresences[i];
if (filter(avatar))
result.Add(avatar);
if (filter(presence))
result.Add(presence);
});
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>
/// Request a scene presence by UUID
/// </summary>
/// <param name="avatarID"></param>
/// <param name="agentID"></param>
/// <returns>null if the agent was not found</returns>
protected internal ScenePresence GetScenePresence(UUID agentID)
{
ScenePresence sp;
lock (m_scenePresences)
{
m_scenePresences.TryGetValue(agentID, out sp);
TryGetAvatar(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>
@ -910,29 +965,19 @@ namespace OpenSim.Region.Framework.Scenes
protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
{
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)
{
ScenePresence[] presences = GetScenePresences();
for (int i = 0; i < presences.Length; i++)
avatar = GetScenePresence(delegate(ScenePresence presence)
{
ScenePresence presence = presences[i];
if (!presence.IsChildAgent)
{
if (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0)
{
avatar = presence;
return true;
}
}
}
avatar = null;
return false;
return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0);
});
return (avatar != null);
}
/// <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
#region Client Event handlers

View File

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

View File

@ -1268,22 +1268,20 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart part in m_parts.Values)
{
// part.Inventory.RemoveScriptInstances();
ScenePresence[] avatars = Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (avatars[i].ParentID == LocalId)
if (avatar.ParentID == LocalId)
{
avatars[i].StandUp();
avatar.StandUp();
}
if (!silent)
{
part.UpdateFlag = 0;
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)
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
// Ugly reference :(
if (avatars[i].UUID == AgentID)
if (avatar.UUID == AgentID)
{
m_parentGroup.GetProperties(avatars[i].ControllingClient);
}
m_parentGroup.GetProperties(avatar.ControllingClient);
}
});
}
// TODO: unused:
@ -1260,11 +1259,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void AddFullUpdateToAllAvatars()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
avatars[i].SceneViewer.QueuePartForUpdate(this);
}
avatar.SceneViewer.QueuePartForUpdate(this);
});
}
public void AddFullUpdateToAvatar(ScenePresence presence)
@ -1285,11 +1283,10 @@ namespace OpenSim.Region.Framework.Scenes
/// Terse updates
public void AddTerseUpdateToAllAvatars()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
avatars[i].SceneViewer.QueuePartForUpdate(this);
}
avatar.SceneViewer.QueuePartForUpdate(this);
});
}
public void AddTerseUpdateToAvatar(ScenePresence presence)
@ -2121,12 +2118,8 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avlist.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
{
ScenePresence av = avlist[i];
if (av.LocalId == localId)
{
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
@ -2171,7 +2164,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
});
}
}
if (colliding.Count > 0)
@ -2257,12 +2250,8 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avlist.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
{
ScenePresence av = avlist[i];
if (av.LocalId == localId)
{
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
@ -2307,7 +2296,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
});
}
}
if (colliding.Count > 0)
@ -2388,12 +2377,8 @@ namespace OpenSim.Region.Framework.Scenes
}
else
{
ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avlist.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence av)
{
ScenePresence av = avlist[i];
if (av.LocalId == localId)
{
if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
@ -2438,7 +2423,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
});
}
}
@ -2877,11 +2862,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void SendFullUpdateToAllClients()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
}
SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
});
}
/// <summary>
@ -2890,13 +2874,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="agentID"></param>
public void SendFullUpdateToAllClientsExcept(UUID agentID)
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
// Ugly reference :(
if (avatars[i].UUID != agentID)
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
}
if (avatar.UUID != agentID)
SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
});
}
/// <summary>
@ -3096,11 +3079,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void SendTerseUpdateToAllClients()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
SendTerseUpdateToClient(avatars[i].ControllingClient);
}
SendTerseUpdateToClient(avatar.ControllingClient);
});
}
public void SetAttachmentPoint(uint AttachmentPoint)

View File

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

View File

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