protected override void Dispose(bool disposing) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (disposing) { #region CLEAN THIS UP // TODO: This may actually be fine here? Might want to move it into Bootstrapper though as "PrintShutdown()" Console.WriteLine(); Console.WriteLine(Strings.Commands.exiting); Console.WriteLine(); #if WEBSOCKETS Log.Info("Shutting down websockets..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); WebSocketNetwork.Stop(); #endif // Except this line, this line is fine. Log.Info("Disposing network..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); Network.Dispose(); // TODO: This probably also needs to not be a global, but will require more work to clean up. Log.Info("Saving player database..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); DbInterface.SavePlayerDatabase(Environment.StackTrace); Log.Info("Saving game database..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); DbInterface.SaveGameDatabase(); // TODO: This needs to not be a global. I'm also in the middle of rewriting the API anyway. Log.Info("Shutting down the API..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); RestApi.Dispose(); #endregion if (ThreadConsole?.IsAlive ?? false) { Log.Info("Shutting down the console thread..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); if (!ThreadConsole.Join(1000)) { try { ThreadConsole.Abort(); } catch (ThreadAbortException threadAbortException) { Log.Error(threadAbortException, $"{nameof(ThreadConsole)} aborted."); } } } if (ThreadLogic?.IsAlive ?? false) { Log.Info("Shutting down the logic thread..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); if (!ThreadLogic.Join(10000)) { try { ThreadLogic.Abort(); } catch (ThreadAbortException threadAbortException) { Log.Error(threadAbortException, $"{nameof(ThreadLogic)} aborted."); } } } } Log.Info("Base dispose." + $" ({stopwatch.ElapsedMilliseconds}ms)"); base.Dispose(disposing); Log.Info("Finished disposing server context." + $" ({stopwatch.ElapsedMilliseconds}ms)"); Console.WriteLine(Strings.Commands.exited); }
protected override void Dispose(bool disposing) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (disposing) { #region CLEAN THIS UP // TODO: This may actually be fine here? Might want to move it into Bootstrapper though as "PrintShutdown()" Console.WriteLine(); Console.WriteLine(Strings.Commands.exiting); Console.WriteLine(); #if WEBSOCKETS Log.Info("Shutting down websockets..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); WebSocketNetwork.Stop(); #endif // Except this line, this line is fine. Log.Info("Disposing network..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); Network.Dispose(); // TODO: This probably also needs to not be a global, but will require more work to clean up. Log.Info("Saving online users/players..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); var savingTasks = new List <Task>(); foreach (var user in Database.PlayerData.User.OnlineList.ToArray()) { savingTasks.Add(Task.Run(() => user.Save())); } Task.WaitAll(savingTasks.ToArray()); // TODO: This probably also needs to not be a global, but will require more work to clean up. Log.Info("Online users/players saved." + $" ({stopwatch.ElapsedMilliseconds}ms)"); //Disconnect All Clients //Will kill their packet handling threads so we have a clean shutdown lock (Globals.ClientLock) { var clients = Globals.Clients.ToArray(); foreach (var client in clients) { client.Disconnect("Server Shutdown", true); } } // TODO: This needs to not be a global. I'm also in the middle of rewriting the API anyway. Log.Info("Shutting down the API..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); RestApi.Dispose(); #endregion if (ThreadConsole?.IsAlive ?? false) { Log.Info("Shutting down the console thread..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); if (!ThreadConsole.Join(1000)) { try { ThreadConsole.Abort(); } catch (ThreadAbortException threadAbortException) { Log.Error(threadAbortException, $"{nameof( ThreadConsole )} aborted."); } } } if (ThreadLogic?.IsAlive ?? false) { Log.Info("Shutting down the logic thread..." + $" ({stopwatch.ElapsedMilliseconds}ms)"); if (!ThreadLogic.Join(10000)) { try { ThreadLogic.Abort(); } catch (ThreadAbortException threadAbortException) { Log.Error(threadAbortException, $"{nameof( ThreadLogic )} aborted."); } } } NetworkHelper.HandlerRegistry.Dispose(); } Log.Info("Base dispose." + $" ({stopwatch.ElapsedMilliseconds}ms)"); base.Dispose(disposing); Log.Info("Finished disposing server context." + $" ({stopwatch.ElapsedMilliseconds}ms)"); Console.WriteLine(Strings.Commands.exited); System.Environment.Exit(-1); }