diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 18d3889a62..3b26dde1fd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -40,7 +40,6 @@ using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Client; - using OpenSim.Framework.Statistics; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -353,6 +352,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected PriorityQueue m_avatarTerseUpdates; private PriorityQueue m_primTerseUpdates; private PriorityQueue m_primFullUpdates; + + /// + /// List used in construction of data blocks for an object update packet. This is to stop us having to + /// continually recreate it. + /// + protected List m_fullUpdateDataBlocksBuilder; + + /// + /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the + /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an + /// ownerless phantom. + /// + /// All manipulation of this set has to occur under a m_primFullUpdate.SyncRoot lock + /// + /// + protected HashSet m_killRecord; + private int m_moneyBalance; private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; @@ -449,6 +465,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_avatarTerseUpdates = new PriorityQueue(); m_primTerseUpdates = new PriorityQueue(); m_primFullUpdates = new PriorityQueue(m_scene.Entities.Count); + m_fullUpdateDataBlocksBuilder = new List(); + m_killRecord = new HashSet(); m_assetService = m_scene.RequestModuleInterface(); m_hyperAssets = m_scene.RequestModuleInterface(); @@ -1489,7 +1507,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP kill.ObjectData[0].ID = localID; kill.Header.Reliable = true; kill.Header.Zerocoded = true; - OutPacket(kill, ThrottleOutPacketType.State); + + lock (m_primFullUpdates.SyncRoot) + { + m_killRecord.Add(localID); + OutPacket(kill, ThrottleOutPacketType.State); + } } /// @@ -3538,21 +3561,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (count == 0) return; - outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; + m_fullUpdateDataBlocksBuilder.Clear(); + for (int i = 0; i < count; i++) { - outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); + ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); + //outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); + if (!m_killRecord.Contains(block.ID)) + { + m_fullUpdateDataBlocksBuilder.Add(block); + // string text = Util.FieldToString(outPacket.ObjectData[i].Text); // if (text.IndexOf("\n") >= 0) // text = text.Remove(text.IndexOf("\n")); // m_log.DebugFormat( // "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", // outPacket.ObjectData[i].ID, text, Name); + } +// else +// { +// m_log.WarnFormat( +// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); +// } } - } - OutPacket(outPacket, ThrottleOutPacketType.State); + outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); + + OutPacket(outPacket, ThrottleOutPacketType.State); + } } public void SendPrimTerseUpdate(SendPrimitiveTerseData data)