From b9a09d2d4febe86028e5d746586426c0f870fe84 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 22 Nov 2025 20:41:03 -0500 Subject: [PATCH] Fix DeviceOS reading in BedrockClientData This is possibly a Configurate/GSON regression as it appears JSON does not handle ordinal -> enum constant well. --- .../session/auth/BedrockClientData.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/core/src/main/java/org/geysermc/geyser/session/auth/BedrockClientData.java b/core/src/main/java/org/geysermc/geyser/session/auth/BedrockClientData.java index 8aad61ede..388576049 100644 --- a/core/src/main/java/org/geysermc/geyser/session/auth/BedrockClientData.java +++ b/core/src/main/java/org/geysermc/geyser/session/auth/BedrockClientData.java @@ -25,18 +25,25 @@ package org.geysermc.geyser.session.auth; +import com.google.gson.Gson; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; import lombok.Getter; import lombok.Setter; import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.floodgate.util.InputMode; import org.geysermc.floodgate.util.UiProfile; +import java.io.IOException; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.UUID; @@ -85,6 +92,7 @@ public final class BedrockClientData { @SerializedName(value = "DeviceModel") private String deviceModel; @SerializedName(value = "DeviceOS") + @JsonAdapter(value = IntToEnumTypeFactory.class) private DeviceOs deviceOs; @SerializedName(value = "UIProfile") private UiProfile uiProfile; @@ -139,4 +147,42 @@ public final class BedrockClientData { return json.getAsString().getBytes(StandardCharsets.UTF_8); } } + + /** + * Creates a JSON parser that reads the incoming enum ordinal and converts it to the enum constant. + */ + private static final class IntToEnumTypeFactory implements TypeAdapterFactory { + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + //noinspection unchecked + Class rawType = (Class) type.getRawType(); + if (!rawType.isEnum()) { + return null; + } + + T[] constants = rawType.getEnumConstants(); + return new TypeAdapter<>() { + @Override + public void write(JsonWriter out, T value) { + } + + @Override + public T read(JsonReader in) throws IOException { + int ordinal = in.nextInt(); + if (ordinal < 0 || ordinal >= constants.length) { + return null; + } + return constants[ordinal]; + } + }; + } + } + +// private static final class IntToEnumDeserializer implements JsonDeserializer> { +// @Override +// public Enum deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { +// System.out.println(typeOfT.getClass().getTypeParameters()[0]); +// return DeviceOs.fromId(json.getAsInt()); +// } +// } }