From 8caac69bb5077233ce12fd9a0d4630d4f53a164c Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Sun, 16 Jun 2024 15:00:58 +0200 Subject: [PATCH] updater 1/? --- DOMAINS-FIREWALL.md | 8 +- pom.xml | 2 +- .../m724/realweather/RealWeatherPlugin.java | 5 +- .../updater/MetadataRetriever.java | 62 +++++++++++++ .../{sign => updater}/SignatureValidator.java | 2 +- .../eu/m724/realweather/updater/Updater.java | 91 +++++++++++++++++++ .../realweather/updater/VersionMetadata.java | 29 ++++++ src/main/resources/plugin.yml | 5 +- 8 files changed, 197 insertions(+), 7 deletions(-) create mode 100644 src/main/java/eu/m724/realweather/updater/MetadataRetriever.java rename src/main/java/eu/m724/realweather/{sign => updater}/SignatureValidator.java (97%) create mode 100644 src/main/java/eu/m724/realweather/updater/Updater.java create mode 100644 src/main/java/eu/m724/realweather/updater/VersionMetadata.java diff --git a/DOMAINS-FIREWALL.md b/DOMAINS-FIREWALL.md index 17d3a92..f32753e 100644 --- a/DOMAINS-FIREWALL.md +++ b/DOMAINS-FIREWALL.md @@ -1,9 +1,11 @@ If you're using a firewall, you must allow the following hosts: -- core functionality: - * rw-api.m724.eu +- updater: + * git.724.rocks - weather: * api.openweathermap.org - thunder: * ws1.blitzortung.org * ws7.blitzortung.org - * ws8.blitzortung.org \ No newline at end of file + * ws8.blitzortung.org + +Subject to change! \ No newline at end of file diff --git a/pom.xml b/pom.xml index 65bd95e..6f3bbb7 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ eu.m724:wtapi - org.java-websocket:Java-WebSocket + diff --git a/src/main/java/eu/m724/realweather/RealWeatherPlugin.java b/src/main/java/eu/m724/realweather/RealWeatherPlugin.java index 0b5f6e5..edefab3 100644 --- a/src/main/java/eu/m724/realweather/RealWeatherPlugin.java +++ b/src/main/java/eu/m724/realweather/RealWeatherPlugin.java @@ -17,11 +17,12 @@ import eu.m724.realweather.commands.LocalTimeCommand; import eu.m724.realweather.mapper.Mapper; import eu.m724.realweather.mapper.MapperConfig; import eu.m724.realweather.object.UserException; -import eu.m724.realweather.sign.SignatureValidator; import eu.m724.realweather.thunder.ThunderConfig; import eu.m724.realweather.thunder.ThunderMaster; import eu.m724.realweather.time.TimeConfig; import eu.m724.realweather.time.TimeMaster; +import eu.m724.realweather.updater.SignatureValidator; +import eu.m724.realweather.updater.Updater; import eu.m724.realweather.weather.WeatherConfig; import eu.m724.realweather.weather.WeatherMaster; import eu.m724.wtapi.provider.exception.ProviderException; @@ -135,6 +136,8 @@ public class RealWeatherPlugin extends JavaPlugin { if (GlobalConstants.timeConfig.enabled) getCommand("localtime").setExecutor(new LocalTimeCommand()); + + new Updater().init(); DebugLogger.info("ended loading", 1); } diff --git a/src/main/java/eu/m724/realweather/updater/MetadataRetriever.java b/src/main/java/eu/m724/realweather/updater/MetadataRetriever.java new file mode 100644 index 0000000..08ec9d3 --- /dev/null +++ b/src/main/java/eu/m724/realweather/updater/MetadataRetriever.java @@ -0,0 +1,62 @@ +package eu.m724.realweather.updater; + +import java.net.ProxySelector; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpClient.Redirect; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.concurrent.CompletableFuture; + +import org.bukkit.plugin.Plugin; + +import com.google.gson.Gson; + +public class MetadataRetriever { + private String version; + + private CompletableFuture currentMetadataCached = null; + + public MetadataRetriever(Plugin plugin) { + this.version = plugin.getDescription().getVersion(); + } + + private CompletableFuture getMetadataFromUrl(String url) { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", "rwu/1") + .build(); + + CompletableFuture> responseFuture = + HttpClient.newBuilder() + .followRedirects(Redirect.NORMAL) + .proxy(ProxySelector.getDefault()).build(). + sendAsync(request, BodyHandlers.ofString()); + + CompletableFuture metadataFuture = + responseFuture.thenApply(response -> { + if (response.statusCode() != 200) + return null; + + VersionMetadata versionMetadata = new Gson().fromJson(response.body(), VersionMetadata.class); + return versionMetadata; + }); + + return metadataFuture; + } + + public CompletableFuture getLatestVersionMetadata() { + return getMetadataFromUrl("https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/latest/latest-v1.json"); + } + + public CompletableFuture getCurrentVersionMetadata() { + if (currentMetadataCached != null) + currentMetadataCached = getVersionMetadata(version); + return currentMetadataCached; + } + + public CompletableFuture getVersionMetadata(String version) { + return getMetadataFromUrl("https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/releases/" + version + "/meta-v1.json"); + } +} diff --git a/src/main/java/eu/m724/realweather/sign/SignatureValidator.java b/src/main/java/eu/m724/realweather/updater/SignatureValidator.java similarity index 97% rename from src/main/java/eu/m724/realweather/sign/SignatureValidator.java rename to src/main/java/eu/m724/realweather/updater/SignatureValidator.java index 3572c1c..39d03ae 100644 --- a/src/main/java/eu/m724/realweather/sign/SignatureValidator.java +++ b/src/main/java/eu/m724/realweather/updater/SignatureValidator.java @@ -1,4 +1,4 @@ -package eu.m724.realweather.sign; +package eu.m724.realweather.updater; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/eu/m724/realweather/updater/Updater.java b/src/main/java/eu/m724/realweather/updater/Updater.java new file mode 100644 index 0000000..142eb66 --- /dev/null +++ b/src/main/java/eu/m724/realweather/updater/Updater.java @@ -0,0 +1,91 @@ +package eu.m724.realweather.updater; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.CompletableFuture; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; + +import eu.m724.realweather.DebugLogger; +import eu.m724.realweather.GlobalConstants; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +public class Updater extends BukkitRunnable implements Listener { + private Plugin plugin = GlobalConstants.getPlugin(); + private MetadataRetriever metadataRetriever = new MetadataRetriever(plugin); + + private VersionMetadata availableUpdate = null; + + private BaseComponent updateMessage = null; + private BaseComponent updateActionMessage = + new ComponentBuilder("To update: ").color(ChatColor.YELLOW) + .append("/rwadmin update").color(ChatColor.AQUA) + .build(); + + public void init() { + this.runTaskTimerAsynchronously(plugin, 0, 216000); // 3h + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + public boolean installUpdate() { + if (availableUpdate == null) + return false; + + // TODO + return true; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (!player.hasPermission("realweather.update.notify")) return; + + if (updateMessage != null) { // TODO make changelog somewhere + player.spigot().sendMessage(updateMessage); + if (player.hasPermission("realweather.admin")) + player.spigot().sendMessage(updateActionMessage); + } + } + + @Override + public void run() { + DebugLogger.info("Checking for update...", 2); + CompletableFuture currentMetadataFuture = + metadataRetriever.getCurrentVersionMetadata(); + + CompletableFuture latestMetadataFuture = + metadataRetriever.getLatestVersionMetadata(); + + VersionMetadata currentMetadata = currentMetadataFuture.join(); + VersionMetadata latestMetadata = latestMetadataFuture.join(); + + DebugLogger.info("Current version: %s (%d)", 2, currentMetadata.label, currentMetadata.id); + DebugLogger.info("Latest version: %s (%d)", 2, latestMetadata.label, latestMetadata.id); + + if (currentMetadata.id >= latestMetadata.id) return; + + availableUpdate = latestMetadata; + + String formattedDate = new SimpleDateFormat("dd.MM").format(new Date(latestMetadata.timestamp)); + + updateMessage = new ComponentBuilder("An update is available!\n") + .color(ChatColor.YELLOW) + .append("RealWeather ").color(ChatColor.GOLD) + .append(latestMetadata.label).color(ChatColor.AQUA).bold(true) + .append(" released ").color(ChatColor.GOLD) + .append(formattedDate).color(ChatColor.AQUA) + .append("\nCurrent: ").color(ChatColor.GRAY) + .append(currentMetadata.label).color(ChatColor.DARK_AQUA) + .build(); + + DebugLogger.info(updateMessage.toString(), 0); + DebugLogger.info(updateActionMessage.toString(), 0); + } +} diff --git a/src/main/java/eu/m724/realweather/updater/VersionMetadata.java b/src/main/java/eu/m724/realweather/updater/VersionMetadata.java new file mode 100644 index 0000000..f020f06 --- /dev/null +++ b/src/main/java/eu/m724/realweather/updater/VersionMetadata.java @@ -0,0 +1,29 @@ +package eu.m724.realweather.updater; + +public class VersionMetadata { + /** + * metadata file version + */ + public final int spec = 1; + + /** + * version id. increments with each version + */ + public int id; + + /** + * release time of a version + */ + public long timestamp; + + /** + * label aka version string + * example: 1.0.0 + */ + public String label; + + /** + * filename of the jar file in the version directory + */ + public String file; +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5d209b2..a0905ba 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,10 +4,13 @@ version: ${project.version} author: Minecon724 website: https://forum.m724.eu/topic/3/realweather-1-0 -api-version: 1.20 +api-version: 1.21 load: STARTUP main: eu.m724.realweather.RealWeatherPlugin +libraries: +- org.java-websocket:Java-WebSocket:1.5.6 + commands: rwadmin: description: RealWeather admin command