diff --git a/src/main/java/emu/grasscutter/Grasscutter.java b/src/main/java/emu/grasscutter/Grasscutter.java index a42cfa3df..c26ed3e49 100644 --- a/src/main/java/emu/grasscutter/Grasscutter.java +++ b/src/main/java/emu/grasscutter/Grasscutter.java @@ -1,8 +1,5 @@ package emu.grasscutter; -import static emu.grasscutter.config.Configuration.SERVER; -import static emu.grasscutter.utils.lang.Language.translate; - import ch.qos.logback.classic.*; import emu.grasscutter.auth.*; import emu.grasscutter.command.*; @@ -21,16 +18,20 @@ import emu.grasscutter.tools.Tools; import emu.grasscutter.utils.*; import emu.grasscutter.utils.lang.Language; import io.netty.util.concurrent.FastThreadLocalThread; -import java.io.*; -import java.util.Calendar; -import java.util.concurrent.*; -import javax.annotation.Nullable; import lombok.*; import org.jline.reader.*; import org.jline.terminal.*; import org.reflections.Reflections; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; +import java.io.*; +import java.util.Calendar; +import java.util.concurrent.*; + +import static emu.grasscutter.config.Configuration.SERVER; +import static emu.grasscutter.utils.lang.Language.translate; + public final class Grasscutter { public static final File configFile = new File("./config.json"); public static final Reflections reflector = new Reflections("emu.grasscutter"); @@ -183,6 +184,8 @@ public final class Grasscutter { private static void onShutdown() { // Disable all plugins. if (pluginManager != null) pluginManager.disablePlugins(); + // Shutdown the game server. + if (gameServer != null) gameServer.onServerShutdown(); try { // Wait for Grasscutter's thread pool to finish. diff --git a/src/main/java/emu/grasscutter/command/CommandMap.java b/src/main/java/emu/grasscutter/command/CommandMap.java index d8c70da06..82295f7cf 100644 --- a/src/main/java/emu/grasscutter/command/CommandMap.java +++ b/src/main/java/emu/grasscutter/command/CommandMap.java @@ -1,15 +1,15 @@ package emu.grasscutter.command; -import static emu.grasscutter.config.Configuration.SERVER; - import emu.grasscutter.Grasscutter; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.player.Player; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import java.util.*; +import it.unimi.dsi.fastutil.objects.*; import org.reflections.Reflections; +import java.util.*; + +import static emu.grasscutter.config.Configuration.SERVER; + @SuppressWarnings({"UnusedReturnValue", "unused"}) public final class CommandMap { private static final int INVALID_UID = Integer.MIN_VALUE; diff --git a/src/main/java/emu/grasscutter/server/game/GameServer.java b/src/main/java/emu/grasscutter/server/game/GameServer.java index 138511c2c..42e85dc22 100644 --- a/src/main/java/emu/grasscutter/server/game/GameServer.java +++ b/src/main/java/emu/grasscutter/server/game/GameServer.java @@ -1,8 +1,5 @@ package emu.grasscutter.server.game; -import static emu.grasscutter.config.Configuration.*; -import static emu.grasscutter.utils.lang.Language.translate; - import emu.grasscutter.*; import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.database.DatabaseHelper; @@ -33,13 +30,17 @@ import emu.grasscutter.server.event.types.ServerEvent; import emu.grasscutter.server.scheduler.ServerTaskScheduler; import emu.grasscutter.task.TaskMap; import emu.grasscutter.utils.Utils; +import kcp.highway.*; +import lombok.*; +import org.jetbrains.annotations.NotNull; + import java.net.*; import java.time.*; import java.util.*; import java.util.concurrent.*; -import kcp.highway.*; -import lombok.*; -import org.jetbrains.annotations.NotNull; + +import static emu.grasscutter.config.Configuration.*; +import static emu.grasscutter.utils.lang.Language.translate; @Getter public final class GameServer extends KcpServer implements Iterable { @@ -164,9 +165,6 @@ public final class GameServer extends KcpServer implements Iterable { // Chata manager this.chatManager = new ChatSystem(this); - - // Hook into shutdown event. - Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown)); } private static InetSocketAddress getAdapterInetSocketAddress() { @@ -330,11 +328,12 @@ public final class GameServer extends KcpServer implements Iterable { var event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call(); + // Save players & the world. this.getPlayers().forEach((uid, player) -> player.getSession().close()); - this.getWorlds().forEach(World::save); Utils.sleep(1000L); // Wait 1 second for operations to finish. + this.stop(); // Stop the server. try { var threadPool = GameSessionManager.getLogicThread();