From 6350d64e88735cca0db4cca5d86abe95c912a528 Mon Sep 17 00:00:00 2001
From: Jens Collaert <63231928+Jens-Co@users.noreply.github.com>
Date: Sun, 1 Oct 2023 19:37:53 +0200
Subject: [PATCH] Use new download API and jar file checksum (#99)
* Update to new download api and sha checking for file integrity
* remove old messages class
* unneeded spacing
* Make the enum return a lowercase string as url component
* Konica wanted changes? :)
* delete file issue catching
* use getters for pojos and up the version number
* initialize gson only once
* Cleanup
---------
Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com>
---
pom.xml | 9 ++-
.../geyserupdater/bungee/BungeeUpdater.java | 20 ++---
.../bungee/command/GeyserUpdateCommand.java | 29 +++----
.../bungee/util/GeyserBungeeDownloader.java | 23 +++---
.../geyserupdater/common/Messages.java | 15 ----
.../common/json_schema/EndpointResponse.java | 75 +++++++++++++++++++
.../common/logger/UpdaterLogger.java | 10 +++
.../geyserupdater/common/util/Constants.java | 11 +++
.../geyserupdater/common/util/FileUtils.java | 72 +++++++++++-------
.../common/util/GeyserDownloadApi.java | 26 +++++++
.../common/util/GeyserProperties.java | 23 +++---
.../common/util/ServerPlatform.java | 18 +++++
.../geyserupdater/spigot/SpigotUpdater.java | 7 +-
.../spigot/command/GeyserUpdateCommand.java | 28 +++----
.../spigot/util/GeyserSpigotDownloader.java | 31 +++-----
.../velocity/VelocityUpdater.java | 18 ++---
.../velocity/command/GeyserUpdateCommand.java | 20 +++--
.../velocity/logger/Slf4jUpdaterLogger.java | 5 ++
.../util/GeyserVelocityDownloader.java | 23 +++---
src/main/resources/bungee.yml | 2 +-
20 files changed, 286 insertions(+), 179 deletions(-)
delete mode 100644 src/main/java/com/projectg/geyserupdater/common/Messages.java
create mode 100644 src/main/java/com/projectg/geyserupdater/common/json_schema/EndpointResponse.java
create mode 100644 src/main/java/com/projectg/geyserupdater/common/util/Constants.java
create mode 100644 src/main/java/com/projectg/geyserupdater/common/util/GeyserDownloadApi.java
create mode 100644 src/main/java/com/projectg/geyserupdater/common/util/ServerPlatform.java
diff --git a/pom.xml b/pom.xml
index f418192f..6ea6d228 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.projectg
GeyserUpdater
GeyserUpdater
- 1.6.2
+ 1.6.3
UTF-8
@@ -70,6 +70,13 @@
2.1.0-SNAPSHOT
provided
+
+
+ org.projectlombok
+ lombok
+ 1.18.28
+ provided
+
diff --git a/src/main/java/com/projectg/geyserupdater/bungee/BungeeUpdater.java b/src/main/java/com/projectg/geyserupdater/bungee/BungeeUpdater.java
index e61f738d..6c946f00 100644
--- a/src/main/java/com/projectg/geyserupdater/bungee/BungeeUpdater.java
+++ b/src/main/java/com/projectg/geyserupdater/bungee/BungeeUpdater.java
@@ -84,20 +84,17 @@ public void onDisable() {
try {
deleteGeyserJar();
break;
- } catch (IOException ioException) {
- logger.warn("An I/O error occurred while attempting to delete an unnecessary Geyser jar! Trying again " + (2 - i) + " more times.");
- ioException.printStackTrace();
+ } catch (Exception e) {
+ logger.warn("An error occurred while attempting to delete an unnecessary Geyser jar! Trying again " + (2 - i) + " more times.");
try {
Thread.sleep(50);
- } catch (InterruptedException interruptException) {
- logger.error("Failed to delay an additional attempt!");
- interruptException.printStackTrace();
+ } catch (InterruptedException interruptedException) {
+ logger.error("Failed to delay an additional attempt!", interruptedException);
}
}
}
- } catch (IOException e) {
- logger.error("An I/O error occurred while attempting to replace the current Geyser jar with the new one!");
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.error("An error occurred while attempting to replace the current Geyser jar with the new one! Giving up.", e);
}
}
@@ -157,9 +154,8 @@ public void scheduleAutoUpdate() {
logger.info("A newer build of Geyser is available! Attempting to download the latest build now...");
GeyserBungeeDownloader.updateGeyser();
}
- } catch (IOException e) {
- logger.error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.");
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.", e);
}
}, 1, getConfig().getLong("Auto-Update-Interval", 24L) * 60, TimeUnit.MINUTES);
}
diff --git a/src/main/java/com/projectg/geyserupdater/bungee/command/GeyserUpdateCommand.java b/src/main/java/com/projectg/geyserupdater/bungee/command/GeyserUpdateCommand.java
index 72309d8d..0f51c189 100644
--- a/src/main/java/com/projectg/geyserupdater/bungee/command/GeyserUpdateCommand.java
+++ b/src/main/java/com/projectg/geyserupdater/bungee/command/GeyserUpdateCommand.java
@@ -1,8 +1,8 @@
package com.projectg.geyserupdater.bungee.command;
import com.projectg.geyserupdater.bungee.util.GeyserBungeeDownloader;
-import com.projectg.geyserupdater.common.Messages;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.GeyserProperties;
import net.md_5.bungee.api.ChatColor;
@@ -11,9 +11,6 @@
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
-import java.io.IOException;
-
-
public class GeyserUpdateCommand extends Command {
public GeyserUpdateCommand() {
@@ -25,33 +22,31 @@ public void execute(CommandSender commandSender, String[] args) {
if (commandSender instanceof ProxiedPlayer player) {
try {
- player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.CHECK_START));
+ player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Constants.CHECK_START));
boolean isLatest = GeyserProperties.isLatestBuild();
if (isLatest) {
- player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.LATEST));
+ player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Constants.LATEST));
} else {
- player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.OUTDATED));
+ player.sendMessage(new TextComponent(ChatColor.GOLD + "[GeyserUpdater] " + Constants.OUTDATED));
GeyserBungeeDownloader.updateGeyser();
}
- } catch (IOException e) {
- player.sendMessage(new TextComponent(ChatColor.RED + "[GeyserUpdater] " + Messages.Command.FAIL_CHECK));
- logger.error(Messages.Command.FAIL_CHECK);
- e.printStackTrace();
+ } catch (Exception e) {
+ player.sendMessage(new TextComponent(ChatColor.RED + "[GeyserUpdater] " + Constants.FAIL_CHECK));
+ logger.error(Constants.FAIL_CHECK, e);
}
} else {
// TODO: filter this against command blocks
try {
- logger.info(Messages.Command.CHECK_START);
+ logger.info(Constants.CHECK_START);
boolean isLatest = GeyserProperties.isLatestBuild();
if (isLatest) {
- logger.info(Messages.Command.LATEST);
+ logger.info(Constants.LATEST);
} else {
- logger.info(Messages.Command.OUTDATED);
+ logger.info(Constants.OUTDATED);
GeyserBungeeDownloader.updateGeyser();
}
- } catch (IOException e) {
- logger.error(Messages.Command.FAIL_CHECK);
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.error(Constants.FAIL_CHECK, e);
}
}
}
diff --git a/src/main/java/com/projectg/geyserupdater/bungee/util/GeyserBungeeDownloader.java b/src/main/java/com/projectg/geyserupdater/bungee/util/GeyserBungeeDownloader.java
index 67d1f7b7..9121acba 100644
--- a/src/main/java/com/projectg/geyserupdater/bungee/util/GeyserBungeeDownloader.java
+++ b/src/main/java/com/projectg/geyserupdater/bungee/util/GeyserBungeeDownloader.java
@@ -2,14 +2,15 @@
import com.projectg.geyserupdater.bungee.BungeeUpdater;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.FileUtils;
-import com.projectg.geyserupdater.common.util.GeyserProperties;
+import com.projectg.geyserupdater.common.util.GeyserDownloadApi;
+import com.projectg.geyserupdater.common.util.ServerPlatform;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
-import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class GeyserBungeeDownloader {
@@ -58,20 +59,14 @@ public static void updateGeyser() {
* @return true if the download was successful, false if not.
*/
private static boolean downloadGeyser() {
- String fileUrl;
- try {
- fileUrl = "https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/" + GeyserProperties.getGeyserGitPropertiesValue("git.branch") + "/lastSuccessfulBuild/artifact/bootstrap/bungeecord/build/libs/Geyser-BungeeCord.jar";
- } catch (IOException e) {
- logger.error("Failed to get the current Geyser branch when attempting to download a new build of Geyser!");
- e.printStackTrace();
- return false;
- }
+ String fileUrl = Constants.GEYSER_BASE_URL + Constants.GEYSER_DOWNLOAD_LINK + ServerPlatform.BUNGEECORD.getUrlComponent();
String outputPath = "plugins/GeyserUpdater/BuildUpdate/Geyser-BungeeCord.jar";
try {
- FileUtils.downloadFile(fileUrl, outputPath);
- } catch (IOException e) {
- logger.error("Failed to download the newest build of Geyser");
- e.printStackTrace();
+ String expectedHash = new GeyserDownloadApi().data().downloads().bungeecord().sha256();
+ FileUtils.downloadFile(fileUrl, outputPath, expectedHash);
+ } catch (Exception e) {
+ logger.error("Failed to download the newest build of Geyser" + e.getMessage());
+ logger.debug("Stack trace: " + e);
return false;
}
diff --git a/src/main/java/com/projectg/geyserupdater/common/Messages.java b/src/main/java/com/projectg/geyserupdater/common/Messages.java
deleted file mode 100644
index 72d0faae..00000000
--- a/src/main/java/com/projectg/geyserupdater/common/Messages.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.projectg.geyserupdater.common;
-
-public class Messages {
-
- public static class Command {
- public static final String CHECK_START = "Checking for updates to Geyser...";
- public static final String LATEST = "You are using the latest build of Geyser!";
- public static final String OUTDATED = "A newer build of Geyser is available! Attempting to download the latest build now...";
- public static final String FAIL_CHECK = "Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.";
- }
-
-}
-
-
-
diff --git a/src/main/java/com/projectg/geyserupdater/common/json_schema/EndpointResponse.java b/src/main/java/com/projectg/geyserupdater/common/json_schema/EndpointResponse.java
new file mode 100644
index 00000000..48338b81
--- /dev/null
+++ b/src/main/java/com/projectg/geyserupdater/common/json_schema/EndpointResponse.java
@@ -0,0 +1,75 @@
+package com.projectg.geyserupdater.common.json_schema;
+
+import lombok.Getter;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+import java.util.List;
+
+@SuppressWarnings({"UnusedDeclaration"})
+@Getter
+@Accessors(fluent = true)
+public class EndpointResponse {
+ private String project_id;
+ private String project_name;
+ private String version;
+ private int build;
+ private Date time;
+ private String channel;
+ private boolean promoted;
+ private List changes;
+ private Downloads downloads;
+
+ @Getter
+ public static class Bungeecord {
+ private String name;
+ private String sha256;
+ }
+
+ @Getter
+ public static class Change {
+ private String commit;
+ private String summary;
+ private String message;
+ }
+
+ @Getter
+ public static class Downloads {
+ private Bungeecord bungeecord;
+ private Fabric fabric;
+ private Spigot spigot;
+ private Sponge sponge;
+ private Standalone standalone;
+ private Velocity velocity;
+ }
+
+ @Getter
+ public static class Fabric {
+ private String name;
+ private String sha256;
+ }
+
+ @Getter
+ public static class Spigot {
+ private String name;
+ private String sha256;
+ }
+
+ @Getter
+ public static class Sponge {
+ private String name;
+ private String sha256;
+ }
+
+ @Getter
+ public static class Standalone {
+ private String name;
+ private String sha256;
+ }
+
+ @Getter
+ public static class Velocity {
+ private String name;
+ private String sha256;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/projectg/geyserupdater/common/logger/UpdaterLogger.java b/src/main/java/com/projectg/geyserupdater/common/logger/UpdaterLogger.java
index db610f46..7683ae03 100644
--- a/src/main/java/com/projectg/geyserupdater/common/logger/UpdaterLogger.java
+++ b/src/main/java/com/projectg/geyserupdater/common/logger/UpdaterLogger.java
@@ -16,6 +16,16 @@ static UpdaterLogger getLogger() {
*/
void error(String message);
+ /**
+ * Logs an error message to the console.
+ *
+ * @param message the message to log to the console
+ */
+ default void error(String message, Throwable throwable) {
+ error(message);
+ throwable.printStackTrace();
+ }
+
/**
* Logs a warning message to the console.
*
diff --git a/src/main/java/com/projectg/geyserupdater/common/util/Constants.java b/src/main/java/com/projectg/geyserupdater/common/util/Constants.java
new file mode 100644
index 00000000..3b016368
--- /dev/null
+++ b/src/main/java/com/projectg/geyserupdater/common/util/Constants.java
@@ -0,0 +1,11 @@
+package com.projectg.geyserupdater.common.util;
+
+public class Constants {
+ public static final String GEYSER_BASE_URL = "https://download.geysermc.org";
+ public static final String GEYSER_LATEST_MASTER_ENDPOINT = "/v2/projects/geyser/versions/latest/builds/latest";
+ public static final String GEYSER_DOWNLOAD_LINK = "/v2/projects/geyser/versions/latest/builds/latest/downloads/";
+ public static final String CHECK_START = "Checking for updates to Geyser...";
+ public static final String LATEST = "You are using the latest build of Geyser!";
+ public static final String OUTDATED = "A newer build of Geyser is available! Attempting to download the latest build now...";
+ public static final String FAIL_CHECK = "Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.";
+}
\ No newline at end of file
diff --git a/src/main/java/com/projectg/geyserupdater/common/util/FileUtils.java b/src/main/java/com/projectg/geyserupdater/common/util/FileUtils.java
index 0f9506df..c5375fb9 100644
--- a/src/main/java/com/projectg/geyserupdater/common/util/FileUtils.java
+++ b/src/main/java/com/projectg/geyserupdater/common/util/FileUtils.java
@@ -1,19 +1,19 @@
package com.projectg.geyserupdater.common.util;
+import com.google.common.hash.Hashing;
+import com.google.common.io.ByteSource;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import org.jetbrains.annotations.Nullable;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
import java.net.URL;
-import java.net.URLConnection;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileUtils {
- // TODO: this whole cached thing only works if you're using checkFile for one file...
/**
* Epoch time of that last occurrence that {@link #checkFile(String, boolean)} directly checked a file. Returns a value of 0 if the check file method has never been called.
@@ -25,6 +25,8 @@ public class FileUtils {
*/
private static boolean cachedResult;
+ // todo this is absolutely abhorrent and assumes we are always downloading the same jar
+
/**
* Check if a file exists.
*
@@ -57,34 +59,46 @@ public static boolean checkFile(String path, boolean allowCached) {
*
* @param fileURL the url of the file
* @param outputPath the path of the output file to write to
+ * @param expectedSha256 the expected sha256 hash of the downloaded file
*/
- public static void downloadFile(String fileURL, String outputPath) throws IOException {
- // TODO: better download code?
-
- UpdaterLogger.getLogger().debug("Attempting to download a file with URL and output path: " + fileURL + " , " + outputPath);
+ public static void downloadFile(String fileURL, String outputPath, @Nullable String expectedSha256) throws IOException {
+ UpdaterLogger logger = UpdaterLogger.getLogger();
+ logger.debug("Attempting to download a file with URL and output path: " + fileURL + " , " + outputPath);
Path outputDirectory = Paths.get(outputPath).getParent();
Files.createDirectories(outputDirectory);
- OutputStream os;
- InputStream is;
- // create a url object
+ // Download Jar file
URL url = new URL(fileURL);
- // connection to the file
- URLConnection connection = url.openConnection();
- // get input stream to the file
- is = connection.getInputStream();
- // get output stream to download file
- os = new FileOutputStream(outputPath);
- final byte[] b = new byte[2048];
- int length;
- // read from input stream and write to output stream
- while ((length = is.read(b)) != -1) {
- os.write(b, 0, length);
+ try (ReadableByteChannel rbc = Channels.newChannel(url.openStream());
+ FileOutputStream fos = new FileOutputStream(outputPath)) {
+
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ } catch (Exception e) {
+ logger.error("Failed to download %s to %s".formatted(fileURL, outputPath), e);
}
- // close streams
- is.close();
- os.close();
- }
-}
+ if (expectedSha256 != null) {
+ // hash the file
+ File file = new File(outputPath);
+ ByteSource byteSource = com.google.common.io.Files.asByteSource(file);
+ String hash = byteSource.hash(Hashing.sha256()).toString();
+
+ // compare
+ if (expectedSha256.equals(hash)) {
+ if (logger.isDebug()) {
+ logger.debug("Successful checksum for %s of %s".formatted(file, hash));
+ }
+ } else {
+ logger.warn("Expected a hash of %s but got %s".formatted(expectedSha256, hash));
+
+ // If the checksum failed we attempt to delete the broken build.
+ if (file.delete()) {
+ logger.warn("Downloaded a jar whose checksum was incorrect, deleting: " + file);
+ } else {
+ logger.error("Failed to delete a defective download, please delete manually: " + file);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/projectg/geyserupdater/common/util/GeyserDownloadApi.java b/src/main/java/com/projectg/geyserupdater/common/util/GeyserDownloadApi.java
new file mode 100644
index 00000000..02e10ef7
--- /dev/null
+++ b/src/main/java/com/projectg/geyserupdater/common/util/GeyserDownloadApi.java
@@ -0,0 +1,26 @@
+package com.projectg.geyserupdater.common.util;
+
+import com.google.gson.Gson;
+import com.projectg.geyserupdater.common.json_schema.EndpointResponse;
+
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class GeyserDownloadApi {
+ private static final Gson gson = new Gson();
+
+ public EndpointResponse data() throws Exception {
+ URL url = new URL(Constants.GEYSER_BASE_URL + Constants.GEYSER_LATEST_MASTER_ENDPOINT);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+
+ if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new IllegalStateException("Received %s from GET of %s".formatted(connection.getResponseCode(), url));
+ }
+
+ try (InputStreamReader reader = new InputStreamReader(connection.getInputStream())) {
+ return gson.fromJson(reader, EndpointResponse.class);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/projectg/geyserupdater/common/util/GeyserProperties.java b/src/main/java/com/projectg/geyserupdater/common/util/GeyserProperties.java
index d84489eb..4c45e261 100644
--- a/src/main/java/com/projectg/geyserupdater/common/util/GeyserProperties.java
+++ b/src/main/java/com/projectg/geyserupdater/common/util/GeyserProperties.java
@@ -2,12 +2,8 @@
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.util.WebUtils;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class GeyserProperties {
@@ -21,14 +17,16 @@ public class GeyserProperties {
* @return true if local build number equals latest build number on Geyser CI
* @throws IOException if it fails to fetch either build number
*/
- public static boolean isLatestBuild() throws IOException {
+ public static boolean isLatestBuild() throws Exception {
UpdaterLogger.getLogger().debug("Running isLatestBuild()");
- int jenkinsBuildNumber = getLatestGeyserBuildNumberFromJenkins(getGeyserGitPropertiesValue("git.branch"));
+ // Removed get branch since current Geyser endpoints do not yet support it
+ // getLatestGeyserBuildNumberFromDownloadPage(getGeyserGitPropertiesValue("git.branch"));
+ int downloadPageBuildNumber = getLatestGeyserBuildNumberFromDownloadPage();
int localBuildNumber = Integer.parseInt(getGeyserGitPropertiesValue("git.build.number"));
// Compare build numbers.
// We treat higher build numbers as "out of date" here because Geyser's build numbers have been (accidentally) reset in the past.
// Self-compiled builds of Geyser simply do not have a `git.build.number` value, so it is /very/ unlikely that a user will ever have a Git build number higher than upstream anyway.
- return jenkinsBuildNumber == localBuildNumber;
+ return downloadPageBuildNumber == localBuildNumber;
}
/** Query the git properties of Geyser
@@ -44,15 +42,12 @@ public static String getGeyserGitPropertiesValue(String propertyKey) throws IOEx
return gitProperties.getProperty(propertyKey);
}
- /** Get the latest build number of a given branch of Geyser from jenkins CI
+ /** Get the latest build number of a given branch of Geyser from Geyser download page.
*
- * @param gitBranch the branch to query
- * @return the latest build number
- * @throws UnsupportedEncodingException if failed to encode the given gitBranch
+ * @return the latest build number from Geyser API
*/
- public static int getLatestGeyserBuildNumberFromJenkins(String gitBranch) throws UnsupportedEncodingException {
+ public static int getLatestGeyserBuildNumberFromDownloadPage() throws Exception {
UpdaterLogger.getLogger().debug("Running getLatestGeyserBuildNumberFromJenkins()");
- String buildXMLContents = WebUtils.getBody("https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/" + URLEncoder.encode(gitBranch, StandardCharsets.UTF_8.toString()) + "/lastSuccessfulBuild/api/xml?xpath=//buildNumber");
- return Integer.parseInt(buildXMLContents.replaceAll("<(\\\\)?(/)?buildNumber>", "").trim());
+ return new GeyserDownloadApi().data().build();
}
}
\ No newline at end of file
diff --git a/src/main/java/com/projectg/geyserupdater/common/util/ServerPlatform.java b/src/main/java/com/projectg/geyserupdater/common/util/ServerPlatform.java
new file mode 100644
index 00000000..6366ae7d
--- /dev/null
+++ b/src/main/java/com/projectg/geyserupdater/common/util/ServerPlatform.java
@@ -0,0 +1,18 @@
+package com.projectg.geyserupdater.common.util;
+
+public enum ServerPlatform {
+ SPIGOT("spigot"),
+ BUNGEECORD("bungeecord"),
+ VELOCITY("velocity");
+
+ private final String urlComponent;
+
+ ServerPlatform(String urlComponent) {
+ this.urlComponent = urlComponent;
+ }
+
+ public String getUrlComponent() {
+ return urlComponent;
+ }
+}
+
diff --git a/src/main/java/com/projectg/geyserupdater/spigot/SpigotUpdater.java b/src/main/java/com/projectg/geyserupdater/spigot/SpigotUpdater.java
index 913a0cdb..56a987da 100644
--- a/src/main/java/com/projectg/geyserupdater/spigot/SpigotUpdater.java
+++ b/src/main/java/com/projectg/geyserupdater/spigot/SpigotUpdater.java
@@ -108,7 +108,7 @@ public void checkUpdaterVersion() {
@Override
public void run() {
String latestVersion = SpigotResourceUpdateChecker.getVersion();
- if (latestVersion == null || latestVersion.length() == 0) {
+ if (latestVersion == null || latestVersion.isEmpty()) {
logger.error("Failed to determine the latest GeyserUpdater version!");
} else {
if (latestVersion.equals(pluginVersion)) {
@@ -138,9 +138,8 @@ public void run() {
UpdaterLogger.getLogger().info("A newer build of Geyser is available! Attempting to download the latest build now...");
GeyserSpigotDownloader.updateGeyser();
}
- } catch (IOException e) {
- UpdaterLogger.getLogger().error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.");
- e.printStackTrace();
+ } catch (Exception e) {
+ UpdaterLogger.getLogger().error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.", e);
}
// Auto-Update-Interval is in hours. We convert it into ticks
}
diff --git a/src/main/java/com/projectg/geyserupdater/spigot/command/GeyserUpdateCommand.java b/src/main/java/com/projectg/geyserupdater/spigot/command/GeyserUpdateCommand.java
index bddb8bf6..b274da3e 100644
--- a/src/main/java/com/projectg/geyserupdater/spigot/command/GeyserUpdateCommand.java
+++ b/src/main/java/com/projectg/geyserupdater/spigot/command/GeyserUpdateCommand.java
@@ -1,7 +1,7 @@
package com.projectg.geyserupdater.spigot.command;
-import com.projectg.geyserupdater.common.Messages;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.GeyserProperties;
import com.projectg.geyserupdater.spigot.util.GeyserSpigotDownloader;
@@ -14,8 +14,6 @@
import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
-
public class GeyserUpdateCommand implements CommandExecutor {
@Override
@@ -24,34 +22,32 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
if (sender instanceof Player player) {
if (command.getName().equalsIgnoreCase("geyserupdate") && player.hasPermission("gupdater.geyserupdate")) {
- sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.CHECK_START);
+ sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Constants.CHECK_START);
try {
boolean isLatest = GeyserProperties.isLatestBuild();
if (isLatest) {
- sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.LATEST);
+ sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Constants.LATEST);
} else {
- sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Messages.Command.OUTDATED);
+ sender.sendMessage(ChatColor.GOLD + "[GeyserUpdater] " + Constants.OUTDATED);
GeyserSpigotDownloader.updateGeyser();
}
- } catch (IOException e) {
- sender.sendMessage(ChatColor.RED + "[GeyserUpdater] " + Messages.Command.FAIL_CHECK);
- logger.error(Messages.Command.FAIL_CHECK);
- e.printStackTrace();
+ } catch (Exception e) {
+ sender.sendMessage(ChatColor.RED + "[GeyserUpdater] " + Constants.FAIL_CHECK);
+ logger.error(Constants.FAIL_CHECK, e);
}
}
} else if (sender instanceof ConsoleCommandSender) {
- logger.info(Messages.Command.CHECK_START);
+ logger.info(Constants.CHECK_START);
try {
boolean isLatest = GeyserProperties.isLatestBuild();
if (isLatest) {
- logger.info(Messages.Command.LATEST);
+ logger.info(Constants.LATEST);
} else {
- logger.info(Messages.Command.OUTDATED);
+ logger.info(Constants.OUTDATED);
GeyserSpigotDownloader.updateGeyser();
}
- } catch (IOException e) {
- logger.error(Messages.Command.FAIL_CHECK);
- e.printStackTrace();
+ } catch (Exception e) {
+ logger.error(Constants.FAIL_CHECK, e);
}
} else {
return false;
diff --git a/src/main/java/com/projectg/geyserupdater/spigot/util/GeyserSpigotDownloader.java b/src/main/java/com/projectg/geyserupdater/spigot/util/GeyserSpigotDownloader.java
index dca20b06..e0b208be 100644
--- a/src/main/java/com/projectg/geyserupdater/spigot/util/GeyserSpigotDownloader.java
+++ b/src/main/java/com/projectg/geyserupdater/spigot/util/GeyserSpigotDownloader.java
@@ -1,8 +1,10 @@
package com.projectg.geyserupdater.spigot.util;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.FileUtils;
-import com.projectg.geyserupdater.common.util.GeyserProperties;
+import com.projectg.geyserupdater.common.util.GeyserDownloadApi;
+import com.projectg.geyserupdater.common.util.ServerPlatform;
import com.projectg.geyserupdater.spigot.SpigotUpdater;
import org.bukkit.Bukkit;
@@ -10,7 +12,6 @@
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
-import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -73,21 +74,14 @@ public void run() {
* @return true if the download was successful, false if not.
*/
private static boolean downloadGeyser() {
- String fileUrl;
- try {
- fileUrl = "https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/" + GeyserProperties.getGeyserGitPropertiesValue("git.branch") + "/lastSuccessfulBuild/artifact/bootstrap/spigot/build/libs/Geyser-Spigot.jar";
- } catch (IOException e) {
- logger.error("Failed to get the current Geyser branch when attempting to download a new build of Geyser!");
- e.printStackTrace();
- return false;
- }
+ String fileUrl = Constants.GEYSER_BASE_URL + Constants.GEYSER_DOWNLOAD_LINK + ServerPlatform.SPIGOT.getUrlComponent();
// todo: make sure we use the update folder defined in bukkit.yml (it can be changed)
String outputPath = "plugins/update/Geyser-Spigot.jar";
try {
- FileUtils.downloadFile(fileUrl, outputPath);
- } catch (IOException e) {
- logger.error("Failed to download the newest build of Geyser");
- e.printStackTrace();
+ String expectedHash = new GeyserDownloadApi().data().downloads().spigot().sha256();
+ FileUtils.downloadFile(fileUrl, outputPath, expectedHash);
+ } catch (Exception e) {
+ logger.error("Failed to download the newest build of Geyser", e);
return false;
}
@@ -116,19 +110,16 @@ public void run() {
try {
spigotServer = SpigotUpdater.getPlugin().getServer().getClass().getMethod("spigot").invoke(SpigotUpdater.getPlugin().getServer());
} catch (NoSuchMethodException e) {
- logger.error("You are not running Spigot (or a fork of it, such as Paper)! GeyserUpdater cannot automatically restart your server!");
- e.printStackTrace();
+ logger.error("You are not running Spigot (or a fork of it, such as Paper)! GeyserUpdater cannot automatically restart your server!", e);
return;
}
Method restartMethod = spigotServer.getClass().getMethod("restart");
restartMethod.setAccessible(true);
restartMethod.invoke(spigotServer);
} catch (NoSuchMethodException e) {
- logger.error("Your server version is too old to be able to be automatically restarted!");
- e.printStackTrace();
+ logger.error("Your server version is too old to be able to be automatically restarted!", e);
} catch (InvocationTargetException | IllegalAccessException e) {
- logger.error("Failed to restart the server!");
- e.printStackTrace();
+ logger.error("Failed to restart the server!", e);
}
}
}.runTaskLater(plugin, 200); // 200 ticks is around 10 seconds (at 20 TPS)
diff --git a/src/main/java/com/projectg/geyserupdater/velocity/VelocityUpdater.java b/src/main/java/com/projectg/geyserupdater/velocity/VelocityUpdater.java
index d9ca5f4a..3aa5843c 100644
--- a/src/main/java/com/projectg/geyserupdater/velocity/VelocityUpdater.java
+++ b/src/main/java/com/projectg/geyserupdater/velocity/VelocityUpdater.java
@@ -36,7 +36,7 @@
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
-@Plugin(id = "geyserupdater", name = "GeyserUpdater", version = "1.6.1", description = "Automatically or manually downloads new builds of Geyser and applies them on server restart.", authors = {"Jens"},
+@Plugin(id = "geyserupdater", name = "GeyserUpdater", version = "1.6.3", description = "Automatically or manually downloads new builds of Geyser and applies them on server restart.", authors = {"KejonaMC"},
dependencies = {@Dependency(id = "geyser")})
public class VelocityUpdater {
@@ -110,20 +110,17 @@ public void onShutdown(ProxyShutdownEvent event) {
try {
deleteGeyserJar();
break;
- } catch (IOException ioException) {
- UpdaterLogger.getLogger().warn("An I/O error occurred while attempting to delete an unnecessary Geyser jar! Trying again " + (2 - i) + " more times.");
- ioException.printStackTrace();
+ } catch (Exception e) {
+ UpdaterLogger.getLogger().warn("An error occurred while attempting to delete an unnecessary Geyser jar! Trying again " + (2 - i) + " more times.");
try {
Thread.sleep(50);
} catch (InterruptedException interruptException) {
- UpdaterLogger.getLogger().error("Failed to delay an additional attempt!");
- interruptException.printStackTrace();
+ UpdaterLogger.getLogger().error("Failed to delay an additional attempt!", interruptException);
}
}
}
} catch (IOException e) {
- UpdaterLogger.getLogger().error("An I/O error occurred while attempting to replace the current Geyser jar with the new one!");
- e.printStackTrace();
+ UpdaterLogger.getLogger().error("An error occurred while attempting to replace the current Geyser jar with the new one! Giving up.", e);
}
}
@@ -181,9 +178,8 @@ public void scheduleAutoUpdate() {
UpdaterLogger.getLogger().info("A newer build of Geyser is available! Attempting to download the latest build now...");
GeyserVelocityDownloader.updateGeyser();
}
- } catch (IOException e) {
- UpdaterLogger.getLogger().error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.");
- e.printStackTrace();
+ } catch (Exception e) {
+ UpdaterLogger.getLogger().error("Failed to check for updates to Geyser! We were unable to reach the Geyser build server, or your local branch does not exist on it.", e);
}
})
.delay(1L, TimeUnit.MINUTES)
diff --git a/src/main/java/com/projectg/geyserupdater/velocity/command/GeyserUpdateCommand.java b/src/main/java/com/projectg/geyserupdater/velocity/command/GeyserUpdateCommand.java
index c5ddae66..b50ade15 100644
--- a/src/main/java/com/projectg/geyserupdater/velocity/command/GeyserUpdateCommand.java
+++ b/src/main/java/com/projectg/geyserupdater/velocity/command/GeyserUpdateCommand.java
@@ -1,6 +1,6 @@
package com.projectg.geyserupdater.velocity.command;
-import com.projectg.geyserupdater.common.Messages;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.GeyserProperties;
import com.projectg.geyserupdater.velocity.util.GeyserVelocityDownloader;
@@ -8,32 +8,30 @@
import com.velocitypowered.api.command.RawCommand;
import net.kyori.adventure.text.Component;
-
-import java.io.IOException;
+import org.jetbrains.annotations.NotNull;
public class GeyserUpdateCommand implements RawCommand {
@Override
- public void execute(final Invocation invocation) {
+ public void execute(final @NotNull Invocation invocation) {
CommandSource source = invocation.source();
try {
- source.sendMessage(Component.text(Messages.Command.CHECK_START));
+ source.sendMessage(Component.text(Constants.CHECK_START));
boolean isLatest = GeyserProperties.isLatestBuild();
if (isLatest) {
- source.sendMessage(Component.text(Messages.Command.LATEST));
+ source.sendMessage(Component.text(Constants.LATEST));
} else {
- source.sendMessage(Component.text(Messages.Command.OUTDATED));
+ source.sendMessage(Component.text(Constants.OUTDATED));
GeyserVelocityDownloader.updateGeyser();
}
- } catch (IOException e) {
- source.sendMessage(Component.text(Messages.Command.FAIL_CHECK));
+ } catch (Exception e) {
+ source.sendMessage(Component.text(Constants.FAIL_CHECK));
e.printStackTrace();
}
}
@Override
- public boolean hasPermission(final Invocation invocation) {
+ public boolean hasPermission(final @NotNull Invocation invocation) {
return invocation.source().hasPermission("gupdater.geyserupdate");
}
}
-
diff --git a/src/main/java/com/projectg/geyserupdater/velocity/logger/Slf4jUpdaterLogger.java b/src/main/java/com/projectg/geyserupdater/velocity/logger/Slf4jUpdaterLogger.java
index d8fbb5f5..fd5b8440 100644
--- a/src/main/java/com/projectg/geyserupdater/velocity/logger/Slf4jUpdaterLogger.java
+++ b/src/main/java/com/projectg/geyserupdater/velocity/logger/Slf4jUpdaterLogger.java
@@ -19,6 +19,11 @@ public void error(String message) {
logger.error(message);
}
+ @Override
+ public void error(String message, Throwable throwable) {
+ logger.error(message, throwable);
+ }
+
@Override
public void warn(String message) {
logger.warn(message);
diff --git a/src/main/java/com/projectg/geyserupdater/velocity/util/GeyserVelocityDownloader.java b/src/main/java/com/projectg/geyserupdater/velocity/util/GeyserVelocityDownloader.java
index d62bb05c..697165ab 100644
--- a/src/main/java/com/projectg/geyserupdater/velocity/util/GeyserVelocityDownloader.java
+++ b/src/main/java/com/projectg/geyserupdater/velocity/util/GeyserVelocityDownloader.java
@@ -1,8 +1,10 @@
package com.projectg.geyserupdater.velocity.util;
import com.projectg.geyserupdater.common.logger.UpdaterLogger;
+import com.projectg.geyserupdater.common.util.Constants;
import com.projectg.geyserupdater.common.util.FileUtils;
-import com.projectg.geyserupdater.common.util.GeyserProperties;
+import com.projectg.geyserupdater.common.util.GeyserDownloadApi;
+import com.projectg.geyserupdater.common.util.ServerPlatform;
import com.projectg.geyserupdater.velocity.VelocityUpdater;
import com.velocitypowered.api.proxy.Player;
@@ -11,7 +13,6 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
-import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class GeyserVelocityDownloader {
@@ -63,20 +64,14 @@ public static void updateGeyser() {
* @return true if the download was successful, false if not.
*/
private static boolean downloadGeyser() {
- String fileUrl;
- try {
- fileUrl = "https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/" + GeyserProperties.getGeyserGitPropertiesValue("git.branch") + "/lastSuccessfulBuild/artifact/bootstrap/velocity/build/libs/Geyser-Velocity.jar";
- } catch (IOException e) {
- logger.error("Failed to get the current Geyser branch when attempting to download a new build of Geyser!");
- e.printStackTrace();
- return false;
- }
+ String fileUrl = Constants.GEYSER_BASE_URL + Constants.GEYSER_DOWNLOAD_LINK + ServerPlatform.VELOCITY.getUrlComponent();
String outputPath = "plugins/GeyserUpdater/BuildUpdate/Geyser-Velocity.jar";
+
try {
- FileUtils.downloadFile(fileUrl, outputPath);
- } catch (IOException e) {
- logger.error("Failed to download the newest build of Geyser");
- e.printStackTrace();
+ String expectedHash = new GeyserDownloadApi().data().downloads().velocity().sha256();
+ FileUtils.downloadFile(fileUrl, outputPath, expectedHash);
+ } catch (Exception e) {
+ logger.error("Failed to download the newest build of Geyser", e);
return false;
}
diff --git a/src/main/resources/bungee.yml b/src/main/resources/bungee.yml
index b2cdfbdb..26733528 100644
--- a/src/main/resources/bungee.yml
+++ b/src/main/resources/bungee.yml
@@ -2,5 +2,5 @@ name: ${project.name}
main: com.projectg.geyserupdater.bungee.BungeeUpdater
version: ${project.version}
description: Automatically or manually downloads new builds of Geyser and applies them on server restart.
-author: Jens
+author: KejonaMC
depends: ["Geyser-BungeeCord"]