mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
Expose server build information
Co-authored-by: Professor Bloodstone <git@bloodstone.dev> Co-authored-by: Mark Vainomaa <mikroskeem@mikroskeem.eu> Co-authored-by: masmc05 <masmc05@gmail.com> Co-authored-by: Riley Park <rileysebastianpark@gmail.com>
This commit is contained in:
parent
376251dab7
commit
05ec73f817
9 changed files with 369 additions and 9 deletions
|
@ -0,0 +1,47 @@
|
||||||
|
package com.destroystokyo.paper.util;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public interface VersionFetcher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount of time to cache results for in milliseconds
|
||||||
|
* <p>
|
||||||
|
* Negative values will never cache.
|
||||||
|
*
|
||||||
|
* @return cache time
|
||||||
|
*/
|
||||||
|
long getCacheTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the version message to cache and show to command senders.
|
||||||
|
*
|
||||||
|
* <p>NOTE: This is run in a new thread separate from that of the command processing thread</p>
|
||||||
|
*
|
||||||
|
* @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
|
||||||
|
* @return the message to show when requesting a version
|
||||||
|
*/
|
||||||
|
Component getVersionMessage(String serverVersion);
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
class DummyVersionFetcher implements VersionFetcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCacheTime() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getVersionMessage(final String serverVersion) {
|
||||||
|
Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
|
||||||
|
Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
|
||||||
|
new Throwable().printStackTrace();
|
||||||
|
return Component.text("Unable to check for updates. No version provider set.", NamedTextColor.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java
Normal file
122
paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
package io.papermc.paper;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.kyori.adventure.util.Services;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the current server build.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface ServerBuildInfo {
|
||||||
|
/**
|
||||||
|
* The brand id for Paper.
|
||||||
|
*/
|
||||||
|
Key BRAND_PAPER_ID = Key.key("papermc", "paper");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@code ServerBuildInfo}.
|
||||||
|
*
|
||||||
|
* @return the {@code ServerBuildInfo}
|
||||||
|
*/
|
||||||
|
static ServerBuildInfo buildInfo() {
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Holder">
|
||||||
|
final class Holder {
|
||||||
|
static final Optional<ServerBuildInfo> INSTANCE = Services.service(ServerBuildInfo.class);
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
return Holder.INSTANCE.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the brand id of the server.
|
||||||
|
*
|
||||||
|
* @return the brand id of the server (e.g. "papermc:paper")
|
||||||
|
*/
|
||||||
|
Key brandId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current server supports the specified brand.
|
||||||
|
*
|
||||||
|
* @param brandId the brand to check (e.g. "papermc:folia")
|
||||||
|
* @return {@code true} if the server supports the specified brand
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
boolean isBrandCompatible(final Key brandId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the brand name of the server.
|
||||||
|
*
|
||||||
|
* @return the brand name of the server (e.g. "Paper")
|
||||||
|
*/
|
||||||
|
String brandName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Minecraft version id.
|
||||||
|
*
|
||||||
|
* @return the Minecraft version id (e.g. "1.20.4", "1.20.2-pre2", "23w31a")
|
||||||
|
*/
|
||||||
|
String minecraftVersionId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Minecraft version name.
|
||||||
|
*
|
||||||
|
* @return the Minecraft version name (e.g. "1.20.4", "1.20.2 Pre-release 2", "23w31a")
|
||||||
|
*/
|
||||||
|
String minecraftVersionName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the build number.
|
||||||
|
*
|
||||||
|
* @return the build number
|
||||||
|
*/
|
||||||
|
OptionalInt buildNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the build time.
|
||||||
|
*
|
||||||
|
* @return the build time
|
||||||
|
*/
|
||||||
|
Instant buildTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the git commit branch.
|
||||||
|
*
|
||||||
|
* @return the git commit branch
|
||||||
|
*/
|
||||||
|
Optional<String> gitBranch();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the git commit hash.
|
||||||
|
*
|
||||||
|
* @return the git commit hash
|
||||||
|
*/
|
||||||
|
Optional<String> gitCommit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a string representation of the server build information.
|
||||||
|
*
|
||||||
|
* @param representation the type of representation
|
||||||
|
* @return a string
|
||||||
|
*/
|
||||||
|
String asString(final StringRepresentation representation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String representation types.
|
||||||
|
*/
|
||||||
|
enum StringRepresentation {
|
||||||
|
/**
|
||||||
|
* A simple version string, in format {@code <minecraftVersionId>-<buildNumber>-<gitCommit>}.
|
||||||
|
*/
|
||||||
|
VERSION_SIMPLE,
|
||||||
|
/**
|
||||||
|
* A simple version string, in format {@code <minecraftVersionId>-<buildNumber>-<gitBranch>@<gitCommit> (<buildTime>)}.
|
||||||
|
*/
|
||||||
|
VERSION_FULL,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package io.papermc.paper.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public final class JarManifests {
|
||||||
|
private JarManifests() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<ClassLoader, Manifest> MANIFESTS = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
|
public static @Nullable Manifest manifest(final Class<?> clazz) {
|
||||||
|
return MANIFESTS.computeIfAbsent(clazz.getClassLoader(), classLoader -> {
|
||||||
|
final String classLocation = "/" + clazz.getName().replace(".", "/") + ".class";
|
||||||
|
final URL resource = clazz.getResource(classLocation);
|
||||||
|
if (resource == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String classFilePath = resource.toString().replace("\\", "/");
|
||||||
|
final String archivePath = classFilePath.substring(0, classFilePath.length() - classLocation.length());
|
||||||
|
try (final InputStream stream = new URL(archivePath + "/META-INF/MANIFEST.MF").openStream()) {
|
||||||
|
return new Manifest(stream);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -110,13 +110,26 @@ public final class Bukkit {
|
||||||
}
|
}
|
||||||
|
|
||||||
Bukkit.server = server;
|
Bukkit.server = server;
|
||||||
server.getLogger().info("This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ")");
|
// Paper start - add git information
|
||||||
|
server.getLogger().info(getVersionMessage());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gets message describing the version server is running.
|
||||||
|
*
|
||||||
|
* @return message describing the version server is running
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String getVersionMessage() {
|
||||||
|
final io.papermc.paper.ServerBuildInfo version = io.papermc.paper.ServerBuildInfo.buildInfo();
|
||||||
|
return "This server is running " + getName() + " version " + version.asString(io.papermc.paper.ServerBuildInfo.StringRepresentation.VERSION_FULL) + " (Implementing API version " + getBukkitVersion() + ")";
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of this server implementation.
|
* Gets the name of this server implementation.
|
||||||
*
|
*
|
||||||
* @return name of this server implementation
|
* @return name of this server implementation
|
||||||
|
* @see io.papermc.paper.ServerBuildInfo#brandName()
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getName() {
|
public static String getName() {
|
||||||
|
@ -127,6 +140,7 @@ public final class Bukkit {
|
||||||
* Gets the version string of this server implementation.
|
* Gets the version string of this server implementation.
|
||||||
*
|
*
|
||||||
* @return version of this server implementation
|
* @return version of this server implementation
|
||||||
|
* @see io.papermc.paper.ServerBuildInfo
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getVersion() {
|
public static String getVersion() {
|
||||||
|
@ -143,6 +157,20 @@ public final class Bukkit {
|
||||||
return server.getBukkitVersion();
|
return server.getBukkitVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paper start - expose game version
|
||||||
|
/**
|
||||||
|
* Gets the version of game this server implements
|
||||||
|
*
|
||||||
|
* @return version of game
|
||||||
|
* @see io.papermc.paper.ServerBuildInfo#minecraftVersionId()
|
||||||
|
* @see io.papermc.paper.ServerBuildInfo#minecraftVersionName()
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String getMinecraftVersion() {
|
||||||
|
return server.getMinecraftVersion();
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a view of all currently logged in players. This {@linkplain
|
* Gets a view of all currently logged in players. This {@linkplain
|
||||||
* Collections#unmodifiableCollection(Collection) view} is a reused
|
* Collections#unmodifiableCollection(Collection) view} is a reused
|
||||||
|
|
|
@ -120,6 +120,16 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||||
@NotNull
|
@NotNull
|
||||||
public String getBukkitVersion();
|
public String getBukkitVersion();
|
||||||
|
|
||||||
|
// Paper start - expose game version
|
||||||
|
/**
|
||||||
|
* Gets the version of game this server implements
|
||||||
|
*
|
||||||
|
* @return version of game
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String getMinecraftVersion();
|
||||||
|
// Paper end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a view of all currently logged in players. This {@linkplain
|
* Gets a view of all currently logged in players. This {@linkplain
|
||||||
* Collections#unmodifiableCollection(Collection) view} is a reused
|
* Collections#unmodifiableCollection(Collection) view} is a reused
|
||||||
|
|
|
@ -156,4 +156,13 @@ public interface UnsafeValues {
|
||||||
return !Bukkit.getUnsafe().isSupportedApiVersion(plugin.getDescription().getAPIVersion());
|
return !Bukkit.getUnsafe().isSupportedApiVersion(plugin.getDescription().getAPIVersion());
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
/**
|
||||||
|
* Called once by the version command on first use, then cached.
|
||||||
|
*/
|
||||||
|
default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
||||||
|
return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher();
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,25 @@ import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.util.StringUtil;
|
import org.bukkit.util.StringUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
// Paper start - version command 2.0
|
||||||
|
import com.destroystokyo.paper.util.VersionFetcher;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
// Paper end - version command 2.0
|
||||||
|
|
||||||
public class VersionCommand extends BukkitCommand {
|
public class VersionCommand extends BukkitCommand {
|
||||||
|
private VersionFetcher versionFetcher; // Paper - version command 2.0
|
||||||
|
private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration
|
||||||
|
if (versionFetcher == null) {
|
||||||
|
versionFetcher = Bukkit.getUnsafe().getVersionFetcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
return versionFetcher;
|
||||||
|
}
|
||||||
|
|
||||||
public VersionCommand(@NotNull String name) {
|
public VersionCommand(@NotNull String name) {
|
||||||
super(name);
|
super(name);
|
||||||
|
|
||||||
|
@ -41,7 +58,7 @@ public class VersionCommand extends BukkitCommand {
|
||||||
if (!testPermission(sender)) return true;
|
if (!testPermission(sender)) return true;
|
||||||
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")");
|
//sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); // Paper - moved to setVersionMessage
|
||||||
sendVersion(sender);
|
sendVersion(sender);
|
||||||
} else {
|
} else {
|
||||||
StringBuilder name = new StringBuilder();
|
StringBuilder name = new StringBuilder();
|
||||||
|
@ -80,8 +97,17 @@ public class VersionCommand extends BukkitCommand {
|
||||||
|
|
||||||
private void describeToSender(@NotNull Plugin plugin, @NotNull CommandSender sender) {
|
private void describeToSender(@NotNull Plugin plugin, @NotNull CommandSender sender) {
|
||||||
PluginDescriptionFile desc = plugin.getDescription();
|
PluginDescriptionFile desc = plugin.getDescription();
|
||||||
sender.sendMessage(ChatColor.GREEN + desc.getName() + ChatColor.WHITE + " version " + ChatColor.GREEN + desc.getVersion());
|
// Paper start - version command 2.0
|
||||||
|
sender.sendMessage(
|
||||||
|
Component.text()
|
||||||
|
.append(Component.text(desc.getName(), NamedTextColor.GREEN))
|
||||||
|
.append(Component.text(" version "))
|
||||||
|
.append(Component.text(desc.getVersion(), NamedTextColor.GREEN)
|
||||||
|
.hoverEvent(Component.text("Click to copy to clipboard", NamedTextColor.WHITE))
|
||||||
|
.clickEvent(ClickEvent.copyToClipboard(desc.getVersion()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// Paper end - version command 2.0
|
||||||
if (desc.getDescription() != null) {
|
if (desc.getDescription() != null) {
|
||||||
sender.sendMessage(desc.getDescription());
|
sender.sendMessage(desc.getDescription());
|
||||||
}
|
}
|
||||||
|
@ -147,14 +173,14 @@ public class VersionCommand extends BukkitCommand {
|
||||||
|
|
||||||
private final ReentrantLock versionLock = new ReentrantLock();
|
private final ReentrantLock versionLock = new ReentrantLock();
|
||||||
private boolean hasVersion = false;
|
private boolean hasVersion = false;
|
||||||
private String versionMessage = null;
|
private Component versionMessage = null; // Paper
|
||||||
private final Set<CommandSender> versionWaiters = new HashSet<CommandSender>();
|
private final Set<CommandSender> versionWaiters = new HashSet<CommandSender>();
|
||||||
private boolean versionTaskStarted = false;
|
private boolean versionTaskStarted = false;
|
||||||
private long lastCheck = 0;
|
private long lastCheck = 0;
|
||||||
|
|
||||||
private void sendVersion(@NotNull CommandSender sender) {
|
private void sendVersion(@NotNull CommandSender sender) {
|
||||||
if (hasVersion) {
|
if (hasVersion) {
|
||||||
if (System.currentTimeMillis() - lastCheck > 21600000) {
|
if (System.currentTimeMillis() - lastCheck > getVersionFetcher().getCacheTime()) { // Paper - use version supplier
|
||||||
lastCheck = System.currentTimeMillis();
|
lastCheck = System.currentTimeMillis();
|
||||||
hasVersion = false;
|
hasVersion = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +195,7 @@ public class VersionCommand extends BukkitCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
versionWaiters.add(sender);
|
versionWaiters.add(sender);
|
||||||
sender.sendMessage("Checking version, please wait...");
|
sender.sendMessage(Component.text("Checking version, please wait...", NamedTextColor.WHITE, TextDecoration.ITALIC)); // Paper
|
||||||
if (!versionTaskStarted) {
|
if (!versionTaskStarted) {
|
||||||
versionTaskStarted = true;
|
versionTaskStarted = true;
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
|
@ -187,6 +213,13 @@ public class VersionCommand extends BukkitCommand {
|
||||||
|
|
||||||
private void obtainVersion() {
|
private void obtainVersion() {
|
||||||
String version = Bukkit.getVersion();
|
String version = Bukkit.getVersion();
|
||||||
|
// Paper start
|
||||||
|
if (version.startsWith("null")) { // running from ide?
|
||||||
|
setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setVersionMessage(getVersionFetcher().getVersionMessage(version));
|
||||||
|
/*
|
||||||
if (version == null) version = "Custom";
|
if (version == null) version = "Custom";
|
||||||
String[] parts = version.substring(0, version.indexOf(' ')).split("-");
|
String[] parts = version.substring(0, version.indexOf(' ')).split("-");
|
||||||
if (parts.length == 4) {
|
if (parts.length == 4) {
|
||||||
|
@ -216,11 +249,24 @@ public class VersionCommand extends BukkitCommand {
|
||||||
} else {
|
} else {
|
||||||
setVersionMessage("Unknown version, custom build?");
|
setVersionMessage("Unknown version, custom build?");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVersionMessage(@NotNull String msg) {
|
// Paper start
|
||||||
|
private void setVersionMessage(final @NotNull Component msg) {
|
||||||
lastCheck = System.currentTimeMillis();
|
lastCheck = System.currentTimeMillis();
|
||||||
versionMessage = msg;
|
final Component message = Component.textOfChildren(
|
||||||
|
Component.text(Bukkit.getVersionMessage(), NamedTextColor.WHITE),
|
||||||
|
Component.newline(),
|
||||||
|
msg
|
||||||
|
);
|
||||||
|
this.versionMessage = Component.text()
|
||||||
|
.append(message)
|
||||||
|
.hoverEvent(Component.text("Click to copy to clipboard", NamedTextColor.WHITE))
|
||||||
|
.clickEvent(ClickEvent.copyToClipboard(PlainTextComponentSerializer.plainText().serialize(message)))
|
||||||
|
.build();
|
||||||
|
// Paper end
|
||||||
versionLock.lock();
|
versionLock.lock();
|
||||||
try {
|
try {
|
||||||
hasVersion = true;
|
hasVersion = true;
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package io.papermc.paper;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class TestServerBuildInfo implements ServerBuildInfo {
|
||||||
|
@Override
|
||||||
|
public @NotNull Key brandId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBrandCompatible(final @NotNull Key brandId) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String brandName() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String minecraftVersionId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String minecraftVersionName() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull OptionalInt buildNumber() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Instant buildTime() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Optional<String> gitBranch() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Optional<String> gitCommit() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String asString(final @NotNull StringRepresentation representation) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
io.papermc.paper.TestServerBuildInfo
|
Loading…
Reference in a new issue