diff --git a/src/main/java/net/skullian/updater/UpdateListener.java b/src/main/java/net/skullian/updater/UpdateListener.java index 1ab06c6..29ece0a 100644 --- a/src/main/java/net/skullian/updater/UpdateListener.java +++ b/src/main/java/net/skullian/updater/UpdateListener.java @@ -25,6 +25,8 @@ public void onJoin(PlayerJoinEvent event) { @EventHandler public void onStart(ServerLoadEvent event) { - checkUpdate(Bukkit.getConsoleSender()); + Scheduler.runTaskAsynchronously( + InteractiveChatPacketEvents.instance, + () -> checkUpdate(Bukkit.getConsoleSender())); } } diff --git a/src/main/java/net/skullian/updater/Updater.java b/src/main/java/net/skullian/updater/Updater.java index e628d77..52b5f04 100644 --- a/src/main/java/net/skullian/updater/Updater.java +++ b/src/main/java/net/skullian/updater/Updater.java @@ -7,46 +7,93 @@ import net.skullian.util.GithubBuildInfo; import net.skullian.util.GithubUtils; import org.bukkit.command.CommandSender; -import org.bukkit.event.Listener; import java.io.IOException; import java.util.Locale; -public class Updater implements Listener { +public final class Updater { + + private Updater() { + } public static UpdateStatus checkUpdate(CommandSender... senders) { GithubBuildInfo currentBuild = GithubBuildInfo.CURRENT; - GithubBuildInfo latestBuild; - GithubUtils.GitHubStatusLookup lookupStatus; - UpdateStatus updateStatus = new UpdateStatus(false, false); try { if (currentBuild.stable()) { - latestBuild = GithubUtils.lookupLatestRelease(); - lookupStatus = GithubUtils.compare(latestBuild.id(), currentBuild.id()); - } else { - latestBuild = null; - lookupStatus = GithubUtils.compare(GithubUtils.MAIN_BRANCH, currentBuild.id()); + return checkStableUpdate(currentBuild, senders, updateStatus); } + + return checkDevelopmentUpdate(currentBuild, senders, updateStatus); } catch (IOException error) { - ChatUtils.sendMessage("Failed to fetch latest version: " + error, senders); + ChatUtils.sendMessage( + "Failed to check for updates. Please try again later.", + senders); + updateStatus.setFailed(true); return updateStatus; } + } + + private static UpdateStatus checkStableUpdate( + GithubBuildInfo currentBuild, + CommandSender[] senders, + UpdateStatus updateStatus) throws IOException { + GithubBuildInfo latestBuild = GithubUtils.lookupLatestRelease(); + + // Stable builds must compare release versions, not a release tag + // against the installed build's commit SHA. + if (currentBuild.name().equals(latestBuild.name())) { + updateStatus.setUpToDate(true); + return updateStatus; + } + + String url = "https://github.com/TerraByteDev/InteractiveChat-PacketEvents/releases/tag/" + + latestBuild.id(); + + ChatUtils.sendMessage( + "A new version of InteractiveChat-PacketEvents is available: " + + latestBuild.name() + "!", + senders); + ChatUtils.sendMessage( + "Download at: " + + url + "", + senders); + + return updateStatus; + } + + private static UpdateStatus checkDevelopmentUpdate( + GithubBuildInfo currentBuild, + CommandSender[] senders, + UpdateStatus updateStatus) throws IOException { + GithubUtils.GitHubStatusLookup lookupStatus = GithubUtils.compare( + GithubUtils.MAIN_BRANCH, + currentBuild.id()); if (lookupStatus.isBehind()) { - if (currentBuild.stable()) { - String url = "https://github.com/TerraByteDev/InteractiveChat-PacketEvents/releases/tag/" + latestBuild.id(); + ChatUtils.sendMessage( + "You are running a development build of InteractiveChat-PacketEvents!\n" + + "The latest available development build is " + + String.format(Locale.ROOT, "%,d", lookupStatus.getDistance()) + + " commits ahead.", + senders); - ChatUtils.sendMessage("A new version of InteractiveChat-PacketEvents is available: " + latestBuild.id() + "!", senders); - ChatUtils.sendMessage("Download at: " + url + "", senders); - } else { - ChatUtils.sendMessage("You are running a development build of InteractiveChat-PacketEvents!\nThe latest available development build is " + String.format(Locale.ROOT, "%,d", lookupStatus.getDistance()) + " commits ahead.", senders); - } + return updateStatus; + } + + if (lookupStatus.getStatus() == GithubUtils.GitHubStatus.FAILURE + || lookupStatus.getStatus() == GithubUtils.GitHubStatus.UNKNOWN + || lookupStatus.getStatus() == GithubUtils.GitHubStatus.DIVERGED) { + ChatUtils.sendMessage( + "Failed to determine whether a newer development build is available.", + senders); + updateStatus.setFailed(true); + return updateStatus; } - updateStatus.setUpToDate(!lookupStatus.isBehind()); + updateStatus.setUpToDate(true); return updateStatus; } @@ -57,5 +104,4 @@ public static final class UpdateStatus { private boolean isUpToDate; private boolean failed; } - } diff --git a/src/main/java/net/skullian/util/GithubUtils.java b/src/main/java/net/skullian/util/GithubUtils.java index cea0ffd..90dd673 100644 --- a/src/main/java/net/skullian/util/GithubUtils.java +++ b/src/main/java/net/skullian/util/GithubUtils.java @@ -22,21 +22,25 @@ public class GithubUtils { private static final String API_BASE = "https://api.github.com/repos/"; // https://docs.github.com/en/rest/releases/releases#get-the-latest-release - private static final String API_LATEST_RELEASE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/releases/latest"; + private static final String API_LATEST_RELEASE = API_BASE + + "TerraByteDev/InteractiveChat-PacketEvents/releases/latest"; // https://docs.github.com/en/rest/commits/commits#compare-two-commits private static final String API_COMPARE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/compare/%s...%s"; - private GithubUtils() {} + private GithubUtils() { + } public static GithubBuildInfo lookupLatestRelease() throws IOException { URL url = new URL(API_LATEST_RELEASE); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); + https.setConnectTimeout(5000); + https.setReadTimeout(5000); final int responseCode = https.getResponseCode(); if (isSuccessfulResponse(responseCode)) { try (InputStream in = https.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { return parseBuildInfo(reader); } } else { @@ -53,11 +57,13 @@ private static GithubBuildInfo parseBuildInfo(BufferedReader reader) { public static GitHubStatusLookup compare(@NotNull String base, @NotNull String head) throws IOException { URL url = new URL(String.format(API_COMPARE, base, head)); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); + https.setConnectTimeout(5000); + https.setReadTimeout(5000); final int responseCode = https.getResponseCode(); if (isSuccessfulResponse(responseCode)) { try (InputStream in = https.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { return parseComparison(reader); } } else if (responseCode == HttpsURLConnection.HTTP_NOT_FOUND) { @@ -119,7 +125,8 @@ public enum GitHubStatus { // Internal types /** - * Represents the case when a BASEHEAD is unknown to GitHub, private builds, for example. + * Represents the case when a BASEHEAD is unknown to GitHub, private builds, for + * example. */ UNKNOWN,