From 715fbecd79377a04bb0617e02cb00675fdc755c9 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 28 May 2008 08:40:22 +0000 Subject: * Implements duplicate packet tracking. This virtually eliminates object duplication causing 2-3 duplicates depending on the UDP connection quality. This also eliminates duplicated chat, etc. * It's verbose currently since this is new. You'll see: [CLIENT]: Warning Duplicate packet detected X Dropping. After this is sufficiently tested we'll remove that m_log.info line. --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 65 +++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index c9a6b84..853d550 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -47,6 +47,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP { public delegate bool PacketMethod(IClientAPI simClient, Packet packet); + public class PacketDupeLimiter + { + public PacketType pktype; + public int timeIn; + public uint packetId; + public PacketDupeLimiter() + { + } + } + /// /// Handles new client connections /// Constructor takes a single Packet and authenticates everything @@ -83,6 +93,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_packetsSent = 0; private int m_lastPacketsSentSentToScene = 0; + private int m_clearDuplicatePacketTrackingOlderThenXSeconds = 30; private int m_probesWithNoIngressPackets = 0; private int m_lastPacketsReceived = 0; @@ -92,6 +103,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly uint m_circuitCode; private int m_moneyBalance; + private Dictionary m_dupeLimiter = new Dictionary(); + private int m_animationSequenceNumber = 1; private byte[] m_channelVersion = Helpers.StringToField("OpenSimulator 0.5"); // Dummy value needed by libSL @@ -3837,6 +3850,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_lastPacketsSentSentToScene = m_packetsSent; } } + protected void ClearOldPacketDupeTracking() + { + lock (m_dupeLimiter) + { + List toEliminate = new List(); + try + { + + foreach (uint seq in m_dupeLimiter.Keys) + { + PacketDupeLimiter pkdata = null; + m_dupeLimiter.TryGetValue(seq, out pkdata); + if (pkdata != null) + { + // doing a foreach loop, so we don't want to modify the dictionary while we're searching it + if (Util.UnixTimeSinceEpoch() - pkdata.timeIn > m_clearDuplicatePacketTrackingOlderThenXSeconds) + toEliminate.Add(seq); + } + } + } + catch (InvalidOperationException) + { + m_log.Info("[PACKET]: Unable to clear dupe check packet data"); + } + + // remove the dupe packets that we detected in the loop above. + uint[] seqsToRemove = toEliminate.ToArray(); + for (int i = 0; i