Esempio n. 1
0
        public void ResendUnacked(UDPClient client)
        {
            lock (client.NeedAcks)
            {
                List <uint> dropAck = new List <uint>();
                int         now     = Environment.TickCount;

                // Resend packets
                foreach (OutgoingPacket outgoing in client.NeedAcks.Values)
                {
                    if (outgoing.TickCount != 0 && now - outgoing.TickCount > 4000)
                    {
                        if (outgoing.ResendCount < 3)
                        {
                            Logger.DebugLog(String.Format("Resending packet #{0} ({1}), {2}ms have passed",
                                                          outgoing.Packet.Header.Sequence, outgoing.Packet.GetType(), now - outgoing.TickCount));

                            outgoing.TickCount            = Environment.TickCount;
                            outgoing.Packet.Header.Resent = true;
                            ++outgoing.ResendCount;
                            //++Stats.ResentPackets;

                            SendPacket(client, outgoing.Packet, PacketCategory.Overhead, false);
                        }
                        else
                        {
                            Logger.Log(String.Format("Dropping packet #{0} ({1}) after {2} failed attempts",
                                                     outgoing.Packet.Header.Sequence, outgoing.Packet.GetType(), outgoing.ResendCount),
                                       Helpers.LogLevel.Warning);

                            dropAck.Add(outgoing.Packet.Header.Sequence);

                            //Disconnect an agent if no packets are received for some time
                            //TODO: 60000 should be a setting somewhere.
                            if (Environment.TickCount - client.Agent.TickLastPacketReceived > 60000)
                            {
                                Logger.Log(String.Format("Ack timeout for {0}, disconnecting", client.Agent.Avatar.Name),
                                           Helpers.LogLevel.Warning);

                                server.DisconnectClient(client.Agent);
                                return;
                            }
                        }
                    }
                }

                if (dropAck.Count != 0)
                {
                    for (int i = 0; i < dropAck.Count; i++)
                    {
                        client.NeedAcks.Remove(dropAck[i]);
                    }
                }
            }
        }