From 38204cc68bf261b4ff9c74f2b15397bf93523156 Mon Sep 17 00:00:00 2001 From: Minecrell Date: Fri, 14 Apr 2023 11:19:38 +0200 Subject: [PATCH] Expose protocol version for status pings Historically we considered the Minecraft protocol versions as "implementation detail" that should not be exposed in SpongeAPI. However, since the addition of the status ping API 8 years ago the protocol version still exists exactly the same way, and there are use cases for checking it (identifying the exact client version) and modifying it (making the server appear as incompatible to clients). Right now plugins have to resort to using implementation-specific code for this, which is complicated and now hopelessly broken for api-10 (due to internal changes in the Minecraft code). Make it possible to check and modify the server version to fix this once and for all. --- .../spongepowered/api/MinecraftVersion.java | 19 ++++++++++++ .../event/server/ClientPingServerEvent.java | 31 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/main/java/org/spongepowered/api/MinecraftVersion.java b/src/main/java/org/spongepowered/api/MinecraftVersion.java index 4236e3ee3a..f973ae4094 100644 --- a/src/main/java/org/spongepowered/api/MinecraftVersion.java +++ b/src/main/java/org/spongepowered/api/MinecraftVersion.java @@ -44,6 +44,16 @@ public interface MinecraftVersion extends Comparable { */ String name(); + /** + * Gets the protocol version of this Minecraft version. + * + * @implNote This should be interpreted together with {@link #isLegacy()}, + * since legacy clients use a different protocol version numbering scheme. + * @return The protocol version + * @see Protocol version (Minecraft Wiki) + */ + int protocolVersion(); + /** * Returns whether this version is an older version that doesn't support * all of the features in {@link StatusResponse}. These versions are only @@ -62,4 +72,13 @@ public interface MinecraftVersion extends Comparable { * @return The data version */ OptionalInt dataVersion(); + + @Override + default int compareTo(MinecraftVersion o) { + final int result = Boolean.compare(isLegacy(), o.isLegacy()); + if (result != 0) { + return result; + } + return protocolVersion() - o.protocolVersion(); + } } diff --git a/src/main/java/org/spongepowered/api/event/server/ClientPingServerEvent.java b/src/main/java/org/spongepowered/api/event/server/ClientPingServerEvent.java index 06de6a169b..474a39d2ec 100644 --- a/src/main/java/org/spongepowered/api/event/server/ClientPingServerEvent.java +++ b/src/main/java/org/spongepowered/api/event/server/ClientPingServerEvent.java @@ -26,6 +26,7 @@ import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.MinecraftVersion; import org.spongepowered.api.event.Cancellable; import org.spongepowered.api.event.Event; import org.spongepowered.api.network.status.Favicon; @@ -92,6 +93,9 @@ interface Response extends StatusResponse { */ void setHidePlayers(boolean hide); + @Override + Version version(); + /** * Sets the {@link Favicon} to display on the client. * @@ -130,6 +134,33 @@ interface Players extends StatusResponse.Players { @Override List profiles(); } + + /** + * Represents the information about the version of the server, sent + * after the {@link ClientPingServerEvent}. + */ + @NoFactoryMethod + interface Version extends MinecraftVersion { + + /** + * Sets the name of the version of the server. This is usually + * displayed on the client if the server is using an incompatible + * protocol version. + * + * @param name The new display name of the server version + */ + void setName(String name); + + /** + * Sets the server protocol version reported to the client. + * Modifying this will change if the client sees the server as + * incompatible or not, forcing it to display the {@link #name()}. + * + * @param protocolVersion The new server protocol version + * @see Protocol version (Minecraft Wiki) + */ + void setProtocolVersion(int protocolVersion); + } } }