mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 15:30:19 +01:00
3b9db2b194
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: bb4e97c6 Add support for Java 23 bc6874dd Bump asm to 9.7.1 50e8a00b PR-1064: Add specific getTopInventory methods for InventoryView derivatives 758b0a0f SPIGOT-7911: Fix Location#isWorldLoaded() for re-loaded worlds 133a64a7 Improve Registry#getOrThrow messages be0f5957 PR-1058: Add tests for Minecraft registry <-> Bukkit fields d1b31df2 PR-1062: Clarify BeaconView documentation 3fab4384 PR-1060: Cache Material to BlockType and ItemType conversion 967a7301 SPIGOT-7906: Increase YAML nesting limit to 100 6ecf033d SPIGOT-7899: Smithing recipes don't require inputs CraftBukkit Changes: 0a7bd6c81 PR-1493: Improve reroute performance and add some tests 54941524c Add support for Java 23 f4d957fff SPIGOT-7915: Fix World#getKeepSpawnInMemory() using Spawn Radius rather than Spawn Chunk Radius ded183674 Fix HIDE_ENCHANTS flag in items without enchantments 308785a0a Bump asm to 9.7.1 and re-add ClassReader to ClassWriter 72ce823cd PR-1487: Add specific getTopInventory methods for InventoryView derivatives 11a5e840c SPIGOT-7907, PR-1484: Improve merchant recipe item matching behavior to more closely align with older versions 45b66f7e4 SPIGOT-7909: Always set HIDE_ENCHANTS flag to item if flag is set 963459791 Increase outdated build delay fc5b2d75f SPIGOT-7910: Fix launching breeze wind charge from API and improve dispenser launch API c7d6428f2 SPIGOT-7856, PR-1483: End platform not dropping items after replacing blocks 2a5572b52 SPIGOT-7780, PR-1482: Cannot edit chunks during unload event 527041ab5 SPIGOT-7902, PR-1477: Fix CraftMetaPotion#hasCustomEffects() does not check if customEffects (List) is empty 5529a1769 Implement base methods for tags 30fbdbaaf Improve Registry#getOrThrow messages 6b71a7322 PR-1475: Add tests for Minecraft registry <-> Bukkit fields 5f24c255c SPIGOT-7908: Mark junit-platform-suite-engine as test scope e4c92ef65 PR-1473: Change tests to use suites, to run tests in different environments and feature flags d25e1e722 PR-1481: Fix BeaconView#set[X]Effect(null) d69a05362 PR-1480: Fix PerMaterialTest#isEdible test running for legacy materials bb3284a89 PR-1479: Use custom #isBlock method in legacy init instead of the one in Material, since it relies on legacy being init 98c57cbbe SPIGOT-7904: Fix NPE for PlayerItemBreakEvent f35bae9ec Fix missing hasJukeboxPlayable 8a6f8b6d8 SPIGOT-7881: CTRL+Pick Block saves position data into item 7913b3be7 SPIGOT-7899: Smithing recipes don't require inputs
756 lines
34 KiB
Diff
756 lines
34 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 6d8f4c3b290609d60dbcabe3d2c8274b017246c8..0c349354ba76dfd2c5f16fb232263b18e77a9a40 100644
|
|
--- a/build.gradle.kts
|
|
+++ b/build.gradle.kts
|
|
@@ -1,4 +1,5 @@
|
|
import io.papermc.paperweight.util.*
|
|
+import java.time.Instant
|
|
|
|
plugins {
|
|
java
|
|
@@ -65,18 +66,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/PaperBootstrap.java b/src/main/java/io/papermc/paper/PaperBootstrap.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..d543b1b107ab8d3eeb1fc3c1cadf489928d2786e
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/PaperBootstrap.java
|
|
@@ -0,0 +1,55 @@
|
|
+package io.papermc.paper;
|
|
+
|
|
+import java.util.List;
|
|
+import joptsimple.OptionSet;
|
|
+import net.minecraft.SharedConstants;
|
|
+import net.minecraft.server.Main;
|
|
+import org.slf4j.Logger;
|
|
+import org.slf4j.LoggerFactory;
|
|
+
|
|
+public final class PaperBootstrap {
|
|
+ private static final Logger LOGGER = LoggerFactory.getLogger("bootstrap");
|
|
+
|
|
+ private PaperBootstrap() {
|
|
+ }
|
|
+
|
|
+ public static void boot(final OptionSet options) {
|
|
+ SharedConstants.tryDetectVersion();
|
|
+
|
|
+ getStartupVersionMessages().forEach(LOGGER::info);
|
|
+
|
|
+ Main.main(options);
|
|
+ }
|
|
+
|
|
+ private static List<String> getStartupVersionMessages() {
|
|
+ final String javaSpecVersion = System.getProperty("java.specification.version");
|
|
+ final String javaVmName = System.getProperty("java.vm.name");
|
|
+ final String javaVmVersion = System.getProperty("java.vm.version");
|
|
+ final String javaVendor = System.getProperty("java.vendor");
|
|
+ final String javaVendorVersion = System.getProperty("java.vendor.version");
|
|
+ final String osName = System.getProperty("os.name");
|
|
+ final String osVersion = System.getProperty("os.version");
|
|
+ final String osArch = System.getProperty("os.arch");
|
|
+
|
|
+ final ServerBuildInfo bi = ServerBuildInfo.buildInfo();
|
|
+ return List.of(
|
|
+ String.format(
|
|
+ "Running Java %s (%s %s; %s %s) on %s %s (%s)",
|
|
+ javaSpecVersion,
|
|
+ javaVmName,
|
|
+ javaVmVersion,
|
|
+ javaVendor,
|
|
+ javaVendorVersion,
|
|
+ osName,
|
|
+ osVersion,
|
|
+ osArch
|
|
+ ),
|
|
+ String.format(
|
|
+ "Loading %s %s for Minecraft %s",
|
|
+ bi.brandName(),
|
|
+ bi.asString(ServerBuildInfo.StringRepresentation.VERSION_FULL),
|
|
+ bi.minecraftVersionId()
|
|
+ )
|
|
+ );
|
|
+ }
|
|
+}
|
|
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 46e03617bb32e4037d700c1b3698d397bd75de5c..2f57739431eb695149019724e2923f0d02e88d07 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
|
|
|
|
@@ -1700,7 +1697,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 b8b2e582115cc42a913b03a35861fa810d774cbb..8f79d7611c3ee1c817d5671152e459ec4f413418 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());
|
|
@@ -607,6 +602,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 034d68c2715b6a90f31e56f949ff3d27235a26eb..a7fbbe40f2382e7af185c4bfdd451fc1998b3636 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;
|
|
|
|
@@ -241,15 +242,17 @@ public class Main {
|
|
deadline.add(Calendar.DAY_OF_YEAR, -28);
|
|
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
|
|
- System.out.println("Loading libraries, please wait...");
|
|
- net.minecraft.server.Main.main(options);
|
|
+
|
|
+ //System.out.println("Loading libraries, please wait...");
|
|
+ //net.minecraft.server.Main.main(options);
|
|
+ io.papermc.paper.PaperBootstrap.boot(options);
|
|
} catch (Throwable t) {
|
|
t.printStackTrace();
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
index f7b80cf8c89ae5eb9d8f0893e05ffc753fdace19..432f019afff36aa6143c052f7387a6c275a09de8 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
@@ -459,6 +459,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
|