Skip to content

Commit b9a09d2

Browse files
committed
Fix DeviceOS reading in BedrockClientData
This is possibly a Configurate/GSON regression as it appears JSON does not handle ordinal -> enum constant well.
1 parent 2ed4eff commit b9a09d2

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

core/src/main/java/org/geysermc/geyser/session/auth/BedrockClientData.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,25 @@
2525

2626
package org.geysermc.geyser.session.auth;
2727

28+
import com.google.gson.Gson;
2829
import com.google.gson.JsonDeserializationContext;
2930
import com.google.gson.JsonDeserializer;
3031
import com.google.gson.JsonElement;
3132
import com.google.gson.JsonParseException;
33+
import com.google.gson.TypeAdapter;
34+
import com.google.gson.TypeAdapterFactory;
3235
import com.google.gson.annotations.JsonAdapter;
3336
import com.google.gson.annotations.SerializedName;
37+
import com.google.gson.reflect.TypeToken;
38+
import com.google.gson.stream.JsonReader;
39+
import com.google.gson.stream.JsonWriter;
3440
import lombok.Getter;
3541
import lombok.Setter;
3642
import org.geysermc.floodgate.util.DeviceOs;
3743
import org.geysermc.floodgate.util.InputMode;
3844
import org.geysermc.floodgate.util.UiProfile;
3945

46+
import java.io.IOException;
4047
import java.lang.reflect.Type;
4148
import java.nio.charset.StandardCharsets;
4249
import java.util.UUID;
@@ -85,6 +92,7 @@ public final class BedrockClientData {
8592
@SerializedName(value = "DeviceModel")
8693
private String deviceModel;
8794
@SerializedName(value = "DeviceOS")
95+
@JsonAdapter(value = IntToEnumTypeFactory.class)
8896
private DeviceOs deviceOs;
8997
@SerializedName(value = "UIProfile")
9098
private UiProfile uiProfile;
@@ -139,4 +147,42 @@ public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationCon
139147
return json.getAsString().getBytes(StandardCharsets.UTF_8);
140148
}
141149
}
150+
151+
/**
152+
* Creates a JSON parser that reads the incoming enum ordinal and converts it to the enum constant.
153+
*/
154+
private static final class IntToEnumTypeFactory implements TypeAdapterFactory {
155+
@Override
156+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
157+
//noinspection unchecked
158+
Class<T> rawType = (Class<T>) type.getRawType();
159+
if (!rawType.isEnum()) {
160+
return null;
161+
}
162+
163+
T[] constants = rawType.getEnumConstants();
164+
return new TypeAdapter<>() {
165+
@Override
166+
public void write(JsonWriter out, T value) {
167+
}
168+
169+
@Override
170+
public T read(JsonReader in) throws IOException {
171+
int ordinal = in.nextInt();
172+
if (ordinal < 0 || ordinal >= constants.length) {
173+
return null;
174+
}
175+
return constants[ordinal];
176+
}
177+
};
178+
}
179+
}
180+
181+
// private static final class IntToEnumDeserializer implements JsonDeserializer<Enum<?>> {
182+
// @Override
183+
// public Enum<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
184+
// System.out.println(typeOfT.getClass().getTypeParameters()[0]);
185+
// return DeviceOs.fromId(json.getAsInt());
186+
// }
187+
// }
142188
}

0 commit comments

Comments
 (0)