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
This commit is contained in:
Alex 2024-06-21 01:54:29 +02:00 committed by GitHub
parent f2858940ca
commit 060a4ee6df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 61 additions and 43 deletions

View file

@ -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
)

View file

@ -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
);

View file

@ -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;
}

View file

@ -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<GameProfile> 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<GameProfile> 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;

View file

@ -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
);

View file

@ -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
)