diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/BukkitScheduler.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/BukkitScheduler.java new file mode 100644 index 0000000..9f40fbe --- /dev/null +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/BukkitScheduler.java @@ -0,0 +1,39 @@ +package com.turikhay.mc.mapmodcompanion.spigot; + +import org.bukkit.plugin.Plugin; + +import java.util.logging.Level; + +public class BukkitScheduler implements PluginScheduler { + private final Plugin plugin; + + public BukkitScheduler(Plugin plugin) { + this.plugin = plugin; + } + + @Override + public void cleanUp() { + } + + @Override + public void schedule(Runnable r) { + if (plugin.getServer().isPrimaryThread()) { + executeTask(r); + } else { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, () -> executeTask(r)); + } + } + + private void executeTask(Runnable r) { + try { + r.run(); + } catch (Throwable t) { + plugin.getLogger().log(Level.SEVERE, "Failed to execute the task", t); + } + } + + @Override + public String toString() { + return "BukkitScheduler{}"; + } +} diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/FoliaSupport.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/FoliaSupport.java new file mode 100644 index 0000000..4d6de4a --- /dev/null +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/FoliaSupport.java @@ -0,0 +1,18 @@ +package com.turikhay.mc.mapmodcompanion.spigot; + +public class FoliaSupport { + private static Boolean IS_FOLIA_SERVER; + + public static boolean isFoliaServer() { + if (IS_FOLIA_SERVER == null) { + boolean isIt = true; + try { + Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); + } catch (Throwable t) { + isIt = false; + } + IS_FOLIA_SERVER = isIt; + } + return IS_FOLIA_SERVER; + } +} diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/MapModCompanion.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/MapModCompanion.java index 9c61653..af35354 100644 --- a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/MapModCompanion.java +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/MapModCompanion.java @@ -38,6 +38,7 @@ public class MapModCompanion extends JavaPlugin { ); private VerboseLogger logger; + private PluginScheduler scheduler; private ScheduledExecutorService fileChangeWatchdogScheduler; private IdRegistry registry; private @Nullable ProtocolLib protocolLib; @@ -63,16 +64,18 @@ public void onLoad() { @Override public void onEnable() { + scheduler = initScheduler(); fileChangeWatchdogScheduler = FileChangeWatchdog.createScheduler(ILogger.ofJava(logger)); new Metrics(this, BSTATS_ID); saveDefaultConfig(); - load(); + scheduler.schedule(this::load); } @Override public void onDisable() { - unload(); + scheduler.schedule(this::unload); fileChangeWatchdogScheduler.shutdown(); + scheduler.cleanUp(); } private void load() { @@ -90,7 +93,7 @@ private void load() { logger, fileChangeWatchdogScheduler, getDataFolder().toPath().resolve("config.yml"), - () -> getServer().getScheduler().scheduleSyncDelayedTask(this, this::reload) + () -> scheduler.schedule(this::reload) ); fileChangeWatchdog.start(); } @@ -108,6 +111,18 @@ private void reload() { load(); } + private PluginScheduler initScheduler() { + PluginScheduler selected; + if (FoliaSupport.isFoliaServer()) { + logger.info("Folia server support enabled"); + selected = new SingleThreadScheduler(ILogger.ofJava(logger)); + } else { + selected = new BukkitScheduler(this); + } + logger.fine("Scheduler: " + selected); + return selected; + } + private IdRegistry initRegistry() { World world = null; if (getConfig().getBoolean("preferDefaultWorld", true)) { diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/PluginScheduler.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/PluginScheduler.java new file mode 100644 index 0000000..401858e --- /dev/null +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/PluginScheduler.java @@ -0,0 +1,7 @@ +package com.turikhay.mc.mapmodcompanion.spigot; + +import com.turikhay.mc.mapmodcompanion.Disposable; + +public interface PluginScheduler extends Disposable { + void schedule(Runnable r); +} diff --git a/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/SingleThreadScheduler.java b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/SingleThreadScheduler.java new file mode 100644 index 0000000..67279d5 --- /dev/null +++ b/spigot/src/main/java/com/turikhay/mc/mapmodcompanion/spigot/SingleThreadScheduler.java @@ -0,0 +1,36 @@ +package com.turikhay.mc.mapmodcompanion.spigot; + +import com.turikhay.mc.mapmodcompanion.DaemonThreadFactory; +import com.turikhay.mc.mapmodcompanion.ILogger; + +import java.util.concurrent.ScheduledThreadPoolExecutor; + +public class SingleThreadScheduler implements PluginScheduler { + + private final ScheduledThreadPoolExecutor service; + + public SingleThreadScheduler(ILogger logger) { + this.service = new ScheduledThreadPoolExecutor( + 1, + new DaemonThreadFactory(logger, SingleThreadScheduler.class) + ); + service.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + } + + @Override + public void cleanUp() { + service.shutdown(); + } + + @Override + public void schedule(Runnable r) { + service.submit(r); + } + + @Override + public String toString() { + return "SingleThreadScheduler{" + + "service=" + service + + '}'; + } +}