diff --git a/README.md b/README.md index b9fe41c..e8c43eb 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,12 @@ startup and logs the result to the console. Optional integration with DiscordSRV. Placeholder `%discord_online%` shows number of connected Discord users. +## Updates + +On startup the plugin contacts GitHub to see if a newer release is available. If one is found a +message with the version number and download link is printed to the console. Releases are +published at [github.com/Locon213/LiveMotdManager/releases](https://github.com/Locon213/LiveMotdManager/releases). + Additional documentation is available in the [wiki](wiki/Home.md). ## License diff --git a/bungee/src/main/java/com/livemotdmanager/bungee/LiveMotdBungee.java b/bungee/src/main/java/com/livemotdmanager/bungee/LiveMotdBungee.java index e02e78b..d0f9fd6 100644 --- a/bungee/src/main/java/com/livemotdmanager/bungee/LiveMotdBungee.java +++ b/bungee/src/main/java/com/livemotdmanager/bungee/LiveMotdBungee.java @@ -37,6 +37,7 @@ public void onEnable() { ProxyServer.getInstance().getPluginManager().registerListener(this, this); ProxyServer.getInstance().getPluginManager().registerCommand(this, new MotdCommand()); setupLogger(); + UpdateChecker.checkAsync(getDescription().getVersion(), getLogger()); } @Override diff --git a/core/src/main/java/com/livemotdmanager/core/UpdateChecker.java b/core/src/main/java/com/livemotdmanager/core/UpdateChecker.java new file mode 100644 index 0000000..55f7517 --- /dev/null +++ b/core/src/main/java/com/livemotdmanager/core/UpdateChecker.java @@ -0,0 +1,62 @@ +package com.livemotdmanager.core; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.logging.Logger; + +/** + * Simple GitHub release update checker. + */ +public final class UpdateChecker { + private static final String API_URL = "https://api.github.com/repos/Locon213/LiveMotdManager/releases/latest"; + private static final String DOWNLOAD_URL = "https://github.com/Locon213/LiveMotdManager/releases"; + + private UpdateChecker() {} + + public static void checkAsync(String currentVersion, Logger logger) { + new Thread(() -> check(currentVersion, logger)).start(); + } + + private static void check(String currentVersion, Logger logger) { + try { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder(URI.create(API_URL)) + .header("Accept", "application/vnd.github+json") + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + String latest = parseLatest(response.body()); + if (latest != null && isNewer(latest, currentVersion)) { + logger.info("A new version of LiveMotdManager is available: " + latest + ". Download at " + DOWNLOAD_URL); + } + } catch (Exception e) { + logger.fine("Update check failed: " + e.getMessage()); + } + } + + private static String parseLatest(String json) { + int idx = json.indexOf("\"tag_name\""); + if (idx == -1) return null; + int start = json.indexOf('"', idx + 10) + 1; + int end = json.indexOf('"', start); + if (start == 0 || end == -1) return null; + String tag = json.substring(start, end); + return tag.startsWith("v") ? tag.substring(1) : tag; + } + + private static boolean isNewer(String latest, String current) { + try { + String[] l = latest.split("\\."); + String[] c = current.split("\\."); + int max = Math.max(l.length, c.length); + for (int i = 0; i < max; i++) { + int li = i < l.length ? Integer.parseInt(l[i]) : 0; + int ci = i < c.length ? Integer.parseInt(c[i]) : 0; + if (li > ci) return true; + if (li < ci) return false; + } + } catch (NumberFormatException ignored) { } + return false; + } +} diff --git a/spigot/src/main/java/com/livemotdmanager/spigot/LiveMotdSpigot.java b/spigot/src/main/java/com/livemotdmanager/spigot/LiveMotdSpigot.java index 85dbabb..9bb4575 100644 --- a/spigot/src/main/java/com/livemotdmanager/spigot/LiveMotdSpigot.java +++ b/spigot/src/main/java/com/livemotdmanager/spigot/LiveMotdSpigot.java @@ -40,6 +40,7 @@ public void onEnable() { getServer().getPluginManager().registerEvents(this, this); getCommand("motd").setExecutor(this); setupLogger(); + UpdateChecker.checkAsync(getDescription().getVersion(), getLogger()); } @Override diff --git a/velocity/src/main/java/com/livemotdmanager/velocity/LiveMotdVelocity.java b/velocity/src/main/java/com/livemotdmanager/velocity/LiveMotdVelocity.java index 0775540..f788436 100644 --- a/velocity/src/main/java/com/livemotdmanager/velocity/LiveMotdVelocity.java +++ b/velocity/src/main/java/com/livemotdmanager/velocity/LiveMotdVelocity.java @@ -40,6 +40,7 @@ public void init() { loadConfig(); setupLogger(); server.getCommandManager().register(server.getCommandManager().metaBuilder("motd").build(), new MotdCommand()); + UpdateChecker.checkAsync(LiveMotdVelocity.class.getAnnotation(Plugin.class).version(), Logger.getLogger("LiveMotdManager")); } private void setupLogger() { diff --git a/wiki/Home.md b/wiki/Home.md index f1dce9d..cc52c4b 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -18,8 +18,8 @@ and the MiniMessage formatted `text` to display. Set `weather.enable` to `true` and specify `city`. Use `%weather_motd%` or `%weather_city%` placeholders in your templates. The `weather.update-interval-minutes` option controls how often -new data is fetched (default 10 minutes).NEED API KEY. - +new data is fetched (default 10 minutes). An API key from OpenWeather is required and must be +placed in `weather.api-key`. ### Discord @@ -34,6 +34,12 @@ Run `/motd help` in game for the complete list. - `/motd info` – show debug information - `/motd force ` – force a configured template +## Updates + +The plugin checks for new releases on GitHub when it starts. If a newer version is available you +will see a console message with a download link. Releases are available at +[github.com/Locon213/LiveMotdManager/releases](https://github.com/Locon213/LiveMotdManager/releases). + ## Building Run `mvn package` to build. Jars are created in each module's `target` directory with names like