Merge branch 'master' into careminster-presence-refactor

This commit is contained in:
Melanie
2010-03-30 21:34:27 +01:00
75 changed files with 1160 additions and 1046 deletions

View File

@@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// Save avatar attachment information
ScenePresence presence;
if (m_scene.AvatarFactory != null && m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
if (m_scene.AvatarFactory != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
m_log.Info(
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
@@ -255,7 +255,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
AttachmentPt = att.RootPart.AttachmentPoint;
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = m_scene.InventoryService.GetItem(item);
@@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
// XXYY!!
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
@@ -314,7 +314,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient)
{
ScenePresence presence;
if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
presence.Appearance.DetachAttachment(itemID);

View File

@@ -388,7 +388,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
try
{
if (m_aScene.AuthenticationService.Authenticate(account.PrincipalID, pass, 1) != string.Empty)
string encpass = Util.Md5Hash(pass);
if (m_aScene.AuthenticationService.Authenticate(account.PrincipalID, encpass, 1) != string.Empty)
{
return account;
}

View File

@@ -358,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
{
ScenePresence presence;
if (s.TryGetAvatar(agentID, out presence))
if (s.TryGetScenePresence(agentID, out presence))
{
// If the agent is in this scene, then we
// are being called twice in a single

View File

@@ -82,7 +82,7 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
responsedata["str_response_string"] = "Request wasn't what was expected";
ScenePresence avatar;
if (!m_scene.TryGetAvatar(AgentId, out avatar))
if (!m_scene.TryGetScenePresence(AgentId, out avatar))
return responsedata;

View File

@@ -190,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (account == null) // foreign
{
ScenePresence sp = null;
if (m_Scene.TryGetAvatar(userID, out sp))
if (m_Scene.TryGetScenePresence(userID, out sp))
{
AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))

View File

@@ -1206,7 +1206,7 @@ namespace OpenSim.Region.CoreModules.InterGrid
{
Scene homeScene = GetRootScene();
ScenePresence avatar = null;
if (homeScene.TryGetAvatar(avatarId,out avatar))
if (homeScene.TryGetScenePresence(avatarId,out avatar))
{
KillAUser ku = new KillAUser(avatar,mod);
Watchdog.StartThread(ku.ShutdownNoLogout, "OGPShutdown", ThreadPriority.Normal, true);

View File

@@ -131,8 +131,8 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
{
// Start http server
// Attach xmlrpc handlers
m_log.Info("[REMOTE_DATA]: " +
"Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
m_log.Info("[XML RPC MODULE]: " +
"Starting up XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort);
httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
httpServer.Start();
@@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
// This should no longer happen, but the check is reasonable anyway
if (null == m_openChannels)
{
m_log.Warn("[RemoteDataReply] Attempt to open channel before initialization is complete");
m_log.Warn("[XML RPC MODULE]: Attempt to open channel before initialization is complete");
return newChannel;
}
@@ -279,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
}
else
{
m_log.Warn("[RemoteDataReply]: Channel or message_id not found");
m_log.Warn("[XML RPC MODULE]: Channel or message_id not found");
}
}
@@ -340,7 +340,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
}
else
{
m_log.Error("UNABLE TO REMOVE COMPLETED REQUEST");
m_log.Error("[XML RPC MODULE]: UNABLE TO REMOVE COMPLETED REQUEST");
}
}
}
@@ -728,4 +728,4 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
return ReqID;
}
}
}
}

View File

@@ -502,7 +502,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private UUID GetSessionID(UUID userID)
{
ScenePresence sp = null;
if (m_Scene.TryGetAvatar(userID, out sp))
if (m_Scene.TryGetScenePresence(userID, out sp))
{
return sp.ControllingClient.SessionId;
}
@@ -521,7 +521,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
if (account == null) // foreign user
{
ScenePresence sp = null;
m_Scene.TryGetAvatar(userID, out sp);
m_Scene.TryGetScenePresence(userID, out sp);
if (sp != null)
{
AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);

View File

@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
ScenePresence sp = null;
foreach (Scene s in m_Scenes)
{
s.TryGetAvatar(clientID, out sp);
s.TryGetScenePresence(clientID, out sp);
if ((sp != null) && !sp.IsChildAgent && (s != scene))
{
m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, but user {1} still in sim. Keeping system folders in cache",

View File

@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
Vector3 position = new Vector3(128, 128, 0);
Vector3 lookat = new Vector3(0, 1, 0);
if (client.Scene.TryGetAvatar(client.AgentId, out sp))
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
{
if (sp is ScenePresence)
{

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

@@ -199,9 +199,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;
}
@@ -382,30 +382,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

@@ -1324,9 +1324,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// Group voodoo
//
if (land.LandData.IsGroupOwned)
if (l.LandData.IsGroupOwned)
{
powers = (GroupPowers)client.GetGroupPowers(land.LandData.GroupID);
powers = (GroupPowers)client.GetGroupPowers(l.LandData.GroupID);
// Not a group member, or no rights at all
//
if (powers == (GroupPowers)0)

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

@@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// this is here because CAPS map requests work even beyond the 10,000 limit.
ScenePresence avatarPresence = null;
m_scene.TryGetAvatar(agentID, out avatarPresence);
m_scene.TryGetScenePresence(agentID, out avatarPresence);
if (avatarPresence != null)
{
@@ -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);
}
@@ -504,7 +489,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (mrs.agentID != UUID.Zero)
{
ScenePresence av = null;
m_scene.TryGetAvatar(mrs.agentID, out av);
m_scene.TryGetScenePresence(mrs.agentID, out av);
if (av != null)
{
if (response.ContainsKey(mrs.itemtype.ToString()))
@@ -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();
}
}