From afa69c059bb7444585acde7083a4580741479de6 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Mon, 2 Dec 2024 17:43:38 +0100 Subject: [PATCH] Add /updates that shows available updates --- .../java/eu/m724/tweaks/TweaksPlugin.java | 2 + .../eu/m724/tweaks/updater/UpdateChecker.java | 8 +- .../m724/tweaks/updater/UpdaterCommands.java | 74 +++++++++++++++++++ .../tweaks/updater/VersionCheckCache.java | 2 +- .../eu/m724/tweaks/updater/VersionFinder.java | 10 ++- .../tweaks/updater/cache/ResourceVersion.java | 3 +- .../updater/cache/UpdateDescription.java | 13 ++++ src/main/resources/plugin.yml | 6 ++ 8 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 src/main/java/eu/m724/tweaks/updater/UpdaterCommands.java create mode 100644 src/main/java/eu/m724/tweaks/updater/cache/UpdateDescription.java diff --git a/src/main/java/eu/m724/tweaks/TweaksPlugin.java b/src/main/java/eu/m724/tweaks/TweaksPlugin.java index a611ee2..6143750 100644 --- a/src/main/java/eu/m724/tweaks/TweaksPlugin.java +++ b/src/main/java/eu/m724/tweaks/TweaksPlugin.java @@ -17,6 +17,7 @@ import eu.m724.tweaks.ping.PingCommands; import eu.m724.tweaks.pomodoro.PomodoroCommands; import eu.m724.tweaks.pomodoro.PomodoroManager; import eu.m724.tweaks.sleep.SleepManager; +import eu.m724.tweaks.updater.UpdaterCommands; import eu.m724.tweaks.updater.UpdaterManager; import eu.m724.tweaks.worldborder.WorldBorderManager; import org.bukkit.plugin.java.JavaPlugin; @@ -79,6 +80,7 @@ public class TweaksPlugin extends JavaPlugin { if (config.updaterEnabled()) { try { new UpdaterManager(this).init(); + getCommand("updates").setExecutor(new UpdaterCommands()); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/eu/m724/tweaks/updater/UpdateChecker.java b/src/main/java/eu/m724/tweaks/updater/UpdateChecker.java index 10c023f..5216e2b 100644 --- a/src/main/java/eu/m724/tweaks/updater/UpdateChecker.java +++ b/src/main/java/eu/m724/tweaks/updater/UpdateChecker.java @@ -13,6 +13,8 @@ import org.bukkit.scheduler.BukkitRunnable; import java.io.FileOutputStream; import java.io.IOException; +import java.time.LocalTime; +import java.time.ZoneOffset; import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -24,7 +26,8 @@ public class UpdateChecker extends BukkitRunnable { private final Set resources; private final Logger logger; - private final Set availableUpdates = new HashSet<>(); + static final Set availableUpdates = new HashSet<>(); + static LocalTime lastChecked = null; UpdateChecker(Plugin plugin, Set resources) { this.logger = Logger.getLogger(plugin.getLogger().getName() + "." + getClass().getSimpleName()); @@ -33,6 +36,7 @@ public class UpdateChecker extends BukkitRunnable { private void checkAll() { //logger.info("Checking for updates"); + lastChecked = LocalTime.now(ZoneOffset.UTC); availableUpdates.clear(); for (VersionedResource versionedResource : Set.copyOf(resources)) { @@ -71,8 +75,6 @@ public class UpdateChecker extends BukkitRunnable { availableUpdates.stream() .map(u -> "- %s (%s -> %s)".formatted(u.resource().name(), u.running().label(), u.latest().label())) .forEach(logger::info); - - // TODO notify player } @Override diff --git a/src/main/java/eu/m724/tweaks/updater/UpdaterCommands.java b/src/main/java/eu/m724/tweaks/updater/UpdaterCommands.java new file mode 100644 index 0000000..6671d9e --- /dev/null +++ b/src/main/java/eu/m724/tweaks/updater/UpdaterCommands.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 Minecon724 + * Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file + * in the project root for the full license text. + */ + +package eu.m724.tweaks.updater; + +import eu.m724.tweaks.Language; +import eu.m724.tweaks.updater.cache.VersionedResource; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.hover.content.Text; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.time.format.DateTimeFormatter; + +public class UpdaterCommands implements CommandExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (UpdateChecker.lastChecked == null) { + sender.sendMessage("Not checked yet"); + return true; + } + + String lastChecked = UpdateChecker.lastChecked.format(DateTimeFormatter.ISO_LOCAL_TIME); + int n = UpdateChecker.availableUpdates.size(); + + if (n > 0) { + BaseComponent[] components = UpdateChecker.availableUpdates.stream() + .map(u -> resourceToBaseComponent(u)) + .toArray(BaseComponent[]::new); + components = new ComponentBuilder(Language.getString("updateAvailableNotice").formatted(n) + "\n") + .append(components) + .create(); + sender.spigot().sendMessage(components); + } else { + sender.sendMessage("No available updates. Last checked: " + lastChecked); + } + + return true; + } + + private BaseComponent resourceToBaseComponent(VersionedResource v) { + Color nameColor = Color.decode("#" + Integer.toHexString(v.resource().name().hashCode()).substring(0, 6)); + ComponentBuilder componentBuilder = new ComponentBuilder(v.resource().name()).color(ChatColor.of(nameColor)) + .append(" (").color(ChatColor.DARK_GRAY) + .append(v.running().label()).color(ChatColor.GRAY) + .append(" -> ").color(ChatColor.DARK_GRAY) + .append(v.latest().label()).color(ChatColor.of(nameColor.brighter())) + .append(")").color(ChatColor.DARK_GRAY) + .event( + new ClickEvent( + ClickEvent.Action.OPEN_URL, + "https://www.spigotmc.org/resources/%d/update?update=%d".formatted(v.resource().resourceId(), v.latest().updateId()) + ) + ) + .event( + new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new Text("Click to open on SpigotMC \"%s\"".formatted(v.latest().description().title())) + ) + ); + + return componentBuilder.build(); + } +} diff --git a/src/main/java/eu/m724/tweaks/updater/VersionCheckCache.java b/src/main/java/eu/m724/tweaks/updater/VersionCheckCache.java index e0cd4ff..7bc9b44 100644 --- a/src/main/java/eu/m724/tweaks/updater/VersionCheckCache.java +++ b/src/main/java/eu/m724/tweaks/updater/VersionCheckCache.java @@ -43,7 +43,7 @@ public class VersionCheckCache { int page = ((bytes[3] & 0xFF) << 8) | (bytes[4] & 0xFF); int versionId = ((bytes[5] & 0xFF) << 16) | ((bytes[6] & 0xFF) << 8) | (bytes[7] & 0xFF); - return new ResourceVersion(resourceId, page, versionId, null); + return new ResourceVersion(resourceId, page, versionId, null, null); } private static void writeResourceVersion(ResourceVersion resourceVersion, OutputStream outputStream) throws IOException { diff --git a/src/main/java/eu/m724/tweaks/updater/VersionFinder.java b/src/main/java/eu/m724/tweaks/updater/VersionFinder.java index 36b8608..35676ef 100644 --- a/src/main/java/eu/m724/tweaks/updater/VersionFinder.java +++ b/src/main/java/eu/m724/tweaks/updater/VersionFinder.java @@ -12,6 +12,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import eu.m724.tweaks.updater.cache.SpigotResource; import eu.m724.tweaks.updater.cache.ResourceVersion; +import eu.m724.tweaks.updater.cache.UpdateDescription; import eu.m724.tweaks.updater.cache.VersionedResource; import java.net.URI; @@ -79,14 +80,19 @@ public class VersionFinder extends CompletableFuture { resource.resourceId(), page, versionJson.get("id").getAsInt(), - versionJson.get("resource_version").getAsString() + versionJson.get("resource_version").getAsString(), + null // no need for changelog of running version ); } latestVersion = new ResourceVersion( resource.resourceId(), page, versionJson.get("id").getAsInt(), - versionJson.get("resource_version").getAsString() + versionJson.get("resource_version").getAsString(), + new UpdateDescription( + versionJson.get("title").getAsString(), + versionJson.get("message").getAsString() + ) ); //System.out.printf("%d %d %s\n", page, versionJson.get("id").getAsInt(), versionJson.get("resource_version").getAsString()); } diff --git a/src/main/java/eu/m724/tweaks/updater/cache/ResourceVersion.java b/src/main/java/eu/m724/tweaks/updater/cache/ResourceVersion.java index ae05966..efd1e48 100644 --- a/src/main/java/eu/m724/tweaks/updater/cache/ResourceVersion.java +++ b/src/main/java/eu/m724/tweaks/updater/cache/ResourceVersion.java @@ -10,5 +10,6 @@ public record ResourceVersion( int resourceId, int page, int updateId, - String label + String label, + UpdateDescription description ) { } diff --git a/src/main/java/eu/m724/tweaks/updater/cache/UpdateDescription.java b/src/main/java/eu/m724/tweaks/updater/cache/UpdateDescription.java new file mode 100644 index 0000000..1837716 --- /dev/null +++ b/src/main/java/eu/m724/tweaks/updater/cache/UpdateDescription.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2024 Minecon724 + * Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file + * in the project root for the full license text. + */ + +package eu.m724.tweaks.updater.cache; + +public record UpdateDescription( + String title, + String description +) { +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2b366b2..d6079d8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -23,6 +23,10 @@ commands: description: Pomodoro management permission: tweaks724.pomodoro aliases: [pom] + updates: + description: See available plugin updates + permission: tweaks724.updates + aliases: [pluginupdates] permissions: tweaks724.chatmanage: @@ -31,4 +35,6 @@ permissions: default: op tweaks724.pomodoro: default: true + tweaks724.updates: + default: op