int totalQueuedPackets = 0; foreach (RemoteClient c in Clients) totalQueuedPackets += c.PacketQueue.Count; // Any leftover time from each client is given to any client that could use it double additionalTime = 0; foreach (RemoteClient c in Clients) { if (!c.TcpClient.Connected) { if (OnPlayerConnectionChanged != null && c.LoggedIn) OnPlayerConnectionChanged(this, new PlayerConnectionEventArgs(ConnectionState.Disconnected, c)); // Despawn } else { newClientList.Add(c); try { // Read in a packet Packet p = Packet.GetPacket((PacketID)c.TcpClient.GetStream().ReadByte(), true); p.ReadPacket(c); p.HandlePacket(this, c); // Write out from the packet queue // For the sake of server speed, each client is limited in the amount // of time per tick they are allocated for sending of packets. DateTime startTime = DateTime.Now; double maxClientSendTime = (1 / 20) * (c.PacketQueue.Count / totalQueuedPackets) + additionalTime; additionalTime = 0; while (c.PacketQueue.Count != 0 && (DateTime.Now - startTime).TotalMilliseconds <= maxClientSendTime) { } if ((DateTime.Now - startTime).TotalMilliseconds <= maxClientSendTime) { additionalTime += maxClientSendTime - (DateTime.Now - startTime).TotalMilliseconds; } } catch { if (OnPlayerConnectionChanged != null && c.LoggedIn) OnPlayerConnectionChanged(this, new PlayerConnectionEventArgs(ConnectionState.Disconnected, c)); // Despawn newClientList.RemoveAt(newClientList.Count - 1); } } } Clients = newClientList;