public void HandleNewClients() { while (!exit) { if (!listener.Pending()) { Thread.Sleep(100); continue; } Client client = new Client(listener.AcceptTcpClient()); string message = client.ReadString(); if (message.StartsWith("/")) { int paramToken = message.IndexOf(' '); if (paramToken == 0) { continue; } string command; string[] parameters = null; string parameter = ""; if (paramToken < 0) { command = message.Substring(1); } else { command = message.Substring(1, paramToken - 1); parameter = message.Substring(paramToken + 1); if (parameter.Contains(" ")) { parameters = parameter.Split(' '); } } if (command == "login" && parameters.Length == 2) { if (credentials.ContainsKey(parameters[0])) { if (credentials[parameters[0]] == parameters[1]) { clientListMutex.WaitOne(); if (clients.ContainsKey(parameters[0])) { DisconnectClient(parameters[0]); } clients.Add(parameters[0], client); clientListMutex.ReleaseMutex(); client.name = parameters[0]; client.WriteString("/accept"); Console.WriteLine("Accepted known client " + parameters[0] + '.'); client.WriteString("Welcome " + parameters[0] + "!"); MoveClientToRoom(client, rooms["global"], ""); } else { client.WriteString("Incorrect password, you've been disconnected from the server"); Console.WriteLine("Incorrect password for user: "******"Credentials unknown, do you want to make a new account? Please type \"yes\""); bool processed = false; while (!processed && !exit) { if (client.Available == 0) { continue; } string confirmationMessage = client.ReadString(); if (confirmationMessage == "yes") { credentials.Add(parameters[0], parameters[1]); clientListMutex.WaitOne(); clients.Add(parameters[0], client); clientListMutex.ReleaseMutex(); client.name = parameters[0]; client.WriteString("/accept"); Console.WriteLine("Accepted new client " + parameters[0] + '.'); client.WriteString("Welcome " + parameters[0] + "!"); MoveClientToRoom(client, rooms["global"], ""); client.timeout = 0; processed = true; } else { Console.WriteLine("Refused new account"); DisconnectClient(client); processed = true; } } } } else { client.WriteString("Something went wrong, you've been disconnected from the server"); Console.WriteLine("unknown command " + command + parameter); DisconnectClient(client); } } } }
public void UpdateClients() { stopwatch = new Stopwatch(); stopwatch.Start(); float previousFrame = 0; while (!exit) { float currentTime = stopwatch.ElapsedTicks / (float)Stopwatch.Frequency; float deltaTime = currentTime - previousFrame; previousFrame = currentTime; for (int i = 0; i < clients.Count; i++) { Client client = clients.ElementAt(i).Value; client.timeout += deltaTime; if (client.timeout > 5f) { todisconnect.Add(client.name); } } clientListMutex.WaitOne(); for (int i = 0; i < todisconnect.Count; i++) { string name = todisconnect[i]; DisconnectClient(name); } clientListMutex.ReleaseMutex(); todisconnect.Clear(); //Second big change, instead of blocking on one client, //we now process all clients IF they have data available for (int i = 0; i < clients.Count; i++) { if (i >= clients.Count || i < 0) { continue; } Client client = clients.ElementAt(i).Value; if (client.Available == 0) { continue; } string message = client.ReadString(); if (message.StartsWith("/")) { i += HandleCommand(message, client); } else { client.WriteString("You said: " + message); message = client.name + " says: " + message; if (client.room != null) { foreach (var other in client.room.clients) { if (other.Key == client.name) { continue; } other.Value.WriteString(message); } message += " in room " + client.room.name; } Console.WriteLine(message); } } foreach (string roomName in todestroy) { rooms.Remove(roomName); } //Although technically not required, now that we are no longer blocking, //it is good to cut your CPU some slack //Thread.Sleep(100); } }