Add proper exit handling

This commit is contained in:
Sanae 2022-02-21 22:05:13 -06:00
parent b3bcf72283
commit 31e70a08b9
2 changed files with 52 additions and 20 deletions

View File

@ -7,7 +7,10 @@ using Timer = System.Timers.Timer;
Server.Server server = new Server.Server();
HashSet<int> shineBag = new HashSet<int>();
int shineTx = 0; // used for logging
// int shineTx = 0; // used for logging
CancellationTokenSource cts = new CancellationTokenSource();
Task listenTask = server.Listen(cts.Token);
Logger consoleLogger = new Logger("Console");
server.ClientJoined += async (c, type) => {
c.Metadata["shineSync"] = new ConcurrentBag<int>();
@ -33,8 +36,8 @@ timer.Start();
bool flipEnabled = Settings.Instance.Flip.EnabledOnStart;
float MarioSize(bool is2d) => is2d ? 180 : 160;
server.PacketHandler = (c, p) => {
Console.WriteLine($"{c.Id} {p}");
switch (p) {
case CostumePacket:
ClientSyncShineBag(c);
@ -141,13 +144,28 @@ CommandHandler.RegisterCommand("savesettings", _ => {
return "Saved settings.json";
});
Console.CancelKeyPress += (_, e) => {
e.Cancel = true;
consoleLogger.Info("Received Ctrl+C");
cts.Cancel();
};
CommandHandler.RegisterCommand("exit", _ => {
cts.Cancel();
return "Shutting down clients";
});
CommandHandler.RegisterCommand("quit", _ => {
cts.Cancel();
return "Shutting down clients";
});
Task.Run(() => {
Logger logger = new Logger("Console");
logger.Info("Run help command for valid commands.");
consoleLogger.Info("Run help command for valid commands.");
while (true) {
string? text = Console.ReadLine();
if (text != null) logger.Info(CommandHandler.GetResult(text));
if (text != null) consoleLogger.Info(CommandHandler.GetResult(text));
}
});
await server.Listen();
await listenTask;

View File

@ -15,7 +15,7 @@ public class Server {
public Func<Client, IPacket, bool>? PacketHandler = null!;
public event Action<Client, ConnectPacket> ClientJoined = null!;
public async Task Listen() {
public async Task Listen(CancellationToken? token = null) {
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
serverSocket.Bind(new IPEndPoint(IPAddress.Parse(Settings.Instance.Server.Address), Settings.Instance.Server.Port));
@ -23,24 +23,38 @@ public class Server {
Logger.Info($"Listening on {serverSocket.LocalEndPoint}");
while (true) {
Socket socket = await serverSocket.AcceptAsync();
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
try {
while (true) {
Socket socket = token.HasValue ? await serverSocket.AcceptAsync(token.Value) : await serverSocket.AcceptAsync();
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
Logger.Warn($"Accepted connection for client {socket.RemoteEndPoint}");
Logger.Warn($"Accepted connection for client {socket.RemoteEndPoint}");
try {
if (Clients.Count > Constants.MaxClients) {
Logger.Warn("Turned away client due to max clients");
await socket.DisconnectAsync(false);
continue;
try {
if (Clients.Count > Constants.MaxClients) {
Logger.Warn("Turned away client due to max clients");
await socket.DisconnectAsync(false);
continue;
}
Task.Run(() => HandleSocket(socket));
} catch {
// super ignore this
}
Task.Run(() => HandleSocket(socket));
} catch {
// super ignore this
}
} catch (OperationCanceledException) {
// ignore the exception, it's just for closing the server
}
Logger.Info("Server closing");
try {
serverSocket.Shutdown(SocketShutdown.Both);
} catch (Exception) {
// ignore
} finally {
serverSocket.Close();
}
Logger.Info("Server closed");
}
public static void FillPacket<T>(PacketHeader header, T packet, Memory<byte> memory) where T : struct, IPacket {