From 060a4ee6df05ca5b2a07e74193a9df386081e2f7 Mon Sep 17 00:00:00 2001 From: Alex <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 21 Jun 2024 01:54:29 +0200 Subject: [PATCH] Fix optional status fields (#821) * Make code more readable before changes * Use proper kyori methods * Make PlayerInfo and VersionInfo optional * Sort ServerStatusInfo fields in the way they appear in the packet --- .../example/MinecraftProtocolTest.java | 4 +- .../protocol/ServerListener.java | 4 +- .../data/status/ServerStatusInfo.java | 5 +- .../ClientboundStatusResponsePacket.java | 79 +++++++++++-------- .../protocol/MinecraftProtocolTest.java | 4 +- .../ClientboundStatusResponsePacketTest.java | 8 +- 6 files changed, 61 insertions(+), 43 deletions(-) diff --git a/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java b/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java index 1dd504cf..86234a4d 100644 --- a/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java +++ b/example/src/main/java/org/geysermc/mcprotocollib/protocol/example/MinecraftProtocolTest.java @@ -66,9 +66,9 @@ public class MinecraftProtocolTest { server.setGlobalFlag(MinecraftConstants.VERIFY_USERS_KEY, VERIFY_USERS); server.setGlobalFlag(MinecraftConstants.SERVER_INFO_BUILDER_KEY, session -> new ServerStatusInfo( - new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), - new PlayerInfo(100, 0, new ArrayList<>()), Component.text("Hello world!"), + new PlayerInfo(100, 0, new ArrayList<>()), + new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), null, false ) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java index 84949fde..b7763e28 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java @@ -160,9 +160,9 @@ public class ServerListener extends SessionAdapter { ServerInfoBuilder builder = session.getFlag(MinecraftConstants.SERVER_INFO_BUILDER_KEY); if (builder == null) { builder = $ -> new ServerStatusInfo( - new VersionInfo(protocol.getCodec().getMinecraftVersion(), protocol.getCodec().getProtocolVersion()), - new PlayerInfo(0, 20, new ArrayList<>()), Component.text("A Minecraft Server"), + new PlayerInfo(0, 20, new ArrayList<>()), + new VersionInfo(protocol.getCodec().getMinecraftVersion(), protocol.getCodec().getProtocolVersion()), null, false ); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/status/ServerStatusInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/status/ServerStatusInfo.java index 55e5c1e4..73556925 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/status/ServerStatusInfo.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/status/ServerStatusInfo.java @@ -6,14 +6,15 @@ import lombok.Data; import lombok.NonNull; import lombok.Setter; import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; @Data @Setter(AccessLevel.NONE) @AllArgsConstructor public class ServerStatusInfo { - private @NonNull VersionInfo versionInfo; - private @NonNull PlayerInfo playerInfo; private @NonNull Component description; + private @Nullable PlayerInfo playerInfo; + private @Nullable VersionInfo versionInfo; private byte[] iconPng; private boolean enforcesSecureChat; } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacket.java index ad642e8b..19912078 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacket.java @@ -48,22 +48,31 @@ public class ClientboundStatusResponsePacket implements MinecraftPacket { public ServerStatusInfo parseInfo() { JsonElement desc = data.get("description"); - Component description = DefaultComponentSerializer.get().serializer().fromJson(desc, Component.class); - JsonObject plrs = data.get("players").getAsJsonObject(); - List profiles = new ArrayList<>(); - if (plrs.has("sample")) { - JsonArray prof = plrs.get("sample").getAsJsonArray(); - if (prof.size() > 0) { - for (int index = 0; index < prof.size(); index++) { - JsonObject o = prof.get(index).getAsJsonObject(); - profiles.add(new GameProfile(o.get("id").getAsString(), o.get("name").getAsString())); + Component description = DefaultComponentSerializer.get().deserializeFromTree(desc); + + PlayerInfo players = null; + if (data.has("players")) { + JsonObject plrs = data.get("players").getAsJsonObject(); + List profiles = new ArrayList<>(); + if (plrs.has("sample")) { + JsonArray prof = plrs.get("sample").getAsJsonArray(); + if (prof.size() > 0) { + for (int index = 0; index < prof.size(); index++) { + JsonObject o = prof.get(index).getAsJsonObject(); + profiles.add(new GameProfile(o.get("id").getAsString(), o.get("name").getAsString())); + } } } + + players = new PlayerInfo(plrs.get("max").getAsInt(), plrs.get("online").getAsInt(), profiles); + } + + VersionInfo version = null; + if (data.has("version")) { + JsonObject ver = data.get("version").getAsJsonObject(); + version = new VersionInfo(ver.get("name").getAsString(), ver.get("protocol").getAsInt()); } - PlayerInfo players = new PlayerInfo(plrs.get("max").getAsInt(), plrs.get("online").getAsInt(), profiles); - JsonObject ver = data.get("version").getAsJsonObject(); - VersionInfo version = new VersionInfo(ver.get("name").getAsString(), ver.get("protocol").getAsInt()); byte[] icon = null; if (data.has("favicon")) { icon = stringToIcon(data.get("favicon").getAsString()); @@ -74,7 +83,7 @@ public class ClientboundStatusResponsePacket implements MinecraftPacket { enforcesSecureChat = data.get("enforcesSecureChat").getAsBoolean(); } - return new ServerStatusInfo(version, players, description, icon, enforcesSecureChat); + return new ServerStatusInfo(description, players, version, icon, enforcesSecureChat); } public ClientboundStatusResponsePacket withInfo(@NonNull ServerStatusInfo info) { @@ -83,30 +92,38 @@ public class ClientboundStatusResponsePacket implements MinecraftPacket { private static JsonObject toJson(ServerStatusInfo info) { JsonObject obj = new JsonObject(); - JsonObject ver = new JsonObject(); - ver.addProperty("name", info.getVersionInfo().getVersionName()); - ver.addProperty("protocol", info.getVersionInfo().getProtocolVersion()); - JsonObject plrs = new JsonObject(); - plrs.addProperty("max", info.getPlayerInfo().getMaxPlayers()); - plrs.addProperty("online", info.getPlayerInfo().getOnlinePlayers()); - if (!info.getPlayerInfo().getPlayers().isEmpty()) { - JsonArray array = new JsonArray(); - for (GameProfile profile : info.getPlayerInfo().getPlayers()) { - JsonObject o = new JsonObject(); - o.addProperty("name", profile.getName()); - o.addProperty("id", profile.getIdAsString()); - array.add(o); - } - plrs.add("sample", array); + obj.add("description", DefaultComponentSerializer.get().serializeToTree(info.getDescription())); + + if (info.getPlayerInfo() != null) { + JsonObject plrs = new JsonObject(); + plrs.addProperty("max", info.getPlayerInfo().getMaxPlayers()); + plrs.addProperty("online", info.getPlayerInfo().getOnlinePlayers()); + if (!info.getPlayerInfo().getPlayers().isEmpty()) { + JsonArray array = new JsonArray(); + for (GameProfile profile : info.getPlayerInfo().getPlayers()) { + JsonObject o = new JsonObject(); + o.addProperty("name", profile.getName()); + o.addProperty("id", profile.getIdAsString()); + array.add(o); + } + + plrs.add("sample", array); + } + obj.add("players", plrs); + } + + if (info.getVersionInfo() != null) { + JsonObject ver = new JsonObject(); + ver.addProperty("name", info.getVersionInfo().getVersionName()); + ver.addProperty("protocol", info.getVersionInfo().getProtocolVersion()); + obj.add("version", ver); } - obj.add("description", new Gson().fromJson(DefaultComponentSerializer.get().serialize(info.getDescription()), JsonElement.class)); - obj.add("players", plrs); - obj.add("version", ver); if (info.getIconPng() != null) { obj.addProperty("favicon", iconToString(info.getIconPng())); } + obj.addProperty("enforcesSecureChat", info.isEnforcesSecureChat()); return obj; diff --git a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java index ce762a3a..c56cb864 100644 --- a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java +++ b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocolTest.java @@ -35,9 +35,9 @@ public class MinecraftProtocolTest { private static final int PORT = 25562; private static final ServerStatusInfo SERVER_INFO = new ServerStatusInfo( - new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), - new PlayerInfo(100, 0, new ArrayList<>()), Component.text("Hello world!"), + new PlayerInfo(100, 0, new ArrayList<>()), + new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), null, false ); diff --git a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacketTest.java b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacketTest.java index 8059af6a..0c95836c 100644 --- a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacketTest.java +++ b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/status/clientbound/ClientboundStatusResponsePacketTest.java @@ -18,11 +18,11 @@ public class ClientboundStatusResponsePacketTest extends PacketTest { public void setup() { this.setPackets(new ClientboundStatusResponsePacket( new ServerStatusInfo( - new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), - new PlayerInfo(100, 10, new ArrayList<>( - Collections.singleton(new GameProfile(UUID.randomUUID(), "Username")) - )), Component.text("Description"), + new PlayerInfo(100, 10, new ArrayList<>( + Collections.singleton(new GameProfile(UUID.randomUUID(), "Username")) + )), + new VersionInfo(MinecraftCodec.CODEC.getMinecraftVersion(), MinecraftCodec.CODEC.getProtocolVersion()), null, false )