using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace Syroot.Worms.Mgame.GameServer
{
///
/// Represents a server listening for incoming client connections and dispatching them into
/// instances.
///
internal class Server
{
// ---- FIELDS -------------------------------------------------------------------------------------------------
private readonly List _clients = new List();
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
internal Server()
{
// Create and read the configuration.
Config = new ConfigurationBuilder()
.AddJsonFile("ServerConfig.json", true)
.Build()
.Get();
}
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
internal Config Config { get; }
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()
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, Config.Port);
tcpListener.Start();
Log.Write(LogCategory.Server, $"Listening on {Config.EndPoint}...");
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();
});
}
}
}
}