diff --git a/MistoxServer/Client/Entities/MistoxServerClient.cs b/MistoxServer/Client/Entities/MistoxServerClient.cs new file mode 100644 index 0000000..86f69e0 --- /dev/null +++ b/MistoxServer/Client/Entities/MistoxServerClient.cs @@ -0,0 +1,24 @@ +using System; + +namespace Mistox.Client { + + public class MistoxServerClient { + public string ServerName { get; set; } = ""; // The Name of the server + public bool Alive { get; set; } = true; // Is the server running + public int Port { get; set; } = 9126; // What Port to bind on + + public event EventHandler onUserConnected; + public void InvokeOnUserConnected(UDPEndpoint ConnectedUser){ + onUserConnected?.Invoke(ConnectedUser, new EventArgs()); + } + public event EventHandler onReceived; + public void InvokeOnReceived(dynamic DataPacket){ + onReceived?.Invoke(DataPacket, new EventArgs()); + } + public event EventHandler onUserDisconnected; + public void InvokeOnUserDisconnected(UDPEndpoint DisconnectedUser){ + onUserDisconnected?.Invoke(DisconnectedUser, new EventArgs()); + } + } + +} diff --git a/MistoxServer/Client/Entities/UDPEndpoint.cs b/MistoxServer/Client/Entities/UDPEndpoint.cs new file mode 100644 index 0000000..c5b003d --- /dev/null +++ b/MistoxServer/Client/Entities/UDPEndpoint.cs @@ -0,0 +1,10 @@ +using System.Net; + +namespace Mistox.Client { + public class UDPEndpoint { + public string UserName { get; set; } = ""; // The Players UserName + public bool Alive { get; set; } = true; // Is the connection alive + public IPEndPoint Destination { get; set; } // The IP destination for the connection + public mUDPClient Connection { get; set; } // The UDP Client Object + } +} \ No newline at end of file diff --git a/MistoxServer/Client/TCPClient.cs b/MistoxServer/Client/TCPClient.cs index 5b0a4bf..d926f85 100644 --- a/MistoxServer/Client/TCPClient.cs +++ b/MistoxServer/Client/TCPClient.cs @@ -6,23 +6,16 @@ using System.Threading.Tasks; //IP Range Updater -namespace MistoxServer.Client { +namespace Mistox.Client { public class mTCPClient : IDisposable { TcpClient Server; - public event EventHandler onConnected; - public event EventHandler onReceived; - public event EventHandler onDisconnected; - - public bool Alive; - bool notified = false; - public mTCPClient( IPEndPoint ServerAddress ) { Server = new TcpClient( AddressFamily.InterNetwork ); Server.NoDelay = true; Server.Connect( ServerAddress ); - Alive = true; + ClientInterface.ServerClientInstance.Alive = true; Thread RThread = new Thread(async () => { await ReceiveThread(); }); RThread.Start(); } @@ -30,29 +23,28 @@ namespace MistoxServer.Client { async Task ReceiveThread() { using( NetworkStream ns = Server.GetStream() ) { try { - while( Alive ) { - if( Server.Connected && !notified ) { + while( ClientInterface.ServerClientInstance.Alive ) { + if( Server.Connected ) { Console.WriteLine( "Connected to server" ); - onConnected?.Invoke( new object(), new EventArgs() ); - notified = true; + ClientInterface.ServerClientInstance.onConnected.Invoke( new object(), new EventArgs() ); } else if( !Server.Connected ) { Console.WriteLine( "Disconnected from server" ); - onDisconnected?.Invoke( new object(), new EventArgs() ); - Alive = false; + ClientInterface.ServerClientInstance.onDisconnected?.Invoke( new object(), new EventArgs() ); + ClientInterface.ServerClientInstance.Alive = false; } byte[] StreamData = new byte[1024]; int bytesRead = await ns.ReadAsync(StreamData, 0, StreamData.Length); if( bytesRead > 0 ) { dynamic data = mSerialize.tReceive( StreamData.Sub( 0, bytesRead ) ); if( data != null ) { - onReceived?.Invoke( data, new EventArgs() ); + ClientInterface.ServerClientInstance.onReceive?.Invoke( data, new EventArgs() ); } } } } catch( Exception ) { Console.WriteLine( "You have disconnected from the server" ); - onDisconnected?.Invoke( new object(), new EventArgs() ); - Alive = false; + ClientInterface.ServerClientInstance.onDisconnected?.Invoke( new object(), new EventArgs() ); + ClientInterface.ServerClientInstance.Alive = false; } } } @@ -63,7 +55,7 @@ namespace MistoxServer.Client { } public void Dispose() { - Alive = false; + ClientInterface.ServerClientInstance.Alive = false; Server.Close(); Server = null; } diff --git a/MistoxServer/Client/UDPClient.cs b/MistoxServer/Client/UDPClient.cs index cedb87e..2a02405 100644 --- a/MistoxServer/Client/UDPClient.cs +++ b/MistoxServer/Client/UDPClient.cs @@ -6,16 +6,12 @@ using System.Threading.Tasks; // Network Sync -namespace MistoxServer.Client { +namespace Mistox.Client { public class mUDPClient : IDisposable { - public event EventHandler onReceived; - Socket udpClient; - bool Alive; - int Port; - public mUDPClient( IPEndPoint ServerAddress ) { + public mUDPClient( IPEndPoint ServerAddress, string ConnectionID ) { udpClient = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp ); udpClient.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true ); udpClient.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, 128 ); diff --git a/MistoxServer/Interface/ClientInterface.cs b/MistoxServer/Interface/ClientInterface.cs index e75c853..6e43f36 100644 --- a/MistoxServer/Interface/ClientInterface.cs +++ b/MistoxServer/Interface/ClientInterface.cs @@ -1,46 +1,43 @@ using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using MistoxServer.Client; +using Mistox.Client; -namespace MistoxServer { - public class ClientInterface : IMistoxServer { +namespace Mistox { + public class ClientInterface { - mTCPClient SlowUpdate; - mUDPClient FastUpdate; - IPEndPoint mPEndPoint; + public static MistoxServerClient ServerClientInstance; + public static mTCPClient serverConnection; + public static ConcurrentDictionary clientConnections; - public event EventHandler onConnected; - public event EventHandler onSlowReceive; - public event EventHandler onFastReceive; - public event EventHandler onDisconnected; + public event EventHandler onUserConnected; + public event EventHandler onReceive; + public event EventHandler onUserDisconnected; public ClientInterface( string IpOrHostName, int Port ) { + + ServerClientInstance = new MistoxServerClient() { + Port = Port + }; + // Get Server IP IPHostEntry host = Dns.GetHostEntry( IpOrHostName ); - + IPEndPoint ServerDenstination = new IPEndPoint(0, 0); foreach( IPAddress entry in host.AddressList ) { if ( entry.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ) { - mPEndPoint = new IPEndPoint( entry, Port ); + ServerDenstination = new IPEndPoint( entry, Port ); } } - - Console.WriteLine( "The client is initilized and trying to connect to the server at ip : " + mPEndPoint.Address ); - // Make a UDP connection to the server - try { - FastUpdate = new mUDPClient( mPEndPoint ); - FastUpdate.onReceived += (object o, EventArgs e) => { onFastReceive?.Invoke( o, e ); }; - } catch( Exception e ) { - Console.WriteLine( "An error has occured with the connection to the server. Error { " ); - Console.WriteLine( e.ToString() ); - Console.WriteLine( "}" ); - } + Console.WriteLine( "The client is initilized and trying to connect to the server at ip : " + ServerDenstination.Address ); + // Make a TCP connection to the server try { - SlowUpdate = new mTCPClient( mPEndPoint ); - SlowUpdate.onConnected += ( object o, EventArgs e ) => { onConnected?.Invoke( o, e ); }; - SlowUpdate.onReceived += ( object o, EventArgs e ) => { onSlowReceive?.Invoke( o, e ); }; - SlowUpdate.onDisconnected += ( object o, EventArgs e ) => { onDisconnected?.Invoke( o, e ); }; + serverConnection = new mTCPClient( ServerDenstination ); + serverConnection.on += + serverConnection.onReceive += ( object o, EventArgs e ) => { onReceive?.Invoke( o, e ); }; + serverConnection.onDisconnected += ( object o, EventArgs e ) => { onUserDisconnected?.Invoke( o, e ); }; } catch( Exception e ) { Console.WriteLine( "An error has occured with the connection to the server. Error { " ); Console.WriteLine( e.ToString() ); @@ -48,12 +45,18 @@ namespace MistoxServer { } } - public async Task Send(Packet data, SendType speed) { - if (SendType.SlowUpdate == speed) { - await SlowUpdate.Send( data ); - } else { - await FastUpdate.Send( data, mPEndPoint ); + public async Task SendAllClients(Packet data) { + foreach(KeyValuePair cur in clientConnections){ + await cur.Value.Connection.Send( data, cur.Value.Destination ); } } + + public async Task SendClient(string UserName, Packet data) { + await clientConnections[UserName].Connection.Send( data, clientConnections[UserName].Destination ); + } + + public async Task SendServer(Packet data) { + await serverConnection.Send( data ); + } } } diff --git a/MistoxServer/Interface/Interface.cs b/MistoxServer/Interface/Interface.cs index 061a291..4d783dc 100644 --- a/MistoxServer/Interface/Interface.cs +++ b/MistoxServer/Interface/Interface.cs @@ -4,12 +4,12 @@ using System.Net; namespace Mistox { public class mServer { - public static ServerInterface newServer(int port, string serverName) { + public static ServerInterface newServer( string serverName, int port ) { DataPacket.BuildNetworkPacketList(); return new ServerInterface(port, serverName); } - public static ClientInterface newClient(string ServerIPOrHostName, int Port) { + public static ClientInterface newClient( string ServerIPOrHostName, int Port ) { DataPacket.BuildNetworkPacketList(); int index = 0; IPAddress[] remoteAddress = Dns.GetHostAddresses(ServerIPOrHostName); diff --git a/MistoxServer/Interface/ServerInterface.cs b/MistoxServer/Interface/ServerInterface.cs index c8518e1..17c18fe 100644 --- a/MistoxServer/Interface/ServerInterface.cs +++ b/MistoxServer/Interface/ServerInterface.cs @@ -8,7 +8,9 @@ using Mistox.Server; namespace Mistox { public class ServerInterface { - MistoxServer ServerInstance; + public static MistoxServer ServerInstance; // Server Data + public static ServerListener Listener; // Server Listener + public static ConcurrentDictionary Connections; // Server Connections public event EventHandler onUserConnected; public event EventHandler onReceive; @@ -21,27 +23,29 @@ namespace Mistox { ServerName = serverName, BindAddress = IPAddress.Any, Port = port, - MaxClients = 10, - Connections = new ConcurrentDictionary() + MaxClients = 10 }; + Connections = new ConcurrentDictionary(); + + // Setup the event handlers + ServerInstance.onUserConnected += onUserConnected; + ServerInstance.onReceived += onReceive; + ServerInstance.onUserDisconnected += onUserDisconnected; // Start listening for connections and wire up the server - ServerInstance.serverListener = new ServerListener( ServerInstance ); - ServerInstance.serverListener.onConnected += onUserConnected; - ServerInstance.serverListener.onReceive += onReceive; - ServerInstance.serverListener.onDisconnected += onUserDisconnected; + Listener = new ServerListener(); Console.WriteLine( "The Server is initilized and waiting for clients to connect at port : " + port ); } public async Task SendAllClients(Packet data) { - foreach( KeyValuePair cur in ServerInstance.Connections ) { + foreach( KeyValuePair cur in Connections ) { await cur.Value.Connection.Send(data); } } public async Task SendClient(string UserName, Packet data) { - await ServerInstance.Connections[UserName].Connection.Send( data ); + await Connections[UserName].Connection.Send( data ); } } } diff --git a/MistoxServer/Server/Entities/MistoxServer.cs b/MistoxServer/Server/Entities/MistoxServer.cs new file mode 100644 index 0000000..812a5dc --- /dev/null +++ b/MistoxServer/Server/Entities/MistoxServer.cs @@ -0,0 +1,27 @@ +using System; +using System.Net; + +namespace Mistox.Server { + + public class MistoxServer { + public string ServerName { get; set; } = ""; // The name of the server + public IPAddress BindAddress { get; set; } = IPAddress.Any; // What IP to bind on + public int Port { get; set; } = 9126; // What Port to bind on + public int MaxClients { get; set; } = 10; // The max players per server + public bool Alive { get; set; } = true; // Is the server running + + public event EventHandler onUserConnected; + public void InvokeOnUserConnected(TcpClientConnection ConnectedUser){ + onUserConnected?.Invoke(ConnectedUser, new EventArgs()); + } + public event EventHandler onReceived; + public void InvokeOnReceived(dynamic DataPacket){ + onReceived?.Invoke(DataPacket, new EventArgs()); + } + public event EventHandler onUserDisconnected; + public void InvokeOnUserDisconnected(TcpClientConnection DisconnectedUser){ + onUserDisconnected?.Invoke(DisconnectedUser, new EventArgs()); + } + } + +} diff --git a/MistoxServer/Server/Entities/TcpClientConnection.cs b/MistoxServer/Server/Entities/TcpClientConnection.cs new file mode 100644 index 0000000..81b0a07 --- /dev/null +++ b/MistoxServer/Server/Entities/TcpClientConnection.cs @@ -0,0 +1,16 @@ +using System; +using System.Net; +using System.Numerics; + +namespace Mistox.Server { + public class TcpClientConnection { + public string UserName { get; set; } = ""; // The Players UserName + public bool IsAuthenticated { get; set; } = false; // Has the player authenticated + public Vector3 Position { get; set; } // The ingame position of the player + public float ConnectionRange { get; set; } // The ingame distance players need to be to be connected together + public DateTime LastHeartbeat { get; set; } = DateTime.UtcNow; // Connection heartbeat for integrity + public bool Connected { get; set; } = true; // Is the connection valid + public IPAddress RemoteAddress { get; set; } // The remote users IP Address + public TCPConnection Connection { get; set; } // The TCP Server Object + } +} \ No newline at end of file diff --git a/MistoxServer/Server/ServerListener.cs b/MistoxServer/Server/ServerListener.cs index 636ca0e..b6655b5 100644 --- a/MistoxServer/Server/ServerListener.cs +++ b/MistoxServer/Server/ServerListener.cs @@ -9,45 +9,39 @@ using System.Threading.Tasks; namespace Mistox.Server { public class ServerListener : IDisposable { - public event EventHandler onConnected; - public event EventHandler onDisconnected; - public event EventHandler onReceive; + TcpListener _Listener; - MistoxServer _MistoxServer; - TcpListener Listener; - - public ServerListener( MistoxServer ServerInstance ) { - _MistoxServer = ServerInstance; + public ServerListener() { Thread ConnectionThread = new Thread(async () => await ListenerThread() ); ConnectionThread.Start(); } async Task ListenerThread() { - Listener = new TcpListener( _MistoxServer.BindAddress, _MistoxServer.Port ); - Listener.Start(); - while( _MistoxServer.Alive ) { - TcpClient client = await Listener.AcceptTcpClientAsync(); - - if (_MistoxServer.Connections.Count + 1 > _MistoxServer.MaxClients) { + _Listener = new TcpListener( ServerInterface.ServerInstance.BindAddress, ServerInterface.ServerInstance.Port ); + _Listener.Start(); + while( ServerInterface.ServerInstance.Alive ) { + TcpClient client = await _Listener.AcceptTcpClientAsync(); + + if (ServerInterface.Connections.Count + 1 > ServerInterface.ServerInstance.MaxClients) { continue; } IPEndPoint remote = client.Client.RemoteEndPoint as IPEndPoint; string connectionID = Guid.NewGuid().ToString(); - _MistoxServer.Connections[connectionID] = new TcpClientConnection() { - Connection = new TCPConnection( client, _MistoxServer, connectionID ), + ServerInterface.Connections[connectionID] = new TcpClientConnection() { + Connection = new TCPConnection( client, connectionID ), RemoteAddress = remote.Address }; Console.WriteLine( "New User Connected" ); - onConnected?.Invoke( _MistoxServer.Connections[connectionID], new EventArgs() ); + ServerInterface.ServerInstance.InvokeOnUserConnected( ServerInterface.Connections[connectionID] ); } } public void Dispose() { - Listener.Stop(); - Listener = null; + _Listener.Stop(); + _Listener = null; } } diff --git a/MistoxServer/Server/TCPConnection.cs b/MistoxServer/Server/TCPConnection.cs index 8fd6ae0..763e283 100644 --- a/MistoxServer/Server/TCPConnection.cs +++ b/MistoxServer/Server/TCPConnection.cs @@ -7,12 +7,10 @@ namespace Mistox.Server { public class TCPConnection : IDisposable { TcpClient _client; - MistoxServer _instance; string _connectionID; - public TCPConnection( TcpClient tcpClient, MistoxServer ServerInstance, string ConnectionID ) { + public TCPConnection( TcpClient tcpClient, string ConnectionID ) { _client = tcpClient; - _instance = ServerInstance; _connectionID = ConnectionID; _client.NoDelay = true; @@ -22,15 +20,15 @@ namespace Mistox.Server { } public async Task ReceiveThread() { - while( _client.Connected && _instance.Connections[_connectionID].Connected ) { + while( _client.Connected && ServerInterface.Connections[_connectionID].Connected ) { try { - _instance.Connections[_connectionID].LastHeartbeat = DateTime.UtcNow; + ServerInterface.Connections[_connectionID].LastHeartbeat = DateTime.UtcNow; byte[] StreamData = new byte[1024]; int bytesRead = await _client.GetStream().ReadAsync(StreamData, 0, StreamData.Length); if( bytesRead > 0 ) { dynamic data = mSerialize.tReceive( StreamData.Sub( 0, bytesRead ) ); if( data != null ) { - _instance.onReceived?.Invoke( data, new EventArgs() ); + ServerInterface.ServerInstance.InvokeOnReceived( data ); } } } catch( Exception ) { @@ -46,9 +44,9 @@ namespace Mistox.Server { } public void Dispose() { - _instance.Connections[_connectionID].Connected = false; - _instance.onUserDisconnected?.Invoke( _instance.Connections[_connectionID], new EventArgs() ); - _instance.Connections.TryRemove( _connectionID, out _ ); + ServerInterface.Connections[_connectionID].Connected = false; + ServerInterface.ServerInstance.InvokeOnUserDisconnected( ServerInterface.Connections[_connectionID] ); + ServerInterface.Connections.TryRemove( _connectionID, out _ ); } } } diff --git a/MistoxServer/Server/serverConnection.cs b/MistoxServer/Server/serverConnection.cs deleted file mode 100644 index 23c1ba6..0000000 --- a/MistoxServer/Server/serverConnection.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Net; - -namespace Mistox.Server { - - public class MistoxServer { - public string ServerName { get; set; } = ""; - public IPAddress BindAddress { get; set; } = IPAddress.Any; - public int Port { get; set; } = 9126; - public int MaxClients { get; set; } = 10; - public bool Alive { get; set; } = true; - public ServerListener serverListener; - public ConcurrentDictionary Connections { get; set; } - - public EventHandler onUserConnected; - public EventHandler onReceived; - public EventHandler onUserDisconnected; - } - - public class TcpClientConnection { - public string UserName { get; set; } = ""; - public bool IsAuthenticated { get; set; } = false; - public DateTime LastHeartbeat { get; set; } = DateTime.UtcNow; - public bool Connected { get; set; } = true; - public IPAddress RemoteAddress { get; set; } - public TCPConnection Connection { get; set; } - } - -}