diff --git a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/CoProcessManager.java b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/CoProcessManager.java index 7023655..7e99ae5 100644 --- a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/CoProcessManager.java +++ b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/CoProcessManager.java @@ -2,31 +2,34 @@ package io.gitlab.jfronny.libjf.coprocess; import io.gitlab.jfronny.libjf.LibJf; import net.fabricmc.api.EnvType; -import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.loader.api.FabricLoader; import java.io.Closeable; import java.io.IOException; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; -public class CoProcessManager implements ModInitializer { - private final List coProcesses = new ArrayList<>(); - @Override - public void onInitialize() { +public class CoProcessManager { + private static final List coProcesses = new ArrayList<>(); + + static { coProcesses.addAll(FabricLoader.getInstance().getEntrypoints(LibJf.MOD_ID + ":coprocess", CoProcess.class)); - Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); - if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) ServerLifecycleEvents.SERVER_STOPPED.register(server -> this.stop()); - start(); + if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) ServerLifecycleEvents.SERVER_STOPPED.register(server -> CoProcessManager.stop()); + Runtime.getRuntime().addShutdownHook(new Thread(CoProcessManager::stop)); } - private void start() { + private static final AtomicBoolean started = new AtomicBoolean(false); + + public static void start() { + if (started.getAndSet(true)) return; for (CoProcess coProcess : coProcesses) { coProcess.start(); } } - private void stop() { + public static void stop() { + if (!started.getAndSet(false)) return; for (Iterator iter = coProcesses.iterator(); iter.hasNext(); ) { CoProcess coProcess = iter.next(); coProcess.stop(); diff --git a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/ThreadCoProcess.java b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/ThreadCoProcess.java index 6f8ad40..dde938e 100644 --- a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/ThreadCoProcess.java +++ b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/coprocess/ThreadCoProcess.java @@ -1,13 +1,24 @@ package io.gitlab.jfronny.libjf.coprocess; public abstract class ThreadCoProcess implements CoProcess, Runnable { + private final boolean isDaemon; private Thread th = null; private boolean closed = true; + + protected ThreadCoProcess() { + this(false); + } + + protected ThreadCoProcess(boolean isDaemon) { + this.isDaemon = isDaemon; + } + @Override public void start() { if (th != null) stop(); closed = false; th = new Thread(this, getClass().getSimpleName()); + th.setDaemon(isDaemon); th.start(); } diff --git a/libjf-base/src/main/java/io/gitlab/jfronny/libjf/mixin/MainMixin.java b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/mixin/MainMixin.java new file mode 100644 index 0000000..0e7fdcc --- /dev/null +++ b/libjf-base/src/main/java/io/gitlab/jfronny/libjf/mixin/MainMixin.java @@ -0,0 +1,27 @@ +package io.gitlab.jfronny.libjf.mixin; + +import io.gitlab.jfronny.libjf.coprocess.CoProcessManager; +import net.fabricmc.api.DedicatedServerModInitializer; +import net.minecraft.server.Main; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.MinecraftDedicatedServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Main.class) +public class MainMixin { + @Unique private static boolean libjf$started = false; + + @Inject(method = "main", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;startServer(Ljava/util/function/Function;)Lnet/minecraft/server/MinecraftServer;")) + private static void onStartServer(String[] args, CallbackInfo ci) { + libjf$started = true; + } + + @Inject(method = "main", at = @At("RETURN")) + private static void onMain(String[] args, CallbackInfo ci) { + if (!libjf$started) CoProcessManager.stop(); + } +} diff --git a/libjf-base/src/main/resources/fabric.mod.json b/libjf-base/src/main/resources/fabric.mod.json index 128bad2..750c7eb 100644 --- a/libjf-base/src/main/resources/fabric.mod.json +++ b/libjf-base/src/main/resources/fabric.mod.json @@ -18,9 +18,10 @@ "fabric-lifecycle-events-v1": "*" }, "entrypoints": { - "main": ["io.gitlab.jfronny.libjf.coprocess.CoProcessManager"], + "main": ["io.gitlab.jfronny.libjf.coprocess.CoProcessManager::start"], "preLaunch": ["io.gitlab.jfronny.libjf.LibJf"] }, + "mixins": ["libjf-base.mixins.json"], "custom": { "modmenu": { "parent": "libjf", diff --git a/libjf-base/src/main/resources/libjf-base.mixins.json b/libjf-base/src/main/resources/libjf-base.mixins.json new file mode 100644 index 0000000..ec6e540 --- /dev/null +++ b/libjf-base/src/main/resources/libjf-base.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.gitlab.jfronny.libjf.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + ], + "server": [ + "MainMixin" + ], + "injectors": { + "defaultRequire": 1 + } +}