diff --git a/cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/selector/SelectorUtils.java b/cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/selector/SelectorUtils.java index f3254252..9fdc4bda 100644 --- a/cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/selector/SelectorUtils.java +++ b/cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/selector/SelectorUtils.java @@ -107,21 +107,50 @@ public Object apply( final ArgumentType type, final StringReader reader ) throws CommandSyntaxException { - final @Nullable Method specialParse = CraftBukkitReflection.findMethod( + // Minecraft 1.21.1 added allowSelectors to Vanilla's internal parse overload. CraftBukkit moved + // its existing overridePermissions parameter to a new three-argument overload to avoid a collision. + final @Nullable Method parseWithSelectorControl = CraftBukkitReflection.findMethod( type.getClass(), "parse", StringReader.class, + boolean.class, boolean.class ); - if (specialParse == null) { - return type.parse(reader); + if (parseWithSelectorControl != null) { + return invokeCraftBukkitParse( + parseWithSelectorControl, + type, + reader, + true, // allowSelectors + true // overridePermissions + ); } - try { - return specialParse.invoke( + + // Before Minecraft 1.21.1, CraftBukkit's only additional parameter was overridePermissions. + final @Nullable Method parseWithPermissionOverride = CraftBukkitReflection.findMethod( + type.getClass(), + "parse", + StringReader.class, + boolean.class + ); + if (parseWithPermissionOverride != null) { + return invokeCraftBukkitParse( + parseWithPermissionOverride, type, reader, - true // CraftBukkit overridePermissions param + true // overridePermissions ); + } + return type.parse(reader); + } + + private static Object invokeCraftBukkitParse( + final Method method, + final ArgumentType type, + final Object... arguments + ) throws CommandSyntaxException { + try { + return method.invoke(type, arguments); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause instanceof CommandSyntaxException) {