Cleaned up access to scenepresences in scenegraph. GetScenePresences and GetAvatars have been removed to consolidate locking and iteration within SceneGraph. All callers which used these to then iterate over presences have been refactored to instead pass their delegates to Scene.ForEachScenePresence(Action<ScenePresence>).

slimupdates
Dan Lake 2010-03-19 05:51:16 -07:00 committed by John Hurliman
parent 73e9b0be72
commit 859bc717a4
22 changed files with 378 additions and 513 deletions

View File

@ -123,10 +123,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
private void DoMove(RequestData rdata)
{
if (rdata.Parameters.Length >= 6)
if (rdata.Parameters.Length < 6)
{
Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId);
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided");
}
else
{
string[] names = rdata.Parameters[PARM_MOVE_AVATAR].Split(Rest.CA_SPACE);
ScenePresence avatar = null;
ScenePresence presence = null;
Scene scene = null;
if (names.Length != 2)
@ -141,21 +146,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
// The first parameter should be an avatar name, look for the
// avatar in the known regions first.
foreach (Scene cs in Rest.main.SceneManager.Scenes)
Rest.main.SceneManager.ForEachScene(delegate(Scene s)
{
foreach (ScenePresence presence in cs.GetAvatars())
s.ForEachScenePresence(delegate(ScenePresence sp)
{
if (presence.Firstname == names[0] &&
presence.Lastname == names[1])
if (sp.Firstname == names[0] && sp.Lastname == names[1])
{
scene = cs;
avatar = presence;
break;
scene = s;
presence = sp;
}
}
}
});
});
if (avatar != null)
if (presence != null)
{
Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}",
MsgId, rdata.Parameters[PARM_MOVE_AVATAR], scene.RegionInfo.RegionName);
@ -166,14 +169,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
Vector3 vector = new Vector3(x,y,z);
avatar.DoAutoPilot(0,vector,avatar.ControllingClient);
presence.DoAutoPilot(0,vector,presence.ControllingClient);
}
catch (Exception e)
{
rdata.Fail(Rest.HttpStatusCodeBadRequest,
String.Format("invalid parameters: {0}", e.Message));
}
}
else
{
@ -183,12 +185,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
rdata.Complete();
rdata.Respond("OK");
}
else
{
Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId);
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided");
}
}

View File

@ -192,7 +192,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
protected string RegionStats(OSHttpResponse httpResponse, Scene scene)
{
int users = scene.GetAvatars().Count;
int users = scene.GetRootAgentCount();
int objects = scene.Entities.Count - users;
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());

View File

@ -117,7 +117,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
rxw.WriteString(s.RegionInfo.InternalEndPoint.ToString());
rxw.WriteEndAttribute();
int users = s.GetAvatars().Count;
int users = s.GetRootAgentCount();
rxw.WriteStartAttribute(String.Empty, "avatars", String.Empty);
rxw.WriteValue(users);
rxw.WriteEndAttribute();

View File

@ -468,26 +468,20 @@ 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
List<ScenePresence> presences = m_scene.GetScenePresences();
foreach(ScenePresence p in presences)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (p.UUID != senderID)
if (sp.UUID != senderID)
{
ScenePresence p = m_scene.GetScenePresence(sp.UUID);
// make sure they are still there, we could be working down a long list
ScenePresence s = m_scene.GetScenePresence(p.UUID);
if (s != null)
// Also make sure they are actually in the region
if (p != null && !p.IsChildAgent)
{
// Also make sure they are actually in the region
if (!s.IsChildAgent)
{
s.ControllingClient.SendTeleportLocationStart();
m_scene.TeleportClientHome(s.UUID, s.ControllingClient);
}
p.ControllingClient.SendTeleportLocationStart();
m_scene.TeleportClientHome(p.UUID, p.ControllingClient);
}
}
}
});
}
private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID)
{
@ -765,12 +759,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void sendRegionInfoPacketToAll()
{
List<ScenePresence> avatars = m_scene.GetAvatars();
for (int i = 0; i < avatars.Count; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
HandleRegionInfoRequest(avatars[i].ControllingClient);
}
if (!sp.IsChildAgent)
HandleRegionInfoRequest(sp.ControllingClient);
});
}
public void sendRegionHandshake(IClientAPI remoteClient)

View File

@ -191,9 +191,9 @@ namespace OpenSim.Region.CoreModules.World.Land
forcedPosition = null;
}
//if we are far away, teleport
else if (Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3)
else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) > 3)
{
Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition));
Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition));
clientAvatar.Teleport(forcedPosition.Value);
forcedPosition = null;
}
@ -374,30 +374,27 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
public void SendOutNearestBanLine(IClientAPI avatar)
public void SendOutNearestBanLine(IClientAPI client)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence presence in avatars)
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null || sp.IsChildAgent)
return;
List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
foreach (ILandObject checkBan in checkLandParcels)
{
if (presence.UUID == avatar.AgentId)
if (checkBan.IsBannedFromLand(client.AgentId))
{
List<ILandObject> checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition);
foreach (ILandObject checkBan in checkLandParcels)
{
if (checkBan.IsBannedFromLand(avatar.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar);
return; //Only send one
}
if (checkBan.IsRestrictedFromLand(avatar.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar);
return; //Only send one
}
}
return;
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, client);
return; //Only send one
}
if (checkBan.IsRestrictedFromLand(client.AgentId))
{
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, client);
return; //Only send one
}
}
return;
}
public void SendLandUpdate(ScenePresence avatar, bool force)

View File

@ -332,36 +332,38 @@ namespace OpenSim.Region.CoreModules.World.Land
public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
ILandObject over = null;
for (int i = 0; i < avatars.Count; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (avatar.IsChildAgent)
return;
ILandObject over = null;
try
{
over =
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
}
catch (Exception)
{
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " +
Math.Round(avatars[i].AbsolutePosition.Y));
m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
Math.Round(avatar.AbsolutePosition.Y));
}
if (over != null)
{
if (over.LandData.LocalID == LandData.LocalID)
{
if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
m_scene.RegionInfo.RegionSettings.AllowDamage)
avatars[i].Invulnerable = false;
avatar.Invulnerable = false;
else
avatars[i].Invulnerable = true;
avatar.Invulnerable = true;
SendLandUpdateToClient(snap_selection, avatars[i].ControllingClient);
SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
}
}
}
});
}
#endregion

View File

@ -62,40 +62,46 @@ namespace OpenSim.Region.CoreModules.World.Sound
public virtual void PlayAttachedSound(
UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius)
{
foreach (ScenePresence p in m_scene.GetAvatars())
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
double dis = Util.GetDistanceTo(p.AbsolutePosition, position);
if (sp.IsChildAgent)
return;
double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
if (dis > 100.0) // Max audio distance
continue;
return;
// Scale by distance
if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0));
else
gain = (float)((double)gain * ((radius - dis) / radius));
p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags);
}
sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags);
});
}
public virtual void TriggerSound(
UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius)
{
foreach (ScenePresence p in m_scene.GetAvatars())
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
double dis = Util.GetDistanceTo(p.AbsolutePosition, position);
if (sp.IsChildAgent)
return;
double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
if (dis > 100.0) // Max audio distance
continue;
return;
// Scale by distance
if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0));
else
gain = (float)((double)gain * ((radius - dis) / radius));
p.ControllingClient.SendTriggeredSound(
sp.ControllingClient.SendTriggeredSound(
soundId, ownerID, objectID, parentID, handle, position, (float)gain);
}
});
}
}
}

View File

@ -509,14 +509,13 @@ namespace OpenSim.Region.CoreModules
private void SunUpdateToAllClients()
{
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence avatar in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (!avatar.IsChildAgent)
if (!sp.IsChildAgent)
{
SunToClient(avatar.ControllingClient);
SunToClient(sp.ControllingClient);
}
}
});
}
#region ISunModule Members

View File

@ -425,9 +425,7 @@ namespace OpenSim.Region.CoreModules
{
if (m_ready)
{
List<ScenePresence> avatars = m_scene.GetAvatars();
if (avatars.Count > 0)
if(m_scene.GetRootAgentCount() > 0)
{
// Ask wind plugin to generate a LL wind array to be cached locally
// Try not to update this too often, as it may involve array copies
@ -437,11 +435,11 @@ namespace OpenSim.Region.CoreModules
m_frameLastUpdateClientArray = m_frame;
}
foreach (ScenePresence avatar in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (!avatar.IsChildAgent)
avatar.ControllingClient.SendWindData(windSpeeds);
}
if (!sp.IsChildAgent)
sp.ControllingClient.SendWindData(windSpeeds);
});
}
}
}

View File

@ -304,25 +304,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
/// <param name="AgentId">AgentID that logged out</param>
private void ClientLoggedOut(UUID AgentId, Scene scene)
{
List<ScenePresence> presences = m_scene.GetAvatars();
int rootcount = 0;
for (int i=0;i<presences.Count;i++)
{
if (presences[i] != null)
{
if (!presences[i].IsChildAgent)
rootcount++;
}
}
if (rootcount <= 1)
StopThread();
lock (m_rootAgents)
{
if (m_rootAgents.Contains(AgentId))
{
m_rootAgents.Remove(AgentId);
}
m_rootAgents.Remove(AgentId);
if(m_rootAgents.Count == 0)
StopThread();
}
}
#endregion
@ -375,11 +361,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
{
// Local Map Item Request
List<ScenePresence> avatars = m_scene.GetAvatars();
int tc = Environment.TickCount;
List<mapItemReply> mapitems = new List<mapItemReply>();
mapItemReply mapitem = new mapItemReply();
if (avatars.Count == 0 || avatars.Count == 1)
if (m_scene.GetRootAgentCount() <= 1)
{
mapitem = new mapItemReply();
mapitem.x = (uint)(xstart + 1);
@ -392,21 +377,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
}
else
{
foreach (ScenePresence av in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
// Don't send a green dot for yourself
if (av.UUID != remoteClient.AgentId)
if (!sp.IsChildAgent && sp.UUID != remoteClient.AgentId)
{
mapitem = new mapItemReply();
mapitem.x = (uint)(xstart + av.AbsolutePosition.X);
mapitem.y = (uint)(ystart + av.AbsolutePosition.Y);
mapitem.x = (uint)(xstart + sp.AbsolutePosition.X);
mapitem.y = (uint)(ystart + sp.AbsolutePosition.Y);
mapitem.id = UUID.Zero;
mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString());
mapitem.Extra = 1;
mapitem.Extra2 = 0;
mapitems.Add(mapitem);
}
}
});
}
remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
}
@ -981,51 +966,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
OSDMap responsemap = new OSDMap();
List<ScenePresence> avatars = m_scene.GetAvatars();
OSDArray responsearr = new OSDArray(avatars.Count);
OSDMap responsemapdata = new OSDMap();
int tc = Environment.TickCount;
/*
foreach (ScenePresence av in avatars)
if (m_scene.GetRootAgentCount() == 0)
{
responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString("TH");
responsemapdata["Extra"] = OSD.FromInteger(0);
responsemapdata["Extra2"] = OSD.FromInteger(0);
responsearr.Add(responsemapdata);
}
responsemap["1"] = responsearr;
*/
if (avatars.Count == 0)
{
responsemapdata = new OSDMap();
OSDMap responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()));
responsemapdata["Extra"] = OSD.FromInteger(0);
responsemapdata["Extra2"] = OSD.FromInteger(0);
OSDArray responsearr = new OSDArray();
responsearr.Add(responsemapdata);
responsemap["6"] = responsearr;
}
else
{
responsearr = new OSDArray(avatars.Count);
foreach (ScenePresence av in avatars)
OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + av.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + av.AbsolutePosition.Y));
OSDMap responsemapdata = new OSDMap();
responsemapdata["X"] = OSD.FromInteger((int)(xstart + sp.AbsolutePosition.X));
responsemapdata["Y"] = OSD.FromInteger((int)(ystart + sp.AbsolutePosition.Y));
responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
responsemapdata["Name"] = OSD.FromString(Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()));
responsemapdata["Extra"] = OSD.FromInteger(1);
responsemapdata["Extra2"] = OSD.FromInteger(0);
responsearr.Add(responsemapdata);
}
});
responsemap["6"] = responsearr;
}
return responsemap;
@ -1107,25 +1076,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
private void MakeChildAgent(ScenePresence avatar)
{
List<ScenePresence> presences = m_scene.GetAvatars();
int rootcount = 0;
for (int i = 0; i < presences.Count; i++)
{
if (presences[i] != null)
{
if (!presences[i].IsChildAgent)
rootcount++;
}
}
if (rootcount <= 1)
StopThread();
lock (m_rootAgents)
{
if (m_rootAgents.Contains(avatar.UUID))
{
m_rootAgents.Remove(avatar.UUID);
}
m_rootAgents.Remove(avatar.UUID);
if (m_rootAgents.Count == 0)
StopThread();
}
}

View File

@ -88,12 +88,12 @@ namespace OpenSim.Region.Examples.SimpleModule
m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false);
}
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence avatar in avatars)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
avatar.AbsolutePosition =
new Vector3((float)Util.RandomClass.Next(100, 200), (float)Util.RandomClass.Next(30, 200), 2);
}
if (!sp.IsChildAgent)
sp.AbsolutePosition =
new Vector3((float)Util.RandomClass.Next(100, 200), (float)Util.RandomClass.Next(30, 200), 2);
});
}
// private void AddComplexObjects(RegionInfo regionInfo, Vector3 pos)

View File

@ -3269,7 +3269,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
ScenePresence sp = GetScenePresence(agent.AgentID);
if (sp != null)
{
m_log.DebugFormat(
@ -3561,8 +3561,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="message">message to display to the user. Reason for being logged off</param>
public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
{
ScenePresence loggingOffUser = null;
loggingOffUser = GetScenePresence(AvatarID);
ScenePresence loggingOffUser = GetScenePresence(AvatarID);
if (loggingOffUser != null)
{
UUID localRegionSecret = UUID.Zero;
@ -3598,8 +3597,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="isFlying"></param>
public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
{
ScenePresence presence;
if(m_sceneGraph.TryGetAvatar(agentID, out presence))
ScenePresence presence = GetScenePresence(agentID);
if(presence != null)
{
try
{
@ -3773,8 +3772,8 @@ namespace OpenSim.Region.Framework.Scenes
public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
Vector3 lookAt, uint teleportFlags)
{
ScenePresence sp;
if(m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp))
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
if (sp != null)
{
uint regionX = m_regInfo.RegionLocX;
uint regionY = m_regInfo.RegionLocY;
@ -3952,17 +3951,17 @@ namespace OpenSim.Region.Framework.Scenes
m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname",
"Agent ID", "Session ID", "Circuit", "IP", "World");
foreach (ScenePresence scenePresence in GetAvatars())
ForEachScenePresence(delegate(ScenePresence sp)
{
m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}",
scenePresence.Firstname,
scenePresence.Lastname,
scenePresence.UUID,
scenePresence.ControllingClient.AgentId,
sp.Firstname,
sp.Lastname,
sp.UUID,
sp.ControllingClient.AgentId,
"Unknown",
"Unknown",
RegionInfo.RegionName);
}
});
break;
}
@ -4128,72 +4127,42 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.RemovePhysicalPrim(num);
}
//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.
/// This list is a new object, so it can be iterated over without locking.
/// </summary>
/// <returns></returns>
public List<ScenePresence> GetAvatars()
public int GetRootAgentCount()
{
return m_sceneGraph.GetAvatars();
return m_sceneGraph.GetRootAgentCount();
}
public int GetChildAgentCount()
{
return m_sceneGraph.GetChildAgentCount();
}
/// <summary>
/// Return a list of all ScenePresences in this region. This returns child agents as well as root agents.
/// This list is a new object, so it can be iterated over without locking.
/// Request a scene presence by UUID. Fast, indexed lookup.
/// </summary>
/// <returns></returns>
public List<ScenePresence> GetScenePresences()
/// <param name="agentID"></param>
/// <returns>null if the presence was not found</returns>
public ScenePresence GetScenePresence(UUID agentID)
{
return m_sceneGraph.GetScenePresences();
return m_sceneGraph.GetScenePresence(agentID);
}
/// <summary>
/// Request a filtered list of ScenePresences in this region.
/// This list is a new object, so it can be iterated over without locking.
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
{
return m_sceneGraph.GetScenePresences(filter);
}
/// <summary>
/// Request a scene presence by UUID
/// </summary>
/// <param name="avatarID"></param>
/// <returns></returns>
public ScenePresence GetScenePresence(UUID 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
/// Request the scene presence by name.
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <returns></returns>
/// <returns>null if the presence was not found</returns>
public ScenePresence GetScenePresence(string firstName, string lastName)
{
return m_sceneGraph.GetScenePresence(firstName, lastName);
}
/// <summary>
/// Request the ScenePresence in this region by localID.
/// Request the scene presence by localID.
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
/// <returns>null if the presence was not found</returns>
public ScenePresence GetScenePresence(uint localID)
{
return m_sceneGraph.GetScenePresence(localID);

View File

@ -699,116 +699,84 @@ 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.
/// Request a copy of m_scenePresences in this World
/// There is no guarantee that presences will remain in the scene after the list is returned.
/// This list should remain private to SceneGraph. Callers wishing to iterate should instead
/// pass a delegate to ForEachScenePresence.
/// </summary>
/// <returns></returns>
protected internal List<ScenePresence> GetScenePresences()
private List<ScenePresence> GetScenePresences()
{
List<ScenePresence> result;
lock (m_scenePresences)
{
result = new List<ScenePresence>(m_scenePresenceArray.Length);
result.AddRange(m_scenePresenceArray);
}
return result;
return new List<ScenePresence>(m_scenePresenceArray);
}
/// <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)
{
List<ScenePresence> result = new List<ScenePresence>();
// Check each ScenePresence against the filter
ForEachScenePresence(delegate(ScenePresence presence)
{
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
/// Request a scene presence by UUID. Fast, indexed lookup.
/// </summary>
/// <param name="agentID"></param>
/// <returns>null if the agent was not found</returns>
/// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(UUID agentID)
{
ScenePresence sp;
TryGetAvatar(agentID, out sp);
lock (m_scenePresences)
{
m_scenePresences.TryGetValue(agentID, out sp);
}
return sp;
}
/// <summary>
/// Request the ScenePresence in this region by localID.
/// Request the scene presence by name.
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(string firstName, string lastName)
{
foreach (ScenePresence presence in GetScenePresences())
{
if (presence.Firstname == firstName && presence.Lastname == lastName)
return presence;
}
return null;
}
/// <summary>
/// Request the scene presence by localID.
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
/// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(uint localID)
{
return GetScenePresence(delegate(ScenePresence presence)
foreach (ScenePresence presence in GetScenePresences())
if (presence.LocalId == localID)
return presence;
return null;
}
protected internal bool TryGetAvatar(UUID agentID, out ScenePresence avatar)
{
lock (m_scenePresences)
{
return (presence.LocalId == localID);
});
m_scenePresences.TryGetValue(agentID, out avatar);
}
return (avatar != null);
}
protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
{
avatar = null;
foreach (ScenePresence presence in GetScenePresences())
{
if (String.Compare(name, presence.ControllingClient.Name, true) == 0)
{
avatar = presence;
break;
}
}
return (avatar != null);
}
/// <summary>
@ -962,24 +930,6 @@ namespace OpenSim.Region.Framework.Scenes
return group.GetChildPart(fullID);
}
protected internal bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
{
lock (m_scenePresences)
{
m_scenePresences.TryGetValue(avatarId, out avatar);
}
return (avatar != null);
}
protected internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
{
avatar = GetScenePresence(delegate(ScenePresence presence)
{
return (String.Compare(avatarName, presence.ControllingClient.Name, true) == 0);
});
return (avatar != null);
}
/// <summary>
/// Returns a list of the entities in the scene. This is a new list so no locking is required to iterate over
/// it
@ -1042,6 +992,10 @@ namespace OpenSim.Region.Framework.Scenes
return UUID.Zero;
}
/// <summary>
/// Performs action on all scene object groups.
/// </summary>
/// <param name="action"></param>
protected internal void ForEachSOG(Action<SceneObjectGroup> action)
{
List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
@ -1061,23 +1015,41 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Performs action on all scene presences.
/// Performs action on all scene presences. This can ultimately run the actions in parallel but
/// any delegates passed in will need to implement their own locking on data they reference and
/// modify outside of the scope of the delegate.
/// </summary>
/// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action)
{
List<ScenePresence> presences = GetScenePresences();
try
{
foreach(ScenePresence presence in presences)
// Once all callers have their delegates configured for parallelism, we can unleash this
/*
Action<ScenePresence> protectedAction = new Action<ScenePresence>(delegate(ScenePresence sp)
{
action(presence);
}
}
catch (Exception e)
try
{
action(sp);
}
catch (Exception e)
{
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
}
});
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
*/
// For now, perform actiona serially
foreach (ScenePresence sp in GetScenePresences())
{
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
try
{
action(sp);
}
catch (Exception e)
{
m_log.Info("[BUG] in " + m_parentScene.RegionInfo.RegionName + ": " + e.ToString());
m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
}
}
}

View File

@ -454,8 +454,10 @@ namespace OpenSim.Region.Framework.Scenes
ForEachCurrentScene(delegate(Scene scene)
{
List<ScenePresence> scenePresences = scene.GetScenePresences();
presences.AddRange(scenePresences);
scene.ForEachScenePresence(delegate(ScenePresence sp)
{
presences.Add(sp);
});
});
return presences;

View File

@ -1321,11 +1321,11 @@ namespace OpenSim.Region.Framework.Scenes
if (volume < 0)
volume = 0;
List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
foreach (ScenePresence p in avatarts)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp)
{
p.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume);
}
if(!sp.IsChildAgent)
sp.ControllingClient.SendAttachedSoundGainChange(UUID, (float)volume);
});
}
/// <summary>
@ -2609,12 +2609,13 @@ namespace OpenSim.Region.Framework.Scenes
}
}
List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
foreach (ScenePresence p in avatarts)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (!(Util.GetDistanceTo(p.AbsolutePosition, AbsolutePosition) >= 100))
p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
}
if (sp.IsChildAgent)
return;
if (!(Util.GetDistanceTo(sp.AbsolutePosition, AbsolutePosition) >= 100))
sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
});
}
public void RemFlag(PrimFlags flag)

View File

@ -2396,35 +2396,33 @@ namespace OpenSim.Region.Framework.Scenes
List<Vector3> CoarseLocations = new List<Vector3>();
List<UUID> AvatarUUIDs = new List<UUID>();
List<ScenePresence> avatars = m_scene.GetAvatars();
for (int i = 0; i < avatars.Count; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
// Requested by LibOMV. Send Course Location on self.
//if (avatars[i] != this)
//{
if (avatars[i].ParentID != 0)
if (sp.IsChildAgent)
return;
if (sp.ParentID != 0)
{
// sitting avatar
SceneObjectPart sop = m_scene.GetSceneObjectPart(sp.ParentID);
if (sop != null)
{
// sitting avatar
SceneObjectPart sop = m_scene.GetSceneObjectPart(avatars[i].ParentID);
if (sop != null)
{
CoarseLocations.Add(sop.AbsolutePosition + avatars[i].m_pos);
AvatarUUIDs.Add(avatars[i].UUID);
}
else
{
// we can't find the parent.. ! arg!
CoarseLocations.Add(avatars[i].m_pos);
AvatarUUIDs.Add(avatars[i].UUID);
}
CoarseLocations.Add(sop.AbsolutePosition + sp.m_pos);
AvatarUUIDs.Add(sp.UUID);
}
else
{
CoarseLocations.Add(avatars[i].m_pos);
AvatarUUIDs.Add(avatars[i].UUID);
// we can't find the parent.. ! arg!
CoarseLocations.Add(sp.m_pos);
AvatarUUIDs.Add(sp.UUID);
}
//}
}
}
else
{
CoarseLocations.Add(sp.m_pos);
AvatarUUIDs.Add(sp.UUID);
}
});
m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
@ -2498,13 +2496,15 @@ namespace OpenSim.Region.Framework.Scenes
m_perfMonMS = Util.EnvironmentTickCount();
// only send update from root agents to other clients; children are only "listening posts"
List<ScenePresence> avatars = m_scene.GetAvatars();
foreach (ScenePresence avatar in avatars)
int count = 0;
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
{
SendFullUpdateToOtherClient(avatar);
}
m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
if (sp.IsChildAgent)
return;
SendFullUpdateToOtherClient(sp);
++count;
});
m_scene.StatsReporter.AddAgentUpdates(count);
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
Animator.SendAnimPack();

View File

@ -318,9 +318,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
{
Scene scene = client.Scene as Scene;
m_log.DebugFormat("[Concierge]: {0} logs off from {1}", client.Name, scene.RegionInfo.RegionName);
List<ScenePresence> avs = scene.GetAvatars();
AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, avs.Count));
UpdateBroker(scene, avs);
AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, client.Name, scene.RegionInfo.RegionName, scene.GetRootAgentCount()));
UpdateBroker(scene);
}
}
@ -331,11 +330,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
{
Scene scene = agent.Scene;
m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName);
List<ScenePresence> avs = scene.GetAvatars();
WelcomeAvatar(agent, scene);
AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name,
scene.RegionInfo.RegionName, avs.Count));
UpdateBroker(scene, avs);
scene.RegionInfo.RegionName, scene.GetRootAgentCount()));
UpdateBroker(scene);
}
}
@ -346,10 +344,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
{
Scene scene = agent.Scene;
m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName);
List<ScenePresence> avs = scene.GetAvatars();
AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name,
scene.RegionInfo.RegionName, avs.Count));
UpdateBroker(scene, avs);
scene.RegionInfo.RegionName, scene.GetRootAgentCount()));
UpdateBroker(scene);
}
}
@ -368,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
}
}
protected void UpdateBroker(IScene scene, List<ScenePresence> avatars)
protected void UpdateBroker(Scene scene)
{
if (String.IsNullOrEmpty(m_brokerURI))
return;
@ -377,24 +374,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
// create XML sniplet
StringBuilder list = new StringBuilder();
if (0 == avatars.Count)
{
list.Append(String.Format("<avatars count=\"0\" region_name=\"{0}\" region_uuid=\"{1}\" timestamp=\"{2}\" />",
scene.RegionInfo.RegionName, scene.RegionInfo.RegionID,
list.Append(String.Format("<avatars count=\"{0}\" region_name=\"{1}\" region_uuid=\"{2}\" timestamp=\"{3}\">\n",
scene.GetRootAgentCount(), scene.RegionInfo.RegionName,
scene.RegionInfo.RegionID,
DateTime.UtcNow.ToString("s")));
}
else
scene.ForEachScenePresence(delegate(ScenePresence sp)
{
list.Append(String.Format("<avatars count=\"{0}\" region_name=\"{1}\" region_uuid=\"{2}\" timestamp=\"{3}\">\n",
avatars.Count, scene.RegionInfo.RegionName,
scene.RegionInfo.RegionID,
DateTime.UtcNow.ToString("s")));
foreach (ScenePresence av in avatars)
if (!sp.IsChildAgent)
{
list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", av.Name, av.UUID));
list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID));
list.Append("</avatars>");
}
list.Append("</avatars>");
}
});
string payload = list.ToString();
// post via REST to broker

View File

@ -707,36 +707,37 @@ namespace OpenSim.Region.RegionCombinerModule
return;
}
List<ScenePresence> avatars = connectiondata.RegionScene.GetAvatars();
List<Vector3> CoarseLocations = new List<Vector3>();
List<UUID> AvatarUUIDs = new List<UUID>();
for (int i = 0; i < avatars.Count; i++)
connectiondata.RegionScene.ForEachScenePresence(delegate(ScenePresence sp)
{
if (avatars[i].UUID != presence.UUID)
if (sp.IsChildAgent)
return;
if (sp.UUID != presence.UUID)
{
if (avatars[i].ParentID != 0)
if (sp.ParentID != 0)
{
// sitting avatar
SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(avatars[i].ParentID);
SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(sp.ParentID);
if (sop != null)
{
CoarseLocations.Add(sop.AbsolutePosition + avatars[i].AbsolutePosition);
AvatarUUIDs.Add(avatars[i].UUID);
CoarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition);
AvatarUUIDs.Add(sp.UUID);
}
else
{
// we can't find the parent.. ! arg!
CoarseLocations.Add(avatars[i].AbsolutePosition);
AvatarUUIDs.Add(avatars[i].UUID);
CoarseLocations.Add(sp.AbsolutePosition);
AvatarUUIDs.Add(sp.UUID);
}
}
else
{
CoarseLocations.Add(avatars[i].AbsolutePosition);
AvatarUUIDs.Add(avatars[i].UUID);
CoarseLocations.Add(sp.AbsolutePosition);
AvatarUUIDs.Add(sp.UUID);
}
}
}
});
DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
}

View File

@ -5092,7 +5092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llGetRegionAgentCount()
{
m_host.AddScriptLPS(1);
return new LSL_Integer(World.GetAvatars().Count);
return new LSL_Integer(World.GetRootAgentCount());
}
public LSL_Vector llGetRegionCorner()
@ -8771,17 +8771,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
landObject.SetMediaUrl(url);
// now send to all (non-child) agents
List<ScenePresence> agents = World.GetAvatars();
foreach (ScenePresence agent in agents)
World.ForEachScenePresence(delegate(ScenePresence sp)
{
agent.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
landData.MediaID,
landData.MediaAutoScale,
mediaType,
description,
width, height,
loop);
}
if (!sp.IsChildAgent)
{
sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
landData.MediaID,
landData.MediaAutoScale,
mediaType,
description,
width, height,
loop);
}
});
}
else if (!presence.IsChildAgent)
{
@ -8802,13 +8804,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (presence == null)
{
// send to all (non-child) agents
List<ScenePresence> agents = World.GetAvatars();
foreach (ScenePresence agent in agents)
World.ForEachScenePresence(delegate(ScenePresence sp)
{
agent.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
(ParcelMediaCommandEnum)commandToSend,
time);
}
if (!sp.IsChildAgent)
{
sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
(ParcelMediaCommandEnum)commandToSend,
time);
}
});
}
else if (!presence.IsChildAgent)
{

View File

@ -697,10 +697,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.None, "osGetAgents");
LSL_List result = new LSL_List();
foreach (ScenePresence avatar in World.GetAvatars())
World.ForEachScenePresence(delegate(ScenePresence sp)
{
result.Add(avatar.Name);
}
if (!sp.IsChildAgent)
result.Add(sp.Name);
});
return result;
}
@ -1985,19 +1986,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
{
foreach (ScenePresence presence in World.GetAvatars())
World.ForEachScenePresence(delegate(ScenePresence sp)
{
if ((presence.Firstname == FirstName) &&
presence.Lastname == SurName)
if (!sp.IsChildAgent &&
sp.Firstname == FirstName &&
sp.Lastname == SurName)
{
// kick client...
if (alert != null)
presence.ControllingClient.Kick(alert);
sp.ControllingClient.Kick(alert);
// ...and close on our side
presence.Scene.IncomingCloseAgent(presence.UUID);
sp.Scene.IncomingCloseAgent(sp.UUID);
}
}
});
}
}

View File

@ -404,70 +404,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
{
List<ScenePresence> presences;
List<SensedEntity> sensedEntities = new List<SensedEntity>();
// If this is an avatar sense by key try to get them directly
// rather than getting a list to scan through
if (ts.keyID != UUID.Zero)
{
ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID);
if (p == null)
return sensedEntities;
presences = new List<ScenePresence>();
presences.Add(p);
}
else
{
presences = new List<ScenePresence>(m_CmdManager.m_ScriptEngine.World.GetScenePresences());
}
// If nobody about quit fast
if (presences.Count == 0)
if(m_CmdManager.m_ScriptEngine.World.GetRootAgentCount() == 0)
return sensedEntities;
SceneObjectPart SensePoint = ts.host;
Vector3 fromRegionPos = SensePoint.AbsolutePosition;
Quaternion q = SensePoint.RotationOffset;
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
bool attached = (SensePoint.AttachmentPoint != 0);
bool nameSearch = (ts.name != null && ts.name != "");
Vector3 toRegionPos;
double dis;
for (int i = 0; i < presences.Count; i++)
Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
{
ScenePresence presence = presences[i];
bool keep = true;
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
return;
// if the object the script is in is attached and the avatar is the owner
// then this one is not wanted
if (attached && presence.UUID == SensePoint.OwnerID)
return;
if (presence.IsDeleted)
continue;
if (presence.IsChildAgent)
keep = false;
toRegionPos = presence.AbsolutePosition;
dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
// are they in range
if (keep && dis <= ts.range)
if (dis <= ts.range)
{
// if the object the script is in is attached and the avatar is the owner
// then this one is not wanted
if (attached && presence.UUID == SensePoint.OwnerID)
keep = false;
// check the name if needed
if (keep && nameSearch && ts.name != presence.Name)
keep = false;
// Are they in the required angle of view
if (keep && ts.arc < Math.PI)
if (ts.arc < Math.PI)
{
// not omni-directional. Can you see it ?
// vec forward_dir = llRot2Fwd(llGetRot())
@ -488,26 +458,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
catch
{
}
if (ang_obj > ts.arc) keep = false;
if (ang_obj <= ts.arc)
{
sensedEntities.Add(new SensedEntity(dis, presence.UUID));
}
}
}
else
{
keep = false;
}
});
// Do not report gods, not even minor ones
if (keep && presence.GodLevel > 0.0)
keep = false;
if (keep) // add to list with distance
{
sensedEntities.Add(new SensedEntity(dis, presence.UUID));
}
// If this is a search by name and we have just found it then no more to do
if (nameSearch && ts.name == presence.Name)
// If this is an avatar sense by key try to get them directly
// rather than getting a list to scan through
if (ts.keyID != UUID.Zero)
{
ScenePresence sp;
// Try direct lookup by UUID
if(!m_CmdManager.m_ScriptEngine.World.TryGetAvatar(ts.keyID, out sp))
return sensedEntities;
senseEntity(sp);
}
else if (ts.name != null && ts.name != "")
{
ScenePresence sp;
// Try lookup by name will return if/when found
if (!m_CmdManager.m_ScriptEngine.World.TryGetAvatarByName(ts.name, out sp))
return sensedEntities;
senseEntity(sp);
}
else
{
m_CmdManager.m_ScriptEngine.World.ForEachScenePresence(senseEntity);
}
return sensedEntities;
}

View File

@ -68,17 +68,15 @@ namespace OpenSim.Region.UserStatistics
HTMLUtil.OL_O(ref output, "");
foreach (Scene scene in all_scenes)
{
List<ScenePresence> avatarInScene = scene.GetScenePresences();
HTMLUtil.LI_O(ref output, String.Empty);
output.Append(scene.RegionInfo.RegionName);
HTMLUtil.OL_O(ref output, String.Empty);
foreach (ScenePresence av in avatarInScene)
scene.ForEachScenePresence(delegate(ScenePresence av)
{
Dictionary<string,string> queues = new Dictionary<string, string>();
Dictionary<string, string> queues = new Dictionary<string, string>();
if (av.ControllingClient is IStatsCollector)
{
IStatsCollector isClient = (IStatsCollector) av.ControllingClient;
IStatsCollector isClient = (IStatsCollector)av.ControllingClient;
queues = decodeQueueReport(isClient.Report());
}
HTMLUtil.LI_O(ref output, String.Empty);
@ -92,8 +90,8 @@ namespace OpenSim.Region.UserStatistics
else
{
output.Append(string.Format("<br /><NOBR>Position: <{0},{1},{2}></NOBR>", (int)av.AbsolutePosition.X,
(int) av.AbsolutePosition.Y,
(int) av.AbsolutePosition.Z));
(int)av.AbsolutePosition.Y,
(int)av.AbsolutePosition.Z));
}
Dictionary<string, int> throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1));
@ -124,7 +122,7 @@ namespace OpenSim.Region.UserStatistics
HTMLUtil.UL_C(ref output);
HTMLUtil.LI_C(ref output);
}
});
HTMLUtil.OL_C(ref output);
}
HTMLUtil.OL_C(ref output);