mirror of
https://github.com/opensim/opensim.git
synced 2026-08-11 03:45:35 +08:00
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.
This commit is contained in:
@@ -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
|
||||
// Try to get the avatar responsible for the killing
|
||||
killingAvatar = deadAvatar.Scene.GetScenePresence(killerObjectLocalID);
|
||||
if (killingAvatar == null)
|
||||
{
|
||||
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];
|
||||
|
||||
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
|
||||
// Cause of death: Unknown
|
||||
deadAvatarMessage = "You died!";
|
||||
}
|
||||
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;
|
||||
DeadAvatar.Scene.TeleportClientHome(DeadAvatar.UUID, DeadAvatar.ControllingClient);
|
||||
try
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
presence.ControllingClient.SendAgentAlertMessage(message, modal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ScenePresence presence = m_scene.GetScenePresence(firstName, lastName);
|
||||
if(presence != null)
|
||||
presence.ControllingClient.SendAgentAlertMessage(message, modal);
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user