using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; namespace Syroot.Worms.OnlineWorms.Server { /// /// Represents a server listening for incoming client connections and dispatching them into /// instances. /// internal class Server { // ---- FIELDS ------------------------------------------------------------------------------------------------- private readonly List _clients = new List(); // ---- PROPERTIES --------------------------------------------------------------------------------------------- internal string Name => "Online Worms Private Server"; internal string RegionName => "Global"; internal ushort Version => 114; /// /// Gets the port under which the server listens for new connections. /// internal int Port { get; private set; } internal Log Log { get; } = new Log(); // ---- METHODS (INTERNAL) ------------------------------------------------------------------------------------- /// /// Starts the server by accepting new client connections under the given and /// dispatching them into asynchronous handling threads. This call is blocking. /// /// The port on which to listen for new client connections. internal void Listen(int port) { Port = port; TcpListener tcpListener = new TcpListener(IPAddress.Any, Port); tcpListener.Start(); Log.Write(LogCategory.Server, $"Listening on port {Port}..."); while (true) { // Continually accept clients. TcpClient tcpClient = tcpListener.AcceptTcpClient(); Log.Write(LogCategory.Connect, $"{tcpClient.Client.RemoteEndPoint} connected"); Client client = new Client(tcpClient, this); _clients.Add(client); // Dispatch the client into its listening thread and remove it when listening aborts. Task.Run(client.Listen).ContinueWith(_ => { Log.Write(LogCategory.Disconnect, $"{client.TcpClient.Client.RemoteEndPoint} disconnected"); _clients.Remove(client); client.Dispose(); }); } } } }