2020-05-06 17:48:49 +08:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2019-05-27 17:13:41 +08:00
From: Zach Brown <zach@zachbr.io>
Date: Mon, 27 May 2019 03:40:05 -0500
Subject: [PATCH] Implement Paper VersionChecker
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
new file mode 100644
2021-03-10 12:56:13 +08:00
index 0000000000000000000000000000000000000000..c8b911e5d013525ffc5d2911ee0e421dd916cb00
2019-05-27 17:13:41 +08:00
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
2021-03-10 12:56:13 +08:00
@@ -0,0 +1,117 @@
2019-05-27 17:13:41 +08:00
+package com.destroystokyo.paper;
+
+import com.destroystokyo.paper.util.VersionFetcher;
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import com.google.gson.*;
2021-03-10 12:56:13 +08:00
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
2019-05-27 17:13:41 +08:00
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class PaperVersionFetcher implements VersionFetcher {
2019-06-25 21:40:54 +08:00
+ private static final java.util.regex.Pattern VER_PATTERN = java.util.regex.Pattern.compile("^([0-9\\.]*)\\-.*R"); // R is an anchor, will always give '-R' at end
2019-12-14 06:56:02 +08:00
+ private static final String GITHUB_BRANCH_NAME = "master";
2019-05-27 17:13:41 +08:00
+ private static @Nullable String mcVer;
+
+ @Override
+ public long getCacheTime() {
+ return 720000;
+ }
+
+ @Nonnull
+ @Override
2021-03-10 12:56:13 +08:00
+ public Component getVersionMessage(@Nonnull String serverVersion) {
2019-05-27 17:13:41 +08:00
+ String[] parts = serverVersion.substring("git-Paper-".length()).split("[-\\s]");
+ return getUpdateStatusMessage("PaperMC/Paper", GITHUB_BRANCH_NAME, parts[0]);
+ }
+
+ private static @Nullable String getMinecraftVersion() {
+ if (mcVer == null) {
+ java.util.regex.Matcher matcher = VER_PATTERN.matcher(org.bukkit.Bukkit.getBukkitVersion());
+ if (matcher.find()) {
+ String result = matcher.group();
2019-06-25 21:40:54 +08:00
+ mcVer = result.substring(0, result.length() - 2); // strip 'R' anchor and trailing '-'
2019-05-27 17:13:41 +08:00
+ } else {
+ org.bukkit.Bukkit.getLogger().warning("Unable to match version to pattern! Report to PaperMC!");
+ org.bukkit.Bukkit.getLogger().warning("Pattern: " + VER_PATTERN.toString());
+ org.bukkit.Bukkit.getLogger().warning("Version: " + org.bukkit.Bukkit.getBukkitVersion());
+ }
+ }
+
+ return mcVer;
+ }
+
2021-03-10 12:56:13 +08:00
+ private static Component getUpdateStatusMessage(@Nonnull String repo, @Nonnull String branch, @Nonnull String versionInfo) {
2019-05-27 17:13:41 +08:00
+ int distance;
+ try {
+ int jenkinsBuild = Integer.parseInt(versionInfo);
+ distance = fetchDistanceFromSiteApi(jenkinsBuild, getMinecraftVersion());
+ } catch (NumberFormatException ignored) {
+ versionInfo = versionInfo.replace("\"", "");
+ distance = fetchDistanceFromGitHub(repo, branch, versionInfo);
+ }
+
+ switch (distance) {
+ case -1:
2021-03-10 12:56:13 +08:00
+ return Component.text("Error obtaining version information", NamedTextColor.YELLOW);
2019-05-27 17:13:41 +08:00
+ case 0:
2021-03-10 12:56:13 +08:00
+ return Component.text("You are running the latest version", NamedTextColor.GREEN);
2019-05-27 17:13:41 +08:00
+ case -2:
2021-03-10 12:56:13 +08:00
+ return Component.text("Unknown version", NamedTextColor.YELLOW);
2019-05-27 17:13:41 +08:00
+ default:
2021-03-10 12:56:13 +08:00
+ return Component.text("You are " + distance + " version(s) behind", NamedTextColor.YELLOW);
2019-05-27 17:13:41 +08:00
+ }
+ }
+
+ private static int fetchDistanceFromSiteApi(int jenkinsBuild, @Nullable String siteApiVersion) {
+ if (siteApiVersion == null) { return -1; }
+ try {
+ try (BufferedReader reader = Resources.asCharSource(
+ new URL("https://papermc.io/api/v1/paper/" + siteApiVersion + "/latest"),
+ Charsets.UTF_8
+ ).openBufferedStream()) {
+ JsonObject json = new Gson().fromJson(reader, JsonObject.class);
+ int latest = json.get("build").getAsInt();
+ return latest - jenkinsBuild;
+ } catch (JsonSyntaxException ex) {
+ ex.printStackTrace();
+ return -1;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
+ // Contributed by Techcable <Techcable@outlook.com> in GH-65
+ private static int fetchDistanceFromGitHub(@Nonnull String repo, @Nonnull String branch, @Nonnull String hash) {
+ try {
+ HttpURLConnection connection = (HttpURLConnection) new URL("https://api.github.com/repos/" + repo + "/compare/" + branch + "..." + hash).openConnection();
+ connection.connect();
+ if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return -2; // Unknown commit
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) {
+ JsonObject obj = new Gson().fromJson(reader, JsonObject.class);
+ String status = obj.get("status").getAsString();
+ switch (status) {
+ case "identical":
+ return 0;
+ case "behind":
+ return obj.get("behind_by").getAsInt();
+ default:
+ return -1;
+ }
+ } catch (JsonSyntaxException | NumberFormatException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
2021-04-22 20:48:49 +08:00
index 8f737f63f280c00c1276bd1dc3ecf60448732ca8..8aa9e7796ea39c09a965750d06c3d358250f33b8 100644
2019-05-27 17:13:41 +08:00
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
2021-04-22 20:48:49 +08:00
@@ -370,6 +370,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
2019-05-27 17:13:41 +08:00
public String getTimingsServerName() {
return com.destroystokyo.paper.PaperConfig.timingsServerName;
}
+
+ @Override
+ public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
+ return new com.destroystokyo.paper.PaperVersionFetcher();
+ }
// Paper end
/**