mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-19 17:37:42 +01:00
Updated Upstream (Paper)
Upstream has released updates that appear to apply and compile correctly Paper Changes: PaperMC/Paper@8f736dbf Improve outdated version check (#12589) PaperMC/Paper@3ebc5b33 Don't apply oversized sanitizers in components disabled by config (#13466)
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
package org.purpurmc.purpur;
|
||||
|
||||
import com.destroystokyo.paper.VersionHistoryManager;
|
||||
import com.destroystokyo.paper.util.VersionFetcher;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.ServerBuildInfo;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.TextColor.color;
|
||||
import static io.papermc.paper.ServerBuildInfo.StringRepresentation.VERSION_SIMPLE;
|
||||
|
||||
/**
|
||||
* Modified version of Paper's Version Fetcher before Fill API implementation.
|
||||
*/
|
||||
@DefaultQualifier(NonNull.class)
|
||||
public class PurpurVersionFetcher implements VersionFetcher {
|
||||
private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
private static final int DISTANCE_ERROR = -1;
|
||||
private static final int DISTANCE_UNKNOWN = -2;
|
||||
private static final String DOWNLOAD_PAGE = "https://purpurmc.org/downloads";
|
||||
private static final String REPOSITORY = "PurpurMC/Purpur";
|
||||
private static final ServerBuildInfo BUILD_INFO;
|
||||
private static final String USER_AGENT;
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
static {
|
||||
BUILD_INFO = ServerBuildInfo.buildInfo();
|
||||
USER_AGENT = BUILD_INFO.brandName() + "/" + BUILD_INFO.asString(VERSION_SIMPLE) + " (https://purpurmc.org)";
|
||||
}
|
||||
|
||||
private static int distance = DISTANCE_UNKNOWN;
|
||||
public int distance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCacheTime() {
|
||||
return 720000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getVersionMessage() {
|
||||
final Component updateMessage;
|
||||
if (BUILD_INFO.buildNumber().isEmpty() && BUILD_INFO.gitCommit().isEmpty()) {
|
||||
updateMessage = text("You are running a development version without access to version information", color(0xFF5300));
|
||||
} else {
|
||||
updateMessage = getUpdateStatusMessage();
|
||||
}
|
||||
final @Nullable Component history = this.getHistory();
|
||||
|
||||
return history != null ? Component.textOfChildren(updateMessage, Component.newline(), history) : updateMessage;
|
||||
}
|
||||
|
||||
private static Component getUpdateStatusMessage() {
|
||||
final OptionalInt buildNumber = BUILD_INFO.buildNumber();
|
||||
if (buildNumber.isPresent()) {
|
||||
distance = fetchDistanceFromSiteApi(buildNumber.getAsInt());
|
||||
} else {
|
||||
final Optional<String> gitBranch = BUILD_INFO.gitBranch();
|
||||
final Optional<String> gitCommit = BUILD_INFO.gitCommit();
|
||||
if (gitBranch.isPresent() && gitCommit.isPresent()) {
|
||||
distance = fetchDistanceFromGitHub(gitBranch.get(), gitCommit.get());
|
||||
}
|
||||
}
|
||||
|
||||
return switch (distance) {
|
||||
case DISTANCE_ERROR -> text("* Error obtaining version information", NamedTextColor.RED);
|
||||
case 0 -> text("* You are running the latest version", NamedTextColor.GREEN);
|
||||
case DISTANCE_UNKNOWN -> text("* Unknown version", NamedTextColor.YELLOW);
|
||||
default -> text("* You are " + distance + " version(s) behind", NamedTextColor.YELLOW)
|
||||
.append(Component.newline())
|
||||
.append(text("Download the new version at: ")
|
||||
.append(text(DOWNLOAD_PAGE, NamedTextColor.GOLD)
|
||||
.hoverEvent(text("Click to open", NamedTextColor.WHITE))
|
||||
.clickEvent(ClickEvent.openUrl(DOWNLOAD_PAGE))));
|
||||
};
|
||||
}
|
||||
|
||||
private static int fetchDistanceFromSiteApi(final int jenkinsBuild) {
|
||||
try {
|
||||
try (final BufferedReader reader = Resources.asCharSource(
|
||||
URI.create("https://api.purpurmc.org/v2/purpur/" + BUILD_INFO.minecraftVersionId()).toURL(),
|
||||
StandardCharsets.UTF_8
|
||||
).openBufferedStream()) {
|
||||
final JsonObject json = new Gson().fromJson(reader, JsonObject.class);
|
||||
final int latest = json.getAsJsonObject("builds").getAsJsonPrimitive("latest").getAsInt();
|
||||
return latest - jenkinsBuild;
|
||||
} catch (final JsonSyntaxException ex) {
|
||||
LOGGER.error("Error parsing json from Purpur's downloads API", ex);
|
||||
return DISTANCE_ERROR;
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error("Error while parsing version", e);
|
||||
return DISTANCE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Contributed by Techcable <Techcable@outlook.com> in PaperMC/Paper GH-65
|
||||
private static int fetchDistanceFromGitHub(final String branch, final String hash) {
|
||||
try {
|
||||
final HttpURLConnection connection = (HttpURLConnection) URI.create("https://api.github.com/repos/%s/compare/%s...%s".formatted(REPOSITORY, branch, hash)).toURL().openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
connection.setRequestProperty("User-Agent", USER_AGENT);
|
||||
connection.connect();
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return DISTANCE_UNKNOWN; // Unknown commit
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
final JsonObject obj = GSON.fromJson(reader, JsonObject.class);
|
||||
final String status = obj.get("status").getAsString();
|
||||
return switch (status) {
|
||||
case "identical" -> 0;
|
||||
case "behind" -> obj.get("behind_by").getAsInt();
|
||||
default -> DISTANCE_ERROR;
|
||||
};
|
||||
} catch (final JsonSyntaxException | NumberFormatException e) {
|
||||
LOGGER.error("Error parsing json from GitHub's API", e);
|
||||
return DISTANCE_ERROR;
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error("Error while parsing version", e);
|
||||
return DISTANCE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Component getHistory() {
|
||||
final VersionHistoryManager.@Nullable VersionData data = VersionHistoryManager.INSTANCE.getVersionData();
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final @Nullable String oldVersion = data.getOldVersion();
|
||||
if (oldVersion == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return text("Previous: " + oldVersion, NamedTextColor.GRAY);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user