From e059596f15c12fc148f9ae4da24fc2239fb3830d Mon Sep 17 00:00:00 2001 From: Zephrynis Date: Wed, 28 Jan 2026 23:23:54 +0000 Subject: [PATCH] Refactor ScriptManager to schedule loading and unloading of scripts on the Minecraft server's tick thread --- .../java/net/jstom/script/ScriptManager.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/jstom/script/ScriptManager.java b/src/main/java/net/jstom/script/ScriptManager.java index 8dbdec8..b63c4d1 100644 --- a/src/main/java/net/jstom/script/ScriptManager.java +++ b/src/main/java/net/jstom/script/ScriptManager.java @@ -1,5 +1,6 @@ package net.jstom.script; +import net.minestom.server.MinecraftServer; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.Source; @@ -8,6 +9,7 @@ import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.ArrayList; public class ScriptManager { private final File scriptsDir; @@ -18,6 +20,10 @@ public class ScriptManager { } public void load() { + MinecraftServer.getSchedulerManager().scheduleNextTick(this::doLoad); + } + + private void doLoad() { if (!scriptsDir.exists()) { scriptsDir.mkdirs(); } @@ -30,13 +36,14 @@ public class ScriptManager { } } - public void loadScript(File file) { + private void loadScript(File file) { String fileName = file.getName(); unloadScript(fileName); // Ensure clean slate if reloading System.out.println("[JStom] Loading script: " + fileName); ScriptApi api = new ScriptApi(); + // Context created on the Tick Thread (because loadScript is called from scheduled tasks) Context context = Context.newBuilder("js") .allowHostAccess(HostAccess.ALL) .allowHostClassLookup(s -> true) @@ -63,7 +70,7 @@ public class ScriptManager { } } - public void unloadScript(String fileName) { + private void unloadScript(String fileName) { ScriptEnv env = loadedScripts.remove(fileName); if (env != null) { env.api.cleanup(); @@ -73,24 +80,32 @@ public class ScriptManager { } public void unload() { + MinecraftServer.getSchedulerManager().scheduleNextTick(this::doUnload); + } + + private void doUnload() { // Copy keys to avoid ConcurrentModificationException - for (String fileName : new java.util.ArrayList<>(loadedScripts.keySet())) { + for (String fileName : new ArrayList<>(loadedScripts.keySet())) { unloadScript(fileName); } } public void reload() { - unload(); - load(); + MinecraftServer.getSchedulerManager().scheduleNextTick(() -> { + doUnload(); + doLoad(); + }); } public void reload(String fileName) { - File file = new File(scriptsDir, fileName); - if (file.exists()) { - loadScript(file); - } else { - System.err.println("[JStom] File not found: " + fileName); - } + MinecraftServer.getSchedulerManager().scheduleNextTick(() -> { + File file = new File(scriptsDir, fileName); + if (file.exists()) { + loadScript(file); + } else { + System.err.println("[JStom] File not found: " + fileName); + } + }); } private static class ScriptEnv { @@ -104,5 +119,4 @@ public class ScriptManager { this.file = file; } } -} - +} \ No newline at end of file