private void AddClient(TcpClient client) { int id = -1; try { if (maxConnections == 0 || clients.Count < maxConnections) { lock (clients) lock (releasedIds) { // Loop until an ID is found. while (id == -1) { // If there are released IDs, use one. if (releasedIds.Count > 0) { id = releasedIds[0]; if (!clients.ContainsKey(id)) { clients.Add(id, new BaseClient(id)); // Reserve this spot. releasedIds.Remove(id); } else { id = -1; continue; } } else { // Assign the next highest client ID if there's no released IDs. id = clients.Count; if (!clients.ContainsKey(id)) { clients.Add(id, new BaseClient(id)); // Reserve this spot here too. } else { id = -1; continue; } } } } clients[id].receivedData = new Packet(); clients[id].onReceived.Run += (protocol, data) => { // Convert the BaseClient to work for the server. switch (protocol) { case Protocols.TCP: clients[id].receivedData.Reset(HandleTcpData(clients[id], data)); return; case Protocols.UDP: // Extra things to do goes here. return; } }; clients[id].onConnected.Run += () => { this.UdpReady(id); }; // Clear the entry from the server. clients[id].onDisconnected.Run += () => { ClearClient(id); }; clients[id].tcp.Receive(clients[id], client); onConnection.RaiseEvent(id); return; } DebugServer(serverTypeName, $"{client.Client.RemoteEndPoint} failed to connect. Max connections of {maxConnections} reached."); } catch { // If the id was never reset. // That means that a client may still exist. // Cleanup. if (id != -1) { ClearClient(id); } } }