Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/java/net/skullian/updater/UpdateListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
}
86 changes: 66 additions & 20 deletions src/main/java/net/skullian/updater/Updater.java
Original file line number Diff line number Diff line change
Expand Up @@ -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("<red>Failed to fetch latest version: " + error, senders);
ChatUtils.sendMessage(
"<red>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(
"<green>A new version of InteractiveChat-PacketEvents is available: "
+ latestBuild.name() + "!",
senders);
ChatUtils.sendMessage(
"<grey>Download at: <click:open_url:'" + url + "'>"
+ url + "</click>",
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(
"<yellow>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("<green>A new version of InteractiveChat-PacketEvents is available: " + latestBuild.id() + "!", senders);
ChatUtils.sendMessage("<grey>Download at: <click:open_url:'" + url + "'>" + url + "</click>", senders);
} else {
ChatUtils.sendMessage("<yellow>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(
"<red>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;
}

Expand All @@ -57,5 +104,4 @@ public static final class UpdateStatus {
private boolean isUpToDate;
private boolean failed;
}

}
17 changes: 12 additions & 5 deletions src/main/java/net/skullian/util/GithubUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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,

Expand Down