diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 6f429905d1..da30a04ab9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3824,6 +3824,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
}
+
+ ///
+ /// Requeue an EntityUpdate when it was not acknowledged by the client.
+ /// We will update the priority and put it in the correct queue, merging update flags
+ /// with any other updates that may be queued for the same entity.
+ /// The original update time is used for the merged update.
+ ///
+ private void ResendPrimUpdate(EntityUpdate update)
+ {
+ // If the update exists in priority queue, it will be updated.
+ // If it does not exist then it will be added with the current (rather than its original) priority
+ uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
+
+ lock (m_entityUpdates.SyncRoot)
+ m_entityUpdates.Enqueue(priority, update);
+ }
+
+ ///
+ /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
+ /// We will update the priority and put it in the correct queue, merging update flags
+ /// with any other updates that may be queued for the same entity.
+ /// The original update time is used for the merged update.
+ ///
+ private void ResendPrimUpdates(List updates, OutgoingPacket oPacket)
+ {
+ // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
+
+ // Remove the update packet from the list of packets waiting for acknowledgement
+ // because we are requeuing the list of updates. They will be resent in new packets
+ // with the most recent state and priority.
+ m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
+
+ // Count this as a resent packet since we are going to requeue all of the updates contained in it
+ Interlocked.Increment(ref m_udpClient.PacketsResent);
+
+ // We're not going to worry about interlock yet since its not currently critical that this total count
+ // is 100% correct
+ m_udpServer.PacketsResentCount++;
+
+ foreach (EntityUpdate update in updates)
+ ResendPrimUpdate(update);
+ }
+
private void ProcessEntityUpdates(int maxUpdates)
{
OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>();
@@ -4044,7 +4087,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < blocks.Count; i++)
packet.ObjectData[i] = blocks[i];
- OutPacket(packet, ThrottleOutPacketType.Unknown, true);
+ OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
}
if (objectUpdateBlocks.IsValueCreated)
@@ -4090,8 +4133,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < blocks.Count; i++)
packet.ObjectData[i] = blocks[i];
-
- OutPacket(packet, ThrottleOutPacketType.Task, true);
+
+ OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
}
#endregion Packet Sending
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 99e7aba1d0..f66534df0e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1245,7 +1245,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int dataLength = buffer.DataLength;
// NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here
- if (!isZerocoded && !isResend)
+ if (!isZerocoded && !isResend && outgoingPacket.UnackedMethod == null)
{
// Keep appending ACKs until there is no room left in the buffer or there are
// no more ACKs to append