dd11ef8441
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 3a3bea52 SPIGOT-7829: Increase maximum outgoing plugin message size to match Vanilla intention 5cd1c8cb SPIGOT-7831: Add CreatureSpawnEvent.SpawnReason#POTION_EFFECT a8e278f0 SPIGOT-7827: Sync EntityPortalEvent with PlayerPortalEvent since non-players can now create portals 53729d12 Remove spurious ApiStatus.Internal annotation b9f57486 SPIGOT-7799, PR-1039: Expose explosion world interaction in EntityExplodeEvent and BlockExplodeEvent 7983b966 PR-1029: Trial changing a small number of inner enums to classes/interfaces to better support custom values CraftBukkit Changes: 403accd56 SPIGOT-7831: Add CreatureSpawnEvent.SpawnReason#POTION_EFFECT 812761660 Increase outdated build delay bed1e3ff6 SPIGOT-7827: Sync EntityPortalEvent with PlayerPortalEvent since non-players can now create portals 2444c8b23 SPIGOT-7823: Suspicious sand and gravel material are not marked as having gravity correctly aceddcd0b SPIGOT-7820: Enum changes - duplicate method name a0d2d6a84 SPIGOT-7813: Material#isInteractable() always returns false 8fd64b091 SPIGOT-7806: Handle both loot and inventory item drop behaviour in PlayerDeathEvent a4ee40b74 SPIGOT-7799, PR-1436: Expose explosion world interaction in EntityExplodeEvent and BlockExplodeEvent 082aa51c5 PR-1424: Trial changing a small number of inner enums to classes/interfaces to better support custom values 66e78a96b SPIGOT-7815: Consider EntityDamageEvent status for Wolf armor damage Spigot Changes: 5bbef5ad SPIGOT-7834: Modify max value for generic.max_absorption
703 Zeilen
33 KiB
Diff
703 Zeilen
33 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Zach Brown <zach.brown@destroystokyo.com>
|
|
Date: Tue, 1 Mar 2016 14:32:43 -0600
|
|
Subject: [PATCH] Expose server build information
|
|
|
|
Co-authored-by: Zach Brown <zach@zachbr.io>
|
|
Co-authored-by: Kyle Wood <kyle@denwav.dev>
|
|
Co-authored-by: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
|
Co-authored-by: Riley Park <rileysebastianpark@gmail.com>
|
|
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
Co-authored-by: masmc05 <masmc05@gmail.com>
|
|
|
|
diff --git a/build.gradle.kts b/build.gradle.kts
|
|
index 404c2eefa88319e0eaf7b0d1d2696c91dd0e0e0b..e7c00486bd831578008c02fcda13f3a555e6a2f1 100644
|
|
--- a/build.gradle.kts
|
|
+++ b/build.gradle.kts
|
|
@@ -1,4 +1,5 @@
|
|
import io.papermc.paperweight.util.*
|
|
+import java.time.Instant
|
|
|
|
plugins {
|
|
java
|
|
@@ -64,18 +65,24 @@ tasks.jar {
|
|
|
|
manifest {
|
|
val git = Git(rootProject.layout.projectDirectory.path)
|
|
+ val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
|
|
+ val build = System.getenv("BUILD_NUMBER") ?: null
|
|
val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim()
|
|
- val implementationVersion = System.getenv("BUILD_NUMBER") ?: "\"$gitHash\""
|
|
+ val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash"
|
|
val date = git("show", "-s", "--format=%ci", gitHash).getText().trim() // Paper
|
|
val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
|
|
attributes(
|
|
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
|
- "Implementation-Title" to "CraftBukkit",
|
|
- "Implementation-Version" to "git-Paper-$implementationVersion",
|
|
+ "Implementation-Title" to "Paper",
|
|
+ "Implementation-Version" to implementationVersion,
|
|
"Implementation-Vendor" to date, // Paper
|
|
- "Specification-Title" to "Bukkit",
|
|
+ "Specification-Title" to "Paper",
|
|
"Specification-Version" to project.version,
|
|
- "Specification-Vendor" to "Bukkit Team",
|
|
+ "Specification-Vendor" to "Paper Team",
|
|
+ "Brand-Id" to "papermc:paper",
|
|
+ "Brand-Name" to "Paper",
|
|
+ "Build-Number" to (build ?: ""),
|
|
+ "Build-Time" to Instant.now().toString(),
|
|
"Git-Branch" to gitBranch, // Paper
|
|
"Git-Commit" to gitHash, // Paper
|
|
"CraftBukkit-Package-Version" to paperweight.craftBukkitPackageVersion.get(), // Paper
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..532306cacd52579cdf37e4aca25887b1ed3ba6a1
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
|
@@ -0,0 +1,146 @@
|
|
+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.Gson;
|
|
+import com.google.gson.JsonArray;
|
|
+import com.google.gson.JsonElement;
|
|
+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.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.stream.StreamSupport;
|
|
+import net.kyori.adventure.text.Component;
|
|
+import net.kyori.adventure.text.event.ClickEvent;
|
|
+import net.kyori.adventure.text.format.NamedTextColor;
|
|
+import net.kyori.adventure.text.format.TextDecoration;
|
|
+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;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public class PaperVersionFetcher 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://papermc.io/downloads/paper";
|
|
+
|
|
+ @Override
|
|
+ public long getCacheTime() {
|
|
+ return 720000;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Component getVersionMessage(final String serverVersion) {
|
|
+ final Component updateMessage;
|
|
+ final ServerBuildInfo build = ServerBuildInfo.buildInfo();
|
|
+ if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) {
|
|
+ updateMessage = text("You are running a development version without access to version information", color(0xFF5300));
|
|
+ } else {
|
|
+ updateMessage = getUpdateStatusMessage("PaperMC/Paper", build);
|
|
+ }
|
|
+ final @Nullable Component history = this.getHistory();
|
|
+
|
|
+ return history != null ? Component.textOfChildren(updateMessage, Component.newline(), history) : updateMessage;
|
|
+ }
|
|
+
|
|
+ private static Component getUpdateStatusMessage(final String repo, final ServerBuildInfo build) {
|
|
+ int distance = DISTANCE_ERROR;
|
|
+
|
|
+ final OptionalInt buildNumber = build.buildNumber();
|
|
+ if (buildNumber.isPresent()) {
|
|
+ distance = fetchDistanceFromSiteApi(build, buildNumber.getAsInt());
|
|
+ } else {
|
|
+ final Optional<String> gitBranch = build.gitBranch();
|
|
+ final Optional<String> gitCommit = build.gitCommit();
|
|
+ if (gitBranch.isPresent() && gitCommit.isPresent()) {
|
|
+ distance = fetchDistanceFromGitHub(repo, gitBranch.get(), gitCommit.get());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return switch (distance) {
|
|
+ case DISTANCE_ERROR -> text("Error obtaining version information", NamedTextColor.YELLOW);
|
|
+ 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 ServerBuildInfo build, final int jenkinsBuild) {
|
|
+ try {
|
|
+ try (final BufferedReader reader = Resources.asCharSource(
|
|
+ URI.create("https://api.papermc.io/v2/projects/paper/versions/" + build.minecraftVersionId()).toURL(),
|
|
+ Charsets.UTF_8
|
|
+ ).openBufferedStream()) {
|
|
+ final JsonObject json = new Gson().fromJson(reader, JsonObject.class);
|
|
+ final JsonArray builds = json.getAsJsonArray("builds");
|
|
+ final int latest = StreamSupport.stream(builds.spliterator(), false)
|
|
+ .mapToInt(JsonElement::getAsInt)
|
|
+ .max()
|
|
+ .orElseThrow();
|
|
+ return latest - jenkinsBuild;
|
|
+ } catch (final JsonSyntaxException ex) {
|
|
+ LOGGER.error("Error parsing json from Paper'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 GH-65
|
|
+ private static int fetchDistanceFromGitHub(final String repo, final String branch, final String hash) {
|
|
+ try {
|
|
+ final HttpURLConnection connection = (HttpURLConnection) URI.create("https://api.github.com/repos/%s/compare/%s...%s".formatted(repo, branch, hash)).toURL().openConnection();
|
|
+ connection.connect();
|
|
+ if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return DISTANCE_UNKNOWN; // Unknown commit
|
|
+ try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) {
|
|
+ final JsonObject obj = new 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 version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..660b2ec6b63a4ceffee44ab11f54dfa7c0d0996f
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java
|
|
@@ -0,0 +1,153 @@
|
|
+package com.destroystokyo.paper;
|
|
+
|
|
+import com.google.common.base.MoreObjects;
|
|
+import com.google.gson.Gson;
|
|
+import com.google.gson.JsonSyntaxException;
|
|
+import java.io.BufferedReader;
|
|
+import java.io.BufferedWriter;
|
|
+import java.io.IOException;
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.nio.file.Files;
|
|
+import java.nio.file.Path;
|
|
+import java.nio.file.Paths;
|
|
+import java.nio.file.StandardOpenOption;
|
|
+import java.util.Objects;
|
|
+import java.util.logging.Level;
|
|
+import java.util.logging.Logger;
|
|
+import org.bukkit.Bukkit;
|
|
+
|
|
+import javax.annotation.Nonnull;
|
|
+import javax.annotation.Nullable;
|
|
+
|
|
+public enum VersionHistoryManager {
|
|
+ INSTANCE;
|
|
+
|
|
+ private final Gson gson = new Gson();
|
|
+
|
|
+ private final Logger logger = Bukkit.getLogger();
|
|
+
|
|
+ private VersionData currentData = null;
|
|
+
|
|
+ VersionHistoryManager() {
|
|
+ final Path path = Paths.get("version_history.json");
|
|
+
|
|
+ if (Files.exists(path)) {
|
|
+ // Basic file santiy checks
|
|
+ if (!Files.isRegularFile(path)) {
|
|
+ if (Files.isDirectory(path)) {
|
|
+ logger.severe(path + " is a directory, cannot be used for version history");
|
|
+ } else {
|
|
+ logger.severe(path + " is not a regular file, cannot be used for version history");
|
|
+ }
|
|
+ // We can't continue
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ try (final BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
|
|
+ currentData = gson.fromJson(reader, VersionData.class);
|
|
+ } catch (final IOException e) {
|
|
+ logger.log(Level.SEVERE, "Failed to read version history file '" + path + "'", e);
|
|
+ return;
|
|
+ } catch (final JsonSyntaxException e) {
|
|
+ logger.log(Level.SEVERE, "Invalid json syntax for file '" + path + "'", e);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ final String version = Bukkit.getVersion();
|
|
+ if (version == null) {
|
|
+ logger.severe("Failed to retrieve current version");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (currentData == null) {
|
|
+ // Empty file
|
|
+ currentData = new VersionData();
|
|
+ currentData.setCurrentVersion(version);
|
|
+ writeFile(path);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!version.equals(currentData.getCurrentVersion())) {
|
|
+ // The version appears to have changed
|
|
+ currentData.setOldVersion(currentData.getCurrentVersion());
|
|
+ currentData.setCurrentVersion(version);
|
|
+ writeFile(path);
|
|
+ }
|
|
+ } else {
|
|
+ // File doesn't exist, start fresh
|
|
+ currentData = new VersionData();
|
|
+ // oldVersion is null
|
|
+ currentData.setCurrentVersion(Bukkit.getVersion());
|
|
+ writeFile(path);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void writeFile(@Nonnull final Path path) {
|
|
+ try (final BufferedWriter writer = Files.newBufferedWriter(
|
|
+ path,
|
|
+ StandardCharsets.UTF_8,
|
|
+ StandardOpenOption.WRITE,
|
|
+ StandardOpenOption.CREATE,
|
|
+ StandardOpenOption.TRUNCATE_EXISTING
|
|
+ )) {
|
|
+ gson.toJson(currentData, writer);
|
|
+ } catch (final IOException e) {
|
|
+ logger.log(Level.SEVERE, "Failed to write to version history file", e);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public VersionData getVersionData() {
|
|
+ return currentData;
|
|
+ }
|
|
+
|
|
+ public static class VersionData {
|
|
+ private String oldVersion;
|
|
+
|
|
+ private String currentVersion;
|
|
+
|
|
+ @Nullable
|
|
+ public String getOldVersion() {
|
|
+ return oldVersion;
|
|
+ }
|
|
+
|
|
+ public void setOldVersion(@Nullable String oldVersion) {
|
|
+ this.oldVersion = oldVersion;
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ public String getCurrentVersion() {
|
|
+ return currentVersion;
|
|
+ }
|
|
+
|
|
+ public void setCurrentVersion(@Nullable String currentVersion) {
|
|
+ this.currentVersion = currentVersion;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return MoreObjects.toStringHelper(this)
|
|
+ .add("oldVersion", oldVersion)
|
|
+ .add("currentVersion", currentVersion)
|
|
+ .toString();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(@Nullable Object o) {
|
|
+ if (this == o) {
|
|
+ return true;
|
|
+ }
|
|
+ if (o == null || getClass() != o.getClass()) {
|
|
+ return false;
|
|
+ }
|
|
+ final VersionData versionData = (VersionData) o;
|
|
+ return Objects.equals(oldVersion, versionData.oldVersion) &&
|
|
+ Objects.equals(currentVersion, versionData.currentVersion);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return Objects.hash(oldVersion, currentVersion);
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..790bad0494454ca12ee152e3de6da3da634d9b20
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
|
@@ -0,0 +1,104 @@
|
|
+package io.papermc.paper;
|
|
+
|
|
+import com.google.common.base.Strings;
|
|
+import io.papermc.paper.util.JarManifests;
|
|
+import java.time.Instant;
|
|
+import java.time.temporal.ChronoUnit;
|
|
+import java.util.Optional;
|
|
+import java.util.OptionalInt;
|
|
+import java.util.jar.Manifest;
|
|
+import net.kyori.adventure.key.Key;
|
|
+import net.minecraft.SharedConstants;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+import org.bukkit.craftbukkit.Main;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+public record ServerBuildInfoImpl(
|
|
+ Key brandId,
|
|
+ String brandName,
|
|
+ String minecraftVersionId,
|
|
+ String minecraftVersionName,
|
|
+ OptionalInt buildNumber,
|
|
+ Instant buildTime,
|
|
+ Optional<String> gitBranch,
|
|
+ Optional<String> gitCommit
|
|
+) implements ServerBuildInfo {
|
|
+ private static final String ATTRIBUTE_BRAND_ID = "Brand-Id";
|
|
+ private static final String ATTRIBUTE_BRAND_NAME = "Brand-Name";
|
|
+ private static final String ATTRIBUTE_BUILD_TIME = "Build-Time";
|
|
+ private static final String ATTRIBUTE_BUILD_NUMBER = "Build-Number";
|
|
+ private static final String ATTRIBUTE_GIT_BRANCH = "Git-Branch";
|
|
+ private static final String ATTRIBUTE_GIT_COMMIT = "Git-Commit";
|
|
+
|
|
+ private static final String BRAND_PAPER_NAME = "Paper";
|
|
+
|
|
+ private static final String BUILD_DEV = "DEV";
|
|
+
|
|
+ public ServerBuildInfoImpl() {
|
|
+ this(JarManifests.manifest(CraftServer.class));
|
|
+ }
|
|
+
|
|
+ private ServerBuildInfoImpl(final Manifest manifest) {
|
|
+ this(
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_BRAND_ID)
|
|
+ .map(Key::key)
|
|
+ .orElse(BRAND_PAPER_ID),
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME)
|
|
+ .orElse(BRAND_PAPER_NAME),
|
|
+ SharedConstants.getCurrentVersion().getId(),
|
|
+ SharedConstants.getCurrentVersion().getName(),
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER)
|
|
+ .map(Integer::parseInt)
|
|
+ .map(OptionalInt::of)
|
|
+ .orElse(OptionalInt.empty()),
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_BUILD_TIME)
|
|
+ .map(Instant::parse)
|
|
+ .orElse(Main.BOOT_TIME),
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_GIT_BRANCH),
|
|
+ getManifestAttribute(manifest, ATTRIBUTE_GIT_COMMIT)
|
|
+ );
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isBrandCompatible(final @NotNull Key brandId) {
|
|
+ return brandId.equals(this.brandId);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @NotNull String asString(final @NotNull StringRepresentation representation) {
|
|
+ final StringBuilder sb = new StringBuilder();
|
|
+ sb.append(this.minecraftVersionId);
|
|
+ sb.append('-');
|
|
+ if (this.buildNumber.isPresent()) {
|
|
+ sb.append(this.buildNumber.getAsInt());
|
|
+ } else {
|
|
+ sb.append(BUILD_DEV);
|
|
+ }
|
|
+ final boolean hasGitBranch = this.gitBranch.isPresent();
|
|
+ final boolean hasGitCommit = this.gitCommit.isPresent();
|
|
+ if (hasGitBranch || hasGitCommit) {
|
|
+ sb.append('-');
|
|
+ }
|
|
+ if (hasGitBranch && representation == StringRepresentation.VERSION_FULL) {
|
|
+ sb.append(this.gitBranch.get());
|
|
+ if (hasGitCommit) {
|
|
+ sb.append('@');
|
|
+ }
|
|
+ }
|
|
+ if (hasGitCommit) {
|
|
+ sb.append(this.gitCommit.get());
|
|
+ }
|
|
+ if (representation == StringRepresentation.VERSION_FULL) {
|
|
+ sb.append(' ');
|
|
+ sb.append('(');
|
|
+ sb.append(this.buildTime.truncatedTo(ChronoUnit.SECONDS));
|
|
+ sb.append(')');
|
|
+ }
|
|
+ return sb.toString();
|
|
+ }
|
|
+
|
|
+ private static Optional<String> getManifestAttribute(final Manifest manifest, final String name) {
|
|
+ final String value = manifest != null ? manifest.getMainAttributes().getValue(name) : null;
|
|
+ return Optional.ofNullable(Strings.emptyToNull(value));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index e9d56d75b7c648f04d3a56942b2866090c570129..57ec168bac3727feb734e28cebc680328c1c4aec 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -43,7 +43,6 @@ import java.util.Set;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.Executor;
|
|
-import java.util.concurrent.RejectedExecutionException;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import java.util.function.BooleanSupplier;
|
|
import java.util.function.Consumer;
|
|
@@ -191,8 +190,6 @@ import net.minecraft.world.phys.Vec2;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.craftbukkit.CraftRegistry;
|
|
-import org.bukkit.craftbukkit.CraftServer;
|
|
-import org.bukkit.craftbukkit.Main;
|
|
import org.bukkit.event.server.ServerLoadEvent;
|
|
// CraftBukkit end
|
|
|
|
@@ -1702,7 +1699,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
|
|
@DontObfuscate
|
|
public String getServerModName() {
|
|
- return "Spigot"; // Spigot - Spigot > // CraftBukkit - cb > vanilla!
|
|
+ return io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
|
|
}
|
|
|
|
public SystemReport fillSystemReport(SystemReport details) {
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index b51c3f8c485496734ea58c15377a1215a334c765..48107f8eb50483430053b990496862d71c9f8a3e 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -218,6 +218,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
// Paper end - initialize global and world-defaults configuration
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
|
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
|
+ com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
|
|
|
this.setPvpAllowed(dedicatedserverproperties.pvp);
|
|
this.setFlightAllowed(dedicatedserverproperties.allowFlight);
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
|
|
index f077b8ff0bf0d96628db3569132696b68fd79921..5f11f5b16766f9d1d5640ae037e259bed9020384 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
|
|
@@ -18,8 +18,10 @@ public class CraftCrashReport implements Supplier<String> {
|
|
|
|
@Override
|
|
public String get() {
|
|
+ final io.papermc.paper.ServerBuildInfo build = io.papermc.paper.ServerBuildInfo.buildInfo(); // Paper
|
|
StringWriter value = new StringWriter();
|
|
try {
|
|
+ value.append("\n BrandInfo: ").append(String.format("%s (%s) version %s", build.brandName(), build.brandId(), build.asString(io.papermc.paper.ServerBuildInfo.StringRepresentation.VERSION_FULL))); // Paper
|
|
value.append("\n Running: ").append(Bukkit.getName()).append(" version ").append(Bukkit.getVersion()).append(" (Implementing API version ").append(Bukkit.getBukkitVersion()).append(") ").append(String.valueOf(MinecraftServer.getServer().usesAuthentication()));
|
|
value.append("\n Plugins: {");
|
|
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index acab477a4a026799319054c2eb4d0f2c99ab3d83..2a36e562967ec6174efe456e489c50ca10ba47e5 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -11,8 +11,6 @@ import com.google.common.collect.MapMaker;
|
|
import com.mojang.authlib.GameProfile;
|
|
import com.mojang.brigadier.StringReader;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
-import com.mojang.brigadier.tree.CommandNode;
|
|
-import com.mojang.brigadier.tree.LiteralCommandNode;
|
|
import com.mojang.serialization.Dynamic;
|
|
import com.mojang.serialization.Lifecycle;
|
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
@@ -27,7 +25,6 @@ import java.net.InetAddress;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
-import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashMap;
|
|
@@ -155,7 +152,6 @@ import org.bukkit.craftbukkit.ban.CraftProfileBanList;
|
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
|
import org.bukkit.craftbukkit.boss.CraftBossBar;
|
|
import org.bukkit.craftbukkit.boss.CraftKeyedBossbar;
|
|
-import org.bukkit.craftbukkit.command.BukkitCommandWrapper;
|
|
import org.bukkit.craftbukkit.command.CraftCommandMap;
|
|
import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
|
import org.bukkit.craftbukkit.entity.CraftEntityFactory;
|
|
@@ -251,7 +247,6 @@ import org.bukkit.plugin.PluginManager;
|
|
import org.bukkit.plugin.ServicesManager;
|
|
import org.bukkit.plugin.SimplePluginManager;
|
|
import org.bukkit.plugin.SimpleServicesManager;
|
|
-import org.bukkit.plugin.java.JavaPluginLoader;
|
|
import org.bukkit.plugin.messaging.Messenger;
|
|
import org.bukkit.plugin.messaging.StandardMessenger;
|
|
import org.bukkit.profile.PlayerProfile;
|
|
@@ -268,7 +263,7 @@ import org.yaml.snakeyaml.error.MarkedYAMLException;
|
|
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
|
|
|
|
public final class CraftServer implements Server {
|
|
- private final String serverName = "CraftBukkit";
|
|
+ private final String serverName = io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
|
|
private final String serverVersion;
|
|
private final String bukkitVersion = Versioning.getBukkitVersion();
|
|
private final Logger logger = Logger.getLogger("Minecraft");
|
|
@@ -324,7 +319,7 @@ public final class CraftServer implements Server {
|
|
return player.getBukkitEntity();
|
|
}
|
|
}));
|
|
- this.serverVersion = CraftServer.class.getPackage().getImplementationVersion();
|
|
+ this.serverVersion = io.papermc.paper.ServerBuildInfo.buildInfo().asString(io.papermc.paper.ServerBuildInfo.StringRepresentation.VERSION_SIMPLE); // Paper - improve version
|
|
this.structureManager = new CraftStructureManager(console.getStructureManager(), console.registryAccess());
|
|
this.dataPackManager = new CraftDataPackManager(this.getServer().getPackRepository());
|
|
this.serverTickManager = new CraftServerTickManager(console.tickRateManager());
|
|
@@ -606,6 +601,13 @@ public final class CraftServer implements Server {
|
|
return this.bukkitVersion;
|
|
}
|
|
|
|
+ // Paper start - expose game version
|
|
+ @Override
|
|
+ public String getMinecraftVersion() {
|
|
+ return console.getServerVersion();
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@Override
|
|
public List<CraftPlayer> getOnlinePlayers() {
|
|
return this.playerView;
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
index 1c8049bbc08be77673d375205bd42a346ff951b8..e37a7aceae6c69083ecf81af4f750c01a5e0eded 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
|
@@ -15,6 +15,7 @@ import joptsimple.OptionSet;
|
|
import joptsimple.util.PathConverter;
|
|
|
|
public class Main {
|
|
+ public static final java.time.Instant BOOT_TIME = java.time.Instant.now(); // Paper - track initial start time
|
|
public static boolean useJline = true;
|
|
public static boolean useConsole = true;
|
|
|
|
@@ -252,13 +253,26 @@ public class Main {
|
|
deadline.add(Calendar.DAY_OF_YEAR, -14);
|
|
if (buildDate.before(deadline.getTime())) {
|
|
System.err.println("*** Error, this build is outdated ***");
|
|
- System.err.println("*** Please download a new build as per instructions from https://www.spigotmc.org/go/outdated-spigot ***");
|
|
+ System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper
|
|
System.err.println("*** Server will start in 20 seconds ***");
|
|
Thread.sleep(TimeUnit.SECONDS.toMillis(20));
|
|
}
|
|
}
|
|
|
|
System.setProperty("library.jansi.version", "Paper"); // Paper - set meaningless jansi version to prevent git builds from crashing on Windows
|
|
+ // Paper start - Log Java and OS versioning to help with debugging plugin issues
|
|
+ java.lang.management.RuntimeMXBean runtimeMX = java.lang.management.ManagementFactory.getRuntimeMXBean();
|
|
+ java.lang.management.OperatingSystemMXBean osMX = java.lang.management.ManagementFactory.getOperatingSystemMXBean();
|
|
+ if (runtimeMX != null && osMX != null) {
|
|
+ String javaInfo = "Java " + runtimeMX.getSpecVersion() + " (" + runtimeMX.getVmName() + " " + runtimeMX.getVmVersion() + ")";
|
|
+ String osInfo = "Host: " + osMX.getName() + " " + osMX.getVersion() + " (" + osMX.getArch() + ")";
|
|
+
|
|
+ System.out.println("System Info: " + javaInfo + " " + osInfo);
|
|
+ } else {
|
|
+ System.out.println("Unable to read system info");
|
|
+ }
|
|
+ // Paper end - Log Java and OS versioning to help with debugging plugin issues
|
|
+
|
|
System.out.println("Loading libraries, please wait...");
|
|
net.minecraft.server.Main.main(options);
|
|
} catch (Throwable t) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
index a356d4d19e4b7a3d08c80a137609d1ed9db7c1b1..e85faddc157869824e30426a7ca2c577552aea9c 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
@@ -464,6 +464,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|
public String getTimingsServerName() {
|
|
return io.papermc.paper.configuration.GlobalConfiguration.get().timings.serverName;
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
|
+ return new com.destroystokyo.paper.PaperVersionFetcher();
|
|
+ }
|
|
// Paper end
|
|
|
|
@Override
|
|
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
|
index f697d45e0ac4e9cdc8a46121510a04c0f294d91f..e086765dec32241bc5a77afcf072c77a40c6d785 100644
|
|
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
|
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
|
@@ -19,7 +19,7 @@ public class WatchdogThread extends Thread
|
|
|
|
private WatchdogThread(long timeoutTime, boolean restart)
|
|
{
|
|
- super( "Spigot Watchdog Thread" );
|
|
+ super( "Paper Watchdog Thread" );
|
|
this.timeoutTime = timeoutTime;
|
|
this.restart = restart;
|
|
}
|
|
@@ -65,14 +65,14 @@ public class WatchdogThread extends Thread
|
|
{
|
|
Logger log = Bukkit.getServer().getLogger();
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
- log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Spigot bug." );
|
|
+ log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
|
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
|
log.log( Level.SEVERE, "\t *Especially* if it looks like HTTP or MySQL operations are occurring" );
|
|
log.log( Level.SEVERE, "If you see a world save or edit, then it means you did far more than your server can handle at once" );
|
|
log.log( Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes" );
|
|
- log.log( Level.SEVERE, "If you are unsure or still think this is a Spigot bug, please report to https://www.spigotmc.org/" );
|
|
+ log.log( Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues" );
|
|
log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" );
|
|
- log.log( Level.SEVERE, "Spigot version: " + Bukkit.getServer().getVersion() );
|
|
+ log.log( Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion() );
|
|
//
|
|
if ( net.minecraft.world.level.Level.lastPhysicsProblem != null )
|
|
{
|
|
@@ -82,7 +82,7 @@ public class WatchdogThread extends Thread
|
|
}
|
|
//
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
|
|
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
|
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
//
|
|
diff --git a/src/main/resources/META-INF/services/io.papermc.paper.ServerBuildInfo b/src/main/resources/META-INF/services/io.papermc.paper.ServerBuildInfo
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..79b4b25784cfeabd5f619ed5454ef843f35041db
|
|
--- /dev/null
|
|
+++ b/src/main/resources/META-INF/services/io.papermc.paper.ServerBuildInfo
|
|
@@ -0,0 +1 @@
|
|
+io.papermc.paper.ServerBuildInfoImpl
|