✨ Work towards making CommandMeta typesafe (#173)
Co-authored-by: Alexander Söderberg <sauilitired@gmail.com>
This commit is contained in:
parent
ab366be24d
commit
1e91273e0e
33 changed files with 450 additions and 64 deletions
|
|
@ -8,10 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Added `@Suggestions` annotated methods
|
- Added `@Suggestions` annotated methods
|
||||||
|
- Type safe meta system
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Moved the parser injector registry into CommandManager and added injection to CommandContext
|
- Moved the parser injector registry into CommandManager and added injection to CommandContext
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
- String keyed command meta
|
||||||
|
|
||||||
## [1.2.0] - 2020-12-07
|
## [1.2.0] - 2020-12-07
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ public final class AnnotationParser<C> {
|
||||||
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
||||||
.with(this.metaFactory.apply(method));
|
.with(this.metaFactory.apply(method));
|
||||||
if (methodOrClassHasAnnotation(method, Confirmation.class)) {
|
if (methodOrClassHasAnnotation(method, Confirmation.class)) {
|
||||||
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
|
metaBuilder.with(CommandConfirmationManager.META_CONFIRMATION_REQUIRED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ public class Command<C> {
|
||||||
* @return {@code true} if the command is hidden, {@code false} if not
|
* @return {@code true} if the command is hidden, {@code false} if not
|
||||||
*/
|
*/
|
||||||
public boolean isHidden() {
|
public boolean isHidden() {
|
||||||
return this.getCommandMeta().getOrDefault("hidden", "true").equals("true");
|
return this.getCommandMeta().getOrDefault(CommandMeta.HIDDEN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -337,7 +337,9 @@ public class Command<C> {
|
||||||
* @param key Meta key
|
* @param key Meta key
|
||||||
* @param value Meta value
|
* @param value Meta value
|
||||||
* @return New builder instance using the inserted meta key-value pair
|
* @return New builder instance using the inserted meta key-value pair
|
||||||
|
* @deprecated for removal since 1.2.0, use the typesafe variant at {@link #meta(CommandMeta.Key, Object)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public @NonNull Builder<C> meta(final @NonNull String key, final @NonNull String value) {
|
public @NonNull Builder<C> meta(final @NonNull String key, final @NonNull String value) {
|
||||||
final CommandMeta commandMeta = SimpleCommandMeta.builder().with(this.commandMeta).with(key, value).build();
|
final CommandMeta commandMeta = SimpleCommandMeta.builder().with(this.commandMeta).with(key, value).build();
|
||||||
return new Builder<>(
|
return new Builder<>(
|
||||||
|
|
@ -351,6 +353,28 @@ public class Command<C> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add command meta to the internal command meta map
|
||||||
|
*
|
||||||
|
* @param <V> Meta value type
|
||||||
|
* @param key Meta key
|
||||||
|
* @param value Meta value
|
||||||
|
* @return New builder instance using the inserted meta key-value pair
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public <V> @NonNull Builder<C> meta(final CommandMeta.@NonNull Key<V> key, final @NonNull V value) {
|
||||||
|
final CommandMeta commandMeta = SimpleCommandMeta.builder().with(this.commandMeta).with(key, value).build();
|
||||||
|
return new Builder<>(
|
||||||
|
this.commandManager,
|
||||||
|
commandMeta,
|
||||||
|
this.senderType,
|
||||||
|
this.commandArguments,
|
||||||
|
this.commandExecutionHandler,
|
||||||
|
this.commandPermission,
|
||||||
|
this.flags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supply a command manager instance to the builder. This will be used when attempting to
|
* Supply a command manager instance to the builder. This will be used when attempting to
|
||||||
* retrieve command argument parsers, in the case that they're needed. This
|
* retrieve command argument parsers, in the case that they're needed. This
|
||||||
|
|
@ -746,7 +770,7 @@ public class Command<C> {
|
||||||
* @return New builder instance that indicates that the constructed command should be hidden
|
* @return New builder instance that indicates that the constructed command should be hidden
|
||||||
*/
|
*/
|
||||||
public @NonNull Builder<C> hidden() {
|
public @NonNull Builder<C> hidden() {
|
||||||
return this.meta("hidden", "true");
|
return this.meta(CommandMeta.HIDDEN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ package cloud.commandframework;
|
||||||
|
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.StaticArgument;
|
import cloud.commandframework.arguments.StaticArgument;
|
||||||
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -55,7 +56,7 @@ public final class CommandHelpHandler<C> {
|
||||||
final List<VerboseHelpEntry<C>> syntaxHints = new ArrayList<>();
|
final List<VerboseHelpEntry<C>> syntaxHints = new ArrayList<>();
|
||||||
for (final Command<C> command : this.commandManager.getCommands()) {
|
for (final Command<C> command : this.commandManager.getCommands()) {
|
||||||
final List<CommandArgument<C, ?>> arguments = command.getArguments();
|
final List<CommandArgument<C, ?>> arguments = command.getArguments();
|
||||||
final String description = command.getCommandMeta().getOrDefault("description", "");
|
final String description = command.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, "");
|
||||||
syntaxHints.add(new VerboseHelpEntry<>(
|
syntaxHints.add(new VerboseHelpEntry<>(
|
||||||
command,
|
command,
|
||||||
this.commandManager.getCommandSyntaxFormatter()
|
this.commandManager.getCommandSyntaxFormatter()
|
||||||
|
|
@ -163,7 +164,7 @@ public final class CommandHelpHandler<C> {
|
||||||
final List<VerboseHelpEntry<C>> syntaxHints = new ArrayList<>();
|
final List<VerboseHelpEntry<C>> syntaxHints = new ArrayList<>();
|
||||||
for (final Command<C> command : availableCommands) {
|
for (final Command<C> command : availableCommands) {
|
||||||
final List<CommandArgument<C, ?>> arguments = command.getArguments();
|
final List<CommandArgument<C, ?>> arguments = command.getArguments();
|
||||||
final String description = command.getCommandMeta().getOrDefault("description", "");
|
final String description = command.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, "");
|
||||||
syntaxHints.add(new VerboseHelpEntry<>(
|
syntaxHints.add(new VerboseHelpEntry<>(
|
||||||
command,
|
command,
|
||||||
this.commandManager.getCommandSyntaxFormatter()
|
this.commandManager.getCommandSyntaxFormatter()
|
||||||
|
|
@ -350,8 +351,8 @@ public final class CommandHelpHandler<C> {
|
||||||
|
|
||||||
private VerboseHelpTopic(final @NonNull Command<C> command) {
|
private VerboseHelpTopic(final @NonNull Command<C> command) {
|
||||||
this.command = command;
|
this.command = command;
|
||||||
final String shortDescription = command.getCommandMeta().getOrDefault("description", "No description");
|
final String shortDescription = command.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, "No description");
|
||||||
this.description = command.getCommandMeta().getOrDefault("long-description", shortDescription);
|
this.description = command.getCommandMeta().getOrDefault(CommandMeta.LONG_DESCRIPTION, shortDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ final class AnnotatedElementAccessor implements AnnotationAccessor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <A extends Annotation> @Nullable A annotation(
|
public <A extends Annotation> @Nullable A annotation(
|
||||||
@NonNull final Class<A> clazz
|
final @NonNull Class<A> clazz
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
return element.getAnnotation(clazz);
|
return element.getAnnotation(clazz);
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ public interface AnnotationAccessor {
|
||||||
final class NullAnnotationAccessor implements AnnotationAccessor {
|
final class NullAnnotationAccessor implements AnnotationAccessor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <A extends Annotation> @Nullable A annotation(@NonNull final Class<A> clazz) {
|
public <A extends Annotation> @Nullable A annotation(final @NonNull Class<A> clazz) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ public final class DelegatingCommandSuggestionEngine<C> implements CommandSugges
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull List<@NonNull String> getSuggestions(
|
public @NonNull List<@NonNull String> getSuggestions(
|
||||||
@NonNull final CommandContext<C> context,
|
final @NonNull CommandContext<C> context,
|
||||||
@NonNull final String input
|
final @NonNull String input
|
||||||
) {
|
) {
|
||||||
final @NonNull LinkedList<@NonNull String> inputQueue = new CommandInputTokenizer(input).tokenize();
|
final @NonNull LinkedList<@NonNull String> inputQueue = new CommandInputTokenizer(input).tokenize();
|
||||||
/* Store a copy of the input queue in the context */
|
/* Store a copy of the input queue in the context */
|
||||||
|
|
|
||||||
|
|
@ -232,15 +232,15 @@ public final class StandardParserRegistry<C> implements ParserRegistry<C> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerSuggestionProvider(
|
public void registerSuggestionProvider(
|
||||||
@NonNull final String name,
|
final @NonNull String name,
|
||||||
@NonNull final BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>> suggestionsProvider
|
final @NonNull BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>> suggestionsProvider
|
||||||
) {
|
) {
|
||||||
this.namedSuggestionProviders.put(name.toLowerCase(Locale.ENGLISH), suggestionsProvider);
|
this.namedSuggestionProviders.put(name.toLowerCase(Locale.ENGLISH), suggestionsProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Optional<BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>>> getSuggestionProvider(
|
public @NonNull Optional<BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>>> getSuggestionProvider(
|
||||||
@NonNull final String name
|
final @NonNull String name
|
||||||
) {
|
) {
|
||||||
final BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>> suggestionProvider =
|
final BiFunction<@NonNull CommandContext<C>, @NonNull String, @NonNull List<String>> suggestionProvider =
|
||||||
this.namedSuggestionProviders.get(name.toLowerCase(Locale.ENGLISH));
|
this.namedSuggestionProviders.get(name.toLowerCase(Locale.ENGLISH));
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<Boolean> apply(
|
public @NonNull ArgumentParseResult<Boolean> apply(
|
||||||
@NonNull final CommandContext<C> context, @NonNull final Queue<@NonNull String> strings
|
final @NonNull CommandContext<C> context, final @NonNull Queue<@NonNull String> strings
|
||||||
) {
|
) {
|
||||||
final String head = strings.peek();
|
final String head = strings.peek();
|
||||||
if (head == null) {
|
if (head == null) {
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
||||||
* @return Created builder
|
* @return Created builder
|
||||||
*/
|
*/
|
||||||
public static <C, E extends Enum<E>> EnumArgument.@NonNull Builder<C, E> newBuilder(
|
public static <C, E extends Enum<E>> EnumArgument.@NonNull Builder<C, E> newBuilder(
|
||||||
@NonNull final Class<E> enumClass,
|
final @NonNull Class<E> enumClass,
|
||||||
final @NonNull String name
|
final @NonNull String name
|
||||||
) {
|
) {
|
||||||
return new EnumArgument.Builder<>(name, enumClass);
|
return new EnumArgument.Builder<>(name, enumClass);
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,8 @@ public final class StringArrayArgument<C> extends CommandArgument<C, String[]> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<String @NonNull []> parse(
|
public @NonNull ArgumentParseResult<String @NonNull []> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String[] result = new String[inputQueue.size()];
|
final String[] result = new String[inputQueue.size()];
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,8 @@ public class SimpleCaptionRegistry<C> implements FactoryDelegatingCaptionRegistr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final @NonNull String getCaption(
|
public final @NonNull String getCaption(
|
||||||
@NonNull final Caption caption,
|
final @NonNull Caption caption,
|
||||||
@NonNull final C sender
|
final @NonNull C sender
|
||||||
) {
|
) {
|
||||||
final BiFunction<Caption, C, String> messageFactory = this.messageFactories.get(caption);
|
final BiFunction<Caption, C, String> messageFactory = this.messageFactories.get(caption);
|
||||||
if (messageFactory == null) {
|
if (messageFactory == null) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import cloud.commandframework.CommandManager;
|
||||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext;
|
import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext;
|
||||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessor;
|
import cloud.commandframework.execution.postprocessor.CommandPostprocessor;
|
||||||
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||||
import cloud.commandframework.services.types.ConsumerService;
|
import cloud.commandframework.services.types.ConsumerService;
|
||||||
import cloud.commandframework.types.tuples.Pair;
|
import cloud.commandframework.types.tuples.Pair;
|
||||||
|
|
@ -54,8 +55,27 @@ public class CommandConfirmationManager<C> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Meta data stored for commands that require confirmation
|
* Meta data stored for commands that require confirmation
|
||||||
|
*
|
||||||
|
* @deprecated for removal since 1.3.0. Use {@link #META_CONFIRMATION_REQUIRED} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static final String CONFIRMATION_REQUIRED_META = "__REQUIRE_CONFIRMATION__";
|
public static final String CONFIRMATION_REQUIRED_META = "__REQUIRE_CONFIRMATION__";
|
||||||
|
|
||||||
|
private static final CommandMeta.Key<String> LEGACY_CONFIRMATION_META = CommandMeta.Key.of(
|
||||||
|
String.class,
|
||||||
|
CONFIRMATION_REQUIRED_META
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meta data stored for commands that require confirmation
|
||||||
|
*
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public static final CommandMeta.Key<Boolean> META_CONFIRMATION_REQUIRED = CommandMeta.Key.of(
|
||||||
|
Boolean.class,
|
||||||
|
"cloud:require_confirmation",
|
||||||
|
meta -> meta.get(LEGACY_CONFIRMATION_META).map(Boolean::valueOf).orElse(null)
|
||||||
|
);
|
||||||
private static final int MAXIMUM_PENDING_SIZE = 100;
|
private static final int MAXIMUM_PENDING_SIZE = 100;
|
||||||
|
|
||||||
private final Consumer<CommandPostprocessingContext<C>> notifier;
|
private final Consumer<CommandPostprocessingContext<C>> notifier;
|
||||||
|
|
@ -120,7 +140,7 @@ public class CommandConfirmationManager<C> {
|
||||||
* @return Builder instance
|
* @return Builder instance
|
||||||
*/
|
*/
|
||||||
public SimpleCommandMeta.@NonNull Builder decorate(final SimpleCommandMeta.@NonNull Builder builder) {
|
public SimpleCommandMeta.@NonNull Builder decorate(final SimpleCommandMeta.@NonNull Builder builder) {
|
||||||
return builder.with(CONFIRMATION_REQUIRED_META, "true");
|
return builder.with(META_CONFIRMATION_REQUIRED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -158,8 +178,7 @@ public class CommandConfirmationManager<C> {
|
||||||
public void accept(final @NonNull CommandPostprocessingContext<C> context) {
|
public void accept(final @NonNull CommandPostprocessingContext<C> context) {
|
||||||
if (!context.getCommand()
|
if (!context.getCommand()
|
||||||
.getCommandMeta()
|
.getCommandMeta()
|
||||||
.getOrDefault(CONFIRMATION_REQUIRED_META, "false")
|
.getOrDefault(META_CONFIRMATION_REQUIRED, false)) {
|
||||||
.equals("true")) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Add it to the "queue" */
|
/* Add it to the "queue" */
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,16 @@
|
||||||
package cloud.commandframework.meta;
|
package cloud.commandframework.meta;
|
||||||
|
|
||||||
import cloud.commandframework.Command;
|
import cloud.commandframework.Command;
|
||||||
|
import io.leangen.geantyref.GenericTypeReflector;
|
||||||
|
import io.leangen.geantyref.TypeToken;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object that is associated with a {@link Command}.
|
* Object that is associated with a {@link Command}.
|
||||||
|
|
@ -37,6 +43,15 @@ import java.util.Optional;
|
||||||
*/
|
*/
|
||||||
public abstract class CommandMeta {
|
public abstract class CommandMeta {
|
||||||
|
|
||||||
|
private static final Key<String> LEGACY_HIDDEN = Key.of(String.class, "hidden");
|
||||||
|
public static final Key<String> DESCRIPTION = Key.of(String.class, "description");
|
||||||
|
public static final Key<String> LONG_DESCRIPTION = Key.of(String.class, "long-description");
|
||||||
|
public static final Key<Boolean> HIDDEN = Key.of(
|
||||||
|
Boolean.class,
|
||||||
|
"cloud:hidden",
|
||||||
|
meta -> Boolean.valueOf(meta.getOrDefault(LEGACY_HIDDEN, "false"))
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new simple command meta builder
|
* Create a new simple command meta builder
|
||||||
*
|
*
|
||||||
|
|
@ -56,7 +71,9 @@ public abstract class CommandMeta {
|
||||||
*
|
*
|
||||||
* @param key Key
|
* @param key Key
|
||||||
* @return Optional that may contain the associated value
|
* @return Optional that may contain the associated value
|
||||||
|
* @deprecated for removal since 1.3.0, see typesafe variant at {@link #get(Key)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract @NonNull Optional<String> getValue(@NonNull String key);
|
public abstract @NonNull Optional<String> getValue(@NonNull String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -65,14 +82,157 @@ public abstract class CommandMeta {
|
||||||
* @param key Key
|
* @param key Key
|
||||||
* @param defaultValue Default value
|
* @param defaultValue Default value
|
||||||
* @return Value, or default value
|
* @return Value, or default value
|
||||||
|
* @deprecated for removal since 1.3.0, see typesafe variant at {@link #getOrDefault(Key, Object)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract @NonNull String getOrDefault(@NonNull String key, @NonNull String defaultValue);
|
public abstract @NonNull String getOrDefault(@NonNull String key, @NonNull String defaultValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value associated with a key.
|
||||||
|
*
|
||||||
|
* @param <V> Value type
|
||||||
|
* @param key Key
|
||||||
|
* @return Optional that may contain the associated value
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public abstract <V> @NonNull Optional<V> get(@NonNull Key<V> key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value if it exists, else return the default value.
|
||||||
|
*
|
||||||
|
* @param <V> Value type
|
||||||
|
* @param key Key
|
||||||
|
* @param defaultValue Default value
|
||||||
|
* @return Value, or default value
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public abstract <V> @NonNull V getOrDefault(@NonNull Key<V> key, @NonNull V defaultValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a copy of the meta map
|
* Get a copy of the meta map
|
||||||
*
|
*
|
||||||
* @return Copy of meta map
|
* @return Copy of meta map
|
||||||
|
* @deprecated for removal since 1.3.0, use {@link #getAllValues()} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract @NonNull Map<@NonNull String, @NonNull String> getAll();
|
public abstract @NonNull Map<@NonNull String, @NonNull String> getAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a copy of the meta map, without type information.
|
||||||
|
*
|
||||||
|
* @return Copy of meta map
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public abstract @NonNull Map<@NonNull String, @NonNull ?> getAllValues();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A key into the metadata map.
|
||||||
|
*
|
||||||
|
* @param <V> value type
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public interface Key<V> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new metadata key.
|
||||||
|
*
|
||||||
|
* @param type the value type
|
||||||
|
* @param key the name for the key
|
||||||
|
* @param <T> the value type
|
||||||
|
* @return a new key
|
||||||
|
*/
|
||||||
|
static <T> @NonNull Key<T> of(final @NonNull Class<T> type, final @NonNull String key) {
|
||||||
|
if (GenericTypeReflector.isMissingTypeParameters(type)) {
|
||||||
|
throw new IllegalArgumentException("Raw type " + type + " is prohibited");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleKey<>(
|
||||||
|
TypeToken.get(requireNonNull(type, "type")),
|
||||||
|
requireNonNull(key, "key"),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new metadata key.
|
||||||
|
*
|
||||||
|
* @param type the value type
|
||||||
|
* @param key the name for the key
|
||||||
|
* @param <T> the value type
|
||||||
|
* @return a new key
|
||||||
|
*/
|
||||||
|
static <T> @NonNull Key<T> of(final @NonNull TypeToken<T> type, final @NonNull String key) {
|
||||||
|
return new SimpleKey<>(
|
||||||
|
requireNonNull(type, "type"),
|
||||||
|
requireNonNull(key, "key"),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new metadata key.
|
||||||
|
*
|
||||||
|
* @param type the value type
|
||||||
|
* @param key the name for the key
|
||||||
|
* @param fallbackDerivation A function that will be called if no value is present for the key
|
||||||
|
* @param <T> the value type
|
||||||
|
* @return a new key
|
||||||
|
*/
|
||||||
|
static <T> @NonNull Key<T> of(
|
||||||
|
final @NonNull Class<T> type,
|
||||||
|
final @NonNull String key,
|
||||||
|
final @NonNull Function<@NonNull CommandMeta, @Nullable T> fallbackDerivation) {
|
||||||
|
return new SimpleKey<>(
|
||||||
|
TypeToken.get(requireNonNull(type, "type")),
|
||||||
|
requireNonNull(key, "key"),
|
||||||
|
fallbackDerivation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new metadata key.
|
||||||
|
*
|
||||||
|
* @param type the value type
|
||||||
|
* @param key the name for the key
|
||||||
|
* @param fallbackDerivation A function that will be called if no value is present for the key
|
||||||
|
* @param <T> the value type
|
||||||
|
* @return a new key
|
||||||
|
*/
|
||||||
|
static <T> @NonNull Key<T> of(
|
||||||
|
final @NonNull TypeToken<T> type,
|
||||||
|
final @NonNull String key,
|
||||||
|
final @NonNull Function<@NonNull CommandMeta, @Nullable T> fallbackDerivation
|
||||||
|
) {
|
||||||
|
return new SimpleKey<>(
|
||||||
|
requireNonNull(type, "type"),
|
||||||
|
requireNonNull(key, "key"),
|
||||||
|
fallbackDerivation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a representation of the type of value this key holds.
|
||||||
|
*
|
||||||
|
* @return the value type
|
||||||
|
*/
|
||||||
|
@NonNull TypeToken<V> getValueType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of this key
|
||||||
|
*
|
||||||
|
* @return the key type
|
||||||
|
*/
|
||||||
|
@NonNull String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a function that can be used to compute a fallback based on existing meta.
|
||||||
|
*
|
||||||
|
* <p>This function will only be used if no value is directly for the key.</p>
|
||||||
|
*
|
||||||
|
* @return the fallback derivation
|
||||||
|
*/
|
||||||
|
@Nullable Function<@NonNull CommandMeta, @Nullable V> getFallbackDerivation();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
//
|
//
|
||||||
package cloud.commandframework.meta;
|
package cloud.commandframework.meta;
|
||||||
|
|
||||||
|
import io.leangen.geantyref.GenericTypeReflector;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -30,6 +31,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple immutable string-string map containing command meta
|
* A simple immutable string-string map containing command meta
|
||||||
|
|
@ -37,12 +39,22 @@ import java.util.Optional;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class SimpleCommandMeta extends CommandMeta {
|
public class SimpleCommandMeta extends CommandMeta {
|
||||||
|
|
||||||
private final Map<String, String> metaMap;
|
private final Map<String, Object> metaMap;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
protected SimpleCommandMeta(final @NonNull Map<@NonNull String, @NonNull String> metaMap) {
|
protected SimpleCommandMeta(final @NonNull Map<@NonNull String, @NonNull String> metaMap) {
|
||||||
this.metaMap = Collections.unmodifiableMap(metaMap);
|
this.metaMap = Collections.unmodifiableMap(metaMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected SimpleCommandMeta(final SimpleCommandMeta source) {
|
||||||
|
this.metaMap = source.metaMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor needs an extra flag to distinguish it from the old one (for reified generics)
|
||||||
|
SimpleCommandMeta(final @NonNull Map<@NonNull String, @NonNull Object> metaMap, final boolean unusedMarkerForNew) {
|
||||||
|
this.metaMap = Collections.unmodifiableMap(metaMap);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new meta builder
|
* Create a new meta builder
|
||||||
*
|
*
|
||||||
|
|
@ -62,35 +74,78 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public final @NonNull Optional<String> getValue(final @NonNull String key) {
|
public final @NonNull Optional<String> getValue(final @NonNull String key) {
|
||||||
return Optional.ofNullable(this.metaMap.get(key));
|
final Object result = this.metaMap.get(key);
|
||||||
|
if (result != null && !(result instanceof String)) {
|
||||||
|
throw new IllegalArgumentException("Key '" + key + "' has been used for a new typed command meta and contains a "
|
||||||
|
+ "non-string value!");
|
||||||
|
}
|
||||||
|
return Optional.ofNullable((String) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public final @NonNull String getOrDefault(final @NonNull String key, final @NonNull String defaultValue) {
|
public final @NonNull String getOrDefault(final @NonNull String key, final @NonNull String defaultValue) {
|
||||||
return this.getValue(key).orElse(defaultValue);
|
return this.getValue(key).orElse(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final @NonNull <V> Optional<V> get(final @NonNull Key<V> key) {
|
||||||
|
final Object value = this.metaMap.get(key.getName());
|
||||||
|
if (value == null) {
|
||||||
|
// Attempt to use a fallback legacy type
|
||||||
|
if (key.getFallbackDerivation() != null) {
|
||||||
|
return Optional.ofNullable(key.getFallbackDerivation().apply(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (!GenericTypeReflector.isSuperType(key.getValueType().getType(), value.getClass())) {
|
||||||
|
throw new IllegalArgumentException("Conflicting argument types between key type of "
|
||||||
|
+ key.getValueType().getType() + " and value type of " + value.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of((V) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final <V> @NonNull V getOrDefault(final @NonNull Key<V> key, final @NonNull V defaultValue) {
|
||||||
|
return this.get(key).orElse(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
public final @NonNull Map<@NonNull String, @NonNull String> getAll() {
|
public final @NonNull Map<@NonNull String, @NonNull String> getAll() {
|
||||||
|
return this.metaMap.entrySet()
|
||||||
|
.stream().filter(ent -> ent.getValue() instanceof String)
|
||||||
|
.collect(Collectors.<Map.Entry<String, Object>, String, String>toMap(
|
||||||
|
Map.Entry::getKey,
|
||||||
|
ent -> ent.getValue().toString()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final @NonNull Map<@NonNull String, @NonNull ?> getAllValues() {
|
||||||
return new HashMap<>(this.metaMap);
|
return new HashMap<>(this.metaMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean equals(final Object o) {
|
public final boolean equals(final Object other) {
|
||||||
if (this == o) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (o == null || getClass() != o.getClass()) {
|
if (other == null || getClass() != other.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final SimpleCommandMeta that = (SimpleCommandMeta) o;
|
final SimpleCommandMeta that = (SimpleCommandMeta) other;
|
||||||
return Objects.equals(metaMap, that.metaMap);
|
return Objects.equals(this.metaMap, that.metaMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int hashCode() {
|
public final int hashCode() {
|
||||||
return Objects.hashCode(metaMap);
|
return Objects.hashCode(this.metaMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -98,7 +153,7 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
*/
|
*/
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private final Map<String, String> map = new HashMap<>();
|
private final Map<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
private Builder() {
|
private Builder() {
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +165,11 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
* @return Builder instance
|
* @return Builder instance
|
||||||
*/
|
*/
|
||||||
public @NonNull Builder with(final @NonNull CommandMeta commandMeta) {
|
public @NonNull Builder with(final @NonNull CommandMeta commandMeta) {
|
||||||
commandMeta.getAll().forEach(this::with);
|
if (commandMeta instanceof SimpleCommandMeta) {
|
||||||
|
this.map.putAll(((SimpleCommandMeta) commandMeta).metaMap);
|
||||||
|
} else {
|
||||||
|
this.map.putAll(commandMeta.getAllValues());
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +179,9 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
* @param key Key
|
* @param key Key
|
||||||
* @param value Value
|
* @param value Value
|
||||||
* @return Builder instance
|
* @return Builder instance
|
||||||
|
* @deprecated For removal since 1.3.0, use {@link #with(Key, Object) the typesafe alternative} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public @NonNull Builder with(
|
public @NonNull Builder with(
|
||||||
final @NonNull String key,
|
final @NonNull String key,
|
||||||
final @NonNull String value
|
final @NonNull String value
|
||||||
|
|
@ -129,13 +190,30 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a new key-value pair in the meta map
|
||||||
|
*
|
||||||
|
* @param <V> Value type
|
||||||
|
* @param key Key
|
||||||
|
* @param value Value
|
||||||
|
* @return Builder instance
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
public <V> @NonNull Builder with(
|
||||||
|
final @NonNull Key<V> key,
|
||||||
|
final @NonNull V value
|
||||||
|
) {
|
||||||
|
this.map.put(key.getName(), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new meta instance
|
* Construct a new meta instance
|
||||||
*
|
*
|
||||||
* @return Meta instance
|
* @return Meta instance
|
||||||
*/
|
*/
|
||||||
public @NonNull SimpleCommandMeta build() {
|
public @NonNull SimpleCommandMeta build() {
|
||||||
return new SimpleCommandMeta(this.map);
|
return new SimpleCommandMeta(this.map, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
//
|
||||||
|
// 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.meta;
|
||||||
|
|
||||||
|
import io.leangen.geantyref.GenericTypeReflector;
|
||||||
|
import io.leangen.geantyref.TypeToken;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
final class SimpleKey<V> implements CommandMeta.Key<V> {
|
||||||
|
|
||||||
|
private final @NonNull TypeToken<V> valueType;
|
||||||
|
private final @NonNull String name;
|
||||||
|
private final @Nullable Function<@NonNull CommandMeta, @Nullable V> derivationFunction;
|
||||||
|
|
||||||
|
SimpleKey(
|
||||||
|
final @NonNull TypeToken<V> valueType,
|
||||||
|
final @NonNull String name,
|
||||||
|
final @Nullable Function<@NonNull CommandMeta, @Nullable V> derivationFunction
|
||||||
|
) {
|
||||||
|
this.valueType = valueType;
|
||||||
|
this.name = name;
|
||||||
|
this.derivationFunction = derivationFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull TypeToken<V> getValueType() {
|
||||||
|
return this.valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Function<@NonNull CommandMeta, @Nullable V> getFallbackDerivation() {
|
||||||
|
return this.derivationFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other == null || getClass() != other.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final SimpleKey<?> that = (SimpleKey<?>) other;
|
||||||
|
return this.valueType.equals(that.valueType)
|
||||||
|
&& this.name.equals(that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 7 * GenericTypeReflector.hashCode(this.valueType.getAnnotatedType())
|
||||||
|
+ 31 * this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ package cloud.commandframework;
|
||||||
|
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.standard.IntegerArgument;
|
import cloud.commandframework.arguments.standard.IntegerArgument;
|
||||||
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||||
import cloud.commandframework.types.tuples.Pair;
|
import cloud.commandframework.types.tuples.Pair;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
|
@ -43,14 +44,14 @@ class CommandHelpHandlerTest {
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
static void setup() {
|
static void setup() {
|
||||||
manager = new TestCommandManager();
|
manager = new TestCommandManager();
|
||||||
final SimpleCommandMeta meta1 = SimpleCommandMeta.builder().with("description", "Command with only literals").build();
|
final SimpleCommandMeta meta1 = SimpleCommandMeta.builder().with(CommandMeta.DESCRIPTION, "Command with only literals").build();
|
||||||
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("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"), Description.of("A number")).build());
|
||||||
|
|
||||||
manager.command(manager.commandBuilder("vec")
|
manager.command(manager.commandBuilder("vec")
|
||||||
.meta("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), Description.of("Vector")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -119,8 +119,8 @@ public class PircBotXCommandManager<C> extends CommandManager<C> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean hasPermission(
|
public final boolean hasPermission(
|
||||||
@NonNull final C sender,
|
final @NonNull C sender,
|
||||||
@NonNull final String permission
|
final @NonNull String permission
|
||||||
) {
|
) {
|
||||||
return this.permissionFunction.apply(sender, permission);
|
return this.permissionFunction.apply(sender, permission);
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@ public class PircBotXCommandManager<C> extends CommandManager<C> {
|
||||||
return this.commandPrefix;
|
return this.commandPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull final Function<User, C> getUserMapper() {
|
final @NonNull Function<User, C> getUserMapper() {
|
||||||
return this.userMapper;
|
return this.userMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,8 +128,8 @@ public final class UserArgument<C> extends CommandArgument<C, User> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<@NonNull User> parse(
|
public @NonNull ArgumentParseResult<@NonNull User> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String input = inputQueue.peek();
|
final String input = inputQueue.peek();
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import cloud.commandframework.exceptions.InvalidCommandSenderException;
|
||||||
import cloud.commandframework.exceptions.InvalidSyntaxException;
|
import cloud.commandframework.exceptions.InvalidSyntaxException;
|
||||||
import cloud.commandframework.exceptions.NoPermissionException;
|
import cloud.commandframework.exceptions.NoPermissionException;
|
||||||
import cloud.commandframework.exceptions.NoSuchCommandException;
|
import cloud.commandframework.exceptions.NoSuchCommandException;
|
||||||
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
|
@ -63,7 +64,7 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
label,
|
label,
|
||||||
cloudCommand.getCommandMeta().getOrDefault("description", ""),
|
cloudCommand.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, ""),
|
||||||
"",
|
"",
|
||||||
aliases
|
aliases
|
||||||
);
|
);
|
||||||
|
|
@ -163,7 +164,7 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return this.cloudCommand.getCommandMeta().getOrDefault("description", "");
|
return this.cloudCommand.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,7 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
||||||
* @return Meta data
|
* @return Meta data
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public @NonNull BukkitCommandMeta createDefaultCommandMeta() {
|
public @NonNull BukkitCommandMeta createDefaultCommandMeta() {
|
||||||
return BukkitCommandMetaBuilder.builder().withDescription("").build();
|
return BukkitCommandMetaBuilder.builder().withDescription("").build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ package cloud.commandframework.bukkit;
|
||||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bukkit-specific command metadata holder.
|
||||||
|
*
|
||||||
|
* @deprecated for removal since 1.3.0. Use the standard {@link SimpleCommandMeta instead}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public class BukkitCommandMeta extends SimpleCommandMeta {
|
public class BukkitCommandMeta extends SimpleCommandMeta {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,7 +40,7 @@ public class BukkitCommandMeta extends SimpleCommandMeta {
|
||||||
* @param simpleCommandMeta Simple command meta data instance that gets mirrored
|
* @param simpleCommandMeta Simple command meta data instance that gets mirrored
|
||||||
*/
|
*/
|
||||||
public BukkitCommandMeta(final @NonNull SimpleCommandMeta simpleCommandMeta) {
|
public BukkitCommandMeta(final @NonNull SimpleCommandMeta simpleCommandMeta) {
|
||||||
super(simpleCommandMeta.getAll());
|
super(simpleCommandMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,15 @@
|
||||||
package cloud.commandframework.bukkit;
|
package cloud.commandframework.bukkit;
|
||||||
|
|
||||||
import cloud.commandframework.meta.CommandMeta;
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
|
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command meta builder with bukkit-specific parameters.
|
||||||
|
*
|
||||||
|
* @deprecated for removal since 1.3.0, use plain {@link SimpleCommandMeta.Builder} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class BukkitCommandMetaBuilder {
|
public final class BukkitCommandMetaBuilder {
|
||||||
|
|
||||||
private BukkitCommandMetaBuilder() {
|
private BukkitCommandMetaBuilder() {
|
||||||
|
|
@ -73,7 +80,7 @@ public final class BukkitCommandMetaBuilder {
|
||||||
* @return Meta instance
|
* @return Meta instance
|
||||||
*/
|
*/
|
||||||
public @NonNull BukkitCommandMeta build() {
|
public @NonNull BukkitCommandMeta build() {
|
||||||
return new BukkitCommandMeta(CommandMeta.simple().with("description", this.description).build());
|
return new BukkitCommandMeta(CommandMeta.simple().with(CommandMeta.DESCRIPTION, this.description).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,8 @@ public final class PlayerArgument<C> extends CommandArgument<C, ProxiedPlayer> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<@NonNull ProxiedPlayer> parse(
|
public @NonNull ArgumentParseResult<@NonNull ProxiedPlayer> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String input = inputQueue.peek();
|
final String input = inputQueue.peek();
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,8 @@ public final class ServerArgument<C> extends CommandArgument<C, ServerInfo> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<@NonNull ServerInfo> parse(
|
public @NonNull ArgumentParseResult<@NonNull ServerInfo> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String input = inputQueue.peek();
|
final String input = inputQueue.peek();
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import cloud.commandframework.exceptions.InvalidCommandSenderException;
|
||||||
import cloud.commandframework.exceptions.InvalidSyntaxException;
|
import cloud.commandframework.exceptions.InvalidSyntaxException;
|
||||||
import cloud.commandframework.exceptions.NoPermissionException;
|
import cloud.commandframework.exceptions.NoPermissionException;
|
||||||
import cloud.commandframework.exceptions.NoSuchCommandException;
|
import cloud.commandframework.exceptions.NoSuchCommandException;
|
||||||
|
import cloud.commandframework.meta.CommandMeta;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.cloudburstmc.server.command.CommandSender;
|
import org.cloudburstmc.server.command.CommandSender;
|
||||||
import org.cloudburstmc.server.command.PluginCommand;
|
import org.cloudburstmc.server.command.PluginCommand;
|
||||||
|
|
@ -61,7 +62,7 @@ final class CloudburstCommand<C> extends PluginCommand<Plugin> {
|
||||||
super(manager.getOwningPlugin(), CommandData.builder(label)
|
super(manager.getOwningPlugin(), CommandData.builder(label)
|
||||||
.addAliases(aliases.toArray(new String[0]))
|
.addAliases(aliases.toArray(new String[0]))
|
||||||
.addPermission(cloudCommand.getCommandPermission().toString())
|
.addPermission(cloudCommand.getCommandPermission().toString())
|
||||||
.setDescription(cloudCommand.getCommandMeta().getOrDefault("description", ""))
|
.setDescription(cloudCommand.getCommandMeta().getOrDefault(CommandMeta.DESCRIPTION, ""))
|
||||||
.build());
|
.build());
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,8 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<@NonNull Player> parse(
|
public @NonNull ArgumentParseResult<@NonNull Player> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String input = inputQueue.peek();
|
final String input = inputQueue.peek();
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,8 @@ public final class ServerArgument<C> extends CommandArgument<C, RegisteredServer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull ArgumentParseResult<@NonNull RegisteredServer> parse(
|
public @NonNull ArgumentParseResult<@NonNull RegisteredServer> parse(
|
||||||
@NonNull final CommandContext<@NonNull C> commandContext,
|
final @NonNull CommandContext<@NonNull C> commandContext,
|
||||||
@NonNull final Queue<@NonNull String> inputQueue
|
final @NonNull Queue<@NonNull String> inputQueue
|
||||||
) {
|
) {
|
||||||
final String input = inputQueue.peek();
|
final String input = inputQueue.peek();
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ import cloud.commandframework.arguments.standard.EnumArgument;
|
||||||
import cloud.commandframework.arguments.standard.IntegerArgument;
|
import cloud.commandframework.arguments.standard.IntegerArgument;
|
||||||
import cloud.commandframework.arguments.standard.StringArrayArgument;
|
import cloud.commandframework.arguments.standard.StringArrayArgument;
|
||||||
import cloud.commandframework.bukkit.BukkitCommandManager;
|
import cloud.commandframework.bukkit.BukkitCommandManager;
|
||||||
import cloud.commandframework.bukkit.BukkitCommandMetaBuilder;
|
|
||||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||||
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||||
|
|
@ -178,9 +177,9 @@ public final class ExamplePlugin extends JavaPlugin {
|
||||||
// @CommandMethod
|
// @CommandMethod
|
||||||
//
|
//
|
||||||
final Function<ParserParameters, CommandMeta> commandMetaFunction = p ->
|
final Function<ParserParameters, CommandMeta> commandMetaFunction = p ->
|
||||||
BukkitCommandMetaBuilder.builder()
|
CommandMeta.simple()
|
||||||
// This will allow you to decorate commands with descriptions
|
// This will allow you to decorate commands with descriptions
|
||||||
.withDescription(p.get(StandardParameters.DESCRIPTION, "No description"))
|
.with(CommandMeta.DESCRIPTION, p.get(StandardParameters.DESCRIPTION, "No description"))
|
||||||
.build();
|
.build();
|
||||||
this.annotationParser = new AnnotationParser<>(
|
this.annotationParser = new AnnotationParser<>(
|
||||||
/* Manager */ this.manager,
|
/* Manager */ this.manager,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ public final class ExampleBot {
|
||||||
*
|
*
|
||||||
* @param args Arguments to start the bot with (NOT used)
|
* @param args Arguments to start the bot with (NOT used)
|
||||||
*/
|
*/
|
||||||
public static void main(@NonNull final String[] args) {
|
public static void main(final @NonNull String[] args) {
|
||||||
SimplixInstaller
|
SimplixInstaller
|
||||||
.instance()
|
.instance()
|
||||||
.register(ExampleBot.class);
|
.register(ExampleBot.class);
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ public class ExampleApplication {
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public ExampleApplication(
|
public ExampleApplication(
|
||||||
@NonNull final DiscordApiComponent discordApiComponent,
|
final @NonNull DiscordApiComponent discordApiComponent,
|
||||||
@NonNull final CommandsComponent commandsComponent,
|
final @NonNull CommandsComponent commandsComponent,
|
||||||
@NonNull final ScheduledExecutorService executorService
|
final @NonNull ScheduledExecutorService executorService
|
||||||
) throws
|
) throws
|
||||||
Exception {
|
Exception {
|
||||||
this.discordApiComponent = discordApiComponent;
|
this.discordApiComponent = discordApiComponent;
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public class CommandsComponent {
|
||||||
* @param discordApiComponent Instance of the {@link DiscordApiComponent} for registering the command listener
|
* @param discordApiComponent Instance of the {@link DiscordApiComponent} for registering the command listener
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public CommandsComponent(@NonNull final DiscordApiComponent discordApiComponent) {
|
public CommandsComponent(final @NonNull DiscordApiComponent discordApiComponent) {
|
||||||
this.discordApiComponent = discordApiComponent;
|
this.discordApiComponent = discordApiComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public class DiscordApiComponent {
|
||||||
*
|
*
|
||||||
* @param token The Discord Bot token
|
* @param token The Discord Bot token
|
||||||
*/
|
*/
|
||||||
public final void login(@NonNull final String token) {
|
public final void login(final @NonNull String token) {
|
||||||
LOG.info("Logging in to Discord...");
|
LOG.info("Logging in to Discord...");
|
||||||
|
|
||||||
this.api = this.builder.setToken(token).login().join();
|
this.api = this.builder.setToken(token).login().join();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue