/// <summary> /// Shuts down the server, saving any necessary data. /// </summary> public void ShutDown(Action callback = null) { shutdownCallback = callback; if (CurThread != Thread.CurrentThread) { NeedShutdown = true; // TODO: Lock for this? return; } ShuttingDown = true; SysConsole.Output(OutputType.INFO, "[Shutdown] Starting to close server..."); Schedule.Tasks.Clear(); foreach (PlayerEntity player in Players) { player.Kick("Server shutting down."); } Object tlock = new Object(); int t = 0; int c = 0; foreach (World world in LoadedWorlds) { t++; // TODO: Thread-safer shutdown sequence! SysConsole.Output(OutputType.INFO, "[Shutdown] Unloading world: " + world.Name); world.UnloadFully(() => { lock (tlock) { c++; } }); } while (true) { lock (tlock) { if (c >= t) { break; } } Thread.Sleep(50); } LoadedWorlds.Clear(); SysConsole.Output(OutputType.INFO, "[Shutdown] Clearing plugins..."); Plugins.UnloadPlugins(); SysConsole.Output(OutputType.INFO, "[Shutdown] Closing server..."); ShutDownQuickly(); }
/// <summary> /// Shuts down the server, saving any necessary data. /// </summary> public void ShutDown(Action callback = null) { ShutdownCallback = callback; if (CurThread != Thread.CurrentThread) { NeedShutdown.Cancel(); return; } ShuttingDown = true; SysConsole.Output(OutputType.INFO, "[Shutdown] Starting to close server..."); ConsoleHandler.OnCommandInput -= CommandInputHandle; Schedule.Tasks.Clear(); foreach (PlayerEntity player in Players) { player.Kick("Server shutting down."); } Object tlock = new Object(); int t = 0; int c = 0; foreach (World world in LoadedWorlds) { t++; SysConsole.Output(OutputType.INFO, "[Shutdown] Unloading world: " + world.Name); world.UnloadFully(() => { lock (tlock) { c++; } }); } while (true) { lock (tlock) { if (c >= t) { break; } } // TODO: Max timeout? Thread.Sleep(50); } LoadedWorlds.Clear(); SysConsole.Output(OutputType.INFO, "[Shutdown] Clearing plugins..."); Plugins.UnloadPlugins(); SysConsole.Output(OutputType.INFO, "[Shutdown] Saving final data..."); long cid; lock (CIDLock) { cid = cID; } lock (SaveFileLock) { Files.WriteText("server_eid.txt", cid.ToString()); } // TODO: CVar save? SysConsole.Output(OutputType.INFO, "[Shutdown] Closing server..."); ShutDownQuickly(); }