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()); +// } +// } }