more docs & tweaks

This commit is contained in:
Jake Potrebic 2024-05-04 15:48:49 -07:00
parent 212b7dc19b
commit 4c64fd66b0
No known key found for this signature in database
GPG Key ID: ECE0B3C133C016C5
2 changed files with 90 additions and 77 deletions

View File

@ -394,10 +394,10 @@ index 0000000000000000000000000000000000000000..2db12952461c92a64505d6646f6f49f8
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..a3fc1fd8ae82da1ef69e3de97d6181bb1b0404f2 index 0000000000000000000000000000000000000000..8109abe46b166c335d05a2cc25e91010aa4fa0f5
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java +++ b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java
@@ -0,0 +1,316 @@ @@ -0,0 +1,315 @@
+package io.papermc.paper.command.brigadier.argument; +package io.papermc.paper.command.brigadier.argument;
+ +
+import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.ArgumentType;
@ -441,10 +441,6 @@ index 0000000000000000000000000000000000000000..a3fc1fd8ae82da1ef69e3de97d6181bb
+ static final Optional<VanillaArgumentProvider> PROVIDER = ServiceLoader.load(VanillaArgumentProvider.class) + static final Optional<VanillaArgumentProvider> PROVIDER = ServiceLoader.load(VanillaArgumentProvider.class)
+ .findFirst(); + .findFirst();
+ +
+ @ApiStatus.Internal
+ ArgumentTypes() {
+ }
+
+ /** + /**
+ * Represents a selector that can capture any + * Represents a selector that can capture any
+ * entity. + * entity.
@ -712,14 +708,17 @@ index 0000000000000000000000000000000000000000..a3fc1fd8ae82da1ef69e3de97d6181bb
+ +
+ private static VanillaArgumentProvider provider() { + private static VanillaArgumentProvider provider() {
+ return PROVIDER.orElseThrow(); + return PROVIDER.orElseThrow();
+ } + }
+
+ private ArgumentTypes() {
+ }
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java b/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java b/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..5d33e1e04b1f279d6ad6371d0cfd9f129fcd8370 index 0000000000000000000000000000000000000000..02acac7f9186677d19c0a62095cc3012bc112961
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java +++ b/src/main/java/io/papermc/paper/command/brigadier/argument/CustomArgumentType.java
@@ -0,0 +1,107 @@ @@ -0,0 +1,106 @@
+package io.papermc.paper.command.brigadier.argument; +package io.papermc.paper.command.brigadier.argument;
+ +
+import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.StringReader;
@ -735,28 +734,28 @@ index 0000000000000000000000000000000000000000..5d33e1e04b1f279d6ad6371d0cfd9f12
+ +
+/** +/**
+ * An argument type that wraps around a native-to-vanilla argument type. + * An argument type that wraps around a native-to-vanilla argument type.
+ * This argument type is special in that the underlying native argument type will + * This argument receives special handling in that the native argument type will
+ * be sent to the client. + * be sent to the client for possible client-side completions and syntax validation.
+ * <p> + * <p>
+ * When extending this class, you have to implement your own parsing logic. If + * When implementing this class, you have to create your own parsing logic from a
+ * you want to have the command value parsed into the native type and then + * {@link StringReader}. If only want to convert from the native type ({@code N}) to the custom
+ * converted to your custom type, use {@link Converted}. + * type ({@code T}), implement {@link Converted} instead.
+ * + *
+ * @param <T> custom type + * @param <T> custom type
+ * @param <N> type with an argument native to minecraft + * @param <N> type with an argument native to vanilla Minecraft (from {@link ArgumentTypes})
+ */ + */
+@ApiStatus.Experimental +@ApiStatus.Experimental
+public interface CustomArgumentType<T, N> extends ArgumentType<T> { +public interface CustomArgumentType<T, N> extends ArgumentType<T> {
+ +
+ /** + /**
+ * Parses the argument using the native argument type. Keep in mind + * Parses the argument into the custom type ({@code T}). Keep in mind
+ * that this parsing will be done on the server. This means that if + * that this parsing will be done on the server. This means that if
+ * you throw a {@link CommandSyntaxException} during parsing, this + * you throw a {@link CommandSyntaxException} during parsing, this
+ * will only show on the server after the user has executed the command + * will only show up to the user after the user has executed the command
+ * not while they are still typing it in. + * not while they are still entering it.
+ * + *
+ * @param reader string reader + * @param reader string reader input
+ * @return value + * @return parsed value
+ * @throws CommandSyntaxException if an error occurs while parsing + * @throws CommandSyntaxException if an error occurs while parsing
+ */ + */
+ @Override + @Override
@ -764,7 +763,7 @@ index 0000000000000000000000000000000000000000..5d33e1e04b1f279d6ad6371d0cfd9f12
+ +
+ /** + /**
+ * Gets the native type that this argument uses, + * Gets the native type that this argument uses,
+ * or the type that is sent to the client. + * the type that is sent to the client.
+ * + *
+ * @return native argument type + * @return native argument type
+ */ + */
@ -798,15 +797,14 @@ index 0000000000000000000000000000000000000000..5d33e1e04b1f279d6ad6371d0cfd9f12
+ +
+ /** + /**
+ * An argument type that wraps around a native-to-vanilla argument type. + * An argument type that wraps around a native-to-vanilla argument type.
+ * This argument is special in that the underlying native argument type + * This argument receives special handling in that the native argument type will
+ * will be sent to the client. + * be sent to the client for possible client-side completions and syntax validation.
+ * <p> + * <p>
+ * The parsed native type will be converted via the implementation of + * The parsed native type will be converted via {@link #convert(Object)}.
+ * {@link #convert(Object)}. Use {@link CustomArgumentType} if you want + * Implement {@link CustomArgumentType} if you want to handle parsing the type manually.
+ * to handle parsing the type yourself.
+ * + *
+ * @param <T> custom type + * @param <T> custom type
+ * @param <N> native type (has an argument native to vanilla Minecraft). + * @param <N> type with an argument native to vanilla Minecraft (from {@link ArgumentTypes})
+ */ + */
+ @ApiStatus.Experimental + @ApiStatus.Experimental
+ interface Converted<T, N> extends CustomArgumentType<T, N> { + interface Converted<T, N> extends CustomArgumentType<T, N> {
@ -818,7 +816,7 @@ index 0000000000000000000000000000000000000000..5d33e1e04b1f279d6ad6371d0cfd9f12
+ } + }
+ +
+ /** + /**
+ * Converts the value from the native type to this argument type. + * Converts the value from the native type to the custom argument type.
+ * + *
+ * @param nativeType native argument provided value + * @param nativeType native argument provided value
+ * @return converted value + * @return converted value

View File

@ -94,10 +94,10 @@ index dd6012b6a097575b2d1471be5069eccee4537c0a..00000000000000000000000000000000
-} -}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java b/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java b/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f3899f33a index 0000000000000000000000000000000000000000..fdca7b774e3465bd8625cb4129ddaedfa75ab28c
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java +++ b/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java
@@ -0,0 +1,251 @@ @@ -0,0 +1,256 @@
+package io.papermc.paper.command.brigadier; +package io.papermc.paper.command.brigadier;
+ +
+import com.google.common.collect.Collections2; +import com.google.common.collect.Collections2;
@ -169,44 +169,49 @@ index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f
+ * This logic is responsible for unwrapping an API node to be supported by NMS. + * This logic is responsible for unwrapping an API node to be supported by NMS.
+ * See the method implementation for detailed steps. + * See the method implementation for detailed steps.
+ * + *
+ * @param wrapped api provided node / node to be "wrapped" + * @param maybeWrappedNode api provided node / node to be "wrapped"
+ * @return wrapped node + * @return wrapped node
+ */ + */
+ @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({"rawtypes", "unchecked"})
+ private @NotNull CommandNode<CommandSourceStack> unwrapNode(CommandNode<CommandSourceStack> wrapped) { + private @NotNull CommandNode<CommandSourceStack> unwrapNode(final CommandNode<CommandSourceStack> maybeWrappedNode) {
+ /* + /*
+ If the type is a shadow node we can assume that the type that it represents is an already supported NMS node. + If the type is a shadow node we can assume that the type that it represents is an already supported NMS node.
+ This is because these are typically minecraft command nodes. + This is because these are typically minecraft command nodes.
+ */ + */
+ if (wrapped instanceof ShadowBrigNode shadowBrigNode) { + if (maybeWrappedNode instanceof final ShadowBrigNode shadowBrigNode) {
+ return (CommandNode) shadowBrigNode.getHandle(); + return (CommandNode) shadowBrigNode.getHandle();
+ } + }
+ +
+ /* + /*
+ This node already has had an unwrapped node created, so we can assume that it's safe to reuse that cached copy. + This node already has had an unwrapped node created, so we can assume that it's safe to reuse that cached copy.
+ */ + */
+ if (wrapped.unwrappedCached != null) { + if (maybeWrappedNode.unwrappedCached != null) {
+ return wrapped.unwrappedCached; + return maybeWrappedNode.unwrappedCached;
+ } + }
+ +
+ // convert the pure brig node into one compatible with the nms dispatcher
+ return this.convertFromPureBrigNode(maybeWrappedNode);
+ }
+
+ private @NotNull CommandNode<CommandSourceStack> convertFromPureBrigNode(final CommandNode<CommandSourceStack> pureNode) {
+ /* + /*
+ Logic for wrapping each node. + Logic for converting a node.
+ */ + */
+ CommandNode<CommandSourceStack> unwrapped; + final CommandNode<CommandSourceStack> converted;
+ if (wrapped instanceof LiteralCommandNode<CommandSourceStack> node) { + if (pureNode instanceof final LiteralCommandNode<CommandSourceStack> node) {
+ /* + /*
+ Remap the literal node, we only have to account + Remap the literal node, we only have to account
+ for the redirect in this case. + for the redirect in this case.
+ */ + */
+ unwrapped = this.simpleUnwrap(node); + converted = this.simpleUnwrap(node);
+ } else if (wrapped instanceof ArgumentCommandNode original) { + } else if (pureNode instanceof final ArgumentCommandNode<CommandSourceStack, ?> pureArgumentNode) {
+ ArgumentType<?> unwrappedArgType = original.getType(); + final ArgumentType<?> pureArgumentType = pureArgumentNode.getType();
+ /* + /*
+ Check to see if this argument type is a wrapped type, if so we know that + Check to see if this argument type is a wrapped type, if so we know that
+ we can unwrap the node to get an NMS type. + we can unwrap the node to get an NMS type.
+ */ + */
+ if (unwrappedArgType instanceof CustomArgumentType<?, ?> customArgumentType) { + if (pureArgumentType instanceof final CustomArgumentType<?, ?> customArgumentType) {
+ final SuggestionProvider suggestionProvider; + final SuggestionProvider<?> suggestionProvider;
+ try { + try {
+ final Method listSuggestions = customArgumentType.getClass().getMethod("listSuggestions", CommandContext.class, SuggestionsBuilder.class); + final Method listSuggestions = customArgumentType.getClass().getMethod("listSuggestions", CommandContext.class, SuggestionsBuilder.class);
+ if (listSuggestions.getDeclaringClass() != CustomArgumentType.class) { + if (listSuggestions.getDeclaringClass() != CustomArgumentType.class) {
@ -218,22 +223,22 @@ index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f
+ throw new IllegalStateException("Could not determine if the custom argument type " + customArgumentType + " overrides listSuggestions", ex); + throw new IllegalStateException("Could not determine if the custom argument type " + customArgumentType + " overrides listSuggestions", ex);
+ } + }
+ +
+ unwrapped = this.unwrapArgumentWrapper(original, customArgumentType, customArgumentType.getNativeType(), suggestionProvider); + converted = this.unwrapArgumentWrapper(pureArgumentNode, customArgumentType, customArgumentType.getNativeType(), suggestionProvider);
+ } else if (unwrappedArgType instanceof VanillaArgumentProviderImpl.NativeWrapperArgumentType<?,?> nativeWrapperArgumentType) { + } else if (pureArgumentType instanceof final VanillaArgumentProviderImpl.NativeWrapperArgumentType<?,?> nativeWrapperArgumentType) {
+ unwrapped = this.unwrapArgumentWrapper(original, nativeWrapperArgumentType, nativeWrapperArgumentType, null); // "null" for suggestion provider so it uses the argument type's suggestion provider + converted = this.unwrapArgumentWrapper(pureArgumentNode, nativeWrapperArgumentType, nativeWrapperArgumentType, null); // "null" for suggestion provider so it uses the argument type's suggestion provider
+ +
+ /* + /*
+ If it's not a wrapped type, it either has to be a primitive or an already + If it's not a wrapped type, it either has to be a primitive or an already
+ defined NMS type. + defined NMS type.
+ This method allows us to check if this is recognized by vanilla. + This method allows us to check if this is recognized by vanilla.
+ */ + */
+ } else if (ArgumentTypeInfos.isClassRecognized(unwrappedArgType.getClass())) { + } else if (ArgumentTypeInfos.isClassRecognized(pureArgumentType.getClass())) {
+ if (ARGUMENT_WHITELIST.contains(unwrappedArgType.getClass())) { + if (ARGUMENT_WHITELIST.contains(pureArgumentType.getClass())) {
+ // If this argument is whitelisted simply unwrap it and ignore the argument type. + // If this argument is whitelisted simply unwrap it and ignore the argument type.
+ unwrapped = this.simpleUnwrap(original); + converted = this.simpleUnwrap(pureArgumentNode);
+ } else { + } else {
+ // If this was an NMS type but not a primitive + // If this was an NMS type but not a primitive
+ throw new IllegalArgumentException("NMS argument type was passed (%s), should be wrapped inside an CustomArgumentType. Don't add NMS args here!".formatted(unwrappedArgType)); + throw new IllegalArgumentException("NMS argument type was passed (%s), should be wrapped inside an CustomArgumentType. Don't add NMS args here!".formatted(pureArgumentType));
+ } + }
+ } else { + } else {
+ // Unknown argument type was passed + // Unknown argument type was passed
@ -246,14 +251,14 @@ index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f
+ /* + /*
+ Add the children to the node, unwrapping each child in the process. + Add the children to the node, unwrapping each child in the process.
+ */ + */
+ for (CommandNode<CommandSourceStack> child : wrapped.getChildren()) { + for (final CommandNode<CommandSourceStack> child : pureNode.getChildren()) {
+ unwrapped.addChild(this.unwrapNode(child)); + converted.addChild(this.unwrapNode(child));
+ } + }
+ +
+ unwrapped.wrappedCached = wrapped; + converted.wrappedCached = pureNode;
+ wrapped.unwrappedCached = unwrapped; + pureNode.unwrappedCached = converted;
+ +
+ return unwrapped; + return converted;
+ } + }
+ +
+ /** + /**
@ -268,7 +273,7 @@ index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f
+ * @param unwrapped argument node + * @param unwrapped argument node
+ * @return wrapped node + * @return wrapped node
+ */ + */
+ private @Nullable CommandNode<CommandSourceStack> wrapNode(@Nullable CommandNode<net.minecraft.commands.CommandSourceStack> unwrapped) { + private @Nullable CommandNode<CommandSourceStack> wrapNode(@Nullable final CommandNode<net.minecraft.commands.CommandSourceStack> unwrapped) {
+ if (unwrapped == null) { + if (unwrapped == null) {
+ return null; + return null;
+ } + }
@ -332,17 +337,17 @@ index 0000000000000000000000000000000000000000..7c7a281ec145c9ffdc8a16739579435f
+ } + }
+ +
+ @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({"rawtypes", "unchecked"})
+ private CommandNode<CommandSourceStack> unwrapArgumentWrapper(final ArgumentCommandNode node, final ArgumentType wrappedArgumentType, final ArgumentType possiblyWrappedNativeArgumentType, @Nullable SuggestionProvider argumentTypeSuggestionProvider) { + private CommandNode<CommandSourceStack> unwrapArgumentWrapper(final ArgumentCommandNode pureNode, final ArgumentType pureArgumentType, final ArgumentType possiblyWrappedNativeArgumentType, @Nullable SuggestionProvider argumentTypeSuggestionProvider) {
+ validatePrimitiveType(possiblyWrappedNativeArgumentType); + validatePrimitiveType(possiblyWrappedNativeArgumentType);
+ final CommandNode redirectNode = node.getRedirect() == null ? null : this.unwrapNode(node.getRedirect()); + final CommandNode redirectNode = pureNode.getRedirect() == null ? null : this.unwrapNode(pureNode.getRedirect());
+ // If there is already a custom suggestion provider, ignore the suggestion provider from the argument type + // If there is already a custom suggestion provider, ignore the suggestion provider from the argument type
+ final SuggestionProvider suggestionProvider = node.getCustomSuggestions() != null ? node.getCustomSuggestions() : argumentTypeSuggestionProvider; + final SuggestionProvider suggestionProvider = pureNode.getCustomSuggestions() != null ? pureNode.getCustomSuggestions() : argumentTypeSuggestionProvider;
+ +
+ ArgumentType nativeArgumentType = possiblyWrappedNativeArgumentType instanceof VanillaArgumentProviderImpl.NativeWrapperArgumentType<?,?> nativeWrapperArgumentType ? nativeWrapperArgumentType.nativeNmsArgumentType() : possiblyWrappedNativeArgumentType; + final ArgumentType nativeArgumentType = possiblyWrappedNativeArgumentType instanceof final VanillaArgumentProviderImpl.NativeWrapperArgumentType<?,?> nativeWrapperArgumentType ? nativeWrapperArgumentType.nativeNmsArgumentType() : possiblyWrappedNativeArgumentType;
+ return new WrappedArgumentCommandNode<>(node.getName(), wrappedArgumentType, nativeArgumentType, node.getCommand(), node.getRequirement(), redirectNode, node.getRedirectModifier(), node.isFork(), suggestionProvider); + return new WrappedArgumentCommandNode<>(pureNode.getName(), pureArgumentType, nativeArgumentType, pureNode.getCommand(), pureNode.getRequirement(), redirectNode, pureNode.getRedirectModifier(), pureNode.isFork(), suggestionProvider);
+ } + }
+ +
+ private CommandNode<CommandSourceStack> simpleUnwrap(CommandNode<CommandSourceStack> node) { + private CommandNode<CommandSourceStack> simpleUnwrap(final CommandNode<CommandSourceStack> node) {
+ return node.createBuilder() + return node.createBuilder()
+ .redirect(node.getRedirect() == null ? null : this.unwrapNode(node.getRedirect())) + .redirect(node.getRedirect() == null ? null : this.unwrapNode(node.getRedirect()))
+ .build(); + .build();
@ -377,7 +382,7 @@ index 0000000000000000000000000000000000000000..0b33c6cf2366568641e6f2fd7f74fb74
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java b/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java b/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..82a57ffc048454fbc4c705adbac83d16c44c5054 index 0000000000000000000000000000000000000000..44715db12d6be06a7655f1bbb5ebb35ea904eb3b
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java +++ b/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java
@@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
@ -398,7 +403,7 @@ index 0000000000000000000000000000000000000000..82a57ffc048454fbc4c705adbac83d16
+ +
+import java.util.Map; +import java.util.Map;
+ +
+public class PaperBrigadier { +public final class PaperBrigadier {
+ +
+ @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"unchecked", "rawtypes"})
+ public static Command wrapNode(CommandNode node) { + public static Command wrapNode(CommandNode node) {
@ -1187,10 +1192,10 @@ index 0000000000000000000000000000000000000000..5f4af57f2054aa278fcc34697fefa0ed
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..7a838bab16b33025b9a2eae8325f353ad9689e1b index 0000000000000000000000000000000000000000..c59bbd90fdf04db837366218b312e7fb80366707
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java +++ b/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java
@@ -0,0 +1,45 @@ @@ -0,0 +1,55 @@
+package io.papermc.paper.command.brigadier.argument; +package io.papermc.paper.command.brigadier.argument;
+ +
+import com.mojang.brigadier.Command; +import com.mojang.brigadier.Command;
@ -1213,23 +1218,33 @@ index 0000000000000000000000000000000000000000..7a838bab16b33025b9a2eae8325f353a
+ */ + */
+public class WrappedArgumentCommandNode<NMS, API> extends ArgumentCommandNode<CommandSourceStack, NMS> { +public class WrappedArgumentCommandNode<NMS, API> extends ArgumentCommandNode<CommandSourceStack, NMS> {
+ +
+ private final ArgumentType<API> argument; + private final ArgumentType<API> pureArgumentType;
+ +
+ public WrappedArgumentCommandNode(String name, ArgumentType<API> argument, ArgumentType<NMS> nms, Command<CommandSourceStack> command, Predicate<CommandSourceStack> requirement, CommandNode<CommandSourceStack> redirect, RedirectModifier<CommandSourceStack> modifier, boolean forks, SuggestionProvider<CommandSourceStack> customSuggestions) { + public WrappedArgumentCommandNode(
+ super(name, nms, command, requirement, redirect, modifier, forks, customSuggestions); + final String name,
+ if (!ArgumentTypeInfos.isClassRecognized(nms.getClass())) { + final ArgumentType<API> pureArgumentType,
+ final ArgumentType<NMS> nmsNativeType,
+ final Command<CommandSourceStack> command,
+ final Predicate<CommandSourceStack> requirement,
+ final CommandNode<CommandSourceStack> redirect,
+ final RedirectModifier<CommandSourceStack> modifier,
+ final boolean forks,
+ final SuggestionProvider<CommandSourceStack> customSuggestions
+ ) {
+ super(name, nmsNativeType, command, requirement, redirect, modifier, forks, customSuggestions);
+ if (!ArgumentTypeInfos.isClassRecognized(nmsNativeType.getClass())) {
+ // Is this argument an NMS argument? + // Is this argument an NMS argument?
+ throw new IllegalArgumentException("Unexpected argument type was passed. This should be an NMS type!"); + throw new IllegalArgumentException("Unexpected argument type was passed: " + nmsNativeType.getClass() + ". This should be an NMS type!");
+ } + }
+ +
+ this.argument = argument; + this.pureArgumentType = pureArgumentType;
+ } + }
+ +
+ // See ArgumentCommandNode#parse + // See ArgumentCommandNode#parse
+ @Override + @Override
+ public void parse(StringReader reader, CommandContextBuilder<CommandSourceStack> contextBuilder) throws CommandSyntaxException { + public void parse(final StringReader reader, final CommandContextBuilder<CommandSourceStack> contextBuilder) throws CommandSyntaxException {
+ final int start = reader.getCursor(); + final int start = reader.getCursor();
+ API result = this.argument.parse(reader); // Use the api argument parser + final API result = this.pureArgumentType.parse(reader); // Use the api argument parser
+ final ParsedArgument<CommandSourceStack, API> parsed = new ParsedArgument<>(start, reader.getCursor(), result); // Return an API parsed argument instead. + final ParsedArgument<CommandSourceStack, API> parsed = new ParsedArgument<>(start, reader.getCursor(), result); // Return an API parsed argument instead.
+ +
+ contextBuilder.withArgument(this.getName(), parsed); + contextBuilder.withArgument(this.getName(), parsed);
@ -1238,7 +1253,7 @@ index 0000000000000000000000000000000000000000..7a838bab16b33025b9a2eae8325f353a
+} +}
diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..685b3da3f294d8c6ab0fe74d1485a81b03f3215a index 0000000000000000000000000000000000000000..f0cc27640bb3db275295a298d608c9d9f88df617
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java +++ b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java
@@ -0,0 +1,332 @@ @@ -0,0 +1,332 @@
@ -1305,8 +1320,8 @@ index 0000000000000000000000000000000000000000..685b3da3f294d8c6ab0fe74d1485a81b
+ } + }
+ +
+ @Override + @Override
+ public boolean containsValue(Object value) { + public boolean containsValue(@Nullable final Object value) {
+ if (value == null) { + if (!(value instanceof Command)) {
+ return false; + return false;
+ } + }
+ +