Skip to content

Commit e006518

Browse files
committed
Update BlockPredicateArgument for 1.18.2
1 parent 9f2afe2 commit e006518

1 file changed

Lines changed: 60 additions & 6 deletions

File tree

cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/parsers/BlockPredicateArgument.java

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@
3636
import com.mojang.brigadier.arguments.ArgumentType;
3737
import io.leangen.geantyref.TypeToken;
3838
import java.lang.reflect.Constructor;
39+
import java.lang.reflect.Field;
3940
import java.lang.reflect.Method;
41+
import java.util.Arrays;
4042
import java.util.List;
43+
import java.util.Objects;
4144
import java.util.Queue;
4245
import java.util.function.BiFunction;
4346
import java.util.function.Predicate;
@@ -141,18 +144,62 @@ private Builder(final @NonNull String name) {
141144
public static final class Parser<C> implements ArgumentParser<C, BlockPredicate> {
142145

143146
private static final Class<?> TAG_CONTAINER_CLASS;
147+
private static final @Nullable Field REGISTRY_REGISTRY;
148+
private static final @Nullable Method REGISTRY_GET;
149+
private static final @Nullable Object BLOCK_REGISTRY_RESOURCE_LOCATION;
144150

145151
static {
152+
Class<?> tagContainerClass;
146153
if (CraftBukkitReflection.MAJOR_REVISION > 12 && CraftBukkitReflection.MAJOR_REVISION < 16) {
147-
TAG_CONTAINER_CLASS = CraftBukkitReflection.needNMSClass("TagRegistry");
154+
tagContainerClass = CraftBukkitReflection.needNMSClass("TagRegistry");
155+
REGISTRY_REGISTRY = null;
156+
REGISTRY_GET = null;
157+
BLOCK_REGISTRY_RESOURCE_LOCATION = null;
148158
} else {
149-
TAG_CONTAINER_CLASS = CraftBukkitReflection.firstNonNullOrThrow(
150-
() -> "Couldn't find TagContainer class",
159+
tagContainerClass = CraftBukkitReflection.firstNonNullOrNull(
151160
CraftBukkitReflection.findNMSClass("ITagRegistry"),
152161
CraftBukkitReflection.findMCClass("tags.ITagRegistry"),
153162
CraftBukkitReflection.findMCClass("tags.TagContainer")
154163
);
164+
if (tagContainerClass == null) {
165+
tagContainerClass = CraftBukkitReflection.firstNonNullOrThrow(
166+
() -> "Registry",
167+
CraftBukkitReflection.findMCClass("core.IRegistry"),
168+
CraftBukkitReflection.findMCClass("core.Registry")
169+
);
170+
final Class<?> tagContainerClassFinal = tagContainerClass;
171+
REGISTRY_REGISTRY = Arrays.stream(tagContainerClass.getDeclaredFields())
172+
.filter(it -> it.getType().equals(tagContainerClassFinal))
173+
.findFirst()
174+
.orElseThrow(() -> new IllegalStateException("Could not find Registry Registry field"));
175+
REGISTRY_REGISTRY.setAccessible(true);
176+
final Class<?> resourceLocationClass = CraftBukkitReflection.firstNonNullOrThrow(
177+
() -> "ResourceLocation class",
178+
CraftBukkitReflection.findMCClass("resources.ResourceLocation"),
179+
CraftBukkitReflection.findMCClass("resources.MinecraftKey")
180+
);
181+
REGISTRY_GET = Arrays.stream(tagContainerClass.getDeclaredMethods())
182+
.filter(it -> it.getParameterCount() == 1
183+
&& it.getParameterTypes()[0].equals(resourceLocationClass)
184+
&& it.getReturnType().equals(Object.class))
185+
.findFirst()
186+
.orElseThrow(() -> new IllegalStateException("Could not find Registry#get(ResourceLocation)"));
187+
final Constructor<?> resourceLocationCtr = CraftBukkitReflection.needConstructor(
188+
resourceLocationClass,
189+
String.class
190+
);
191+
try {
192+
BLOCK_REGISTRY_RESOURCE_LOCATION = resourceLocationCtr.newInstance("block");
193+
} catch (final ReflectiveOperationException e) {
194+
throw new RuntimeException(e);
195+
}
196+
} else {
197+
REGISTRY_REGISTRY = null;
198+
REGISTRY_GET = null;
199+
BLOCK_REGISTRY_RESOURCE_LOCATION = null;
200+
}
155201
}
202+
TAG_CONTAINER_CLASS = tagContainerClass;
156203
}
157204

158205
private static final Class<?> CRAFT_WORLD_CLASS = CraftBukkitReflection.needOBCClass("CraftWorld");
@@ -206,8 +253,7 @@ public static final class Parser<C> implements ArgumentParser<C, BlockPredicate>
206253
.filter(it -> it.getReturnType().equals(MINECRAFT_SERVER_CLASS) && it.getParameterCount() == 0)
207254
.findFirst()
208255
.orElseThrow(() -> new IllegalStateException("Could not find CommandSourceStack#getServer."));
209-
private static final Method GET_TAG_REGISTRY_METHOD = CraftBukkitReflection.firstNonNullOrThrow(
210-
() -> "getTags method on MinecraftServer",
256+
private static final @Nullable Method GET_TAG_REGISTRY_METHOD = CraftBukkitReflection.firstNonNullOrNull(
211257
CraftBukkitReflection.findMethod(MINECRAFT_SERVER_CLASS, "getTagRegistry"),
212258
CraftBukkitReflection.findMethod(MINECRAFT_SERVER_CLASS, "getTags"),
213259
CraftBukkitReflection.streamMethods(MINECRAFT_SERVER_CLASS)
@@ -239,7 +285,15 @@ private ArgumentParser<C, BlockPredicate> createParser() throws ReflectiveOperat
239285
final Object commandSourceStack = ctx.get(WrappedBrigadierParser.COMMAND_CONTEXT_BRIGADIER_NATIVE_SENDER);
240286
try {
241287
final Object server = GET_SERVER_METHOD.invoke(commandSourceStack);
242-
final Object tagRegistry = GET_TAG_REGISTRY_METHOD.invoke(server);
288+
final Object tagRegistry;
289+
if (GET_TAG_REGISTRY_METHOD != null) {
290+
tagRegistry = GET_TAG_REGISTRY_METHOD.invoke(server);
291+
} else {
292+
Objects.requireNonNull(REGISTRY_GET, "REGISTRY_GET");
293+
Objects.requireNonNull(REGISTRY_REGISTRY, "REGISTRY_REGISTRY");
294+
final Object registryRegistry = REGISTRY_REGISTRY.get(null);
295+
tagRegistry = REGISTRY_GET.invoke(registryRegistry, BLOCK_REGISTRY_RESOURCE_LOCATION);
296+
}
243297
final Predicate<Object> predicate = (Predicate<Object>) CREATE_PREDICATE_METHOD.invoke(result, tagRegistry);
244298
return ArgumentParseResult.success(new BlockPredicateImpl(predicate));
245299
} catch (final ReflectiveOperationException ex) {

0 commit comments

Comments
 (0)