using System; using System.Net.Sockets; using System.Threading.Tasks; using System.Net; using SBRL.Utilities; using System.IO; using System.Collections.Generic; namespace PixelHub.Server { /// /// Provides the server component of the Hull Pixelbot server that can be used to control any number of pixel bots at once. /// public class PixelHub { TextWriter logger; IPAddress bindAddress = IPAddress.Any; int port; TcpListener server; /// /// A list of PixelBots that are currently connected to the PixelHub. /// public List ConnectedBots = new List(); /// /// Whether the Hull Pixelbot serve is currently active and listening. /// public bool Active { get; private set; } = false; /// /// The IPAddress that the PixelHub is (or should be) bound to. /// /// /// You can only set this Property with generating an exception if the server /// hasn't already been started with List(). /// public IPAddress BindAddress { get { return bindAddress; } set { if (Active == true) throw new InvalidOperationException("Error: The bind address can't be changed once the server has started listening!"); bindAddress = value; } } public int Port { get { return port; } set { if (Active == true) throw new InvalidOperationException("Error: The port can't be changed once the server has started listening!"); port = value; } } public IPEndPoint Endpoint { get { return new IPEndPoint(BindAddress, Port); } } public PixelHub(int inPort, TextWriter inLogger) { Port = inPort; logger = inLogger; } public PixelHub(int inPort) : this(inPort, Console.Out) { } public async Task Listen() { server = new TcpListener(Endpoint); logger.WriteLine("TCP Listener set up on {0}.", Endpoint); Active = true; while(true) { TcpClient nextClient = await server.AcceptTcpClientAsync(); AsyncTools.ForgetTask(Handle(nextClient)); } // TODO: Add an shutdown CancellationToken thingy here //Active = false; } private async Task Handle(TcpClient client) { logger.WriteLine("Accepted connection from {0}.", client.Client.RemoteEndPoint); PixelBot pixelBot = new PixelBot(client); ConnectedBots.Add(pixelBot); await pixelBot.Handle(); ConnectedBots.Remove(pixelBot); logger.WriteLine("Lost connection from {0}.", client.Client.RemoteEndPoint); } } }