Add command aliases

This commit is contained in:
Alexander Söderberg 2020-09-13 19:02:46 +02:00
parent f70227ad7f
commit 2cb367903f
No known key found for this signature in database
GPG key ID: C0207FF7EA146678
5 changed files with 68 additions and 9 deletions

View file

@ -126,14 +126,16 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
* *
* @param commandName Base command component * @param commandName Base command component
* @param commandMeta Command meta instance * @param commandMeta Command meta instance
* @param aliases Command aliases
* @param <C> Command sender type * @param <C> Command sender type
* @param <M> Command meta type * @param <M> Command meta type
* @return Command builder * @return Command builder
*/ */
@Nonnull @Nonnull
public static <C extends CommandSender, M extends CommandMeta> Builder<C, M> newBuilder(@Nonnull final String commandName, public static <C extends CommandSender, M extends CommandMeta> Builder<C, M> newBuilder(@Nonnull final String commandName,
@Nonnull final M commandMeta) { @Nonnull final M commandMeta,
return new Builder<>(commandMeta, null, Collections.singletonList(StaticComponent.required(commandName)), @Nonnull final String... aliases) {
return new Builder<>(commandMeta, null, Collections.singletonList(StaticComponent.required(commandName, aliases)),
new CommandExecutionHandler.NullCommandExecutionHandler<>(), ""); new CommandExecutionHandler.NullCommandExecutionHandler<>(), "");
} }

View file

@ -35,9 +35,9 @@ import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
import com.intellectualsites.commands.execution.CommandResult; import com.intellectualsites.commands.execution.CommandResult;
import com.intellectualsites.commands.execution.CommandSuggestionProcessor; import com.intellectualsites.commands.execution.CommandSuggestionProcessor;
import com.intellectualsites.commands.execution.FilteringCommandSuggestionProcessor; import com.intellectualsites.commands.execution.FilteringCommandSuggestionProcessor;
import com.intellectualsites.commands.execution.preprocessor.AcceptingCommandPreprocessor;
import com.intellectualsites.commands.execution.preprocessor.CommandPreprocessingContext; import com.intellectualsites.commands.execution.preprocessor.CommandPreprocessingContext;
import com.intellectualsites.commands.execution.preprocessor.CommandPreprocessor; import com.intellectualsites.commands.execution.preprocessor.CommandPreprocessor;
import com.intellectualsites.commands.execution.preprocessor.AcceptingCommandPreprocessor;
import com.intellectualsites.commands.internal.CommandRegistrationHandler; import com.intellectualsites.commands.internal.CommandRegistrationHandler;
import com.intellectualsites.commands.meta.CommandMeta; import com.intellectualsites.commands.meta.CommandMeta;
import com.intellectualsites.commands.sender.CommandSender; import com.intellectualsites.commands.sender.CommandSender;
@ -48,6 +48,7 @@ import javax.annotation.Nonnull;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Function; import java.util.function.Function;
@ -186,12 +187,28 @@ public abstract class CommandManager<C extends CommandSender, M extends CommandM
/** /**
* Create a new command builder * Create a new command builder
* *
* @param name Command name * @param name Command name
* @param meta Command meta * @param aliases Command aliases
* @param meta Command meta
* @return Builder instance * @return Builder instance
*/ */
@Nonnull @Nonnull
public Command.Builder<C, M> commandBuilder(@Nonnull final String name, @Nonnull final M meta) { public Command.Builder<C, M> commandBuilder(@Nonnull final String name,
@Nonnull final Set<String> aliases,
@Nonnull final M meta) {
return Command.newBuilder(name, meta, aliases.toArray(new String[0]));
}
/**
* Create a new command builder
*
* @param name Command name
* @param meta Command meta
* @return Builder instance
*/
@Nonnull
public Command.Builder<C, M> commandBuilder(@Nonnull final String name,
@Nonnull final M meta) {
return Command.newBuilder(name, meta); return Command.newBuilder(name, meta);
} }
@ -208,7 +225,6 @@ public abstract class CommandManager<C extends CommandSender, M extends CommandM
return Command.newBuilder(name, this.createDefaultCommandMeta()); return Command.newBuilder(name, this.createDefaultCommandMeta());
} }
/** /**
* Get the internal command tree. This should not be accessed unless you know what you * Get the internal command tree. This should not be accessed unless you know what you
* are doing * are doing

View file

@ -336,6 +336,7 @@ public final class CommandTree<C extends CommandSender, M extends CommandMeta> {
* *
* @param command Command to insert * @param command Command to insert
*/ */
@SuppressWarnings("unchecked")
public void insertCommand(@Nonnull final Command<C, M> command) { public void insertCommand(@Nonnull final Command<C, M> command) {
synchronized (this.commandLock) { synchronized (this.commandLock) {
Node<CommandComponent<C, ?>> node = this.internalTree; Node<CommandComponent<C, ?>> node = this.internalTree;
@ -343,6 +344,10 @@ public final class CommandTree<C extends CommandSender, M extends CommandMeta> {
Node<CommandComponent<C, ?>> tempNode = node.getChild(component); Node<CommandComponent<C, ?>> tempNode = node.getChild(component);
if (tempNode == null) { if (tempNode == null) {
tempNode = node.addChild(component); tempNode = node.addChild(component);
} else if (component instanceof StaticComponent && tempNode.getValue() != null) {
for (final String alias : ((StaticComponent<C>) component).getAliases()) {
((StaticComponent<C>) tempNode.getValue()).registerAlias(alias);
}
} }
if (node.children.size() > 0) { if (node.children.size() > 0) {
node.children.sort(Comparator.comparing(Node::getValue)); node.children.sort(Comparator.comparing(Node::getValue));

View file

@ -75,6 +75,25 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
return new StaticComponent<>(false, name, aliases); return new StaticComponent<>(false, name, aliases);
} }
/**
* Register a new alias
*
* @param alias New alias
*/
public void registerAlias(@Nonnull final String alias) {
((StaticComponentParser<C>) this.getParser()).acceptedStrings.add(alias);
}
/**
* Get an immutable view of the aliases
*
* @return Immutable view of the component aliases
*/
@Nonnull
public Set<String> getAliases() {
return Collections.unmodifiableSet(((StaticComponentParser<C>) this.getParser()).getAcceptedStrings());
}
private static final class StaticComponentParser<C extends CommandSender> implements ComponentParser<C, String> { private static final class StaticComponentParser<C extends CommandSender> implements ComponentParser<C, String> {
@ -111,6 +130,15 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
return Collections.singletonList(this.name); return Collections.singletonList(this.name);
} }
/**
* Get the accepted strings
*
* @return Accepted strings
*/
@Nonnull
public Set<String> getAcceptedStrings() {
return this.acceptedStrings;
}
} }
} }

View file

@ -50,8 +50,9 @@ class CommandTreeTest {
.withComponent(StaticComponent.required("one")).build()) .withComponent(StaticComponent.required("one")).build())
.registerCommand(commandManager.commandBuilder("test", SimpleCommandMeta.empty()) .registerCommand(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
.withComponent(StaticComponent.required("two")).withPermission("no").build()) .withComponent(StaticComponent.required("two")).withPermission("no").build())
.registerCommand(commandManager.commandBuilder("test", SimpleCommandMeta.empty()) .registerCommand(commandManager.commandBuilder("test", Collections.singleton("other"),
.withComponent(StaticComponent.required("opt")) SimpleCommandMeta.empty())
.withComponent(StaticComponent.required("opt", "öpt"))
.withComponent(IntegerComponent .withComponent(IntegerComponent
.optional("num", EXPECTED_INPUT_NUMBER)) .optional("num", EXPECTED_INPUT_NUMBER))
.build()); .build());
@ -79,6 +80,13 @@ class CommandTreeTest {
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()))); .ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
} }
@Test
void testAlias() {
commandManager.getCommandTree()
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("other", "öpt", "12")))
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
}
@Test @Test
void getSuggestions() { void getSuggestions() {
Assertions.assertFalse( Assertions.assertFalse(