Prevent command arguments from being used in multiple commands

Also get rid of some random annoying warnings.
This commit is contained in:
Alexander Söderberg 2020-10-05 16:17:18 +02:00
parent b564ecf60d
commit a4544a8550
No known key found for this signature in database
GPG key ID: FACEA5B0F4C1BF80
5 changed files with 44 additions and 2 deletions

View file

@ -384,6 +384,11 @@ public class Command<C> {
*/
public <T> @NonNull Builder<C> argument(final @NonNull CommandArgument<C, T> argument,
final @NonNull Description description) {
if (argument.isArgumentRegistered()) {
throw new IllegalArgumentException("The provided argument has already been associated with a command."
+ " Use CommandArgument#copy to create a copy of the argument.");
}
argument.setArgumentRegistered();
final Map<CommandArgument<C, ?>, Description> commandArgumentMap = new LinkedHashMap<>(this.commandArguments);
commandArgumentMap.put(argument, description);
return new Builder<>(this.commandManager,

View file

@ -82,6 +82,10 @@ public class CommandArgument<C, T> implements Comparable<CommandArgument<?, ?>>
* Suggestion provider
*/
private final BiFunction<CommandContext<C>, String, List<String>> suggestionsProvider;
/**
* Whether or not the argument has been used before
*/
private boolean argumentRegistered = false;
private Command<C> owningCommand;
@ -328,6 +332,22 @@ public class CommandArgument<C, T> implements Comparable<CommandArgument<?, ?>>
return builder.build();
}
/**
* Check whether or not the argument has been used in a command
*
* @return {@code true} if the argument has been used in a command, else {@code false}
*/
public boolean isArgumentRegistered() {
return this.argumentRegistered;
}
/**
* Indicate that the argument has been associated with a command
*/
public void setArgumentRegistered() {
this.argumentRegistered = true;
}
/**
* Mutable builder for {@link CommandArgument} instances

View file

@ -23,6 +23,7 @@
//
package cloud.commandframework;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.compound.ArgumentPair;
import cloud.commandframework.arguments.standard.IntegerArgument;
import cloud.commandframework.arguments.standard.StringArgument;
@ -213,6 +214,15 @@ class CommandTreeTest {
manager.executeCommand(new TestCommandSender(), "flags --num 500");
}
@Test
void testDuplicateArgument() {
final CommandArgument<TestCommandSender, String> argument = StringArgument.of("test");
manager.command(manager.commandBuilder("one").argument(argument));
Assertions.assertThrows(IllegalArgumentException.class, () ->
manager.command(manager.commandBuilder("two").argument(argument)));
}
public static final class SpecificCommandSender extends TestCommandSender {
}

View file

@ -85,7 +85,7 @@ public final class CloudBrigadierManager<C, S> {
private final Map<Class<?>, cloud.commandframework.types.tuples.Pair<Function<? extends ArgumentParser<C, ?>,
? extends ArgumentType<?>>, Boolean>> mappers;
private final Map<Class<?>, Supplier<ArgumentType<?>>> defaultArgumentTypeSuppliers;
private final Map<@NonNull Class<?>, @NonNull Supplier<@Nullable ArgumentType<?>>> defaultArgumentTypeSuppliers;
private final Supplier<CommandContext<C>> dummyContextProvider;
private final CommandManager<C> commandManager;
@ -214,7 +214,7 @@ public final class CloudBrigadierManager<C, S> {
* @param supplier Supplier that supplies the argument type
*/
public void registerDefaultArgumentTypeSupplier(final @NonNull Class<?> clazz,
final @NonNull Supplier<@NonNull ArgumentType<?>> supplier) {
final @NonNull Supplier<@Nullable ArgumentType<?>> supplier) {
this.defaultArgumentTypeSuppliers.put(clazz, supplier);
}
@ -238,7 +238,13 @@ public final class CloudBrigadierManager<C, S> {
final @NonNull ArgumentParser<C, T> argument) {
final Supplier<ArgumentType<?>> argumentTypeSupplier = this.defaultArgumentTypeSuppliers
.get(GenericTypeReflector.erase(clazz.getType()));
@Nullable final ArgumentType<?> defaultType;
if (argumentTypeSupplier != null) {
defaultType = argumentTypeSupplier.get();
} else {
defaultType = null;
}
if (defaultType != null) {
return new Pair<>(argumentTypeSupplier.get(), true);
}
return new Pair<>(StringArgumentType.string(), false);

View file

@ -169,6 +169,7 @@ class PaperBrigadierListener<C> implements Listener {
}
@EventHandler
@SuppressWarnings("deprecation")
public void onCommandRegister(@Nonnull final CommandRegisteredEvent<BukkitBrigadierCommandSource> event) {
if (!(event.getCommand() instanceof PluginIdentifiableCommand)) {
return;