diff --git a/pom.xml b/pom.xml
index 9e30680..21a93d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,12 +42,19 @@
+
org.bstats
bstats-bukkit
3.0.2
compile
+
+
+ eu.m724
+ jarupdater
+ 0.1.2
+
@@ -72,15 +79,20 @@
3.6.0
false
- true
- full
+
org.bstats
-
eu.m724.giants
+
+
+ org.bstats:*
+ eu.m724:jarupdater
+
+
diff --git a/src/main/java/eu/m724/giants/Configuration.java b/src/main/java/eu/m724/giants/Configuration.java
index 1b34d40..a754743 100644
--- a/src/main/java/eu/m724/giants/Configuration.java
+++ b/src/main/java/eu/m724/giants/Configuration.java
@@ -19,6 +19,8 @@ public class Configuration {
private final File file;
private final Logger logger;
+ String updater;
+
boolean ai;
double attackDamage;
@@ -42,6 +44,13 @@ public class Configuration {
public void load() {
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
+ updater = config.getString("updater", "true");
+ if (updater.equalsIgnoreCase("true")) {
+ updater = "release";
+ } else if (updater.equalsIgnoreCase("false")) {
+ updater = null;
+ }
+
ai = config.getBoolean("ai");
chance = config.getDouble("chance");
diff --git a/src/main/java/eu/m724/giants/GiantsCommand.java b/src/main/java/eu/m724/giants/GiantsCommand.java
index a8337ef..14366c0 100644
--- a/src/main/java/eu/m724/giants/GiantsCommand.java
+++ b/src/main/java/eu/m724/giants/GiantsCommand.java
@@ -1,5 +1,6 @@
package eu.m724.giants;
+import eu.m724.giants.updater.UpdateCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -20,9 +21,12 @@ public class GiantsCommand implements CommandExecutor {
private final GiantsPlugin plugin;
private final Configuration configuration;
- public GiantsCommand(GiantsPlugin plugin, Configuration configuration) {
+ private final UpdateCommand updateCommand;
+
+ public GiantsCommand(GiantsPlugin plugin, Configuration configuration, UpdateCommand updateCommand) {
this.plugin = plugin;
this.configuration = configuration;
+ this.updateCommand = updateCommand;
}
@Override
@@ -128,6 +132,11 @@ public class GiantsCommand implements CommandExecutor {
} else {
sender.sendMessage("Jump delay: " + configuration.jumpDelay);
}
+ } else if (action.equals("update")) {
+ if (updateCommand != null)
+ updateCommand.onCommand(sender, command, label, args);
+ else
+ sender.sendMessage("Updater is disabled");
}
return true;
diff --git a/src/main/java/eu/m724/giants/GiantsPlugin.java b/src/main/java/eu/m724/giants/GiantsPlugin.java
index 438ca14..bfdf89d 100644
--- a/src/main/java/eu/m724/giants/GiantsPlugin.java
+++ b/src/main/java/eu/m724/giants/GiantsPlugin.java
@@ -1,5 +1,7 @@
package eu.m724.giants;
+import eu.m724.giants.updater.PluginUpdater;
+import eu.m724.giants.updater.UpdateCommand;
import org.bstats.bukkit.Metrics;
import org.bukkit.Location;
import org.bukkit.command.CommandExecutor;
@@ -24,7 +26,14 @@ public class GiantsPlugin extends JavaPlugin implements CommandExecutor {
configuration.load();
- getCommand("giants").setExecutor(new GiantsCommand(this, configuration));
+ UpdateCommand updateCommand = null;
+ if (configuration.updater != null) {
+ PluginUpdater updater = PluginUpdater.build(this, configuration.updater);
+ updater.initNotifier();
+ updateCommand = new UpdateCommand(updater);
+ }
+
+ getCommand("giants").setExecutor(new GiantsCommand(this, configuration, updateCommand));
giantProcessor.start();
@@ -37,6 +46,7 @@ public class GiantsPlugin extends JavaPlugin implements CommandExecutor {
} catch (Exception e) {
getLogger().info("Not using bStats (" + e.getClass().getName() + ")");
}
+
}
// TODO api, untested
diff --git a/src/main/java/eu/m724/giants/updater/PluginEnvironment.java b/src/main/java/eu/m724/giants/updater/PluginEnvironment.java
new file mode 100644
index 0000000..ce22d9d
--- /dev/null
+++ b/src/main/java/eu/m724/giants/updater/PluginEnvironment.java
@@ -0,0 +1,14 @@
+package eu.m724.giants.updater;
+
+import eu.m724.jarupdater.environment.ConstantEnvironment;
+import org.bukkit.plugin.Plugin;
+
+import java.nio.file.Path;
+
+public class PluginEnvironment extends ConstantEnvironment {
+ public PluginEnvironment(Plugin plugin, String channel) {
+ super(plugin.getDescription().getVersion(),
+ channel,
+ Path.of(plugin.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/m724/giants/updater/PluginUpdater.java b/src/main/java/eu/m724/giants/updater/PluginUpdater.java
new file mode 100644
index 0000000..28aba62
--- /dev/null
+++ b/src/main/java/eu/m724/giants/updater/PluginUpdater.java
@@ -0,0 +1,33 @@
+package eu.m724.giants.updater;
+
+import eu.m724.jarupdater.Updater;
+import eu.m724.jarupdater.download.Downloader;
+import eu.m724.jarupdater.download.SimpleDownloader;
+import eu.m724.jarupdater.environment.Environment;
+import eu.m724.jarupdater.live.GiteaMetadataDAO;
+import eu.m724.jarupdater.live.MetadataDAO;
+import eu.m724.jarupdater.live.MetadataFacade;
+import org.bukkit.plugin.Plugin;
+
+public class PluginUpdater extends Updater {
+ private final Plugin plugin;
+
+ private PluginUpdater(Environment environment, MetadataFacade metadataProvider, Downloader downloader, Plugin plugin) {
+ super(environment, metadataProvider, downloader);
+ this.plugin = plugin;
+ }
+
+ public static PluginUpdater build(Plugin plugin, String channel) {
+ Environment environment = new PluginEnvironment(plugin, channel);
+ MetadataDAO metadataDAO = new GiteaMetadataDAO("https://git.m724.eu/Minecon724/giants-metadata", "master");
+ MetadataFacade metadataFacade = new MetadataFacade(environment, metadataDAO);
+ Downloader downloader = new SimpleDownloader("giants");
+
+ return new PluginUpdater(environment, metadataFacade, downloader, plugin);
+ }
+
+ public void initNotifier() {
+ UpdateNotifier updateNotifier = new UpdateNotifier(plugin, this, (version) -> {});
+ updateNotifier.register();
+ }
+}
diff --git a/src/main/java/eu/m724/giants/updater/UpdateCommand.java b/src/main/java/eu/m724/giants/updater/UpdateCommand.java
new file mode 100644
index 0000000..21cd9e1
--- /dev/null
+++ b/src/main/java/eu/m724/giants/updater/UpdateCommand.java
@@ -0,0 +1,88 @@
+package eu.m724.giants.updater;
+
+import eu.m724.jarupdater.Updater;
+import eu.m724.jarupdater.object.Version;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+
+import java.nio.file.NoSuchFileException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * not actually a command but deserves a separate file
+ */
+public class UpdateCommand {
+ private final Updater updater;
+
+ public UpdateCommand(Updater updater) {
+ this.updater = updater;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ sender.sendMessage("Please wait...");
+ sender.sendMessage("Channel: " + updater.getEnvironment().getChannel());
+ CompletableFuture latestFuture = updater.getLatestVersion();
+
+ if (args.length == 1) { // remember this function is proxied
+ latestFuture.thenAccept(metadata -> {
+ if (metadata != null) {
+ sender.sendMessage("An update is available!");
+ sender.sendMessage("Giants " + metadata.getLabel() + " released " + formatDate(metadata.getTimestamp()));
+ sender.sendMessage("To download: /giants update download");
+ } else {
+ sender.sendMessage("No new updates");
+ updater.getCurrentVersion().thenAccept(metadata2 -> {
+ sender.sendMessage("You're on Giants " + metadata2.getLabel() + " released " + formatDate(metadata2.getTimestamp()));
+ }).exceptionally(e -> {
+ sender.sendMessage("Error retrieving information about current version, see console for details. " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ });
+ }
+ }).exceptionally(e -> {
+ sender.sendMessage("Error checking for update. See console for details.");
+ e.printStackTrace();
+ return null;
+ });
+ } else {
+ String action = args[1]; // remember this function is proxied
+
+ if (action.equals("download")) {
+ sender.sendMessage("Started download");
+
+ updater.downloadLatestVersion().thenAccept(file -> {
+ sender.sendMessage("Download finished, install with /giants update install");
+ }).exceptionally(e -> {
+ sender.sendMessage("Download failed. See console for details.");
+ e.printStackTrace();
+ return null;
+ });
+ } else if (action.equals("install")) {
+ try {
+ updater.installLatestVersion().thenAccept(v -> {
+ sender.sendMessage("Installation completed, restart server to apply.");
+ }).exceptionally(e -> {
+ sender.sendMessage("Install failed, see console for details. " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ });
+ } catch (NoSuchFileException e) {
+ sender.sendMessage("First, download the update: /giants update download");
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private String formatDate(long timestamp) { // TODO move this
+ return LocalDate.ofEpochDay(timestamp / 86400).format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
+ }
+
+}
diff --git a/src/main/java/eu/m724/giants/updater/UpdateNotifier.java b/src/main/java/eu/m724/giants/updater/UpdateNotifier.java
new file mode 100644
index 0000000..bfd7c3d
--- /dev/null
+++ b/src/main/java/eu/m724/giants/updater/UpdateNotifier.java
@@ -0,0 +1,66 @@
+package eu.m724.giants.updater;
+
+import eu.m724.jarupdater.Updater;
+import eu.m724.jarupdater.object.Version;
+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 java.io.IOException;
+import java.util.concurrent.CompletionException;
+import java.util.function.Consumer;
+
+public class UpdateNotifier extends BukkitRunnable implements Listener { // TODO move this to jarupdater
+ private final Updater updater;
+ private final Consumer updateConsumer;
+
+ private final Plugin plugin;
+ private Version latestVersion;
+
+ public UpdateNotifier(Plugin plugin, Updater updater, Consumer updateConsumer) {
+ this.plugin = plugin;
+ this.updater = updater;
+ this.updateConsumer = updateConsumer;
+ }
+
+ public void register() {
+ this.runTaskTimerAsynchronously(plugin, 0, 432000); // 6h
+ plugin.getServer().getPluginManager().registerEvents(this, plugin);
+ }
+
+ @Override
+ public void run() {
+ try {
+ latestVersion = updater.getLatestVersion().join();
+ } catch (CompletionException e) {
+ Throwable ex = e.getCause();
+
+ if (ex instanceof IOException)
+ plugin.getLogger().info("error trying to contact update server: " + ex.getMessage());
+ else e.printStackTrace();
+ }
+
+ if (latestVersion == null) return;
+ plugin.getLogger().info("Giants are outdated. /giants update");
+
+ for (Player player : plugin.getServer().getOnlinePlayers()) {
+ if (player.hasPermission("giants.update.notify")) {
+ player.sendMessage("Giants are outdated. /giants update");
+ }
+ }
+
+ updateConsumer.accept(latestVersion);
+
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent e) {
+ Player player = e.getPlayer();
+ if (latestVersion != null && player.hasPermission("giants.update.notify")) {
+ player.sendMessage("Giants are outdated. /giants update");
+ }
+ }
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 964dab4..baa67bd 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,6 +1,12 @@
# Notes:
# To have no values in a list, remove every value below it and change to [] like `effects: []`
+# Enable updater
+# It still requires an admin to confirm update
+updater: true
+
+###
+
# If disabled, the giant will not move or attack
ai: true
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c7fdeca..35f8527 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -15,4 +15,14 @@ permissions:
default: op
giants.command.serialize:
description: Permits /giants serialize
- default: op
\ No newline at end of file
+ default: op
+ giants.command.update:
+ description: Permits /giants update. Doesn't permit installing update, giants.update for that
+ default: op
+
+ giants.update.downloading:
+ description: Permits DOWNLOADING the latest update of the Giants plugin.
+ default: op
+ giants.update.install:
+ description: Permits INSTALLING the latest update of the Giants plugin.
+ default: op