aboutsummaryrefslogtreecommitdiffstats
path: root/bukkit
diff options
context:
space:
mode:
Diffstat (limited to 'bukkit')
-rw-r--r--bukkit/build.gradle4
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java22
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitServerSchedulerAdapter.java22
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminUpdateCommandHandler.java2
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java2
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/listener/PlayerJoinListener.java4
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java2
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/runnable/QuestsAutoSaveRunnable.java8
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/ServerScheduler.java101
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedRunnable.java65
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/WrappedTask.java30
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitServerSchedulerAdapter.java64
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/bukkit/BukkitWrappedTask.java32
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaServerScheduler.java90
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/scheduler/folia/FoliaWrappedTask.java32
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java2
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PermissionTaskType.java10
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/PlaytimeTaskType.java10
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java2
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java10
-rw-r--r--bukkit/src/main/resources/plugin.yml1
21 files changed, 459 insertions, 56 deletions
diff --git a/bukkit/build.gradle b/bukkit/build.gradle
index f32151b3..49355f55 100644
--- a/bukkit/build.gradle
+++ b/bukkit/build.gradle
@@ -55,6 +55,10 @@ dependencies {
compileOnly('io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT') {
exclude(group: 'it.unimi.dsi', module: 'fastutil') // exclude fastutil just to don't use it (for 1.8 support)
}
+ // Folia
+ compileOnly('dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT') {
+ exclude(group: 'it.unimi.dsi', module: 'fastutil') // exclude fastutil just to don't use it (for 1.8 support)
+ }
// ASkyBlock
compileOnly('com.wasteofplastic:askyblock:3.0.9.4') { transitive = false }
// AuthLib
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<Player, String, String> 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<String, String> 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<UUID> 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.
+ * <p>
+ * Folia: Synced with the server daylight cycle tick.
+ * <p>
+ * 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.
+ * <p>
+ * Folia: Run in the dedicated async thread.
+ * <p>
+ * 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.
+ * <p>
+ * Folia: Synced with the server daylight cycle tick.
+ * <p>
+ * 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.
+ * <p>
+ * Folia: Run in the dedicated async thread.
+ * <p>
+ * 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.
+ * <p>
+ * Folia: Synced with the tick of the region of the entity (even if the entity moves).
+ * <p>
+ * 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.
+ * <p>
+ * Folia: Synced with the server daylight cycle tick.
+ * <p>
+ * 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
diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml
index b36a207e..243e6b73 100644
--- a/bukkit/src/main/resources/plugin.yml
+++ b/bukkit/src/main/resources/plugin.yml
@@ -9,6 +9,7 @@ author: "LMBishop & contributors"
softdepend: [ASkyBlock, BentoBox, Citizens, CoreProtect, Essentials, FabledSkyblock, IridiumSkyblock, MythicMobs, PlaceholderAPI, PlayerBlockTracker, PlayerPoints, ShopGUIPlus, SuperiorSkyblock2, uSkyBlock, Votifier, VotingPlugin]
prefix: Quests
api-version: "1.13" # allows new API features but Quests will still work pre-1.13
+folia-supported: true
commands:
quests: