Skip to content

Commit

Permalink
Merge pull request #177 from re-ovo/main
Browse files Browse the repository at this point in the history
Fixed MinecraftComponentSerializer not working due to relocation
  • Loading branch information
zml2008 authored Jun 19, 2024
2 parents dd97b66 + 7724203 commit 609e417
Showing 1 changed file with 19 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findClass;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findCraftClass;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findMcClassName;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findMethod;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findNmsClass;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findNmsClassName;
import static net.kyori.adventure.platform.bukkit.MinecraftReflection.findStaticMethod;
Expand Down Expand Up @@ -87,6 +88,8 @@ public static boolean isSupported() {
}

private static final @Nullable Class<?> CLASS_JSON_DESERIALIZER = findClass("com.goo".concat("gle.gson.JsonDeserializer")); // Hide from relocation checkers
private static final @Nullable Class<?> CLASS_JSON_ELEMENT = findClass("com.goo".concat("gle.gson.JsonElement"));
private static final @Nullable Class<?> CLASS_JSON_PARSER = findClass("com.goo".concat("gle.gson.JsonParser"));
private static final @Nullable Class<?> CLASS_CHAT_COMPONENT = findClass(
findNmsClassName("IChatBaseComponent"),
findMcClassName("network.chat.IChatBaseComponent"),
Expand All @@ -97,9 +100,10 @@ public static boolean isSupported() {
findMcClassName("core.IRegistryCustom"),
findMcClassName("core.RegistryAccess")
);
private static final @Nullable MethodHandle PARSE_JSON = findMethod(CLASS_JSON_PARSER, "parse", CLASS_JSON_ELEMENT, String.class);
private static final @Nullable MethodHandle GET_REGISTRY = findStaticMethod(CLASS_CRAFT_REGISTRY, "getMinecraftRegistry", CLASS_REGISTRY_ACCESS);
private static final AtomicReference<RuntimeException> INITIALIZATION_ERROR = new AtomicReference<>(new UnsupportedOperationException());

private static final Object JSON_PARSER_INSTANCE;
private static final Object MC_TEXT_GSON;
private static final MethodHandle TEXT_SERIALIZER_DESERIALIZE;
private static final MethodHandle TEXT_SERIALIZER_SERIALIZE;
Expand All @@ -108,12 +112,16 @@ public static boolean isSupported() {

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

try {
if (CLASS_JSON_PARSER != null) {
jsonParserInstance = CLASS_JSON_PARSER.getDeclaredConstructor().newInstance();
}
if (CLASS_CHAT_COMPONENT != null) {
final Object registryAccess = GET_REGISTRY != null ? GET_REGISTRY.invoke() : null;
// Chat serializer //
Expand Down Expand Up @@ -165,26 +173,26 @@ public static boolean isSupported() {
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))
.filter(m -> m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(CLASS_JSON_ELEMENT))
.findFirst()
.orElse(null);
final Method serializeTree = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> m.getReturnType().equals(JsonElement.class))
.filter(m -> m.getReturnType().equals(CLASS_JSON_ELEMENT))
.filter(m -> m.getParameterCount() == 1 && CLASS_CHAT_COMPONENT.isAssignableFrom(m.getParameterTypes()[0]))
.findFirst()
.orElse(null);
final Method deserializeTreeWithRegistryAccess = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> CLASS_CHAT_COMPONENT.isAssignableFrom(m.getReturnType()))
.filter(m -> m.getParameterCount() == 2)
.filter(m -> m.getParameterTypes()[0].equals(JsonElement.class))
.filter(m -> m.getParameterTypes()[0].equals(CLASS_JSON_ELEMENT))
.filter(m -> m.getParameterTypes()[1].isInstance(registryAccess))
.findFirst()
.orElse(null);
final Method serializeTreeWithRegistryAccess = Arrays.stream(declaredMethods)
.filter(m -> Modifier.isStatic(m.getModifiers()))
.filter(m -> m.getReturnType().equals(JsonElement.class))
.filter(m -> m.getReturnType().equals(CLASS_JSON_ELEMENT))
.filter(m -> m.getParameterCount() == 2)
.filter(m -> CLASS_CHAT_COMPONENT.isAssignableFrom(m.getParameterTypes()[0]))
.filter(m -> m.getParameterTypes()[1].isInstance(registryAccess))
Expand Down Expand Up @@ -215,6 +223,7 @@ public static boolean isSupported() {
}

MC_TEXT_GSON = gson;
JSON_PARSER_INSTANCE = jsonParserInstance;
TEXT_SERIALIZER_DESERIALIZE = textSerializerDeserialize;
TEXT_SERIALIZER_SERIALIZE = textSerializerSerialize;
TEXT_SERIALIZER_DESERIALIZE_TREE = textSerializerDeserializeTree;
Expand All @@ -228,15 +237,15 @@ public static boolean isSupported() {
if (!SUPPORTED) throw INITIALIZATION_ERROR.get();

try {
final JsonElement element;
final Object element;
if (TEXT_SERIALIZER_SERIALIZE_TREE != null) {
element = (JsonElement) TEXT_SERIALIZER_SERIALIZE_TREE.invoke(input);
element = 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 gson().serializer().fromJson(element, Component.class);
return gson().serializer().fromJson(element.toString(), Component.class);
} catch (final Throwable error) {
throw new UnsupportedOperationException(error);
}
Expand All @@ -250,7 +259,8 @@ public static boolean isSupported() {
final JsonElement json = gson().serializer().toJsonTree(component);
try {
if (TEXT_SERIALIZER_DESERIALIZE_TREE != null) {
return TEXT_SERIALIZER_DESERIALIZE_TREE.invoke(json);
final Object unRelocatedJsonElement = PARSE_JSON.invoke(JSON_PARSER_INSTANCE, json.toString());
return TEXT_SERIALIZER_DESERIALIZE_TREE.invoke(unRelocatedJsonElement);
}
return ((Gson) MC_TEXT_GSON).fromJson(json, CLASS_CHAT_COMPONENT);
} catch (final Throwable error) {
Expand Down

0 comments on commit 609e417

Please sign in to comment.