1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

Fix DeviceOS reading in BedrockClientData

This is possibly a Configurate/GSON regression as it appears JSON does not handle ordinal -> enum constant well.
This commit is contained in:
Camotoy
2025-11-22 20:41:03 -05:00
parent 2ed4eff18f
commit b9a09d2d4f

View File

@@ -25,18 +25,25 @@
package org.geysermc.geyser.session.auth; package org.geysermc.geyser.session.auth;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonParseException; 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.JsonAdapter;
import com.google.gson.annotations.SerializedName; 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.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.floodgate.util.DeviceOs; import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.floodgate.util.InputMode; import org.geysermc.floodgate.util.InputMode;
import org.geysermc.floodgate.util.UiProfile; import org.geysermc.floodgate.util.UiProfile;
import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
@@ -85,6 +92,7 @@ public final class BedrockClientData {
@SerializedName(value = "DeviceModel") @SerializedName(value = "DeviceModel")
private String deviceModel; private String deviceModel;
@SerializedName(value = "DeviceOS") @SerializedName(value = "DeviceOS")
@JsonAdapter(value = IntToEnumTypeFactory.class)
private DeviceOs deviceOs; private DeviceOs deviceOs;
@SerializedName(value = "UIProfile") @SerializedName(value = "UIProfile")
private UiProfile uiProfile; private UiProfile uiProfile;
@@ -139,4 +147,42 @@ public final class BedrockClientData {
return json.getAsString().getBytes(StandardCharsets.UTF_8); 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 <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
//noinspection unchecked
Class<T> rawType = (Class<T>) 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<Enum<?>> {
// @Override
// public Enum<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// System.out.println(typeOfT.getClass().getTypeParameters()[0]);
// return DeviceOs.fromId(json.getAsInt());
// }
// }
} }