90 lines
3.6 KiB
C#
90 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Net;
|
|
using System.Threading.Tasks;
|
|
using Mistox.ResevedPackets;
|
|
|
|
namespace Mistox.Server {
|
|
|
|
public class MistoxServer {
|
|
|
|
// Class Definitions
|
|
|
|
public string ServerName { get; private set; } = ""; // The name of the server
|
|
public int MaxClients { get; set; } = 10; // The max players per server
|
|
public float ConnectionRange { get; set; } = 40; // InGame distance for valid conections
|
|
public string ConnectionKey { get; set; } = ""; // The connection key for the server
|
|
public int ConnectionTimeoutSeconds { get; set; } = 10; // If no reply in time kill the connection
|
|
public bool Alive { get; set; } = true; // Is the server running
|
|
public ConcurrentDictionary<string, ServerConnection> Connections; // All the active connections. key is username
|
|
|
|
private readonly ServerListener Listener; // The Connection Listener singleton
|
|
|
|
public MistoxServer(IPEndPoint ListenerAddress, string serverName) {
|
|
Connections = new ConcurrentDictionary<string, ServerConnection>();
|
|
ServerName = serverName;
|
|
Listener = new ServerListener(ListenerAddress, this);
|
|
Console.WriteLine( "The Server is initilized and waiting for clients to connect at port : " + ListenerAddress.Port );
|
|
}
|
|
|
|
|
|
async Task ProcessAuthRequest(ServerConnection user, UserAuthPacket packet) {
|
|
packet.ServerName = ServerName;
|
|
if (packet.ConnectionKey == ConnectionKey) {
|
|
packet.AuthSuccessful = 1;
|
|
Connections.TryRemove(user.UserName, out _);
|
|
user.UserName = packet.UserName;
|
|
Connections[packet.UserName] = user;
|
|
user.IsAuthenticated = true;
|
|
} else {
|
|
packet.AuthSuccessful = -1;
|
|
}
|
|
await SendClient(packet.UserName, packet);
|
|
}
|
|
|
|
// Functions
|
|
|
|
public event Action<ServerConnection> onUserConnected;
|
|
public void InvokeUserConnected( ServerConnection user ){
|
|
onUserConnected?.Invoke( user );
|
|
}
|
|
|
|
public event Action<ServerConnection, dynamic> onDataReceived;
|
|
public void InvokeDataReceived( ServerConnection user, dynamic data ){
|
|
switch (data as object) {
|
|
case UserAuthPacket packet:
|
|
if (!user.IsAuthenticated) {
|
|
Task.Run(async () => {
|
|
try {
|
|
await ProcessAuthRequest(user, packet);
|
|
} catch {}
|
|
});
|
|
}
|
|
break;
|
|
case null:
|
|
Console.WriteLine("Received a null packet.");
|
|
break;
|
|
default:
|
|
onDataReceived?.Invoke(user, data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public event Action<ServerConnection> onUserDisconnected;
|
|
public void InvokeUserDisconnected( ServerConnection user ){
|
|
onUserDisconnected?.Invoke( user );
|
|
}
|
|
|
|
public async Task SendAllClients<Packet>(Packet data) {
|
|
foreach( ServerConnection cur in Connections.Values ) {
|
|
await cur.Send(data);
|
|
}
|
|
}
|
|
|
|
public async Task SendClient<Packet>(string UserName, Packet data) {
|
|
await Connections[UserName].Send( data );
|
|
}
|
|
}
|
|
|
|
}
|