Run extension pre/post/init at sensible times.

This commit is contained in:
mworzala 2021-12-03 21:33:39 -05:00 committed by TheMode
parent 0491a63e0c
commit d273ff401b
3 changed files with 61 additions and 25 deletions

View File

@ -617,12 +617,17 @@ public final class MinecraftServer {
Check.stateCondition(!initialized, "#start can only be called after #init"); Check.stateCondition(!initialized, "#start can only be called after #init");
Check.stateCondition(started, "The server is already started"); Check.stateCondition(started, "The server is already started");
extensionManager.start();
extensionManager.gotoPreInit();
MinecraftServer.started = true; MinecraftServer.started = true;
LOGGER.info("Starting Minestom server."); LOGGER.info("Starting Minestom server.");
updateManager.start(); updateManager.start();
extensionManager.gotoInit();
// Init server // Init server
try { try {
server.init(new InetSocketAddress(address, port)); server.init(new InetSocketAddress(address, port));
@ -630,24 +635,11 @@ public final class MinecraftServer {
e.printStackTrace(); 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 // Start server
server.start(); server.start();
extensionManager.gotoPostInit();
LOGGER.info("Minestom server started successfully."); LOGGER.info("Minestom server started successfully.");
if (terminalEnabled) { if (terminalEnabled) {

View File

@ -9,6 +9,7 @@ import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode; import net.minestom.server.event.EventNode;
import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.ping.ResponseDataConsumer;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -40,10 +41,7 @@ public class ExtensionManager {
private final File extensionFolder = new File("extensions"); private final File extensionFolder = new File("extensions");
private final File dependenciesFolder = new File(extensionFolder, ".libs"); private final File dependenciesFolder = new File(extensionFolder, ".libs");
private Path extensionDataRoot = extensionFolder.toPath(); private Path extensionDataRoot = extensionFolder.toPath();
private boolean loaded; private int state = 0; // -1=do not start, 0=not started, 1=started, 2=preinit, 3=init, 4=postinit
// Option
private boolean loadOnStartup = true;
public ExtensionManager() { 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)} * @return true if extensions are loaded in {@link net.minestom.server.MinecraftServer#start(String, int, ResponseDataConsumer)}
*/ */
public boolean shouldLoadOnStartup() { 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 * @param loadOnStartup true to load extensions on startup, false to do nothing
*/ */
public void setLoadOnStartup(boolean loadOnStartup) { public void setLoadOnStartup(boolean loadOnStartup) {
this.loadOnStartup = loadOnStartup; Check.stateCondition(state < 1, "Extensions have already been initialized");
this.state = loadOnStartup ? 0 : -1;
} }
@NotNull @NotNull
@ -97,6 +96,45 @@ public class ExtensionManager {
return extensions.containsKey(name); 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 // Loading
// //
@ -143,10 +181,7 @@ public class ExtensionManager {
* <p> * <p>
* And finally make a scheduler to clean observers per extension. * And finally make a scheduler to clean observers per extension.
*/ */
public void loadExtensions() { private void loadExtensions() {
Check.stateCondition(loaded, "Extensions are already loaded!");
this.loaded = true;
// Initialize folders // Initialize folders
{ {
// Make extensions folder if necessary // Make extensions folder if necessary

View File

@ -1,8 +1,17 @@
package testextension; package testextension;
import net.minestom.server.MinecraftServer;
import net.minestom.server.extensions.Extension; import net.minestom.server.extensions.Extension;
public class TestExtension extends 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 @Override
public void initialize() { public void initialize() {
System.out.println("Hello from extension!"); System.out.println("Hello from extension!");