From 536b4dd6edcb11597f5e11a0ff4e1ca02fd97c45 Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:09:12 +0200 Subject: [PATCH 01/10] Added support for multithreaded servers Replaced Bukkit's schedulers by Java's native ones --- .../updatechecker/ThreadScheduler.java | 33 +++++++++++++++++++ .../updatechecker/UpdateChecker.java | 26 ++++++++------- 2 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java diff --git a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java new file mode 100644 index 0000000..95ddce4 --- /dev/null +++ b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java @@ -0,0 +1,33 @@ +package com.jeff_media.updatechecker; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class ThreadScheduler { + public static ScheduledExecutorService runTask(Runnable task) { + return runTask(task, 1/20L, TimeUnit.MILLISECONDS); + } + + public static ScheduledExecutorService runTask(Runnable task, long delay, TimeUnit timeUnit) { + // Create a ScheduledExecutorService with a single thread + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + scheduler.schedule(task, delay, timeUnit); + + return scheduler; + } + + public static ScheduledExecutorService scheduleRepeatingTask(Runnable task, long delay, long period, TimeUnit timeUnit) { + // Create a ScheduledExecutorService with a single thread + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + scheduler.scheduleAtFixedRate(task, delay, period, timeUnit); + + return scheduler; + } + + public static void stopScheduler(ScheduledExecutorService scheduler) { + if(!scheduler.isShutdown()) scheduler.shutdown(); + } +} diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index 501c6fb..c0bb802 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -33,6 +33,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; /** @@ -81,7 +83,9 @@ public class UpdateChecker { private BiConsumer onSuccess = (requesters, latestVersion) -> { }; private String paidDownloadLink = null; - private int taskId = -1; + //private int taskId = -1; + @Nullable + private ScheduledExecutorService task = null; private int timeout = 0; private String usedVersion; private String userAgentString = null; @@ -277,12 +281,12 @@ public boolean isSuppressUpToDateMessage() { public UpdateChecker checkEveryXHours(double hours) { double minutes = hours * 60; double seconds = minutes * 60; - long ticks = ((int) seconds) * 20L; + long milliseconds = ((int) seconds) * 1000L; stop(); - if (ticks > 0) { - taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> checkNow(Bukkit.getConsoleSender()), ticks, ticks); + if (milliseconds > 0) { + task = ThreadScheduler.scheduleRepeatingTask(() -> checkNow(Bukkit.getConsoleSender()), milliseconds, milliseconds, TimeUnit.MILLISECONDS); } else { - taskId = -1; + task = null; } return this; } @@ -293,10 +297,10 @@ public UpdateChecker checkEveryXHours(double hours) { * its previous task. */ public UpdateChecker stop() { - if (taskId != -1) { - Bukkit.getScheduler().cancelTask(taskId); + if (task != null) { + ThreadScheduler.stopScheduler(task); } - taskId = -1; + task = null; return this; } @@ -320,7 +324,7 @@ public UpdateChecker checkNow(@Nullable CommandSender... requesters) { userAgentString = UserAgentBuilder.getDefaultUserAgent().build(); } - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + ThreadScheduler.runTask(() -> { UpdateCheckEvent updateCheckEvent; @@ -345,12 +349,12 @@ public UpdateChecker checkNow(@Nullable CommandSender... requesters) { updateCheckEvent = new UpdateCheckEvent(UpdateCheckSuccess.SUCCESS); } catch (final IOException exception) { updateCheckEvent = new UpdateCheckEvent(UpdateCheckSuccess.FAIL); - Bukkit.getScheduler().runTask(plugin, () -> getOnFail().accept(requesters, exception)); + ThreadScheduler.runTask(() -> getOnFail().accept(requesters, exception)); } UpdateCheckEvent finalUpdateCheckEvent = updateCheckEvent.setRequesters(requesters); - Bukkit.getScheduler().runTask(plugin, () -> { + ThreadScheduler.runTask(() -> { if (finalUpdateCheckEvent.getSuccess() == UpdateCheckSuccess.SUCCESS) { getOnSuccess().accept(requesters, latestVersion); From 5dac8ad4939f5589b287f0568a2a879649450a5f Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:12:42 +0200 Subject: [PATCH 02/10] Update ThreadScheduler.java --- .../java/com/jeff_media/updatechecker/ThreadScheduler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java index 95ddce4..831f9f3 100644 --- a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java +++ b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java @@ -5,14 +5,14 @@ import java.util.concurrent.TimeUnit; public class ThreadScheduler { + // Create a ScheduledExecutorService with a single thread + public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + public static ScheduledExecutorService runTask(Runnable task) { return runTask(task, 1/20L, TimeUnit.MILLISECONDS); } public static ScheduledExecutorService runTask(Runnable task, long delay, TimeUnit timeUnit) { - // Create a ScheduledExecutorService with a single thread - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - scheduler.schedule(task, delay, timeUnit); return scheduler; From b60eee16b90cbfc025cdc1b3daf2741f4b8de133 Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:15:28 +0200 Subject: [PATCH 03/10] Fixed a little bug with ms --- .../java/com/jeff_media/updatechecker/ThreadScheduler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java index 831f9f3..1191703 100644 --- a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java +++ b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java @@ -9,7 +9,8 @@ public class ThreadScheduler { public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public static ScheduledExecutorService runTask(Runnable task) { - return runTask(task, 1/20L, TimeUnit.MILLISECONDS); + // Divide 1s -> 1000ms by the amount of ticks per seconds + return runTask(task, 1000/20L, TimeUnit.MILLISECONDS); } public static ScheduledExecutorService runTask(Runnable task, long delay, TimeUnit timeUnit) { From 9adc68a2315a299b56756614930b978dadda0aae Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Fri, 30 Aug 2024 17:15:52 +0200 Subject: [PATCH 04/10] Bruh, forgot to remove one line --- .../java/com/jeff_media/updatechecker/ThreadScheduler.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java index 1191703..97ef6e1 100644 --- a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java +++ b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java @@ -20,9 +20,6 @@ public static ScheduledExecutorService runTask(Runnable task, long delay, TimeUn } public static ScheduledExecutorService scheduleRepeatingTask(Runnable task, long delay, long period, TimeUnit timeUnit) { - // Create a ScheduledExecutorService with a single thread - ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - scheduler.scheduleAtFixedRate(task, delay, period, timeUnit); return scheduler; From 3cfb265fb8d8ac61979eb734f653b4014b71f158 Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:09:04 +0200 Subject: [PATCH 05/10] Added comments, fixed bugs --- .../updatechecker/ThreadScheduler.java | 29 +++++++++++++++++-- .../updatechecker/UpdateChecker.java | 1 - 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java index 97ef6e1..afb95d6 100644 --- a/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java +++ b/src/main/java/com/jeff_media/updatechecker/ThreadScheduler.java @@ -6,26 +6,51 @@ public class ThreadScheduler { // Create a ScheduledExecutorService with a single thread - public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public static ScheduledExecutorService runTask(Runnable task) { - // Divide 1s -> 1000ms by the amount of ticks per seconds + // Divide 1s -> 1000ms by the amount of ticks per seconds to execute this task every tick return runTask(task, 1000/20L, TimeUnit.MILLISECONDS); } + /** + * Run a task after a delay using {@link ThreadScheduler#scheduler} + * @param task The task to run from the scheduler + * @param delay The delay before the {@link Runnable} is run + * @param timeUnit The time unit used for the delay + * @return The used scheduler instance + */ public static ScheduledExecutorService runTask(Runnable task, long delay, TimeUnit timeUnit) { + makeSchedulerIfDown(); scheduler.schedule(task, delay, timeUnit); return scheduler; } + /** + * Repeat a task after a delay for a given period using {@link ThreadScheduler#scheduler} + * @param task The task to run from the scheduler + * @param delay The delay before the {@link Runnable} is run + * @param period The period between each execution + * @param timeUnit The time unit used for the delay and the period + * @return The used scheduler instance + */ public static ScheduledExecutorService scheduleRepeatingTask(Runnable task, long delay, long period, TimeUnit timeUnit) { + makeSchedulerIfDown(); scheduler.scheduleAtFixedRate(task, delay, period, timeUnit); return scheduler; } + /** + * Stop the given scheduler + * @param scheduler The scheduler to stop + */ public static void stopScheduler(ScheduledExecutorService scheduler) { if(!scheduler.isShutdown()) scheduler.shutdown(); } + + private static void makeSchedulerIfDown() { + if(scheduler.isShutdown()) scheduler = Executors.newScheduledThreadPool(1); + } } diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index c0bb802..9c6d79b 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -83,7 +83,6 @@ public class UpdateChecker { private BiConsumer onSuccess = (requesters, latestVersion) -> { }; private String paidDownloadLink = null; - //private int taskId = -1; @Nullable private ScheduledExecutorService task = null; private int timeout = 0; From d51cf0333cc2f0bbd01fb81caed99488a203ee2c Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:39:56 +0100 Subject: [PATCH 06/10] Added folia support --- pom.xml | 23 +++++++++++++- .../updatechecker/UpdateChecker.java | 30 ++++++++++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index a7964b0..56529ca 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.5.0 true @@ -82,6 +82,17 @@ + + + com.github.Anon8281:UniversalScheduler + + + + + com.github.Anon8281.universalScheduler + com.jeff_media.updatechecker.universalScheduler + + @@ -146,6 +157,10 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + jitpack.io + https://jitpack.io + @@ -167,6 +182,12 @@ 23.0.0 provided + + com.github.Anon8281 + UniversalScheduler + 0.1.6 + compile + diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index 501c6fb..795524e 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -18,6 +18,10 @@ package com.jeff_media.updatechecker; +import com.github.Anon8281.universalScheduler.UniversalScheduler; +import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; +import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; @@ -81,7 +85,9 @@ public class UpdateChecker { private BiConsumer onSuccess = (requesters, latestVersion) -> { }; private String paidDownloadLink = null; - private int taskId = -1; + private static TaskScheduler scheduler; + @Nullable + private MyScheduledTask updaterTask = null; private int timeout = 0; private String usedVersion; private String userAgentString = null; @@ -107,7 +113,6 @@ public UpdateChecker(@NotNull JavaPlugin plugin, @NotNull VersionSupplier suppli } private void init() { - Objects.requireNonNull(plugin, "Plugin cannot be null."); this.usedVersion = plugin.getDescription().getVersion().trim(); @@ -116,6 +121,8 @@ private void init() { usingPaidVersion = true; } + scheduler = UniversalScheduler.getScheduler(plugin); + if (!listenerAlreadyRegistered) { Bukkit.getPluginManager().registerEvents(new UpdateCheckListener(), plugin); listenerAlreadyRegistered = true; @@ -280,9 +287,9 @@ public UpdateChecker checkEveryXHours(double hours) { long ticks = ((int) seconds) * 20L; stop(); if (ticks > 0) { - taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> checkNow(Bukkit.getConsoleSender()), ticks, ticks); + updaterTask = getScheduler().runTaskTimer(() -> checkNow(Bukkit.getConsoleSender()), ticks, ticks); } else { - taskId = -1; + updaterTask = null; } return this; } @@ -293,10 +300,10 @@ public UpdateChecker checkEveryXHours(double hours) { * its previous task. */ public UpdateChecker stop() { - if (taskId != -1) { - Bukkit.getScheduler().cancelTask(taskId); + if (updaterTask != null) { + updaterTask.cancel(); } - taskId = -1; + updaterTask = null; return this; } @@ -616,6 +623,15 @@ protected Plugin getPlugin() { return plugin; } + /** + * Gets the TaskScheduler instance used by the UpdateChecker + * + * @return TaskScheduler instance used by the UpdateChecker + */ + public static TaskScheduler getScheduler() { + return scheduler; + } + /** * Gets the Spigot User ID of the user who downloaded the plugin if it's a premium plugin, otherwise "%%__USER__%%" * From 105f416ed8e8b8166e266eade0e1130d2388d0ff Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:47:51 +0100 Subject: [PATCH 07/10] Removed unused import --- src/main/java/com/jeff_media/updatechecker/UpdateChecker.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index 795524e..fd8e87c 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -21,7 +21,6 @@ import com.github.Anon8281.universalScheduler.UniversalScheduler; import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; -import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; From d4dca1cb35e2bc7047ed28f0bf3a7a2572b9606b Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Sun, 12 Jan 2025 16:42:13 +0100 Subject: [PATCH 08/10] Bumped version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 56529ca..fc87ab0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.jeff_media SpigotUpdateChecker - 3.0.3 + 3.0.4 jar From 5f64340cb8a179760e32840ddd48fe8a47097fbc Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Sun, 12 Jan 2025 17:12:04 +0100 Subject: [PATCH 09/10] Bumped version for UpdateChecker --- src/main/java/com/jeff_media/updatechecker/UpdateChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index fd8e87c..9d3b84c 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -44,7 +44,7 @@ @SuppressWarnings("UnusedReturnValue") public class UpdateChecker { - static final String VERSION = "3.0.1"; + static final String VERSION = "3.0.4"; private static final String SPIGOT_CHANGELOG_SUFFIX = "/history"; private static final String SPIGOT_DOWNLOAD_LINK = "https://www.spigotmc.org/resources/"; private static final String SPIGOT_UPDATE_API = "https://api.spigotmc.org/simple/0.2/index.php?action=getResource&id=%s"; From 9a5d5331ba5c712b0296de7832609ae31dc09a0d Mon Sep 17 00:00:00 2001 From: Paulem <66211574+Paulem79@users.noreply.github.com> Date: Thu, 16 Jan 2025 20:09:04 +0100 Subject: [PATCH 10/10] Replaced all schedulers --- .../java/com/jeff_media/updatechecker/UpdateChecker.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java index 9d3b84c..fe80785 100644 --- a/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java +++ b/src/main/java/com/jeff_media/updatechecker/UpdateChecker.java @@ -326,7 +326,7 @@ public UpdateChecker checkNow(@Nullable CommandSender... requesters) { userAgentString = UserAgentBuilder.getDefaultUserAgent().build(); } - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + getScheduler().runTaskAsynchronously(() -> { UpdateCheckEvent updateCheckEvent; @@ -351,12 +351,12 @@ public UpdateChecker checkNow(@Nullable CommandSender... requesters) { updateCheckEvent = new UpdateCheckEvent(UpdateCheckSuccess.SUCCESS); } catch (final IOException exception) { updateCheckEvent = new UpdateCheckEvent(UpdateCheckSuccess.FAIL); - Bukkit.getScheduler().runTask(plugin, () -> getOnFail().accept(requesters, exception)); + getScheduler().runTask(() -> getOnFail().accept(requesters, exception)); } UpdateCheckEvent finalUpdateCheckEvent = updateCheckEvent.setRequesters(requesters); - Bukkit.getScheduler().runTask(plugin, () -> { + getScheduler().runTask(() -> { if (finalUpdateCheckEvent.getSuccess() == UpdateCheckSuccess.SUCCESS) { getOnSuccess().accept(requesters, latestVersion);