protected void KillObjectHandler(object sender, PacketReceivedEventArgs e)
{
Packet packet = e.Packet;
Simulator simulator = e.Simulator;
KillObjectPacket kill = (KillObjectPacket)packet;
// Notify first, so that handler has a chance to get a
// reference from the ObjectTracker to the object being killed
uint[] killed = new uint[kill.ObjectData.Length];
for (int i = 0; i < kill.ObjectData.Length; i++)
{
OnKillObject(new KillObjectEventArgs(simulator, kill.ObjectData[i].ID));
killed[i] = kill.ObjectData[i].ID;
}
OnKillObjects(new KillObjectsEventArgs(e.Simulator, killed));
lock (simulator.ObjectsPrimitives.Dictionary)
{
List<uint> removeAvatars = new List<uint>();
List<uint> removePrims = new List<uint>();
if (Client.Settings.OBJECT_TRACKING)
{
uint localID;
for (int i = 0; i < kill.ObjectData.Length; i++)
{
localID = kill.ObjectData[i].ID;
if (simulator.ObjectsPrimitives.Dictionary.ContainsKey(localID))
removePrims.Add(localID);
foreach (KeyValuePair<uint, Primitive> prim in simulator.ObjectsPrimitives.Dictionary)
{
if (prim.Value.ParentID == localID)
{
OnKillObject(new KillObjectEventArgs(simulator, prim.Key));
removePrims.Add(prim.Key);
}
}
}
}
if (Client.Settings.AVATAR_TRACKING)
{
lock (simulator.ObjectsAvatars.Dictionary)
{
uint localID;
for (int i = 0; i < kill.ObjectData.Length; i++)
{
localID = kill.ObjectData[i].ID;
if (simulator.ObjectsAvatars.Dictionary.ContainsKey(localID))
removeAvatars.Add(localID);
List<uint> rootPrims = new List<uint>();
foreach (KeyValuePair<uint, Primitive> prim in simulator.ObjectsPrimitives.Dictionary)
{
if (prim.Value.ParentID == localID)
{
OnKillObject(new KillObjectEventArgs(simulator, prim.Key));
removePrims.Add(prim.Key);
rootPrims.Add(prim.Key);
}
}
foreach (KeyValuePair<uint, Primitive> prim in simulator.ObjectsPrimitives.Dictionary)
{
if (rootPrims.Contains(prim.Value.ParentID))
{
OnKillObject(new KillObjectEventArgs(simulator, prim.Key));
removePrims.Add(prim.Key);
}
}
}
//Do the actual removing outside of the loops but still inside the lock.
//This safely prevents the collection from being modified during a loop.
foreach (uint removeID in removeAvatars)
simulator.ObjectsAvatars.Dictionary.Remove(removeID);
}
}
if (Client.Settings.CACHE_PRIMITIVES)
{
simulator.DataPool.ReleasePrims(removePrims);
}
foreach (uint removeID in removePrims)
simulator.ObjectsPrimitives.Dictionary.Remove(removeID);
}
}