public void Process() { int packetsInQueue = sendQueue.Count; for (int i = 0; i < packetsInQueue; i++) { Packet packet = sendQueue.Dequeue(); // check if the packet con be sent if (GameServer.Now >= packet.SendAfter) { packet.IncreaseAttempts(); if (GameServer.Send(packet, endPoint)) { // all fine if (packet.NeedAck) { ackTable[packet.Id] = packet; } } // on error, retry sending only if NOT OneShot else if (!packet.OneShot) { if (packet.Attempts < 3) { // retry sending after 1 second packet.SendAfter = GameServer.Now + 1.0f; sendQueue.Enqueue(packet); } } } else { // it is too early, re-enqueue the packet sendQueue.Enqueue(packet); } } // check ack table List <uint> deadPackets = new List <uint>(); foreach (uint id in ackTable.Keys) { Packet packet = ackTable[id]; if (packet.IsExpired) { if (packet.Attempts < 3) { sendQueue.Enqueue(packet); } else { deadPackets.Add(id); } } } foreach (uint id in deadPackets) { ackTable.Remove(id); } }