* 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.0.6.0-stable
parent
5752c1f5c2
commit
715fbecd79
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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<uint, PacketDupeLimiter> m_dupeLimiter = new Dictionary<uint, PacketDupeLimiter>();
|
||||
|
||||
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<uint> toEliminate = new List<uint>();
|
||||
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<seqsToRemove.Length; i++)
|
||||
{
|
||||
if (m_dupeLimiter.ContainsKey(seqsToRemove[i]))
|
||||
m_dupeLimiter.Remove(seqsToRemove[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -3866,7 +3913,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
protected void ProcessInPacket(Packet Pack)
|
||||
{
|
||||
ack_pack(Pack);
|
||||
|
||||
lock (m_dupeLimiter)
|
||||
{
|
||||
if (m_dupeLimiter.ContainsKey(Pack.Header.Sequence))
|
||||
{
|
||||
m_log.Info("[CLIENT]: Warning Duplicate packet detected" + Pack.Type.ToString() + " Dropping.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PacketDupeLimiter pkdedupe = new PacketDupeLimiter();
|
||||
pkdedupe.packetId = Pack.Header.ID;
|
||||
pkdedupe.pktype = Pack.Type;
|
||||
pkdedupe.timeIn = Util.UnixTimeSinceEpoch();
|
||||
m_dupeLimiter.Add(Pack.Header.Sequence, pkdedupe);
|
||||
}
|
||||
}
|
||||
//m_log.Info("Sequence"
|
||||
if (ProcessPacketMethod(Pack))
|
||||
{
|
||||
//there is a handler registered that handled this packet type
|
||||
|
|
Loading…
Reference in New Issue