core: Use the ArgumentDescription interface for descriptions

This allows minecraft-extras to provide an implementation that
uses Adventure chat components to represent the description.
This commit is contained in:
Zach Levis 2021-01-11 23:08:24 -08:00 committed by Alexander Söderberg
parent fa16fc8ef2
commit b38c725dc5
19 changed files with 903 additions and 94 deletions

View file

@ -23,9 +23,9 @@
// //
package cloud.commandframework.annotations; package cloud.commandframework.annotations;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command; import cloud.commandframework.Command;
import cloud.commandframework.CommandManager; import cloud.commandframework.CommandManager;
import cloud.commandframework.Description;
import cloud.commandframework.annotations.injection.ParameterInjectorRegistry; import cloud.commandframework.annotations.injection.ParameterInjectorRegistry;
import cloud.commandframework.annotations.injection.RawArgs; import cloud.commandframework.annotations.injection.RawArgs;
import cloud.commandframework.annotations.parsers.MethodArgumentParser; import cloud.commandframework.annotations.parsers.MethodArgumentParser;
@ -434,7 +434,7 @@ public final class AnnotationParser<C> {
} }
final String description = argumentDescriptions.getOrDefault(argument, ""); final String description = argumentDescriptions.getOrDefault(argument, "");
builder = builder.argument(argument, Description.of(description)); builder = builder.argument(argument, ArgumentDescription.of(description));
} }
} }
/* Try to find the command sender type */ /* Try to find the command sender type */

View file

@ -23,8 +23,8 @@
// //
package cloud.commandframework.annotations; package cloud.commandframework.annotations;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.CommandManager; import cloud.commandframework.CommandManager;
import cloud.commandframework.Description;
import cloud.commandframework.arguments.CommandArgument; import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.flags.CommandFlag; import cloud.commandframework.arguments.flags.CommandFlag;
import cloud.commandframework.arguments.parser.ArgumentParser; import cloud.commandframework.arguments.parser.ArgumentParser;
@ -60,7 +60,7 @@ final class FlagExtractor implements Function<@NonNull Method, Collection<@NonNu
final Flag flag = parameter.getAnnotation(Flag.class); final Flag flag = parameter.getAnnotation(Flag.class);
final CommandFlag.Builder<Void> builder = this.commandManager final CommandFlag.Builder<Void> builder = this.commandManager
.flagBuilder(flag.value()) .flagBuilder(flag.value())
.withDescription(Description.of(flag.description())) .withDescription(ArgumentDescription.of(flag.description()))
.withAliases(flag.aliases()); .withAliases(flag.aliases());
if (parameter.getType().equals(boolean.class)) { if (parameter.getType().equals(boolean.class)) {
flags.add(builder.build()); flags.add(builder.build());

View file

@ -0,0 +1,80 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg & Contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package cloud.commandframework;
import cloud.commandframework.arguments.CommandArgument;
import org.checkerframework.checker.nullness.qual.NonNull;
import static java.util.Objects.requireNonNull;
/**
* A description for a {@link CommandArgument}
*
* @since 1.4.0
*/
public interface ArgumentDescription {
/**
* Get an empty command description.
*
* @return Command description
*/
@SuppressWarnings("deprecation")
static @NonNull ArgumentDescription empty() {
return Description.EMPTY;
}
/**
* Create a command description instance.
*
* @param string Command description
* @return Created command description
*/
@SuppressWarnings("deprecation")
static @NonNull ArgumentDescription of(final @NonNull String string) {
if (requireNonNull(string, "string").isEmpty()) {
return Description.EMPTY;
} else {
return new Description(string);
}
}
/**
* Get the plain-text description.
*
* @return Command description
*/
@NonNull String getDescription();
/**
* Get whether or not this description contains contents.
*
* @return if this description is empty or not
*/
default boolean isEmpty() {
return this.getDescription().isEmpty();
}
}

View file

@ -209,6 +209,7 @@ public class Command<C> {
// Converts a map of CommandArgument and Description pairs to a List of CommandComponent // Converts a map of CommandArgument and Description pairs to a List of CommandComponent
// Used for backwards-compatibility // Used for backwards-compatibility
@SuppressWarnings("deprecation")
private static <C> @NonNull List<@NonNull CommandComponent<C>> mapToComponents( private static <C> @NonNull List<@NonNull CommandComponent<C>> mapToComponents(
final @NonNull Map<@NonNull CommandArgument<C, ?>, @NonNull Description> commandArguments final @NonNull Map<@NonNull CommandArgument<C, ?>, @NonNull Description> commandArguments
) { ) {
@ -227,12 +228,35 @@ public class Command<C> {
* @param aliases Command aliases * @param aliases Command aliases
* @param <C> Command sender type * @param <C> Command sender type
* @return Command builder * @return Command builder
* @deprecated for removal since 1.4.0. Use {@link #newBuilder(String, CommandMeta, ArgumentDescription, String...)} instead.
*/ */
@Deprecated
public static <C> @NonNull Builder<C> newBuilder( public static <C> @NonNull Builder<C> newBuilder(
final @NonNull String commandName, final @NonNull String commandName,
final @NonNull CommandMeta commandMeta, final @NonNull CommandMeta commandMeta,
final @NonNull Description description, final @NonNull Description description,
final @NonNull String... aliases final @NonNull String... aliases
) {
return newBuilder(commandName, commandMeta, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder. Is recommended to use the builder methods
* in {@link CommandManager} rather than invoking this method directly.
*
* @param commandName Base command argument
* @param commandMeta Command meta instance
* @param description Command description
* @param aliases Command aliases
* @param <C> Command sender type
* @return Command builder
* @since 1.4.0
*/
public static <C> @NonNull Builder<C> newBuilder(
final @NonNull String commandName,
final @NonNull CommandMeta commandMeta,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) { ) {
final List<CommandComponent<C>> commands = new ArrayList<>(); final List<CommandComponent<C>> commands = new ArrayList<>();
commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), description)); commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), description));
@ -263,7 +287,7 @@ public class Command<C> {
final @NonNull String... aliases final @NonNull String... aliases
) { ) {
final List<CommandComponent<C>> commands = new ArrayList<>(); final List<CommandComponent<C>> commands = new ArrayList<>();
commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), Description.empty())); commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), ArgumentDescription.empty()));
return new Builder<>( return new Builder<>(
null, null,
commandMeta, commandMeta,
@ -343,7 +367,7 @@ public class Command<C> {
public @NonNull String getArgumentDescription(final @NonNull CommandArgument<C, ?> argument) { public @NonNull String getArgumentDescription(final @NonNull CommandArgument<C, ?> argument) {
for (final CommandComponent<C> component : this.components) { for (final CommandComponent<C> component : this.components) {
if (component.getArgument().equals(argument)) { if (component.getArgument().equals(argument)) {
return component.getDescription().getDescription(); return component.getArgumentDescription().getDescription();
} }
} }
throw new IllegalArgumentException("Command argument not found: " + argument); throw new IllegalArgumentException("Command argument not found: " + argument);
@ -512,7 +536,9 @@ public class Command<C> {
* @param description Literal description * @param description Literal description
* @param aliases Argument aliases * @param aliases Argument aliases
* @return New builder instance with the modified command chain * @return New builder instance with the modified command chain
* @deprecated for removal since 1.4.0. Use {@link #literal(String, ArgumentDescription, String...)} instead.
*/ */
@Deprecated
public @NonNull Builder<C> literal( public @NonNull Builder<C> literal(
final @NonNull String main, final @NonNull String main,
final @NonNull Description description, final @NonNull Description description,
@ -521,6 +547,23 @@ public class Command<C> {
return this.argument(StaticArgument.of(main, aliases), description); return this.argument(StaticArgument.of(main, aliases), description);
} }
/**
* Inserts a required {@link StaticArgument} into the command chain
*
* @param main Main argument name
* @param description Literal description
* @param aliases Argument aliases
* @return New builder instance with the modified command chain
* @since 1.4.0
*/
public @NonNull Builder<C> literal(
final @NonNull String main,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) {
return this.argument(StaticArgument.of(main, aliases), description);
}
/** /**
* Add a new command argument with an empty description to the command * Add a new command argument with an empty description to the command
* *
@ -530,7 +573,7 @@ public class Command<C> {
* @return New builder instance with the command argument inserted into the argument list * @return New builder instance with the command argument inserted into the argument list
*/ */
public <T> @NonNull Builder<C> argument(final CommandArgument.@NonNull Builder<C, T> builder) { public <T> @NonNull Builder<C> argument(final CommandArgument.@NonNull Builder<C, T> builder) {
return this.argument(builder.build(), Description.empty()); return this.argument(builder.build(), ArgumentDescription.empty());
} }
/** /**
@ -541,7 +584,7 @@ public class Command<C> {
* @return New builder instance with the command argument inserted into the argument list * @return New builder instance with the command argument inserted into the argument list
*/ */
public <T> @NonNull Builder<C> argument(final @NonNull CommandArgument<C, T> argument) { public <T> @NonNull Builder<C> argument(final @NonNull CommandArgument<C, T> argument) {
return this.argument(argument, Description.empty()); return this.argument(argument, ArgumentDescription.empty());
} }
/** /**
@ -551,10 +594,28 @@ public class Command<C> {
* @param description Argument description * @param description Argument description
* @param <T> Argument type * @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list * @return New builder instance with the command argument inserted into the argument list
* @deprecated for removal since 1.4.0. Use {@link #argument(CommandArgument, ArgumentDescription)} instead.
*/ */
@Deprecated
public <T> @NonNull Builder<C> argument( public <T> @NonNull Builder<C> argument(
final @NonNull CommandArgument<C, T> argument, final @NonNull CommandArgument<C, T> argument,
final @NonNull Description description final @NonNull Description description
) {
return this.argument(argument, (ArgumentDescription) description);
}
/**
* Add a new command argument to the command
*
* @param argument Argument to add
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @since 1.4.0
*/
public <T> @NonNull Builder<C> argument(
final @NonNull CommandArgument<C, T> argument,
final @NonNull ArgumentDescription description
) { ) {
if (argument.isArgumentRegistered()) { if (argument.isArgumentRegistered()) {
throw new IllegalArgumentException("The provided argument has already been associated with a command." throw new IllegalArgumentException("The provided argument has already been associated with a command."
@ -582,10 +643,29 @@ public class Command<C> {
* @param description Argument description * @param description Argument description
* @param <T> Argument type * @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list * @return New builder instance with the command argument inserted into the argument list
* @deprecated for removal since 1.4.0. Use {@link #argument(CommandArgument.Builder, ArgumentDescription)} instead.
*/ */
@Deprecated
public <T> @NonNull Builder<C> argument( public <T> @NonNull Builder<C> argument(
final CommandArgument.@NonNull Builder<C, T> builder, final CommandArgument.@NonNull Builder<C, T> builder,
final @NonNull Description description final @NonNull Description description
) {
return this.argument(builder, (ArgumentDescription) description);
}
/**
* Add a new command argument to the command
*
* @param builder Argument to add. {@link CommandArgument.Builder#build()} will be invoked
* and the result will be registered in the command.
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @since 1.4.0
*/
public <T> @NonNull Builder<C> argument(
final CommandArgument.@NonNull Builder<C, T> builder,
final @NonNull ArgumentDescription description
) { ) {
final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents); final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents);
commandComponents.add(CommandComponent.of(builder.build(), description)); commandComponents.add(CommandComponent.of(builder.build(), description));
@ -640,12 +720,41 @@ public class Command<C> {
* @param <U> First type * @param <U> First type
* @param <V> Second type * @param <V> Second type
* @return Builder instance with the argument inserted * @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use {@link #argumentPair(String, Pair, Pair, ArgumentDescription)} instead.
*/ */
@Deprecated
public <U, V> @NonNull Builder<C> argumentPair( public <U, V> @NonNull Builder<C> argumentPair(
final @NonNull String name, final @NonNull String name,
final @NonNull Pair<@NonNull String, @NonNull String> names, final @NonNull Pair<@NonNull String, @NonNull String> names,
final @NonNull Pair<@NonNull Class<U>, @NonNull Class<V>> parserPair, final @NonNull Pair<@NonNull Class<U>, @NonNull Class<V>> parserPair,
final @NonNull Description description final @NonNull Description description
) {
return this.argumentPair(name, names, parserPair, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to {@link Pair}
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param names Pair containing the names of the sub-arguments
* @param parserPair Pair containing the types of the sub-arguments. There must be parsers for these types registered
* in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by the
* {@link CommandManager} attached to this command
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull Pair<@NonNull String, @NonNull String> names,
final @NonNull Pair<@NonNull Class<U>, @NonNull Class<V>> parserPair,
final @NonNull ArgumentDescription description
) { ) {
if (this.commandManager == null) { if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached"); throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -672,7 +781,10 @@ public class Command<C> {
* @param <V> Second type * @param <V> Second type
* @param <O> Output type * @param <O> Output type
* @return Builder instance with the argument inserted * @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use
* {@link #argumentPair(String, TypeToken, Pair, Pair, BiFunction, ArgumentDescription)} instead.
*/ */
@Deprecated
public <U, V, O> @NonNull Builder<C> argumentPair( public <U, V, O> @NonNull Builder<C> argumentPair(
final @NonNull String name, final @NonNull String name,
final @NonNull TypeToken<O> outputType, final @NonNull TypeToken<O> outputType,
@ -680,6 +792,38 @@ public class Command<C> {
final @NonNull Pair<Class<U>, Class<V>> parserPair, final @NonNull Pair<Class<U>, Class<V>> parserPair,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper, final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final @NonNull Description description final @NonNull Description description
) {
return this.argumentPair(name, outputType, names, parserPair, mapper, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to a custom type.
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param outputType The output type
* @param names Pair containing the names of the sub-arguments
* @param parserPair Pair containing the types of the sub-arguments. There must be parsers for these types registered
* in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by the
* {@link CommandManager} attached to this command
* @param mapper Mapper that maps from {@link Pair} to the custom type
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V, O> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
final @NonNull Pair<String, String> names,
final @NonNull Pair<Class<U>, Class<V>> parserPair,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final @NonNull ArgumentDescription description
) { ) {
if (this.commandManager == null) { if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached"); throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -707,12 +851,43 @@ public class Command<C> {
* @param <V> Second type * @param <V> Second type
* @param <W> Third type * @param <W> Third type
* @return Builder instance with the argument inserted * @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use {@link #argumentTriplet(String, Triplet, Triplet, ArgumentDescription)}
* instead.
*/ */
@Deprecated
public <U, V, W> @NonNull Builder<C> argumentTriplet( public <U, V, W> @NonNull Builder<C> argumentTriplet(
final @NonNull String name, final @NonNull String name,
final @NonNull Triplet<String, String, String> names, final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet, final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull Description description final @NonNull Description description
) {
return this.argumentTriplet(name, names, parserTriplet, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to {@link cloud.commandframework.types.tuples.Triplet}
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param names Triplet containing the names of the sub-arguments
* @param parserTriplet Triplet containing the types of the sub-arguments. There must be parsers for these types
* registered in the {@link cloud.commandframework.arguments.parser.ParserRegistry}
* used by the {@link CommandManager} attached to this command
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <W> Third type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V, W> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull ArgumentDescription description
) { ) {
if (this.commandManager == null) { if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached"); throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -740,15 +915,57 @@ public class Command<C> {
* @param <W> Third type * @param <W> Third type
* @param <O> Output type * @param <O> Output type
* @return Builder instance with the argument inserted * @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0, use
* {@link #argumentTriplet(String, TypeToken, Triplet, Triplet, BiFunction, ArgumentDescription)} instead.
*/
@Deprecated
public <U, V, W, O> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final @NonNull Description description
) {
return this.argumentTriplet(
name,
outputType,
names,
parserTriplet,
mapper,
(ArgumentDescription) description
);
}
/**
* Create a new argument triplet that maps to a custom type.
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param outputType The output type
* @param names Triplet containing the names of the sub-arguments
* @param parserTriplet Triplet containing the types of the sub-arguments. There must be parsers for these types
* registered in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by
* the {@link CommandManager} attached to this command
* @param mapper Mapper that maps from {@link Triplet} to the custom type
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <W> Third type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/ */
public <U, V, W, O> @NonNull Builder<C> argumentTriplet( public <U, V, W, O> @NonNull Builder<C> argumentTriplet(
final @NonNull String name, final @NonNull String name,
final @NonNull TypeToken<O> outputType, final @NonNull TypeToken<O> outputType,
final @NonNull Triplet<String, String, String> names, final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
Class<W>> parserTriplet,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper, final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final @NonNull Description description final @NonNull ArgumentDescription description
) { ) {
if (this.commandManager == null) { if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached"); throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -852,7 +1069,7 @@ public class Command<C> {
continue; continue;
} }
final CommandArgument<C, ?> builtArgument = argument.copy(); final CommandArgument<C, ?> builtArgument = argument.copy();
builder = builder.argument(builtArgument, component.getDescription()); builder = builder.argument(builtArgument, component.getArgumentDescription());
} }
if (this.commandPermission.toString().isEmpty()) { if (this.commandPermission.toString().isEmpty()) {
builder = builder.permission(command.getCommandPermission()); builder = builder.permission(command.getCommandPermission());
@ -910,9 +1127,9 @@ public class Command<C> {
public @NonNull Command<C> build() { public @NonNull Command<C> build() {
final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents); final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents);
/* Construct flag node */ /* Construct flag node */
if (!flags.isEmpty()) { if (!this.flags.isEmpty()) {
final FlagArgument<C> flagArgument = new FlagArgument<>(this.flags); final FlagArgument<C> flagArgument = new FlagArgument<>(this.flags);
commandComponents.add(CommandComponent.of(flagArgument, Description.of("Command flags"))); commandComponents.add(CommandComponent.of(flagArgument, ArgumentDescription.of("Command flags")));
} }
return new Command<>( return new Command<>(
Collections.unmodifiableList(commandComponents), Collections.unmodifiableList(commandComponents),

View file

@ -37,7 +37,7 @@ import java.util.Objects;
public final class CommandComponent<C> { public final class CommandComponent<C> {
private final CommandArgument<C, ?> argument; private final CommandArgument<C, ?> argument;
private final Description description; private final ArgumentDescription description;
/** /**
* Initializes a new CommandComponent * Initializes a new CommandComponent
@ -47,7 +47,7 @@ public final class CommandComponent<C> {
*/ */
private CommandComponent( private CommandComponent(
final @NonNull CommandArgument<C, ?> commandArgument, final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull Description commandDescription final @NonNull ArgumentDescription commandDescription
) { ) {
this.argument = commandArgument; this.argument = commandArgument;
this.description = commandDescription; this.description = commandDescription;
@ -66,14 +66,30 @@ public final class CommandComponent<C> {
* Gets the command component description * Gets the command component description
* *
* @return command component description * @return command component description
* @deprecated for removal since 1.4.0. Use {@link #getArgumentDescription()} instead.
*/ */
@Deprecated
public @NonNull Description getDescription() { public @NonNull Description getDescription() {
if (this.description instanceof Description) {
return (Description) this.description;
} else {
return new Description(this.description.getDescription());
}
}
/**
* Gets the command component description
*
* @return command component description
* @since 1.4.0
*/
public @NonNull ArgumentDescription getArgumentDescription() {
return this.description; return this.description;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getArgument(), getDescription()); return Objects.hash(this.getArgument(), this.getArgumentDescription());
} }
@Override @Override
@ -81,9 +97,9 @@ public final class CommandComponent<C> {
if (this == o) { if (this == o) {
return true; return true;
} else if (o instanceof CommandComponent) { } else if (o instanceof CommandComponent) {
CommandComponent<?> that = (CommandComponent<?>) o; final CommandComponent<?> that = (CommandComponent<?>) o;
return getArgument().equals(that.getArgument()) return this.getArgument().equals(that.getArgument())
&& getDescription().equals(that.getDescription()); && this.getArgumentDescription().equals(that.getArgumentDescription());
} else { } else {
return false; return false;
} }
@ -102,11 +118,28 @@ public final class CommandComponent<C> {
* @param commandArgument Command Component Argument * @param commandArgument Command Component Argument
* @param commandDescription Command Component Description * @param commandDescription Command Component Description
* @return new CommandComponent * @return new CommandComponent
* @deprecated for removal since 1.4.0. Use {@link #of(CommandArgument, ArgumentDescription)} instead.
*/ */
@Deprecated
public static <C> @NonNull CommandComponent<C> of( public static <C> @NonNull CommandComponent<C> of(
final @NonNull CommandArgument<C, ?> commandArgument, final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull Description commandDescription final @NonNull Description commandDescription
) { ) {
return new CommandComponent<C>(commandArgument, commandDescription); return new CommandComponent<C>(commandArgument, commandDescription);
} }
/**
* Creates a new CommandComponent with the provided argument and description
*
* @param <C> Command sender type
* @param commandArgument Command Component Argument
* @param commandDescription Command Component Description
* @return new CommandComponent
*/
public static <C> @NonNull CommandComponent<C> of(
final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull ArgumentDescription commandDescription
) {
return new CommandComponent<C>(commandArgument, commandDescription);
}
} }

View file

@ -353,12 +353,40 @@ public abstract class CommandManager<C> {
* @param description Description for the root literal * @param description Description for the root literal
* @param meta Command meta * @param meta Command meta
* @return Builder instance * @return Builder instance
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, Collection, Description, CommandMeta)} instead.
*/ */
@Deprecated
public Command.@NonNull Builder<C> commandBuilder( public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name, final @NonNull String name,
final @NonNull Collection<String> aliases, final @NonNull Collection<String> aliases,
final @NonNull Description description, final @NonNull Description description,
final @NonNull CommandMeta meta final @NonNull CommandMeta meta
) {
return commandBuilder(name, aliases, (ArgumentDescription) description, meta);
}
/**
* Create a new command builder. This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param aliases Command aliases
* @param description Description for the root literal
* @param meta Command meta
* @return Builder instance
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull Collection<String> aliases,
final @NonNull ArgumentDescription description,
final @NonNull CommandMeta meta
) { ) {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
@ -393,7 +421,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
meta, meta,
Description.empty(), ArgumentDescription.empty(),
aliases.toArray(new String[0]) aliases.toArray(new String[0])
).manager(this); ).manager(this);
} }
@ -413,12 +441,41 @@ public abstract class CommandManager<C> {
* @param description Description for the root literal * @param description Description for the root literal
* @param aliases Command aliases * @param aliases Command aliases
* @return Builder instance * @return Builder instance
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, CommandMeta, ArgumentDescription, String...)}
* instead.
*/ */
@Deprecated
public Command.@NonNull Builder<C> commandBuilder( public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name, final @NonNull String name,
final @NonNull CommandMeta meta, final @NonNull CommandMeta meta,
final @NonNull Description description, final @NonNull Description description,
final @NonNull String... aliases final @NonNull String... aliases
) {
return this.commandBuilder(name, meta, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder. This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param meta Command meta
* @param description Description for the root literal
* @param aliases Command aliases
* @return Builder instance
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull CommandMeta meta,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) { ) {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
@ -453,7 +510,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
meta, meta,
Description.empty(), ArgumentDescription.empty(),
aliases aliases
).manager(this); ).manager(this);
} }
@ -476,11 +533,41 @@ public abstract class CommandManager<C> {
* @return Builder instance * @return Builder instance
* @throws UnsupportedOperationException If the command manager does not support default command meta creation * @throws UnsupportedOperationException If the command manager does not support default command meta creation
* @see #createDefaultCommandMeta() Default command meta creation * @see #createDefaultCommandMeta() Default command meta creation
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, ArgumentDescription, String...)} instead.
*/ */
@Deprecated
public Command.@NonNull Builder<C> commandBuilder( public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name, final @NonNull String name,
final @NonNull Description description, final @NonNull Description description,
final @NonNull String... aliases final @NonNull String... aliases
) {
return this.commandBuilder(name, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder using default command meta created by {@link #createDefaultCommandMeta()}.
* <p>
* This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param description Description for the root literal
* @param aliases Command aliases
* @return Builder instance
* @throws UnsupportedOperationException If the command manager does not support default command meta creation
* @see #createDefaultCommandMeta() Default command meta creation
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) { ) {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
@ -516,7 +603,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder( return Command.<C>newBuilder(
name, name,
this.createDefaultCommandMeta(), this.createDefaultCommandMeta(),
Description.empty(), ArgumentDescription.empty(),
aliases aliases
).manager(this); ).manager(this);
} }

View file

@ -28,17 +28,20 @@ import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
* {@link CommandArgument} description * {@link CommandArgument} description
*
* @deprecated to become package-private since 1.4.0. Use {@link ArgumentDescription} instead.
*/ */
public final class Description { @Deprecated
public final class Description implements ArgumentDescription {
/** /**
* Empty command description * Empty command description
*/ */
private static final Description EMPTY = Description.of(""); static final Description EMPTY = new Description("");
private final String description; private final String description;
private Description(final @NonNull String description) { Description(final @NonNull String description) {
this.description = description; this.description = description;
} }
@ -46,7 +49,9 @@ public final class Description {
* Get an empty command description * Get an empty command description
* *
* @return Command description * @return Command description
* @deprecated for removal since 1.4.0. See {@link ArgumentDescription#empty()}
*/ */
@Deprecated
public static @NonNull Description empty() { public static @NonNull Description empty() {
return EMPTY; return EMPTY;
} }
@ -56,7 +61,9 @@ public final class Description {
* *
* @param string Command description * @param string Command description
* @return Created command description * @return Created command description
* @deprecated for removal since 1.4.0. See {@link ArgumentDescription#of(String)}
*/ */
@Deprecated
public static @NonNull Description of(final @NonNull String string) { public static @NonNull Description of(final @NonNull String string) {
return new Description(string); return new Description(string);
} }
@ -66,6 +73,7 @@ public final class Description {
* *
* @return Command description * @return Command description
*/ */
@Override
public @NonNull String getDescription() { public @NonNull String getDescription() {
return this.description; return this.description;
} }

View file

@ -23,7 +23,7 @@
// //
package cloud.commandframework.arguments.flags; package cloud.commandframework.arguments.flags;
import cloud.commandframework.Description; import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.arguments.CommandArgument; import cloud.commandframework.arguments.CommandArgument;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -46,14 +46,14 @@ public final class CommandFlag<T> {
private final @NonNull String name; private final @NonNull String name;
private final @NonNull String @NonNull [] aliases; private final @NonNull String @NonNull [] aliases;
private final @NonNull Description description; private final @NonNull ArgumentDescription description;
private final @Nullable CommandArgument<?, T> commandArgument; private final @Nullable CommandArgument<?, T> commandArgument;
private CommandFlag( private CommandFlag(
final @NonNull String name, final @NonNull String name,
final @NonNull String @NonNull [] aliases, final @NonNull String @NonNull [] aliases,
final @NonNull Description description, final @NonNull ArgumentDescription description,
final @Nullable CommandArgument<?, T> commandArgument final @Nullable CommandArgument<?, T> commandArgument
) { ) {
this.name = Objects.requireNonNull(name, "name cannot be null"); this.name = Objects.requireNonNull(name, "name cannot be null");
@ -95,8 +95,24 @@ public final class CommandFlag<T> {
* <p> * <p>
* *
* @return Flag description * @return Flag description
* @deprecated for removal since 1.4.0. Use {@link #getArgumentDescription()} instead.
*/ */
public @NonNull Description getDescription() { @Deprecated
public cloud.commandframework.@NonNull Description getDescription() {
if (this.description instanceof cloud.commandframework.Description) {
return ((cloud.commandframework.Description) this.description);
} else {
return cloud.commandframework.Description.of(this.description.getDescription());
}
}
/**
* Get the flag description.
*
* @return Flag description
* @since 1.4.0
*/
public @NonNull ArgumentDescription getArgumentDescription() {
return this.description; return this.description;
} }
@ -119,16 +135,16 @@ public final class CommandFlag<T> {
if (this == o) { if (this == o) {
return true; return true;
} }
if (o == null || getClass() != o.getClass()) { if (o == null || this.getClass() != o.getClass()) {
return false; return false;
} }
final CommandFlag<?> that = (CommandFlag<?>) o; final CommandFlag<?> that = (CommandFlag<?>) o;
return getName().equals(that.getName()); return this.getName().equals(that.getName());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getName()); return Objects.hash(this.getName());
} }
@ -136,13 +152,13 @@ public final class CommandFlag<T> {
private final String name; private final String name;
private final String[] aliases; private final String[] aliases;
private final Description description; private final ArgumentDescription description;
private final CommandArgument<?, T> commandArgument; private final CommandArgument<?, T> commandArgument;
private Builder( private Builder(
final @NonNull String name, final @NonNull String name,
final @NonNull String[] aliases, final @NonNull String[] aliases,
final @NonNull Description description, final @NonNull ArgumentDescription description,
final @Nullable CommandArgument<?, T> commandArgument final @Nullable CommandArgument<?, T> commandArgument
) { ) {
this.name = name; this.name = name;
@ -152,7 +168,7 @@ public final class CommandFlag<T> {
} }
private Builder(final @NonNull String name) { private Builder(final @NonNull String name) {
this(name, new String[0], Description.empty(), null); this(name, new String[0], ArgumentDescription.empty(), null);
} }
/** /**
@ -191,8 +207,21 @@ public final class CommandFlag<T> {
* *
* @param description Flag description * @param description Flag description
* @return New builder instance * @return New builder instance
* @deprecated for removal since 1.4.0. Use {@link #withDescription(ArgumentDescription)} instead.
*/ */
public Builder<T> withDescription(final @NonNull Description description) { @Deprecated
public Builder<T> withDescription(final cloud.commandframework.@NonNull Description description) {
return this.withDescription((ArgumentDescription) description);
}
/**d
* Create a new builder instance using the given flag description
*
* @param description Flag description
* @return New builder instance
* @since 1.4.0
*/
public Builder<T> withDescription(final @NonNull ArgumentDescription description) {
return new Builder<>(this.name, this.aliases, description, this.commandArgument); return new Builder<>(this.name, this.aliases, description, this.commandArgument);
} }

View file

@ -52,13 +52,13 @@ class CommandHelpHandlerTest {
manager.command(manager.commandBuilder("test", meta1).literal("this").literal("thing").build()); manager.command(manager.commandBuilder("test", meta1).literal("this").literal("thing").build());
final SimpleCommandMeta meta2 = SimpleCommandMeta.builder().with(CommandMeta.DESCRIPTION, "Command with variables").build(); final SimpleCommandMeta meta2 = SimpleCommandMeta.builder().with(CommandMeta.DESCRIPTION, "Command with variables").build();
manager.command(manager.commandBuilder("test", meta2).literal("int"). manager.command(manager.commandBuilder("test", meta2).literal("int").
argument(IntegerArgument.of("int"), Description.of("A number")).build()); argument(IntegerArgument.of("int"), ArgumentDescription.of("A number")).build());
manager.command(manager.commandBuilder("test").argument(StringArgument.of("potato"))); manager.command(manager.commandBuilder("test").argument(StringArgument.of("potato")));
manager.command(manager.commandBuilder("vec") manager.command(manager.commandBuilder("vec")
.meta(CommandMeta.DESCRIPTION, "Takes in a vector") .meta(CommandMeta.DESCRIPTION, "Takes in a vector")
.argumentPair("vec", Pair.of("x", "y"), .argumentPair("vec", Pair.of("x", "y"),
Pair.of(Double.class, Double.class), Description.of("Vector") Pair.of(Double.class, Double.class), ArgumentDescription.of("Vector")
) )
.build()); .build());
} }
@ -241,7 +241,7 @@ class CommandHelpHandlerTest {
while (iterator.hasNext()) { while (iterator.hasNext()) {
final CommandComponent<TestCommandSender> component = iterator.next(); final CommandComponent<TestCommandSender> component = iterator.next();
String description = component.getDescription().getDescription(); String description = component.getArgumentDescription().getDescription();
if (!description.isEmpty()) { if (!description.isEmpty()) {
description = ": " + description; description = ": " + description;
} }

View file

@ -66,13 +66,13 @@ public class CommandSuggestionsTest {
manager.command(manager.commandBuilder("com") manager.command(manager.commandBuilder("com")
.argumentPair("com", Pair.of("x", "y"), Pair.of(Integer.class, TestEnum.class), .argumentPair("com", Pair.of("x", "y"), Pair.of(Integer.class, TestEnum.class),
Description.empty() ArgumentDescription.empty()
) )
.argument(IntegerArgument.of("int"))); .argument(IntegerArgument.of("int")));
manager.command(manager.commandBuilder("com2") manager.command(manager.commandBuilder("com2")
.argumentPair("com", Pair.of("x", "enum"), .argumentPair("com", Pair.of("x", "enum"),
Pair.of(Integer.class, TestEnum.class), Description.empty() Pair.of(Integer.class, TestEnum.class), ArgumentDescription.empty()
)); ));
manager.command(manager.commandBuilder("flags") manager.command(manager.commandBuilder("flags")

View file

@ -236,9 +236,9 @@ class CommandTreeTest {
// Create and register a command // Create and register a command
Command<TestCommandSender> command = manager.commandBuilder("component") Command<TestCommandSender> command = manager.commandBuilder("component")
.literal("literal", "literalalias") .literal("literal", "literalalias")
.literal("detail", Description.of("detaildescription")) .literal("detail", ArgumentDescription.of("detaildescription"))
.argument(CommandArgument.ofType(int.class, "argument"), .argument(CommandArgument.ofType(int.class, "argument"),
Description.of("argumentdescription")) ArgumentDescription.of("argumentdescription"))
.build(); .build();
manager.command(command); manager.command(command);
@ -264,10 +264,10 @@ class CommandTreeTest {
Assertions.assertEquals(TypeToken.get(int.class), arguments.get(3).getValueType()); Assertions.assertEquals(TypeToken.get(int.class), arguments.get(3).getValueType());
// Check description is set for all components, is empty when not specified // Check description is set for all components, is empty when not specified
Assertions.assertEquals("", components.get(0).getDescription().getDescription()); Assertions.assertEquals("", components.get(0).getArgumentDescription().getDescription());
Assertions.assertEquals("", components.get(1).getDescription().getDescription()); Assertions.assertEquals("", components.get(1).getArgumentDescription().getDescription());
Assertions.assertEquals("detaildescription", components.get(2).getDescription().getDescription()); Assertions.assertEquals("detaildescription", components.get(2).getArgumentDescription().getDescription());
Assertions.assertEquals("argumentdescription", components.get(3).getDescription().getDescription()); Assertions.assertEquals("argumentdescription", components.get(3).getArgumentDescription().getDescription());
} }
@Test @Test

View file

@ -23,6 +23,7 @@
// //
package cloud.commandframework.kotlin package cloud.commandframework.kotlin
import cloud.commandframework.ArgumentDescription
import cloud.commandframework.Command import cloud.commandframework.Command
import cloud.commandframework.CommandManager import cloud.commandframework.CommandManager
import cloud.commandframework.Description import cloud.commandframework.Description
@ -52,6 +53,8 @@ public class MutableCommandBuilder<C : Any> {
* @param commandManager the command manager which will own this command * @param commandManager the command manager which will own this command
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public constructor( public constructor(
name: String, name: String,
description: Description = Description.empty(), description: Description = Description.empty(),
@ -62,6 +65,25 @@ public class MutableCommandBuilder<C : Any> {
this.commandBuilder = commandManager.commandBuilder(name, description, *aliases) this.commandBuilder = commandManager.commandBuilder(name, description, *aliases)
} }
/**
* Create a new [MutableCommandBuilder]
*
* @param name name for the root command node
* @param description description for the root command node
* @param aliases aliases for the root command node
* @param commandManager the command manager which will own this command
* @since 1.4.0
*/
public constructor(
name: String,
description: ArgumentDescription = ArgumentDescription.empty(),
aliases: Array<String> = emptyArray(),
commandManager: CommandManager<C>
) {
this.commandManager = commandManager
this.commandBuilder = commandManager.commandBuilder(name, description, *aliases)
}
/** /**
* Create a new [MutableCommandBuilder] and invoke the provided receiver lambda on it * Create a new [MutableCommandBuilder] and invoke the provided receiver lambda on it
* *
@ -72,6 +94,8 @@ public class MutableCommandBuilder<C : Any> {
* @param lambda receiver lambda which will be invoked on the new builder * @param lambda receiver lambda which will be invoked on the new builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public constructor( public constructor(
name: String, name: String,
description: Description = Description.empty(), description: Description = Description.empty(),
@ -82,6 +106,26 @@ public class MutableCommandBuilder<C : Any> {
lambda(this) lambda(this)
} }
/**
* Create a new [MutableCommandBuilder] and invoke the provided receiver lambda on it
*
* @param name name for the root command node
* @param description description for the root command node
* @param aliases aliases for the root command node
* @param commandManager the command manager which will own this command
* @param lambda receiver lambda which will be invoked on the new builder
* @since 1.4.0
*/
public constructor(
name: String,
description: ArgumentDescription = ArgumentDescription.empty(),
aliases: Array<String> = emptyArray(),
commandManager: CommandManager<C>,
lambda: MutableCommandBuilder<C>.() -> Unit
) : this(name, description, aliases, commandManager) {
lambda(this)
}
private constructor( private constructor(
commandManager: CommandManager<C>, commandManager: CommandManager<C>,
commandBuilder: Command.Builder<C> commandBuilder: Command.Builder<C>
@ -165,6 +209,8 @@ public class MutableCommandBuilder<C : Any> {
* @return a copy of this mutable builder * @return a copy of this mutable builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun copy( public fun copy(
literal: String, literal: String,
description: Description, description: Description,
@ -175,6 +221,25 @@ public class MutableCommandBuilder<C : Any> {
lambda(this) lambda(this)
} }
/**
* Make a new copy of this [MutableCommandBuilder], append a literal, and invoke the provided receiver lambda on it
*
* @param literal name for the literal
* @param description description for the literal
* @param lambda receiver lambda which will be invoked on the new builder
* @return a copy of this mutable builder
* @since 1.4.0
*/
public fun copy(
literal: String,
description: ArgumentDescription,
lambda: MutableCommandBuilder<C>.() -> Unit
): MutableCommandBuilder<C> =
copy().apply {
literal(literal, description)
lambda(this)
}
/** /**
* Make a new copy of this [MutableCommandBuilder], append a literal, and invoke the provided receiver lambda on it * Make a new copy of this [MutableCommandBuilder], append a literal, and invoke the provided receiver lambda on it
* *
@ -247,6 +312,8 @@ public class MutableCommandBuilder<C : Any> {
* @see [CommandManager.command] * @see [CommandManager.command]
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun registerCopy( public fun registerCopy(
literal: String, literal: String,
description: Description, description: Description,
@ -254,6 +321,25 @@ public class MutableCommandBuilder<C : Any> {
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
copy(literal, description, lambda).register() copy(literal, description, lambda).register()
/**
* Create a new copy of this mutable builder, append a literal, act on it with a receiver lambda, and then register it with
* the owning
* command manager
*
* @param literal name for the literal
* @param description description for the literal
* @param lambda receiver lambda which will be invoked on the new builder
* @return the new mutable builder
* @see [CommandManager.command]
* @since 1.4.0
*/
public fun registerCopy(
literal: String,
description: ArgumentDescription,
lambda: MutableCommandBuilder<C>.() -> Unit
): MutableCommandBuilder<C> =
copy(literal, description, lambda).register()
/** /**
* Set the value for a certain [CommandMeta.Key] in the command meta storage for this builder * Set the value for a certain [CommandMeta.Key] in the command meta storage for this builder
* *
@ -414,12 +500,28 @@ public class MutableCommandBuilder<C : Any> {
* @return this mutable builder * @return this mutable builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun argument( public fun argument(
argument: CommandArgument<C, *>, argument: CommandArgument<C, *>,
description: Description = Description.empty() description: Description = Description.empty()
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
mutate { it.argument(argument, description) } mutate { it.argument(argument, description) }
/**
* Add a new argument to this command
*
* @param argument argument to add
* @param description description of the argument
* @return this mutable builder
* @since 1.4.0
*/
public fun argument(
argument: CommandArgument<C, *>,
description: ArgumentDescription = ArgumentDescription.empty()
): MutableCommandBuilder<C> =
mutate { it.argument(argument, description) }
/** /**
* Add a new argument to this command * Add a new argument to this command
* *
@ -428,12 +530,28 @@ public class MutableCommandBuilder<C : Any> {
* @return this mutable builder * @return this mutable builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun argument( public fun argument(
argument: CommandArgument.Builder<C, *>, argument: CommandArgument.Builder<C, *>,
description: Description = Description.empty() description: Description = Description.empty()
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
mutate { it.argument(argument, description) } mutate { it.argument(argument, description) }
/**
* Add a new argument to this command
*
* @param argument argument to add
* @param description description of the argument
* @return this mutable builder
* @since 1.4.0
*/
public fun argument(
argument: CommandArgument.Builder<C, *>,
description: ArgumentDescription = ArgumentDescription.empty()
): MutableCommandBuilder<C> =
mutate { it.argument(argument, description) }
/** /**
* Add a new argument to this command * Add a new argument to this command
* *
@ -442,12 +560,28 @@ public class MutableCommandBuilder<C : Any> {
* @return this mutable builder * @return this mutable builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun argument( public fun argument(
description: Description = Description.empty(), description: Description = Description.empty(),
argumentSupplier: () -> CommandArgument<C, *> argumentSupplier: () -> CommandArgument<C, *>
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
mutate { it.argument(argumentSupplier(), description) } mutate { it.argument(argumentSupplier(), description) }
/**
* Add a new argument to this command
*
* @param description description of the argument
* @param argumentSupplier supplier of the argument to add
* @return this mutable builder
* @since 1.4.0
*/
public fun argument(
description: ArgumentDescription = ArgumentDescription.empty(),
argumentSupplier: () -> CommandArgument<C, *>
): MutableCommandBuilder<C> =
mutate { it.argument(argumentSupplier(), description) }
/** /**
* Add a new literal argument to this command * Add a new literal argument to this command
* *
@ -457,6 +591,8 @@ public class MutableCommandBuilder<C : Any> {
* @return this mutable builder * @return this mutable builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun literal( public fun literal(
name: String, name: String,
description: Description = Description.empty(), description: Description = Description.empty(),
@ -464,6 +600,22 @@ public class MutableCommandBuilder<C : Any> {
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
mutate { it.literal(name, description, *aliases) } mutate { it.literal(name, description, *aliases) }
/**
* Add a new literal argument to this command
*
* @param name main argument name
* @param description literal description
* @param aliases argument aliases
* @return this mutable builder
* @since 1.4.0
*/
public fun literal(
name: String,
description: ArgumentDescription = ArgumentDescription.empty(),
vararg aliases: String
): MutableCommandBuilder<C> =
mutate { it.literal(name, description, *aliases) }
/** /**
* Set the [CommandExecutionHandler] for this builder * Set the [CommandExecutionHandler] for this builder
* *
@ -489,7 +641,7 @@ public class MutableCommandBuilder<C : Any> {
public fun flag( public fun flag(
name: String, name: String,
aliases: Array<String> = emptyArray(), aliases: Array<String> = emptyArray(),
description: Description = Description.empty(), description: ArgumentDescription = ArgumentDescription.empty(),
argumentSupplier: () -> CommandArgument<C, *> argumentSupplier: () -> CommandArgument<C, *>
): MutableCommandBuilder<C> = mutate { ): MutableCommandBuilder<C> = mutate {
it.flag( it.flag(
@ -514,7 +666,7 @@ public class MutableCommandBuilder<C : Any> {
public fun flag( public fun flag(
name: String, name: String,
aliases: Array<String> = emptyArray(), aliases: Array<String> = emptyArray(),
description: Description = Description.empty(), description: ArgumentDescription = ArgumentDescription.empty(),
argument: CommandArgument<C, *> argument: CommandArgument<C, *>
): MutableCommandBuilder<C> = mutate { ): MutableCommandBuilder<C> = mutate {
it.flag( it.flag(
@ -539,7 +691,7 @@ public class MutableCommandBuilder<C : Any> {
public fun flag( public fun flag(
name: String, name: String,
aliases: Array<String> = emptyArray(), aliases: Array<String> = emptyArray(),
description: Description = Description.empty(), description: ArgumentDescription = ArgumentDescription.empty(),
argumentBuilder: CommandArgument.Builder<C, *> argumentBuilder: CommandArgument.Builder<C, *>
): MutableCommandBuilder<C> = mutate { ): MutableCommandBuilder<C> = mutate {
it.flag( it.flag(
@ -563,7 +715,7 @@ public class MutableCommandBuilder<C : Any> {
public fun flag( public fun flag(
name: String, name: String,
aliases: Array<String> = emptyArray(), aliases: Array<String> = emptyArray(),
description: Description = Description.empty(), description: ArgumentDescription = ArgumentDescription.empty(),
): MutableCommandBuilder<C> = mutate { ): MutableCommandBuilder<C> = mutate {
it.flag( it.flag(
this.commandManager.flagBuilder(name) this.commandManager.flagBuilder(name)

View file

@ -23,6 +23,7 @@
// //
package cloud.commandframework.kotlin.extension package cloud.commandframework.kotlin.extension
import cloud.commandframework.ArgumentDescription
import cloud.commandframework.Command import cloud.commandframework.Command
import cloud.commandframework.CommandManager import cloud.commandframework.CommandManager
import cloud.commandframework.Description import cloud.commandframework.Description
@ -38,6 +39,8 @@ import kotlin.reflect.KClass
* @param lambda receiver lambda which will be invoked on the new builder * @param lambda receiver lambda which will be invoked on the new builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun <C : Any> CommandManager<C>.commandBuilder( public fun <C : Any> CommandManager<C>.commandBuilder(
name: String, name: String,
description: Description = Description.empty(), description: Description = Description.empty(),
@ -46,6 +49,23 @@ public fun <C : Any> CommandManager<C>.commandBuilder(
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
MutableCommandBuilder(name, description, aliases, this, lambda) MutableCommandBuilder(name, description, aliases, this, lambda)
/**
* Create a new [MutableCommandBuilder] and invoke the provided receiver lambda on it
*
* @param name name for the root command node
* @param description description for the root command node
* @param aliases aliases for the root command node
* @param lambda receiver lambda which will be invoked on the new builder
* @since 1.4.0
*/
public fun <C : Any> CommandManager<C>.commandBuilder(
name: String,
description: ArgumentDescription = ArgumentDescription.empty(),
aliases: Array<String> = emptyArray(),
lambda: MutableCommandBuilder<C>.() -> Unit
): MutableCommandBuilder<C> =
MutableCommandBuilder(name, description, aliases, this, lambda)
/** /**
* Create a new [MutableCommandBuilder] which will invoke the provided receiver lambda, and then register itself with the * Create a new [MutableCommandBuilder] which will invoke the provided receiver lambda, and then register itself with the
* owning [CommandManager] * owning [CommandManager]
@ -56,6 +76,8 @@ public fun <C : Any> CommandManager<C>.commandBuilder(
* @param lambda receiver lambda which will be invoked on the new builder * @param lambda receiver lambda which will be invoked on the new builder
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(message = "ArgumentDescription should be used over Description", level = DeprecationLevel.HIDDEN)
public fun <C : Any> CommandManager<C>.buildAndRegister( public fun <C : Any> CommandManager<C>.buildAndRegister(
name: String, name: String,
description: Description = Description.empty(), description: Description = Description.empty(),
@ -64,6 +86,24 @@ public fun <C : Any> CommandManager<C>.buildAndRegister(
): MutableCommandBuilder<C> = ): MutableCommandBuilder<C> =
commandBuilder(name, description, aliases, lambda).register() commandBuilder(name, description, aliases, lambda).register()
/**
* Create a new [MutableCommandBuilder] which will invoke the provided receiver lambda, and then register itself with the
* owning [CommandManager]
*
* @param name name for the root command node
* @param description description for the root command node
* @param aliases aliases for the root command node
* @param lambda receiver lambda which will be invoked on the new builder
* @since 1.4.0
*/
public fun <C : Any> CommandManager<C>.buildAndRegister(
name: String,
description: ArgumentDescription = ArgumentDescription.empty(),
aliases: Array<String> = emptyArray(),
lambda: MutableCommandBuilder<C>.() -> Unit
): MutableCommandBuilder<C> =
commandBuilder(name, description, aliases, lambda).register()
/** /**
* Build the provided [MutableCommandBuilder]s into [Command]s, and then register them with the command manager * Build the provided [MutableCommandBuilder]s into [Command]s, and then register them with the command manager
* *
@ -98,7 +138,24 @@ public fun <C : Any> Command.Builder<C>.senderType(type: KClass<out C>): Command
* @return the description * @return the description
* @since 1.3.0 * @since 1.3.0
*/ */
@Suppress("DEPRECATION")
@Deprecated(
message = "Use interface variant that allows for rich text",
replaceWith = ReplaceWith("argumentDescription(description)")
)
public fun description( public fun description(
description: String = "" description: String = ""
): Description = ): Description =
if (description.isEmpty()) Description.empty() else Description.of(description) if (description.isEmpty()) Description.empty() else Description.of(description)
/**
* Get a [ArgumentDescription], defaulting to [ArgumentDescription.empty]
*
* @param description description string
* @return the description
* @since 1.4.0
*/
public fun argumentDescription(
description: String = ""
): ArgumentDescription =
if (description.isEmpty()) ArgumentDescription.empty() else ArgumentDescription.of(description)

View file

@ -27,10 +27,7 @@ import cloud.commandframework.CommandManager
import cloud.commandframework.arguments.standard.StringArgument import cloud.commandframework.arguments.standard.StringArgument
import cloud.commandframework.execution.CommandExecutionCoordinator import cloud.commandframework.execution.CommandExecutionCoordinator
import cloud.commandframework.internal.CommandRegistrationHandler import cloud.commandframework.internal.CommandRegistrationHandler
import cloud.commandframework.kotlin.extension.buildAndRegister import cloud.commandframework.kotlin.extension.*
import cloud.commandframework.kotlin.extension.command
import cloud.commandframework.kotlin.extension.commandBuilder
import cloud.commandframework.kotlin.extension.description
import cloud.commandframework.meta.CommandMeta import cloud.commandframework.meta.CommandMeta
import cloud.commandframework.meta.SimpleCommandMeta import cloud.commandframework.meta.SimpleCommandMeta
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
@ -48,7 +45,7 @@ class CommandBuildingDSLTest {
senderType<SpecificCommandSender>() senderType<SpecificCommandSender>()
literal("dsl") literal("dsl")
argument(description("An amazing command argument")) { argument(argumentDescription("An amazing command argument")) {
StringArgument.of("moment") StringArgument.of("moment")
} }
handler { handler {

View file

@ -1,4 +1,5 @@
dependencies { dependencies {
api(project(":cloud-core")) api(project(":cloud-core"))
api("net.kyori", "adventure-api", Versions.adventureApi) api("net.kyori", "adventure-api", Versions.adventureApi)
api("net.kyori", "adventure-text-serializer-plain", Versions.adventureApi)
} }

View file

@ -23,6 +23,7 @@
// //
package cloud.commandframework.minecraft.extras; package cloud.commandframework.minecraft.extras;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command; import cloud.commandframework.Command;
import cloud.commandframework.CommandComponent; import cloud.commandframework.CommandComponent;
import cloud.commandframework.CommandHelpHandler; import cloud.commandframework.CommandHelpHandler;
@ -488,7 +489,7 @@ public final class MinecraftHelp<C> {
final CommandComponent<C> component = iterator.next(); final CommandComponent<C> component = iterator.next();
final CommandArgument<C, ?> argument = component.getArgument(); final CommandArgument<C, ?> argument = component.getArgument();
String syntax = this.commandManager.getCommandSyntaxFormatter() final String syntax = this.commandManager.getCommandSyntaxFormatter()
.apply(Collections.singletonList(argument), null); .apply(Collections.singletonList(argument), null);
final TextComponent.Builder textComponent = text() final TextComponent.Builder textComponent = text()
@ -502,10 +503,10 @@ public final class MinecraftHelp<C> {
); );
textComponent.append(text(")", this.colors.alternateHighlight)); textComponent.append(text(")", this.colors.alternateHighlight));
} }
final String description = component.getDescription().getDescription(); final ArgumentDescription description = component.getArgumentDescription();
if (!description.isEmpty()) { if (!description.isEmpty()) {
textComponent.append(text(" - ", this.colors.accent)); textComponent.append(text(" - ", this.colors.accent));
textComponent.append(this.descriptionDecorator.apply(description).color(this.colors.text)); textComponent.append(this.formatDescription(description).colorIfAbsent(this.colors.text));
} }
audience.sendMessage(textComponent); audience.sendMessage(textComponent);
@ -514,6 +515,14 @@ public final class MinecraftHelp<C> {
audience.sendMessage(this.footer(sender)); audience.sendMessage(this.footer(sender));
} }
private Component formatDescription(final ArgumentDescription description) {
if (description instanceof RichDescription) {
return ((RichDescription) description).getContents();
} else {
return this.descriptionDecorator.apply(description.getDescription());
}
}
private @NonNull Component showingResults( private @NonNull Component showingResults(
final @NonNull C sender, final @NonNull C sender,
final @NonNull String query final @NonNull String query

View file

@ -0,0 +1,133 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg & Contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package cloud.commandframework.minecraft.extras;
import cloud.commandframework.ArgumentDescription;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import net.kyori.adventure.translation.GlobalTranslator;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Locale;
import static java.util.Objects.requireNonNull;
/**
* An argument description implementation that uses Adventure components.
*
* @since 1.4.0
*/
public final class RichDescription implements ArgumentDescription {
private static final RichDescription EMPTY = new RichDescription(Component.empty());
private final Component contents;
RichDescription(final Component contents) {
this.contents = contents;
}
/**
* Get an empty description.
*
* @return the empty description
*/
public static @NonNull RichDescription empty() {
return EMPTY;
}
/**
* Create a new rich description from the provided component.
*
* @param contents the rich contents
* @return a new rich description
*/
public static @NonNull RichDescription of(final @NonNull ComponentLike contents) {
final Component componentContents = requireNonNull(contents, "contents").asComponent();
if (Component.empty().equals(componentContents)) {
return EMPTY;
}
return new RichDescription(componentContents);
}
/* Translatable helper methods */
/**
* Create a rich description pointing to a translation key.
*
* @param key the translation key
* @return a new rich description
*/
public static @NonNull RichDescription translatable(final @NonNull String key) {
requireNonNull(key, "key");
return new RichDescription(Component.translatable(key));
}
/**
* Create a rich description pointing to a translation key.
*
* @param key the translation key
* @param args the arguments to use with the translation key
* @return a new rich description
*/
public static @NonNull RichDescription translatable(
final @NonNull String key,
final @NonNull ComponentLike @NonNull... args
) {
requireNonNull(key, "key");
requireNonNull(args, "args");
return new RichDescription(Component.translatable(key, args));
}
/**
* {@inheritDoc}
*
* @deprecated to discourage use. A plain serialization is a somewhat expensive and lossy operation, use
* {@link #getContents()} instead.
*/
@Override
@Deprecated
public @NonNull String getDescription() {
return PlainComponentSerializer.plain().serialize(GlobalTranslator.render(this.contents, Locale.getDefault()));
}
/**
* Get the contents of this description.
*
* @return the component contents of this description
*/
public @NonNull Component getContents() {
return this.contents;
}
@Override
public boolean isEmpty() {
return Component.empty().equals(this.contents);
}
}

View file

@ -23,9 +23,9 @@
// //
package cloud.commandframework.examples.bukkit; package cloud.commandframework.examples.bukkit;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command; import cloud.commandframework.Command;
import cloud.commandframework.CommandTree; import cloud.commandframework.CommandTree;
import cloud.commandframework.Description;
import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler;
import cloud.commandframework.minecraft.extras.MinecraftHelp; import cloud.commandframework.minecraft.extras.MinecraftHelp;
import cloud.commandframework.annotations.AnnotationParser; import cloud.commandframework.annotations.AnnotationParser;
@ -56,6 +56,7 @@ import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.execution.CommandExecutionCoordinator; import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.extra.confirmation.CommandConfirmationManager; import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
import cloud.commandframework.meta.CommandMeta; import cloud.commandframework.meta.CommandMeta;
import cloud.commandframework.minecraft.extras.RichDescription;
import cloud.commandframework.minecraft.extras.TextColorArgument; import cloud.commandframework.minecraft.extras.TextColorArgument;
import cloud.commandframework.paper.PaperCommandManager; import cloud.commandframework.paper.PaperCommandManager;
import cloud.commandframework.tasks.TaskConsumer; import cloud.commandframework.tasks.TaskConsumer;
@ -63,8 +64,9 @@ import cloud.commandframework.types.tuples.Triplet;
import io.leangen.geantyref.TypeToken; import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.identity.Identity; import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -87,6 +89,8 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
import static net.kyori.adventure.text.Component.text;
/** /**
* Example plugin class * Example plugin class
*/ */
@ -196,10 +200,10 @@ public final class ExamplePlugin extends JavaPlugin {
.withArgumentParsingHandler() .withArgumentParsingHandler()
.withCommandExecutionHandler() .withCommandExecutionHandler()
.withDecorator( .withDecorator(
component -> Component.text() component -> text()
.append(Component.text("[", NamedTextColor.DARK_GRAY)) .append(text("[", NamedTextColor.DARK_GRAY))
.append(Component.text("Example", NamedTextColor.GOLD)) .append(text("Example", NamedTextColor.GOLD))
.append(Component.text("] ", NamedTextColor.DARK_GRAY)) .append(text("] ", NamedTextColor.DARK_GRAY))
.append(component).build() .append(component).build()
).apply(manager, bukkitAudiences::sender); ).apply(manager, bukkitAudiences::sender);
// //
@ -234,7 +238,7 @@ public final class ExamplePlugin extends JavaPlugin {
.literal("me") .literal("me")
// Require a player sender // Require a player sender
.senderType(Player.class) .senderType(Player.class)
.argument(worldArgument, Description.of("World name")) .argument(worldArgument, ArgumentDescription.of("World name"))
.argumentTriplet( .argumentTriplet(
"coords", "coords",
TypeToken.get(Vector.class), TypeToken.get(Vector.class),
@ -243,7 +247,7 @@ public final class ExamplePlugin extends JavaPlugin {
(sender, triplet) -> new Vector(triplet.getFirst(), triplet.getSecond(), (sender, triplet) -> new Vector(triplet.getFirst(), triplet.getSecond(),
triplet.getThird() triplet.getThird()
), ),
Description.of("Coordinates") ArgumentDescription.of("Coordinates")
) )
.handler(context -> manager.taskRecipe().begin(context) .handler(context -> manager.taskRecipe().begin(context)
.synchronous(commandContext -> { .synchronous(commandContext -> {
@ -258,7 +262,7 @@ public final class ExamplePlugin extends JavaPlugin {
.senderType(Player.class) .senderType(Player.class)
.argument( .argument(
SingleEntitySelectorArgument.of("entity"), SingleEntitySelectorArgument.of("entity"),
Description.of("Entity to teleport") ArgumentDescription.of("Entity to teleport")
) )
.literal("here") .literal("here")
.handler( .handler(
@ -277,7 +281,7 @@ public final class ExamplePlugin extends JavaPlugin {
)) ))
.command(builder.literal("teleport") .command(builder.literal("teleport")
.meta(CommandMeta.DESCRIPTION, "Teleport to a world") .meta(CommandMeta.DESCRIPTION, "Teleport to a world")
.argument(WorldArgument.of("world"), Description.of("World to teleport to")) .argument(WorldArgument.of("world"), ArgumentDescription.of("World to teleport to"))
.handler(context -> manager.taskRecipe().begin(context).synchronous(ctx -> { .handler(context -> manager.taskRecipe().begin(context).synchronous(ctx -> {
final Player player = (Player) ctx.getSender(); final Player player = (Player) ctx.getSender();
player.teleport(ctx.<World>get("world").getSpawnLocation()); player.teleport(ctx.<World>get("world").getSpawnLocation());
@ -330,23 +334,23 @@ public final class ExamplePlugin extends JavaPlugin {
.literal("helpcolors") .literal("helpcolors")
.argument( .argument(
TextColorArgument.of("primary"), TextColorArgument.of("primary"),
Description.of("The primary color for the color scheme") RichDescription.of(text("The primary color for the color scheme", Style.style(TextDecoration.ITALIC)))
) )
.argument( .argument(
TextColorArgument.of("highlight"), TextColorArgument.of("highlight"),
Description.of("The primary color used to highlight commands and queries") RichDescription.of(text("The primary color used to highlight commands and queries"))
) )
.argument( .argument(
TextColorArgument.of("alternate_highlight"), TextColorArgument.of("alternate_highlight"),
Description.of("The secondary color used to highlight commands and queries") RichDescription.of(text("The secondary color used to highlight commands and queries"))
) )
.argument( .argument(
TextColorArgument.of("text"), TextColorArgument.of("text"),
Description.of("The color used for description text") RichDescription.of(text("The color used for description text"))
) )
.argument( .argument(
TextColorArgument.of("accent"), TextColorArgument.of("accent"),
Description.of("The color used for accents and symbols") RichDescription.of(text("The color used for accents and symbols"))
) )
.handler(c -> minecraftHelp.setHelpColors(MinecraftHelp.HelpColors.of( .handler(c -> minecraftHelp.setHelpColors(MinecraftHelp.HelpColors.of(
c.get("primary"), c.get("primary"),
@ -363,7 +367,7 @@ public final class ExamplePlugin extends JavaPlugin {
manager.command( manager.command(
manager.commandBuilder( manager.commandBuilder(
"arraycommand", "arraycommand",
Description.of("Bukkit-esque cmmand") ArgumentDescription.of("Bukkit-esque cmmand")
).argument( ).argument(
StringArrayArgument.optional( StringArrayArgument.optional(
"args", "args",
@ -375,7 +379,7 @@ public final class ExamplePlugin extends JavaPlugin {
return Collections.emptyList(); return Collections.emptyList();
} }
), ),
Description.of("Arguments") ArgumentDescription.of("Arguments")
).handler(context -> { ).handler(context -> {
final String[] args = context.getOrDefault("args", new String[0]); final String[] args = context.getOrDefault("args", new String[0]);
context.getSender().sendMessage("You wrote: " + StringUtils.join(args, " ")); context.getSender().sendMessage("You wrote: " + StringUtils.join(args, " "));
@ -408,7 +412,7 @@ public final class ExamplePlugin extends JavaPlugin {
private void commandClear(final @NonNull Player player) { private void commandClear(final @NonNull Player player) {
player.getInventory().clear(); player.getInventory().clear();
this.bukkitAudiences.player(player) this.bukkitAudiences.player(player)
.sendMessage(Identity.nil(), Component.text("Your inventory has been cleared", NamedTextColor.GOLD)); .sendMessage(Identity.nil(), text("Your inventory has been cleared", NamedTextColor.GOLD));
} }
@CommandMethod("example give <material> <amount>") @CommandMethod("example give <material> <amount>")
@ -452,8 +456,8 @@ public final class ExamplePlugin extends JavaPlugin {
) { ) {
bukkitAudiences.sender(sender).sendMessage( bukkitAudiences.sender(sender).sendMessage(
Identity.nil(), Identity.nil(),
Component.text().append(Component.text("You have been given ", NamedTextColor.AQUA)) text().append(text("You have been given ", NamedTextColor.AQUA))
.append(Component.text(money, NamedTextColor.GOLD)) .append(text(money, NamedTextColor.GOLD))
); );
} }

View file

@ -23,9 +23,9 @@
// //
package cloud.commandframework.examples.bungee; package cloud.commandframework.examples.bungee;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command; import cloud.commandframework.Command;
import cloud.commandframework.CommandTree; import cloud.commandframework.CommandTree;
import cloud.commandframework.Description;
import cloud.commandframework.arguments.CommandArgument; import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.bungee.BungeeCommandManager; import cloud.commandframework.bungee.BungeeCommandManager;
import cloud.commandframework.bungee.arguments.PlayerArgument; import cloud.commandframework.bungee.arguments.PlayerArgument;
@ -35,8 +35,8 @@ import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.extra.confirmation.CommandConfirmationManager; import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
import cloud.commandframework.meta.CommandMeta; import cloud.commandframework.meta.CommandMeta;
import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler;
import cloud.commandframework.minecraft.extras.RichDescription;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences; import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
@ -46,6 +46,8 @@ import net.md_5.bungee.api.plugin.Plugin;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
import static net.kyori.adventure.text.Component.text;
public final class ExamplePlugin extends Plugin { public final class ExamplePlugin extends Plugin {
private BungeeCommandManager<CommandSender> manager; private BungeeCommandManager<CommandSender> manager;
@ -78,10 +80,10 @@ public final class ExamplePlugin extends Plugin {
30L, 30L,
TimeUnit.SECONDS, TimeUnit.SECONDS,
context -> bungeeAudiences.sender(context.getCommandContext().getSender()).sendMessage( context -> bungeeAudiences.sender(context.getCommandContext().getSender()).sendMessage(
Component.text( text(
"Confirmation required. Confirm using /example confirm.", NamedTextColor.RED)), "Confirmation required. Confirm using /example confirm.", NamedTextColor.RED)),
sender -> bungeeAudiences.sender(sender).sendMessage( sender -> bungeeAudiences.sender(sender).sendMessage(
Component.text("You do not have any pending commands.", NamedTextColor.RED)) text("You do not have any pending commands.", NamedTextColor.RED))
); );
this.confirmationManager.registerConfirmationProcessor(manager); this.confirmationManager.registerConfirmationProcessor(manager);
@ -91,10 +93,10 @@ public final class ExamplePlugin extends Plugin {
.withInvalidSenderHandler() .withInvalidSenderHandler()
.withNoPermissionHandler() .withNoPermissionHandler()
.withArgumentParsingHandler() .withArgumentParsingHandler()
.withDecorator(component -> Component.text() .withDecorator(component -> text()
.append(Component.text("[", NamedTextColor.DARK_GRAY)) .append(text("[", NamedTextColor.DARK_GRAY))
.append(Component.text("Example", NamedTextColor.GOLD)) .append(text("Example", NamedTextColor.GOLD))
.append(Component.text("] ", NamedTextColor.DARK_GRAY)) .append(text("] ", NamedTextColor.DARK_GRAY))
.append(component).build() .append(component).build()
).apply(manager, bungeeAudiences::sender); ).apply(manager, bungeeAudiences::sender);
this.constructCommands(); this.constructCommands();
@ -121,12 +123,12 @@ public final class ExamplePlugin extends Plugin {
this.manager.command( this.manager.command(
manager.commandBuilder("player") manager.commandBuilder("player")
.senderType(ProxiedPlayer.class) .senderType(ProxiedPlayer.class)
.argument(playerArgument, Description.of("Player name")) .argument(playerArgument, RichDescription.of(text("Player ").append(text("name", NamedTextColor.GOLD))))
.handler(context -> { .handler(context -> {
final ProxiedPlayer player = context.get("player"); final ProxiedPlayer player = context.get("player");
bungeeAudiences.sender(context.getSender()).sendMessage( bungeeAudiences.sender(context.getSender()).sendMessage(
Component.text("Selected ", NamedTextColor.GOLD) text("Selected ", NamedTextColor.GOLD)
.append(Component.text(player.getDisplayName(), NamedTextColor.AQUA)) .append(text(player.getDisplayName(), NamedTextColor.AQUA))
); );
}) })
); );
@ -137,12 +139,12 @@ public final class ExamplePlugin extends Plugin {
this.manager.command( this.manager.command(
this.manager.commandBuilder("server") this.manager.commandBuilder("server")
.senderType(ProxiedPlayer.class) .senderType(ProxiedPlayer.class)
.argument(serverArgument, Description.of("Server name")) .argument(serverArgument, ArgumentDescription.of("Server name"))
.handler(context -> { .handler(context -> {
final ServerInfo server = context.get("server"); final ServerInfo server = context.get("server");
bungeeAudiences.sender(context.getSender()).sendMessage( bungeeAudiences.sender(context.getSender()).sendMessage(
Component.text("Selected ", NamedTextColor.GOLD) text("Selected ", NamedTextColor.GOLD)
.append(Component.text(server.getName(), NamedTextColor.AQUA)) .append(text(server.getName(), NamedTextColor.AQUA))
); );
}) })
); );