Skip to content

Commit a71123c

Browse files
committed
feat(bukkit/paper): Update RegistryReflection for Minecraft 1.21
closes #78
1 parent e82f9fc commit a71123c

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/internal/CraftBukkitReflection.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
package org.incendo.cloud.bukkit.internal;
2525

2626
import java.lang.reflect.Constructor;
27+
import java.lang.reflect.Executable;
2728
import java.lang.reflect.Field;
2829
import java.lang.reflect.Method;
30+
import java.lang.reflect.Modifier;
2931
import java.util.Arrays;
3032
import java.util.function.Supplier;
3133
import java.util.stream.Stream;
@@ -203,6 +205,14 @@ public final class CraftBukkitReflection {
203205
}
204206
}
205207

208+
public static @Nullable Constructor<?> findConstructor(final @NonNull Class<?> holder, final @NonNull Class<?>... parameters) {
209+
try {
210+
return holder.getDeclaredConstructor(parameters);
211+
} catch (final NoSuchMethodException ex) {
212+
return null;
213+
}
214+
}
215+
206216
public static boolean classExists(final @NonNull String className) {
207217
return findClass(className) != null;
208218
}
@@ -235,6 +245,20 @@ public static Stream<Method> streamMethods(final @NonNull Class<?> clazz) {
235245
return Arrays.stream(clazz.getDeclaredMethods());
236246
}
237247

248+
public static Object invokeConstructorOrStaticMethod(
249+
final Executable executable,
250+
final Object... args
251+
) throws ReflectiveOperationException {
252+
if (executable instanceof Constructor<?>) {
253+
return ((Constructor<?>) executable).newInstance(args);
254+
} else {
255+
if (!Modifier.isStatic(executable.getModifiers())) {
256+
throw new IllegalArgumentException("Method " + executable + " is not static.");
257+
}
258+
return ((Method) executable).invoke(null, args);
259+
}
260+
}
261+
238262
private CraftBukkitReflection() {
239263
}
240264
}

cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/internal/RegistryReflection.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
package org.incendo.cloud.bukkit.internal;
2525

2626
import io.leangen.geantyref.GenericTypeReflector;
27-
import java.lang.reflect.Constructor;
27+
import java.lang.reflect.Executable;
2828
import java.lang.reflect.Field;
2929
import java.lang.reflect.Method;
3030
import java.lang.reflect.Modifier;
@@ -51,10 +51,7 @@ public final class RegistryReflection {
5151
"net.minecraft.resources.MinecraftKey",
5252
"net.minecraft.resources.ResourceLocation"
5353
);
54-
private static final Constructor<?> RESOURCE_LOCATION_CTR = CraftBukkitReflection.needConstructor(
55-
RESOURCE_LOCATION_CLASS,
56-
String.class
57-
);
54+
private static final Executable NEW_RESOURCE_LOCATION;
5855

5956
private RegistryReflection() {
6057
}
@@ -65,6 +62,7 @@ private RegistryReflection() {
6562
REGISTRY_REGISTRY = null;
6663
REGISTRY_GET = null;
6764
REGISTRY_KEY = null;
65+
NEW_RESOURCE_LOCATION = null;
6866
} else {
6967
registryClass = CraftBukkitReflection.firstNonNullOrThrow(
7068
() -> "Registry",
@@ -90,6 +88,13 @@ private RegistryReflection() {
9088
.filter(m -> m.getParameterCount() == 0 && m.getReturnType().equals(resourceKeyClass))
9189
.findFirst()
9290
.orElse(null);
91+
92+
NEW_RESOURCE_LOCATION = CraftBukkitReflection.firstNonNullOrThrow(
93+
() -> "Could not find ResourceLocation#parse(String) or ResourceLocation#<init>(String)",
94+
CraftBukkitReflection.findConstructor(RESOURCE_LOCATION_CLASS, String.class), // <= 1.20.6
95+
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "parse", String.class), // 1.21+
96+
CraftBukkitReflection.findMethod(RESOURCE_LOCATION_CLASS, "a", String.class)
97+
);
9398
}
9499
}
95100

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

123128
public static Object createResourceLocation(final String str) {
124129
try {
125-
return RESOURCE_LOCATION_CTR.newInstance(str);
130+
return CraftBukkitReflection.invokeConstructorOrStaticMethod(NEW_RESOURCE_LOCATION, str);
126131
} catch (final ReflectiveOperationException e) {
127132
throw new RuntimeException(e);
128133
}

0 commit comments

Comments
 (0)