Skip to content

Commit

Permalink
feat(bukkit/paper): Update RegistryReflection for Minecraft 1.21
Browse files Browse the repository at this point in the history
closes #78
  • Loading branch information
jpenilla committed Jun 16, 2024
1 parent e82f9fc commit a71123c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
package org.incendo.cloud.bukkit.internal;

import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.function.Supplier;
import java.util.stream.Stream;
Expand Down Expand Up @@ -203,6 +205,14 @@ public final class CraftBukkitReflection {
}
}

public static @Nullable Constructor<?> findConstructor(final @NonNull Class<?> holder, final @NonNull Class<?>... parameters) {
try {
return holder.getDeclaredConstructor(parameters);
} catch (final NoSuchMethodException ex) {
return null;
}
}

public static boolean classExists(final @NonNull String className) {
return findClass(className) != null;
}
Expand Down Expand Up @@ -235,6 +245,20 @@ public static Stream<Method> streamMethods(final @NonNull Class<?> clazz) {
return Arrays.stream(clazz.getDeclaredMethods());
}

public static Object invokeConstructorOrStaticMethod(
final Executable executable,
final Object... args
) throws ReflectiveOperationException {
if (executable instanceof Constructor<?>) {
return ((Constructor<?>) executable).newInstance(args);
} else {
if (!Modifier.isStatic(executable.getModifiers())) {
throw new IllegalArgumentException("Method " + executable + " is not static.");
}
return ((Method) executable).invoke(null, args);
}
}

private CraftBukkitReflection() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
package org.incendo.cloud.bukkit.internal;

import io.leangen.geantyref.GenericTypeReflector;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
Expand All @@ -51,10 +51,7 @@ public final class RegistryReflection {
"net.minecraft.resources.MinecraftKey",
"net.minecraft.resources.ResourceLocation"
);
private static final Constructor<?> RESOURCE_LOCATION_CTR = CraftBukkitReflection.needConstructor(
RESOURCE_LOCATION_CLASS,
String.class
);
private static final Executable NEW_RESOURCE_LOCATION;

private RegistryReflection() {
}
Expand All @@ -65,6 +62,7 @@ private RegistryReflection() {
REGISTRY_REGISTRY = null;
REGISTRY_GET = null;
REGISTRY_KEY = null;
NEW_RESOURCE_LOCATION = null;
} else {
registryClass = CraftBukkitReflection.firstNonNullOrThrow(
() -> "Registry",
Expand All @@ -90,6 +88,13 @@ private RegistryReflection() {
.filter(m -> m.getParameterCount() == 0 && m.getReturnType().equals(resourceKeyClass))
.findFirst()
.orElse(null);

NEW_RESOURCE_LOCATION = CraftBukkitReflection.firstNonNullOrThrow(
() -> "Could not find ResourceLocation#parse(String) or ResourceLocation#<init>(String)",
CraftBukkitReflection.findConstructor(RESOURCE_LOCATION_CLASS, String.class), // <= 1.20.6
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "parse", String.class), // 1.21+
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "a", String.class)
);
}
}

Expand Down Expand Up @@ -122,7 +127,7 @@ public static Object registryByName(final String name) {

public static Object createResourceLocation(final String str) {
try {
return RESOURCE_LOCATION_CTR.newInstance(str);
return CraftBukkitReflection.invokeConstructorOrStaticMethod(NEW_RESOURCE_LOCATION, str);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
Expand Down

0 comments on commit a71123c

Please sign in to comment.