Skip to content

Commit

Permalink
Fix MinecraftComponentSerializer on 1.20.3
Browse files Browse the repository at this point in the history
  • Loading branch information
56738 committed Dec 6, 2023
1 parent dda3e32 commit 46ace62
Showing 1 changed file with 58 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,15 @@ public static boolean isSupported() {
private static final Object MC_TEXT_GSON;
private static final MethodHandle TEXT_SERIALIZER_DESERIALIZE;
private static final MethodHandle TEXT_SERIALIZER_SERIALIZE;
private static final MethodHandle TEXT_SERIALIZER_DESERIALIZE_TREE;
private static final MethodHandle TEXT_SERIALIZER_SERIALIZE_TREE;

static {
Object gson = null;
MethodHandle textSerializerDeserialize = null;
MethodHandle textSerializerSerialize = null;
MethodHandle textSerializerDeserializeTree = null;
MethodHandle textSerializerSerializeTree = null;

try {
if (CLASS_CHAT_COMPONENT != null) {
Expand Down Expand Up @@ -126,26 +130,45 @@ public static boolean isSupported() {
if (gsonField != null) {
gsonField.setAccessible(true);
gson = gsonField.get(null);
} else {
final Method[] declaredMethods = chatSerializerClass.getDeclaredMethods();
final Method deserialize = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> CLASS_CHAT_COMPONENT.isAssignableFrom(m.getReturnType()))
.filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(String.class))
.min(Comparator.comparing(Method::getName)) // prefer the #a method
.orElse(null);
final Method serialize = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> m.getReturnType().equals(String.class))
.filter(m -> m.getParameterCount() == 1 && CLASS_CHAT_COMPONENT.isAssignableFrom(m.getParameterTypes()[0]))
.findFirst()
.orElse(null);
if (deserialize != null) {
textSerializerDeserialize = lookup().unreflect(deserialize);
}
if (serialize != null) {
textSerializerSerialize = lookup().unreflect(serialize);
}
}
}
for (Class<?> serializerClass : CLASS_CHAT_COMPONENT.getClasses()) {
final Method[] declaredMethods = serializerClass.getDeclaredMethods();
final Method deserialize = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> CLASS_CHAT_COMPONENT.isAssignableFrom(m.getReturnType()))
.filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(String.class))
.min(Comparator.comparing(Method::getName)) // prefer the #a method
.orElse(null);
final Method serialize = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> m.getReturnType().equals(String.class))
.filter(m -> m.getParameterCount() == 1 && CLASS_CHAT_COMPONENT.isAssignableFrom(m.getParameterTypes()[0]))
.findFirst()
.orElse(null);
final Method deserializeTree = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> CLASS_CHAT_COMPONENT.isAssignableFrom(m.getReturnType()))
.filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(JsonElement.class))
.min(Comparator.comparing(Method::getName)) // prefer the #a method
.orElse(null);
final Method serializeTree = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> m.getReturnType().equals(JsonElement.class))
.filter(m -> m.getParameterCount() == 1 && CLASS_CHAT_COMPONENT.isAssignableFrom(m.getParameterTypes()[0]))
.findFirst()
.orElse(null);
if (deserialize != null) {
textSerializerDeserialize = lookup().unreflect(deserialize);
}
if (serialize != null) {
textSerializerSerialize = lookup().unreflect(serialize);
}
if (deserializeTree != null) {
textSerializerDeserializeTree = lookup().unreflect(deserializeTree);
}
if (serializeTree != null) {
textSerializerSerializeTree = lookup().unreflect(serializeTree);
}
}
}
Expand All @@ -156,20 +179,26 @@ public static boolean isSupported() {
MC_TEXT_GSON = gson;
TEXT_SERIALIZER_DESERIALIZE = textSerializerDeserialize;
TEXT_SERIALIZER_SERIALIZE = textSerializerSerialize;
TEXT_SERIALIZER_DESERIALIZE_TREE = textSerializerDeserializeTree;
TEXT_SERIALIZER_SERIALIZE_TREE = textSerializerSerializeTree;
}

private static final boolean SUPPORTED = MC_TEXT_GSON != null || (TEXT_SERIALIZER_DESERIALIZE != null && TEXT_SERIALIZER_SERIALIZE != null);
private static final boolean SUPPORTED = MC_TEXT_GSON != null || (TEXT_SERIALIZER_DESERIALIZE != null && TEXT_SERIALIZER_SERIALIZE != null) || (TEXT_SERIALIZER_DESERIALIZE_TREE != null && TEXT_SERIALIZER_SERIALIZE_TREE != null);

@Override
public @NotNull Component deserialize(final @NotNull Object input) {
if (!SUPPORTED) throw INITIALIZATION_ERROR.get();

try {
if (MC_TEXT_GSON != null) {
final JsonElement element = ((Gson) MC_TEXT_GSON).toJsonTree(input);
return gson().serializer().fromJson(element, Component.class);
final JsonElement element;
if (TEXT_SERIALIZER_SERIALIZE_TREE != null) {
element = (JsonElement) TEXT_SERIALIZER_SERIALIZE_TREE.invoke(input);
} else if (MC_TEXT_GSON != null) {
element = ((Gson) MC_TEXT_GSON).toJsonTree(input);
} else {
return gson().deserialize((String) TEXT_SERIALIZER_SERIALIZE.invoke(input));
}
return GsonComponentSerializer.gson().deserialize((String) TEXT_SERIALIZER_SERIALIZE.invoke(input));
return gson().serializer().fromJson(element, Component.class);
} catch (final Throwable error) {
throw new UnsupportedOperationException(error);
}
Expand All @@ -179,9 +208,12 @@ public static boolean isSupported() {
public @NotNull Object serialize(final @NotNull Component component) {
if (!SUPPORTED) throw INITIALIZATION_ERROR.get();

if (MC_TEXT_GSON != null) {
if (TEXT_SERIALIZER_DESERIALIZE_TREE != null || MC_TEXT_GSON != null) {
final JsonElement json = gson().serializer().toJsonTree(component);
try {
if (TEXT_SERIALIZER_DESERIALIZE_TREE != null) {
return TEXT_SERIALIZER_DESERIALIZE_TREE.invoke(json);
}
return ((Gson) MC_TEXT_GSON).fromJson(json, CLASS_CHAT_COMPONENT);
} catch (final Throwable error) {
throw new UnsupportedOperationException(error);
Expand Down

0 comments on commit 46ace62

Please sign in to comment.