/// <summary> /// Stats the tcplistener and accepts new connections /// </summary> public async void Start() { Logger.Log("Starting listener at " + IPAddress.Loopback + ":" + Network.PORT, "Server side"); Network.AddMessage("Server started"); listener = new TcpListener(IPAddress.Any, Network.PORT); CurrentGameState = GameState.Lobby; try { listener.Start(); Accepting = true; PingThread(); while (!Stopping) { var client = await listener.AcceptTcpClientAsync(); if (client == null) break; if (Stopping) break; var connection = new ClientConnection("newUser" + nextUserId++, client, ReceiveMessage, CloseClient); connection.StartSend(Network.MakeServerMessage(MessageType.Hello, connection)); connection.StartSend(Network.MakeServerMessage(MessageType.SettingsUpdate, MapWidth, MapHeight, UnitCap)); Logger.Log("Client connected " + connection.Name, "Server"); if (!Accepting) { connection.Close("Server is not accepting any new connections right now"); continue; } string userListMsg; lock (ClientConnections) { ClientConnections.Add(connection); userListMsg = Network.MakeServerMessage(MessageType.UserList, ClientConnections); } SendToAll(userListMsg); } } #region exception handling catch (InvalidOperationException ex) { Logger.Log("InvalidOperationException: " + ex.Message, "Server side"); } catch (SocketException ex) { Logger.Log("SocketException: " + ex.Message, "Server side"); } #endregion Accepting = false; Logger.Log("Server no longer listening", "Server side"); Network.AddMessage("Server stopped"); }
/// <summary> /// Closes the client connection /// </summary> /// <param name="client">Client to disconnect</param> /// <param name="reason">Reason of disconnecting</param> public void CloseClient(ClientConnection client, string reason) { lock (ClientConnections) { if (!ClientConnections.Contains(client)) return; ClientConnections.Remove(client); } Logger.Log("Closing client " + client.Name + ", Reason: " + reason, "Server"); client.Close(reason); if (CurrentGameState == GameState.Started && client.IngamePlayerId.HasValue) { if (Game.Players == null) return; Player player = Game.Players.FirstOrDefault(p => p.Id == client.IngamePlayerId); player.ApplyState(Player.PlayerState.Defeated); } }