diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java index 61e86fc7..318e150e 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java @@ -52,7 +52,11 @@ import com.mojang.brigadier.arguments.ArgumentType; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Arrays; +import java.util.Map; import org.bukkit.NamespacedKey; import org.checkerframework.checker.nullness.qual.NonNull; @@ -71,7 +75,7 @@ public final class MinecraftArgumentTypes { private static final Constructor MINECRAFT_KEY_CONSTRUCTOR; private static final Method ARGUMENT_REGISTRY_GET_BY_KEY_METHOD; - private static final Field ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD; + private static final Field BY_CLASS_MAP_FIELD; static { try { @@ -101,11 +105,20 @@ public final class MinecraftArgumentTypes { .findFirst().orElseThrow(NoSuchMethodException::new); ARGUMENT_REGISTRY_GET_BY_KEY_METHOD.setAccessible(true); - Class argumentRegistryEntry = ARGUMENT_REGISTRY_GET_BY_KEY_METHOD.getReturnType(); - ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD = Arrays.stream(argumentRegistryEntry.getDeclaredFields()) - .filter(field -> field.getType() == Class.class) - .findFirst().orElseThrow(NoSuchFieldException::new); - ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD.setAccessible(true); + BY_CLASS_MAP_FIELD = Arrays.stream(argumentRegistry.getDeclaredFields()) + .filter(field -> Modifier.isStatic(field.getModifiers())) + .filter(field -> field.getType().equals(Map.class)) + .filter(field -> { + final ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType(); + final Type param = parameterizedType.getActualTypeArguments()[0]; + if (!(param instanceof ParameterizedType)) { + return false; + } + return ((ParameterizedType) param).getRawType().equals(Class.class); + }) + .findFirst() + .orElseThrow(NoSuchFieldException::new); + BY_CLASS_MAP_FIELD.setAccessible(true); } catch (ReflectiveOperationException e) { throw new ExceptionInInitializerError(e); } @@ -129,8 +142,13 @@ public final class MinecraftArgumentTypes { throw new IllegalArgumentException(key.toString()); } - final Class argument = (Class) ARGUMENT_REGISTRY_ENTRY_CLASS_FIELD.get(entry); - return (Class>) argument; + final Map, Object> map = (Map, Object>) BY_CLASS_MAP_FIELD.get(null); + for (final Map.Entry, Object> mapEntry : map.entrySet()) { + if (mapEntry.getValue() == entry) { + return (Class>) mapEntry.getKey(); + } + } + throw new IllegalArgumentException(key.toString()); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); }