mirror of
https://github.com/Sanae6/SmoOnlineServer.git
synced 2024-11-25 04:35:18 +00:00
Add proper exit handling
This commit is contained in:
parent
b3bcf72283
commit
31e70a08b9
2 changed files with 52 additions and 20 deletions
|
@ -7,7 +7,10 @@ using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
Server.Server server = new Server.Server();
|
Server.Server server = new Server.Server();
|
||||||
HashSet<int> shineBag = new HashSet<int>();
|
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) => {
|
server.ClientJoined += async (c, type) => {
|
||||||
c.Metadata["shineSync"] = new ConcurrentBag<int>();
|
c.Metadata["shineSync"] = new ConcurrentBag<int>();
|
||||||
|
@ -33,8 +36,8 @@ timer.Start();
|
||||||
bool flipEnabled = Settings.Instance.Flip.EnabledOnStart;
|
bool flipEnabled = Settings.Instance.Flip.EnabledOnStart;
|
||||||
|
|
||||||
float MarioSize(bool is2d) => is2d ? 180 : 160;
|
float MarioSize(bool is2d) => is2d ? 180 : 160;
|
||||||
|
|
||||||
server.PacketHandler = (c, p) => {
|
server.PacketHandler = (c, p) => {
|
||||||
|
Console.WriteLine($"{c.Id} {p}");
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case CostumePacket:
|
case CostumePacket:
|
||||||
ClientSyncShineBag(c);
|
ClientSyncShineBag(c);
|
||||||
|
@ -141,13 +144,28 @@ CommandHandler.RegisterCommand("savesettings", _ => {
|
||||||
return "Saved settings.json";
|
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(() => {
|
Task.Run(() => {
|
||||||
Logger logger = new Logger("Console");
|
consoleLogger.Info("Run help command for valid commands.");
|
||||||
logger.Info("Run help command for valid commands.");
|
|
||||||
while (true) {
|
while (true) {
|
||||||
string? text = Console.ReadLine();
|
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;
|
|
@ -15,7 +15,7 @@ public class Server {
|
||||||
public Func<Client, IPacket, bool>? PacketHandler = null!;
|
public Func<Client, IPacket, bool>? PacketHandler = null!;
|
||||||
public event Action<Client, ConnectPacket> ClientJoined = 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);
|
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||||
serverSocket.Bind(new IPEndPoint(IPAddress.Parse(Settings.Instance.Server.Address), Settings.Instance.Server.Port));
|
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}");
|
Logger.Info($"Listening on {serverSocket.LocalEndPoint}");
|
||||||
|
|
||||||
while (true) {
|
try {
|
||||||
Socket socket = await serverSocket.AcceptAsync();
|
while (true) {
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 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 {
|
try {
|
||||||
if (Clients.Count > Constants.MaxClients) {
|
if (Clients.Count > Constants.MaxClients) {
|
||||||
Logger.Warn("Turned away client due to max clients");
|
Logger.Warn("Turned away client due to max clients");
|
||||||
await socket.DisconnectAsync(false);
|
await socket.DisconnectAsync(false);
|
||||||
continue;
|
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 {
|
public static void FillPacket<T>(PacketHeader header, T packet, Memory<byte> memory) where T : struct, IPacket {
|
||||||
|
|
Loading…
Reference in a new issue