diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 11115976a..88fd7e333 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -617,12 +617,17 @@ public final class MinecraftServer { Check.stateCondition(!initialized, "#start can only be called after #init"); Check.stateCondition(started, "The server is already started"); + extensionManager.start(); + extensionManager.gotoPreInit(); + MinecraftServer.started = true; LOGGER.info("Starting Minestom server."); updateManager.start(); + extensionManager.gotoInit(); + // Init server try { server.init(new InetSocketAddress(address, port)); @@ -630,24 +635,11 @@ public final class MinecraftServer { e.printStackTrace(); } - if (extensionManager.shouldLoadOnStartup()) { - final long loadStartTime = System.nanoTime(); - // Load extensions - extensionManager.loadExtensions(); - // Init extensions - extensionManager.getExtensions().forEach(Extension::preInitialize); - extensionManager.getExtensions().forEach(Extension::initialize); - extensionManager.getExtensions().forEach(Extension::postInitialize); - - final double loadTime = MathUtils.round((System.nanoTime() - loadStartTime) / 1_000_000D, 2); - LOGGER.info("Extensions loaded in {}ms", loadTime); - } else { - LOGGER.warn("Extension loadOnStartup option is set to false, extensions are therefore neither loaded or initialized."); - } - // Start server server.start(); + extensionManager.gotoPostInit(); + LOGGER.info("Minestom server started successfully."); if (terminalEnabled) { diff --git a/src/main/java/net/minestom/server/extensions/ExtensionManager.java b/src/main/java/net/minestom/server/extensions/ExtensionManager.java index 7b8775407..3bbdd296d 100644 --- a/src/main/java/net/minestom/server/extensions/ExtensionManager.java +++ b/src/main/java/net/minestom/server/extensions/ExtensionManager.java @@ -9,6 +9,7 @@ import net.minestom.server.event.Event; import net.minestom.server.event.EventNode; import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -40,10 +41,7 @@ public class ExtensionManager { private final File extensionFolder = new File("extensions"); private final File dependenciesFolder = new File(extensionFolder, ".libs"); private Path extensionDataRoot = extensionFolder.toPath(); - private boolean loaded; - - // Option - private boolean loadOnStartup = true; + private int state = 0; // -1=do not start, 0=not started, 1=started, 2=preinit, 3=init, 4=postinit public ExtensionManager() { } @@ -56,7 +54,7 @@ public class ExtensionManager { * @return true if extensions are loaded in {@link net.minestom.server.MinecraftServer#start(String, int, ResponseDataConsumer)} */ public boolean shouldLoadOnStartup() { - return loadOnStartup; + return state != -1; } /** @@ -67,7 +65,8 @@ public class ExtensionManager { * @param loadOnStartup true to load extensions on startup, false to do nothing */ public void setLoadOnStartup(boolean loadOnStartup) { - this.loadOnStartup = loadOnStartup; + Check.stateCondition(state < 1, "Extensions have already been initialized"); + this.state = loadOnStartup ? 0 : -1; } @NotNull @@ -97,6 +96,45 @@ public class ExtensionManager { return extensions.containsKey(name); } + // + // Init phases + // + + @ApiStatus.Internal + public void start() { + if (state == -1) { + LOGGER.warn("Extension loadOnStartup option is set to false, extensions are therefore neither loaded or initialized."); + return; + } + Check.stateCondition(state != 0, "ExtensionManager has already been started"); + loadExtensions(); + state = 1; + } + + @ApiStatus.Internal + public void gotoPreInit() { + if (state == -1) return; + Check.stateCondition(state != 1, "Extensions have already done pre initialization"); + extensions.values().forEach(Extension::preInitialize); + state = 2; + } + + @ApiStatus.Internal + public void gotoInit() { + if (state == -1) return; + Check.stateCondition(state != 2, "Extensions have already done initialization"); + extensions.values().forEach(Extension::initialize); + state = 3; + } + + @ApiStatus.Internal + public void gotoPostInit() { + if (state == -1) return; + Check.stateCondition(state != 3, "Extensions have already done post initialization"); + extensions.values().forEach(Extension::postInitialize); + state = 4; + } + // // Loading // @@ -143,10 +181,7 @@ public class ExtensionManager { *

* And finally make a scheduler to clean observers per extension. */ - public void loadExtensions() { - Check.stateCondition(loaded, "Extensions are already loaded!"); - this.loaded = true; - + private void loadExtensions() { // Initialize folders { // Make extensions folder if necessary diff --git a/src/test/java/testextension/TestExtension.java b/src/test/java/testextension/TestExtension.java index 3d2d72685..765678704 100644 --- a/src/test/java/testextension/TestExtension.java +++ b/src/test/java/testextension/TestExtension.java @@ -1,8 +1,17 @@ package testextension; +import net.minestom.server.MinecraftServer; import net.minestom.server.extensions.Extension; public class TestExtension extends Extension { + + @Override + public void preInitialize() { + System.out.println("During preinit"); + MinecraftServer.setTerminalEnabled(false); + System.out.println("Mwahaha i disabled the terminal"); + } + @Override public void initialize() { System.out.println("Hello from extension!");