From e5c0237bcb45c5d308e0a2b763f50ac97135c768 Mon Sep 17 00:00:00 2001 From: Nahuel Dolores Date: Fri, 21 Jul 2023 11:26:44 -0300 Subject: Add support for Folia --- .../quests/bukkit/BukkitQuestsPlugin.java | 22 +++-- .../bukkit/BukkitServerSchedulerAdapter.java | 22 ----- .../bukkit/command/AdminUpdateCommandHandler.java | 2 +- .../bukkit/hook/papi/QuestsPlaceholders.java | 2 +- .../quests/bukkit/listener/PlayerJoinListener.java | 4 +- .../questcontroller/NormalQuestController.java | 2 +- .../bukkit/runnable/QuestsAutoSaveRunnable.java | 8 +- .../quests/bukkit/scheduler/ServerScheduler.java | 101 +++++++++++++++++++++ .../quests/bukkit/scheduler/WrappedRunnable.java | 65 +++++++++++++ .../quests/bukkit/scheduler/WrappedTask.java | 30 ++++++ .../bukkit/BukkitServerSchedulerAdapter.java | 64 +++++++++++++ .../bukkit/scheduler/bukkit/BukkitWrappedTask.java | 32 +++++++ .../scheduler/folia/FoliaServerScheduler.java | 90 ++++++++++++++++++ .../bukkit/scheduler/folia/FoliaWrappedTask.java | 32 +++++++ .../bukkit/tasktype/type/InventoryTaskType.java | 2 +- .../bukkit/tasktype/type/PermissionTaskType.java | 10 +- .../bukkit/tasktype/type/PlaytimeTaskType.java | 10 +- .../type/dependent/CitizensDeliverTaskType.java | 2 +- .../dependent/PlaceholderAPIEvaluateTaskType.java | 10 +- 19 files changed, 454 insertions(+), 56 deletions(-) delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitServerSchedulerAdapter.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/ServerScheduler.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedRunnable.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedTask.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitServerSchedulerAdapter.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitWrappedTask.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaServerScheduler.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaWrappedTask.java (limited to 'bukkit/src/main/java/com') diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java index 7ad3ef5e..35fd3fc8 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java @@ -30,6 +30,10 @@ import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStackRegistry; import com.leonardobishop.quests.bukkit.questcompleter.BukkitQuestCompleter; import com.leonardobishop.quests.bukkit.questcontroller.NormalQuestController; import com.leonardobishop.quests.bukkit.runnable.QuestsAutoSaveRunnable; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; +import com.leonardobishop.quests.bukkit.scheduler.bukkit.BukkitServerSchedulerAdapter; +import com.leonardobishop.quests.bukkit.scheduler.ServerScheduler; +import com.leonardobishop.quests.bukkit.scheduler.folia.FoliaServerScheduler; import com.leonardobishop.quests.bukkit.storage.MySqlStorageProvider; import com.leonardobishop.quests.bukkit.storage.YamlStorageProvider; import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskTypeManager; @@ -46,7 +50,6 @@ import com.leonardobishop.quests.common.plugin.Quests; import com.leonardobishop.quests.common.quest.QuestCompleter; import com.leonardobishop.quests.common.quest.QuestManager; import com.leonardobishop.quests.common.questcontroller.QuestController; -import com.leonardobishop.quests.common.scheduler.ServerScheduler; import com.leonardobishop.quests.common.storage.StorageProvider; import com.leonardobishop.quests.common.tasktype.TaskType; import com.leonardobishop.quests.common.tasktype.TaskTypeManager; @@ -60,7 +63,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -100,8 +102,8 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { private VersionSpecificHandler versionSpecificHandler; private LogHistory logHistory; - private BukkitTask questAutoSaveTask; - private BukkitTask questQueuePollTask; + private QuestsAutoSaveRunnable questAutoSaveTask; + private WrappedTask questQueuePollTask; private BiFunction placeholderAPIProcessor; @Override @@ -162,7 +164,9 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { this.generateConfigurations(); this.questsConfig = new BukkitQuestsConfig(new File(super.getDataFolder() + File.separator + "config.yml")); this.questManager = new QuestManager(this); - this.serverScheduler = new BukkitServerSchedulerAdapter(this); + + this.serverScheduler = FoliaServerScheduler.FOLIA ? new FoliaServerScheduler(this) : new BukkitServerSchedulerAdapter(this); + questsLogger.info("Running server scheduler: " + serverScheduler.getServerSchedulerName()); // Load base configuration for use during rest of startup procedure if (!this.reloadBaseConfiguration()) { @@ -271,7 +275,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { super.getServer().getPluginManager().registerEvents(new PlayerLeaveListener(this), this); // Register task types after the server has fully started - Bukkit.getScheduler().runTask(this, () -> { + getScheduler().doSync(() -> { // Setup external plugin hooks if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { this.placeholderAPIHook = new PlaceholderAPIHook(); @@ -448,6 +452,8 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { try { qPlayerManager.getStorageProvider().shutdown(); } catch (Exception ignored) { } + + serverScheduler.cancelAllTasks(); } @Override @@ -502,7 +508,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { long autoSaveInterval = this.getConfig().getLong("options.performance-tweaking.quest-autosave-interval", 12000); try { if (questAutoSaveTask != null) questAutoSaveTask.cancel(); - questAutoSaveTask = Bukkit.getScheduler().runTaskTimer(this, () -> new QuestsAutoSaveRunnable(this), autoSaveInterval, autoSaveInterval); + questAutoSaveTask = new QuestsAutoSaveRunnable(this, autoSaveInterval); } catch (Exception ex) { questsLogger.debug("Cannot cancel and restart quest autosave task"); } @@ -510,7 +516,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { long queueExecuteInterval = this.getConfig().getLong("options.performance-tweaking.quest-queue-executor-interval", 1); try { if (questQueuePollTask != null) questQueuePollTask.cancel(); - questQueuePollTask = Bukkit.getScheduler().runTaskTimer(this, (BukkitQuestCompleter) questCompleter, queueExecuteInterval, queueExecuteInterval); + questQueuePollTask = serverScheduler.runTaskTimer((BukkitQuestCompleter) questCompleter, queueExecuteInterval, queueExecuteInterval); } catch (Exception ex) { questsLogger.debug("Cannot cancel and restart queue executor task"); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitServerSchedulerAdapter.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitServerSchedulerAdapter.java deleted file mode 100644 index 8619642b..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitServerSchedulerAdapter.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.leonardobishop.quests.bukkit; - -import com.leonardobishop.quests.common.scheduler.ServerScheduler; - -public class BukkitServerSchedulerAdapter implements ServerScheduler { - - private final BukkitQuestsPlugin plugin; - - public BukkitServerSchedulerAdapter(BukkitQuestsPlugin plugin) { - this.plugin = plugin; - } - - @Override - public void doSync(Runnable runnable) { - plugin.getServer().getScheduler().runTask(plugin, runnable); - } - - @Override - public void doAsync(Runnable runnable) { - plugin.getServer().getScheduler().runTaskAsynchronously(plugin, runnable); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminUpdateCommandHandler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminUpdateCommandHandler.java index cbe8be3a..f899fcc4 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminUpdateCommandHandler.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminUpdateCommandHandler.java @@ -21,7 +21,7 @@ public class AdminUpdateCommandHandler implements CommandHandler { @Override public void handle(CommandSender sender, String[] args) { sender.sendMessage(ChatColor.GRAY + "Checking for updates..."); - Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + plugin.getScheduler().doAsync(() -> { plugin.getUpdater().check(); if (plugin.getUpdater().isUpdateReady()) { Messages.QUEST_UPDATER.send(sender, diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java index b19e68d8..040f8821 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java @@ -285,7 +285,7 @@ public class QuestsPlaceholders extends PlaceholderExpansion implements Cacheabl final Map map = new HashMap<>(); map.put(params, result); cache.put(player, map); - Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> cache.get(player).remove(params), plugin.getConfig().getInt("options.placeholder-cache-time", 10) * 20L); + plugin.getScheduler().runTaskLaterAsynchronously(() -> cache.get(player).remove(params), plugin.getConfig().getInt("options.placeholder-cache-time", 10) * 20L); } return result; } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/listener/PlayerJoinListener.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/listener/PlayerJoinListener.java index dbe27ffc..a1d779ae 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/listener/PlayerJoinListener.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/listener/PlayerJoinListener.java @@ -28,12 +28,12 @@ public class PlayerJoinListener implements Listener { .replace("{newver}", plugin.getUpdater().getReturnedVersion()) .replace("{oldver}", plugin.getUpdater().getInstalledVersion()) .replace("{link}", plugin.getUpdater().getUpdateLink()); - Bukkit.getScheduler().runTaskLater(this.plugin, () -> event.getPlayer().sendMessage(updateMessage), 50L); + plugin.getScheduler().runTaskLaterAtEntity(event.getPlayer(), () -> event.getPlayer().sendMessage(updateMessage), 50L); } final Player player = event.getPlayer(); plugin.getQuestsLogger().debug("PlayerJoinListener: " + player.getUniqueId() + " (" + player.getName() + ")"); - plugin.getServer().getScheduler().runTaskLater(plugin, () -> { + plugin.getScheduler().runTaskLater(() -> { if (!player.isOnline()) return; plugin.getPlayerManager().loadPlayer(player.getUniqueId()).thenAccept(qPlayer -> { if (qPlayer == null) return; diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java index a3684878..f5cacc61 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java @@ -222,7 +222,7 @@ public class NormalQuestController implements QuestController { PlayerFinishQuestEvent questFinishEvent = new PlayerFinishQuestEvent(player, qPlayer, questProgress, questFinishMessage); Bukkit.getPluginManager().callEvent(questFinishEvent); // PlayerFinishQuestEvent -- end - Bukkit.getServer().getScheduler().runTask(plugin, () -> { + plugin.getScheduler().doSync(() -> { for (String s : quest.getRewards()) { s = s.replace("{player}", player.getName()); if (plugin.getConfig().getBoolean("options.quests-use-placeholderapi")) { diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/runnable/QuestsAutoSaveRunnable.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/runnable/QuestsAutoSaveRunnable.java index 34c1a5f6..d9999a96 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/runnable/QuestsAutoSaveRunnable.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/runnable/QuestsAutoSaveRunnable.java @@ -1,27 +1,27 @@ package com.leonardobishop.quests.bukkit.runnable; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.WrappedRunnable; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; import java.util.LinkedList; import java.util.Queue; import java.util.UUID; -public class QuestsAutoSaveRunnable extends BukkitRunnable { +public class QuestsAutoSaveRunnable extends WrappedRunnable { private final Queue queue = new LinkedList<>(); private final BukkitQuestsPlugin plugin; - public QuestsAutoSaveRunnable(BukkitQuestsPlugin plugin) { + public QuestsAutoSaveRunnable(BukkitQuestsPlugin plugin, long autoSaveInterval) { for (Player player : Bukkit.getOnlinePlayers()) { queue.add(player.getUniqueId()); } this.plugin = plugin; - this.runTaskTimer(plugin, 2L, 2L); + this.runTaskTimer(plugin.getScheduler(), autoSaveInterval, autoSaveInterval); } @Override diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/ServerScheduler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/ServerScheduler.java new file mode 100644 index 00000000..79fc9306 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/ServerScheduler.java @@ -0,0 +1,101 @@ +package com.leonardobishop.quests.bukkit.scheduler; + +import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; + +public interface ServerScheduler extends com.leonardobishop.quests.common.scheduler.ServerScheduler { + + /** + * Cancel all tasks related to this server. + */ + void cancelAllTasks(); + + /** + * Cancel the provided wrapped task. + * + * @param wrappedTask Wrapped task to cancel. + */ + void cancelTask(@NotNull WrappedTask wrappedTask); + + /** + * Run a new task timer. + *

+ * Folia: Synced with the server daylight cycle tick. + *

+ * Paper: Synced with the server main thread. + * + * @param runnable Runnable to run. + * @param delay Delay before first execution. Must be greater than zero. + * @param period Delay between executions. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + WrappedTask runTaskTimer(@NotNull Runnable runnable, long delay, long period); + + /** + * Run a new task timer asynchronously. + *

+ * Folia: Run in the dedicated async thread. + *

+ * Paper: Run in the dedicated async thread. + * + * @param runnable Runnable to run. + * @param delay Delay before first execution. Must be greater than zero. + * @param period Delay between executions. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + WrappedTask runTaskTimerAsynchronously(@NotNull Runnable runnable, long delay, long period); + + /** + * Run a new task later. + *

+ * Folia: Synced with the server daylight cycle tick. + *

+ * Paper: Synced with the server main thread. + * + * @param runnable Runnable to run. + * @param delay Delay before first execution. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + WrappedTask runTaskLater(@NotNull Runnable runnable, long delay); + + /** + * Run a new task later asynchronously. + *

+ * Folia: Run in the dedicated async thread. + *

+ * Paper: Run in the dedicated async thread. + * + * @param runnable Runnable to run. + * @param delay Delay before first execution. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + WrappedTask runTaskLaterAsynchronously(@NotNull Runnable runnable, long delay); + + /** + * Run a new task later. + *

+ * Folia: Synced with the tick of the region of the entity (even if the entity moves). + *

+ * Paper: Synced with the server main thread. + * + * @param runnable Runnable to run. + * @param delay Delay before first execution. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + WrappedTask runTaskLaterAtEntity(@NotNull Entity entity, @NotNull Runnable runnable, long delay); + + /** + * Get the server scheduler name. + * + * @return {@link String} server scheduler name. + */ + @NotNull + default String getServerSchedulerName() { + return getClass().getSimpleName(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedRunnable.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedRunnable.java new file mode 100644 index 00000000..3d8377a4 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedRunnable.java @@ -0,0 +1,65 @@ +package com.leonardobishop.quests.bukkit.scheduler; + +import org.jetbrains.annotations.NotNull; + +/** + * Wrapped runnable. + */ +public abstract class WrappedRunnable implements Runnable { + + private WrappedTask wrappedTask; + + /** + * Returns true if this task has been cancelled. + * + * @return true if the task has been cancelled + * @throws IllegalStateException if task was not scheduled yet + */ + public synchronized boolean isCancelled() throws IllegalStateException { + checkScheduled(); + return wrappedTask.isCancelled(); + } + + /** + * Run a new task timer. + *

+ * Folia: Synced with the server daylight cycle tick. + *

+ * Paper: Synced with the server main thread. + * + * @param delay Delay before first execution. Must be greater than zero. + * @param period Delay between executions. Must be greater than zero. + * @return {@link WrappedTask} task reference. + */ + @NotNull + public WrappedTask runTaskTimer(@NotNull ServerScheduler serverScheduler, long delay, long period) { + return setupTask(serverScheduler.runTaskTimer(this, delay, period)); + } + + /** + * Attempts to cancel this task. + * + * @throws IllegalStateException if task was not scheduled yet + */ + public synchronized void cancel() throws IllegalStateException { + wrappedTask.cancel(); + } + + private void checkScheduled() { + if (wrappedTask == null) { + throw new IllegalStateException("Not scheduled yet"); + } + } + + private void checkNotYetScheduled() { + if (wrappedTask != null) { + throw new IllegalStateException("Task is already scheduled!"); + } + } + + @NotNull + private WrappedTask setupTask(@NotNull final WrappedTask wrappedTask) { + this.wrappedTask = wrappedTask; + return wrappedTask; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedTask.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedTask.java new file mode 100644 index 00000000..00c96b46 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedTask.java @@ -0,0 +1,30 @@ +package com.leonardobishop.quests.bukkit.scheduler; + +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +/** + * Wrapped task for the scheduler. + */ +public interface WrappedTask { + + /** + * Cancel the task. + */ + void cancel(); + + /** + * Check if the task is cancelled. + * + * @return {@code true} if it is cancelled, {@code false} otherwise. + */ + boolean isCancelled(); + + /** + * Get the owning plugin for this task. + * + * @return {@link Plugin} plugin. + */ + @NotNull + Plugin getOwningPlugin(); +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitServerSchedulerAdapter.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitServerSchedulerAdapter.java new file mode 100644 index 00000000..bc261a8d --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitServerSchedulerAdapter.java @@ -0,0 +1,64 @@ +package com.leonardobishop.quests.bukkit.scheduler.bukkit; + +import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.ServerScheduler; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; +import org.bukkit.entity.Entity; +import org.bukkit.scheduler.BukkitScheduler; +import org.jetbrains.annotations.NotNull; + +public class BukkitServerSchedulerAdapter implements ServerScheduler { + + private final BukkitQuestsPlugin plugin; + private final BukkitScheduler bukkitScheduler; + + public BukkitServerSchedulerAdapter(BukkitQuestsPlugin plugin) { + this.plugin = plugin; + this.bukkitScheduler = plugin.getServer().getScheduler(); + } + + @Override + public void cancelAllTasks() { + bukkitScheduler.cancelTasks(plugin); + } + + @Override + public void cancelTask(@NotNull WrappedTask wrappedTask) { + wrappedTask.cancel(); + } + + @Override + public @NotNull WrappedTask runTaskTimer(@NotNull Runnable runnable, long delay, long period) { + return new BukkitWrappedTask(bukkitScheduler.runTaskTimer(plugin, runnable, delay, period)); + } + + @Override + public @NotNull WrappedTask runTaskTimerAsynchronously(@NotNull Runnable runnable, long delay, long period) { + return new BukkitWrappedTask(bukkitScheduler.runTaskTimerAsynchronously(plugin, runnable, delay, period)); + } + + @Override + public @NotNull WrappedTask runTaskLater(@NotNull Runnable runnable, long delay) { + return new BukkitWrappedTask(bukkitScheduler.runTaskLater(plugin, runnable, delay)); + } + + @Override + public @NotNull WrappedTask runTaskLaterAsynchronously(@NotNull Runnable runnable, long delay) { + return new BukkitWrappedTask(bukkitScheduler.runTaskLaterAsynchronously(plugin, runnable, delay)); + } + + @Override + public @NotNull WrappedTask runTaskLaterAtEntity(@NotNull Entity entity, @NotNull Runnable runnable, long delay) { + return runTaskLater(runnable, delay); + } + + @Override + public void doSync(Runnable runnable) { + bukkitScheduler.runTask(plugin, runnable); + } + + @Override + public void doAsync(Runnable runnable) { + bukkitScheduler.runTaskAsynchronously(plugin, runnable); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitWrappedTask.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitWrappedTask.java new file mode 100644 index 00000000..9977c2f8 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitWrappedTask.java @@ -0,0 +1,32 @@ +package com.leonardobishop.quests.bukkit.scheduler.bukkit; + +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class BukkitWrappedTask implements WrappedTask { + + private final BukkitTask bukkitTask; + + public BukkitWrappedTask(@NotNull BukkitTask bukkitTask) { + this.bukkitTask = Objects.requireNonNull(bukkitTask); + } + + @Override + public void cancel() { + bukkitTask.cancel(); + } + + @Override + public boolean isCancelled() { + return bukkitTask.isCancelled(); + } + + @Override + public @NotNull Plugin getOwningPlugin() { + return bukkitTask.getOwner(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaServerScheduler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaServerScheduler.java new file mode 100644 index 00000000..d33564b5 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaServerScheduler.java @@ -0,0 +1,90 @@ +package com.leonardobishop.quests.bukkit.scheduler.folia; + +import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.ServerScheduler; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; +import io.papermc.paper.threadedregions.scheduler.AsyncScheduler; +import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler; +import io.papermc.paper.threadedregions.scheduler.RegionScheduler; +import org.bukkit.Server; +import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +public class FoliaServerScheduler implements ServerScheduler { + + public static final boolean FOLIA; + static { + boolean folia; + try { + Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); + folia = true; + } catch (ClassNotFoundException e) { + folia = false; + } + FOLIA = folia; + } + + private final BukkitQuestsPlugin plugin; + + private final GlobalRegionScheduler globalRegionScheduler; + private final AsyncScheduler asyncScheduler; + private final RegionScheduler regionScheduler; + + public FoliaServerScheduler(BukkitQuestsPlugin plugin) { + this.plugin = plugin; + + final Server server = plugin.getServer(); + this.globalRegionScheduler = server.getGlobalRegionScheduler(); + this.asyncScheduler = server.getAsyncScheduler(); + this.regionScheduler = server.getRegionScheduler(); + } + + @Override + public void cancelAllTasks() { + globalRegionScheduler.cancelTasks(plugin); + asyncScheduler.cancelTasks(plugin); + } + + @Override + public void cancelTask(@NotNull WrappedTask wrappedTask) { + wrappedTask.cancel(); + } + + @Override + public @NotNull WrappedTask runTaskTimer(@NotNull Runnable runnable, long delay, long period) { + return new FoliaWrappedTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period)); + } + + @Override + public @NotNull WrappedTask runTaskTimerAsynchronously(@NotNull Runnable runnable, long delay, long period) { + return new FoliaWrappedTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50L, period * 50L, TimeUnit.MILLISECONDS)); + } + + @Override + public @NotNull WrappedTask runTaskLater(@NotNull Runnable runnable, long delay) { + return new FoliaWrappedTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay)); + } + + @Override + public @NotNull WrappedTask runTaskLaterAsynchronously(@NotNull Runnable runnable, long delay) { + return new FoliaWrappedTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS)); + } + + @Override + public @NotNull WrappedTask runTaskLaterAtEntity(@NotNull Entity entity, @NotNull Runnable runnable, long delay) { + return new FoliaWrappedTask(Objects.requireNonNull(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), () -> {}, delay))); + } + + @Override + public void doSync(Runnable runnable) { + globalRegionScheduler.run(plugin, task -> runnable.run()); + } + + @Override + public void doAsync(Runnable runnable) { + asyncScheduler.runNow(plugin, task -> runnable.run()); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaWrappedTask.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaWrappedTask.java new file mode 100644 index 00000000..ca135c33 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaWrappedTask.java @@ -0,0 +1,32 @@ +package com.leonardobishop.quests.bukkit.scheduler.folia; + +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; +import io.papermc.paper.threadedregions.scheduler.ScheduledTask; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class FoliaWrappedTask implements WrappedTask { + + private final ScheduledTask scheduledTask; + + public FoliaWrappedTask(@NotNull ScheduledTask scheduledTask) { + this.scheduledTask = Objects.requireNonNull(scheduledTask); + } + + @Override + public void cancel() { + scheduledTask.cancel(); + } + + @Override + public boolean isCancelled() { + return scheduledTask.isCancelled(); + } + + @Override + public @NotNull Plugin getOwningPlugin() { + return scheduledTask.getOwningPlugin(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java index 93373377..cb2564b9 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java @@ -91,7 +91,7 @@ public final class InventoryTaskType extends BukkitTaskType { private void checkInventory(Player player, long delay) { if (player.hasMetadata("NPC")) return; - Bukkit.getScheduler().runTaskLater(plugin, () -> checkInventory(player), delay); + plugin.getScheduler().runTaskLaterAtEntity(player, () -> checkInventory(player), delay); } private void checkInventory(Player player) { diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PermissionTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PermissionTaskType.java index 06defd46..b389a625 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PermissionTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PermissionTaskType.java @@ -1,6 +1,8 @@ package com.leonardobishop.quests.bukkit.tasktype.type; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.WrappedRunnable; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskType; import com.leonardobishop.quests.bukkit.util.TaskUtils; import com.leonardobishop.quests.common.player.QPlayer; @@ -9,13 +11,11 @@ import com.leonardobishop.quests.common.quest.Quest; import com.leonardobishop.quests.common.quest.Task; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitTask; public final class PermissionTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private BukkitTask poll; + private WrappedTask poll; public PermissionTaskType(BukkitQuestsPlugin plugin) { super("permission", TaskUtils.TASK_ATTRIBUTION_STRING, "Test if a player has a permission"); @@ -26,7 +26,7 @@ public final class PermissionTaskType extends BukkitTaskType { @Override public void onReady() { - this.poll = new BukkitRunnable() { + this.poll = new WrappedRunnable() { @Override public void run() { for (Player player : Bukkit.getOnlinePlayers()) { @@ -55,7 +55,7 @@ public final class PermissionTaskType extends BukkitTaskType { } } } - }.runTaskTimer(plugin, 30L, 30L); + }.runTaskTimer(plugin.getScheduler(), 30L, 30L); } @Override diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PlaytimeTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PlaytimeTaskType.java index bccd7295..82377c78 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PlaytimeTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PlaytimeTaskType.java @@ -1,6 +1,8 @@ package com.leonardobishop.quests.bukkit.tasktype.type; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.WrappedRunnable; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskType; import com.leonardobishop.quests.bukkit.util.TaskUtils; import com.leonardobishop.quests.common.player.QPlayer; @@ -9,13 +11,11 @@ import com.leonardobishop.quests.common.quest.Quest; import com.leonardobishop.quests.common.quest.Task; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitTask; public final class PlaytimeTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private BukkitTask poll; + private WrappedTask poll; public PlaytimeTaskType(BukkitQuestsPlugin plugin) { super("playtime", TaskUtils.TASK_ATTRIBUTION_STRING, "Track the amount of playing time a user has been on"); @@ -29,7 +29,7 @@ public final class PlaytimeTaskType extends BukkitTaskType { @Override public void onReady() { if (this.poll == null) { - this.poll = new BukkitRunnable() { + this.poll = new WrappedRunnable() { @Override public void run() { for (Player player : Bukkit.getOnlinePlayers()) { @@ -69,7 +69,7 @@ public final class PlaytimeTaskType extends BukkitTaskType { } } } - }.runTaskTimer(plugin, 1200L, 1200L); + }.runTaskTimer(plugin.getScheduler(), 1200L, 1200L); } } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java index 5bccf409..3996bc23 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java @@ -57,7 +57,7 @@ public final class CitizensDeliverTaskType extends BukkitTaskType { @SuppressWarnings("SameParameterValue") private void checkInventory(Player player, NPC npc, long delay) { if (player.hasMetadata("NPC")) return; - Bukkit.getScheduler().runTaskLater(plugin, () -> checkInventory(player, npc), delay); + plugin.getScheduler().runTaskLaterAtEntity(player, () -> checkInventory(player, npc), delay); } @SuppressWarnings("deprecation") diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java index 9b41192c..67491687 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java @@ -1,6 +1,8 @@ package com.leonardobishop.quests.bukkit.tasktype.type.dependent; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.scheduler.WrappedRunnable; +import com.leonardobishop.quests.bukkit.scheduler.WrappedTask; import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskType; import com.leonardobishop.quests.bukkit.util.TaskUtils; import com.leonardobishop.quests.common.config.ConfigProblem; @@ -11,15 +13,13 @@ import com.leonardobishop.quests.common.quest.Task; import me.clip.placeholderapi.PlaceholderAPI; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitTask; import java.util.Arrays; public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private BukkitTask poll; + private WrappedTask poll; public PlaceholderAPIEvaluateTaskType(BukkitQuestsPlugin plugin) { super("placeholderapi_evaluate", TaskUtils.TASK_ATTRIBUTION_STRING, "Evaluate the result of a placeholder"); @@ -52,7 +52,7 @@ public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType { @Override public void onReady() { - this.poll = new BukkitRunnable() { + this.poll = new WrappedRunnable() { @Override public void run() { for (Player player : Bukkit.getOnlinePlayers()) { @@ -136,7 +136,7 @@ public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType { } } } - }.runTaskTimer(plugin, 30L, 30L); + }.runTaskTimer(plugin.getScheduler(), 30L, 30L); } @Override -- cgit v1.2.3-70-g09d2