✨ Merge pull request #43
* ✨ Add a new caption system to allow for the configuration of… * ✨ Add caption support to all numerical types * Add more standard pasres to the registry * Add default messages for captions * ✨ Improve captions in core * Add captions for Bukkit * ✨ Add FactoryDelegatingCaptionRegistry.java
This commit is contained in:
parent
378d57964f
commit
6ab1c8a2e0
46 changed files with 1482 additions and 200 deletions
|
|
@ -34,6 +34,7 @@ import cloud.commandframework.arguments.parser.ParserParameter;
|
||||||
import cloud.commandframework.arguments.parser.ParserParameters;
|
import cloud.commandframework.arguments.parser.ParserParameters;
|
||||||
import cloud.commandframework.arguments.parser.StandardParameters;
|
import cloud.commandframework.arguments.parser.StandardParameters;
|
||||||
import cloud.commandframework.arguments.preprocessor.RegexPreprocessor;
|
import cloud.commandframework.arguments.preprocessor.RegexPreprocessor;
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||||
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
||||||
|
|
@ -97,7 +98,10 @@ public final class AnnotationParser<C> {
|
||||||
this.flagExtractor = new FlagExtractor(manager);
|
this.flagExtractor = new FlagExtractor(manager);
|
||||||
this.registerAnnotationMapper(CommandDescription.class, d ->
|
this.registerAnnotationMapper(CommandDescription.class, d ->
|
||||||
ParserParameters.single(StandardParameters.DESCRIPTION, d.value()));
|
ParserParameters.single(StandardParameters.DESCRIPTION, d.value()));
|
||||||
this.registerPreprocessorMapper(Regex.class, annotation -> RegexPreprocessor.of(annotation.value()));
|
this.registerPreprocessorMapper(Regex.class, annotation -> RegexPreprocessor.of(
|
||||||
|
annotation.value(),
|
||||||
|
Caption.of(annotation.failureCaption())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,12 @@ public @interface Regex {
|
||||||
*/
|
*/
|
||||||
@NonNull String value();
|
@NonNull String value();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the caption used to generate the failure exception.
|
||||||
|
* Defaults to {@link cloud.commandframework.captions.StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_REGEX}
|
||||||
|
*
|
||||||
|
* @return Failure caption key
|
||||||
|
*/
|
||||||
|
@NonNull String failureCaption() default "argument.parse.failure.regex";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
import cloud.commandframework.arguments.parser.ParserParameter;
|
import cloud.commandframework.arguments.parser.ParserParameter;
|
||||||
import cloud.commandframework.arguments.parser.ParserRegistry;
|
import cloud.commandframework.arguments.parser.ParserRegistry;
|
||||||
import cloud.commandframework.arguments.parser.StandardParserRegistry;
|
import cloud.commandframework.arguments.parser.StandardParserRegistry;
|
||||||
|
import cloud.commandframework.captions.CaptionRegistry;
|
||||||
|
import cloud.commandframework.captions.SimpleCaptionRegistryFactory;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.context.CommandContextFactory;
|
import cloud.commandframework.context.CommandContextFactory;
|
||||||
import cloud.commandframework.context.StandardCommandContextFactory;
|
import cloud.commandframework.context.StandardCommandContextFactory;
|
||||||
|
|
@ -92,6 +94,7 @@ public abstract class CommandManager<C> {
|
||||||
private CommandSyntaxFormatter<C> commandSyntaxFormatter = new StandardCommandSyntaxFormatter<>();
|
private CommandSyntaxFormatter<C> commandSyntaxFormatter = new StandardCommandSyntaxFormatter<>();
|
||||||
private CommandSuggestionProcessor<C> commandSuggestionProcessor = new FilteringCommandSuggestionProcessor<>();
|
private CommandSuggestionProcessor<C> commandSuggestionProcessor = new FilteringCommandSuggestionProcessor<>();
|
||||||
private CommandRegistrationHandler commandRegistrationHandler;
|
private CommandRegistrationHandler commandRegistrationHandler;
|
||||||
|
private CaptionRegistry<C> captionRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command manager instance
|
* Create a new command manager instance
|
||||||
|
|
@ -111,6 +114,7 @@ public abstract class CommandManager<C> {
|
||||||
}, new AcceptingCommandPreprocessor<>());
|
}, new AcceptingCommandPreprocessor<>());
|
||||||
this.servicePipeline.registerServiceType(new TypeToken<CommandPostprocessor<C>>() {
|
this.servicePipeline.registerServiceType(new TypeToken<CommandPostprocessor<C>>() {
|
||||||
}, new AcceptingCommandPostprocessor<>());
|
}, new AcceptingCommandPostprocessor<>());
|
||||||
|
this.captionRegistry = new SimpleCaptionRegistryFactory<C>().create();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -124,7 +128,11 @@ public abstract class CommandManager<C> {
|
||||||
final @NonNull C commandSender,
|
final @NonNull C commandSender,
|
||||||
final @NonNull String input
|
final @NonNull String input
|
||||||
) {
|
) {
|
||||||
final CommandContext<C> context = this.commandContextFactory.create(false, commandSender);
|
final CommandContext<C> context = this.commandContextFactory.create(
|
||||||
|
false,
|
||||||
|
commandSender,
|
||||||
|
this.captionRegistry
|
||||||
|
);
|
||||||
final LinkedList<String> inputQueue = new CommandInputTokenizer(input).tokenize();
|
final LinkedList<String> inputQueue = new CommandInputTokenizer(input).tokenize();
|
||||||
try {
|
try {
|
||||||
if (this.preprocessContext(context, inputQueue) == State.ACCEPTED) {
|
if (this.preprocessContext(context, inputQueue) == State.ACCEPTED) {
|
||||||
|
|
@ -153,7 +161,8 @@ public abstract class CommandManager<C> {
|
||||||
) {
|
) {
|
||||||
final CommandContext<C> context = this.commandContextFactory.create(
|
final CommandContext<C> context = this.commandContextFactory.create(
|
||||||
true,
|
true,
|
||||||
commandSender
|
commandSender,
|
||||||
|
this.captionRegistry
|
||||||
);
|
);
|
||||||
return this.commandSuggestionEngine.getSuggestions(context, input);
|
return this.commandSuggestionEngine.getSuggestions(context, input);
|
||||||
}
|
}
|
||||||
|
|
@ -240,6 +249,33 @@ public abstract class CommandManager<C> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the caption registry
|
||||||
|
*
|
||||||
|
* @return Caption registry
|
||||||
|
*/
|
||||||
|
public final @NonNull CaptionRegistry<C> getCaptionRegistry() {
|
||||||
|
return this.captionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the caption registry
|
||||||
|
*
|
||||||
|
* @param captionRegistry New caption registry
|
||||||
|
*/
|
||||||
|
public final void setCaptionRegistry(final @NonNull CaptionRegistry<C> captionRegistry) {
|
||||||
|
this.captionRegistry = captionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the default caption registry
|
||||||
|
*
|
||||||
|
* @param captionRegistry Caption registry to use
|
||||||
|
*/
|
||||||
|
public final void registerDefaultCaptions(final @NonNull CaptionRegistry<C> captionRegistry) {
|
||||||
|
this.captionRegistry = captionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the command sender has the required permission. If the permission node is
|
* Check if the command sender has the required permission. If the permission node is
|
||||||
* empty, this should return {@code true}
|
* empty, this should return {@code true}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@
|
||||||
package cloud.commandframework.arguments.preprocessor;
|
package cloud.commandframework.arguments.preprocessor;
|
||||||
|
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
|
@ -42,10 +45,27 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
||||||
|
|
||||||
private final String rawPattern;
|
private final String rawPattern;
|
||||||
private final Predicate<@NonNull String> predicate;
|
private final Predicate<@NonNull String> predicate;
|
||||||
|
private final Caption failureCaption;
|
||||||
|
|
||||||
private RegexPreprocessor(final @NonNull String pattern) {
|
private RegexPreprocessor(
|
||||||
|
final @NonNull String pattern,
|
||||||
|
final @NonNull Caption failureCaption
|
||||||
|
) {
|
||||||
this.rawPattern = pattern;
|
this.rawPattern = pattern;
|
||||||
this.predicate = Pattern.compile(pattern).asPredicate();
|
this.predicate = Pattern.compile(pattern).asPredicate();
|
||||||
|
this.failureCaption = failureCaption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new preprocessor using {@link cloud.commandframework.captions.StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_REGEX}
|
||||||
|
* as the failure caption
|
||||||
|
*
|
||||||
|
* @param pattern Regular expression
|
||||||
|
* @param <C> Command sender type
|
||||||
|
* @return Preprocessor instance
|
||||||
|
*/
|
||||||
|
public static <C> @NonNull RegexPreprocessor<C> of(final @NonNull String pattern) {
|
||||||
|
return of(pattern, StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_REGEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,10 +73,14 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
||||||
*
|
*
|
||||||
* @param pattern Regular expression
|
* @param pattern Regular expression
|
||||||
* @param <C> Command sender type
|
* @param <C> Command sender type
|
||||||
|
* @param failureCaption Caption sent when the input is invalid
|
||||||
* @return Preprocessor instance
|
* @return Preprocessor instance
|
||||||
*/
|
*/
|
||||||
public static <C> @NonNull RegexPreprocessor<C> of(final @NonNull String pattern) {
|
public static <C> @NonNull RegexPreprocessor<C> of(
|
||||||
return new RegexPreprocessor<>(pattern);
|
final @NonNull String pattern,
|
||||||
|
final @NonNull Caption failureCaption
|
||||||
|
) {
|
||||||
|
return new RegexPreprocessor<>(pattern, failureCaption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -73,7 +97,9 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
||||||
return ArgumentParseResult.failure(
|
return ArgumentParseResult.failure(
|
||||||
new RegexValidationException(
|
new RegexValidationException(
|
||||||
this.rawPattern,
|
this.rawPattern,
|
||||||
head
|
head,
|
||||||
|
this.failureCaption,
|
||||||
|
context
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -86,21 +112,33 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
||||||
|
|
||||||
private final String pattern;
|
private final String pattern;
|
||||||
private final String failedString;
|
private final String failedString;
|
||||||
|
private final Caption failureCaption;
|
||||||
|
private final CommandContext<?> commandContext;
|
||||||
|
|
||||||
private RegexValidationException(
|
private RegexValidationException(
|
||||||
@NonNull final String pattern,
|
final @NonNull String pattern,
|
||||||
@NonNull final String failedString
|
final @NonNull String failedString,
|
||||||
|
final @NonNull Caption failureCaption,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
) {
|
) {
|
||||||
this.pattern = pattern;
|
this.pattern = pattern;
|
||||||
this.failedString = failedString;
|
this.failedString = failedString;
|
||||||
|
this.failureCaption = failureCaption;
|
||||||
|
this.commandContext = commandContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return String.format(
|
return this.commandContext.formatMessage(
|
||||||
"Input '%s' does not match the required pattern '%s'",
|
this.failureCaption,
|
||||||
failedString,
|
CaptionVariable.of(
|
||||||
pattern
|
"input",
|
||||||
|
this.failedString
|
||||||
|
),
|
||||||
|
CaptionVariable.of(
|
||||||
|
"pattern",
|
||||||
|
this.pattern
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -183,7 +186,7 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
||||||
return ArgumentParseResult.success(false);
|
return ArgumentParseResult.success(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.failure(new BooleanParseException(input, false));
|
return ArgumentParseResult.failure(new BooleanParseException(input, false, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String uppercaseInput = input.toUpperCase();
|
final String uppercaseInput = input.toUpperCase();
|
||||||
|
|
@ -196,7 +199,7 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
||||||
return ArgumentParseResult.success(false);
|
return ArgumentParseResult.success(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.failure(new BooleanParseException(input, true));
|
return ArgumentParseResult.failure(new BooleanParseException(input, true, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -222,7 +225,7 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
||||||
/**
|
/**
|
||||||
* Boolean parse exception
|
* Boolean parse exception
|
||||||
*/
|
*/
|
||||||
public static final class BooleanParseException extends IllegalArgumentException {
|
public static final class BooleanParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
private final boolean liberal;
|
private final boolean liberal;
|
||||||
|
|
@ -230,17 +233,26 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
||||||
/**
|
/**
|
||||||
* Construct a new boolean parse exception
|
* Construct a new boolean parse exception
|
||||||
*
|
*
|
||||||
* @param input String input
|
* @param input Input
|
||||||
* @param liberal Liberal value
|
* @param liberal Whether or not the parser allows truthy and falsy values, or strictly true/false
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public BooleanParseException(
|
public BooleanParseException(
|
||||||
final @NonNull String input,
|
final @NonNull String input,
|
||||||
final boolean liberal
|
final boolean liberal,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
) {
|
) {
|
||||||
|
super(
|
||||||
|
BooleanParser.class,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_BOOLEAN,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.liberal = liberal;
|
this.liberal = liberal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the supplied input
|
* Get the supplied input
|
||||||
*
|
*
|
||||||
|
|
@ -259,11 +271,6 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
||||||
return liberal;
|
return liberal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("Could not parse boolean from '%s'.", input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,15 +198,19 @@ public final class ByteArgument<C> extends CommandArgument<C, Byte> {
|
||||||
new ByteParseException(
|
new ByteParseException(
|
||||||
input,
|
input,
|
||||||
this.min,
|
this.min,
|
||||||
this.max
|
this.max,
|
||||||
|
commandContext
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(
|
return ArgumentParseResult.failure(
|
||||||
new ByteParseException(input, this.min,
|
new ByteParseException(
|
||||||
this.max
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -256,9 +260,21 @@ public final class ByteArgument<C> extends CommandArgument<C, Byte> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public ByteParseException(final @NonNull String input, final byte min, final byte max) {
|
public ByteParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final byte min,
|
||||||
|
final byte max,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
ByteParser.class,
|
||||||
|
context
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -130,7 +133,7 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.length() != 1) {
|
if (input.length() != 1) {
|
||||||
return ArgumentParseResult.failure(new CharParseException(input));
|
return ArgumentParseResult.failure(new CharParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.success(input.charAt(0));
|
return ArgumentParseResult.success(input.charAt(0));
|
||||||
|
|
@ -147,7 +150,7 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
||||||
/**
|
/**
|
||||||
* Char parse exception
|
* Char parse exception
|
||||||
*/
|
*/
|
||||||
public static final class CharParseException extends IllegalArgumentException {
|
public static final class CharParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -155,8 +158,15 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
||||||
* Construct a new Char parse exception
|
* Construct a new Char parse exception
|
||||||
*
|
*
|
||||||
* @param input String input
|
* @param input String input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public CharParseException(final @NonNull String input) {
|
public CharParseException(final @NonNull String input, final @NonNull CommandContext<?> context) {
|
||||||
|
super(
|
||||||
|
CharacterParser.class,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_CHAR,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,11 +179,6 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("'%s' is not a valid character.", input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,22 @@ public final class DoubleArgument<C> extends CommandArgument<C, Double> {
|
||||||
try {
|
try {
|
||||||
final double value = Double.parseDouble(input);
|
final double value = Double.parseDouble(input);
|
||||||
if (value < this.min || value > this.max) {
|
if (value < this.min || value > this.max) {
|
||||||
return ArgumentParseResult.failure(new DoubleParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new DoubleParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(new DoubleParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new DoubleParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,9 +247,21 @@ public final class DoubleArgument<C> extends CommandArgument<C, Double> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param commandContext Command context
|
||||||
*/
|
*/
|
||||||
public DoubleParseException(final @NonNull String input, final double min, final double max) {
|
public DoubleParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final double min,
|
||||||
|
final double max,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
DoubleParser.class,
|
||||||
|
commandContext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -174,7 +177,7 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.failure(new EnumParseException(input, this.enumClass));
|
return ArgumentParseResult.failure(new EnumParseException(input, this.enumClass, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -193,7 +196,7 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class EnumParseException extends IllegalArgumentException {
|
public static final class EnumParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
private final Class<? extends Enum<?>> enumClass;
|
private final Class<? extends Enum<?>> enumClass;
|
||||||
|
|
@ -203,11 +206,20 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
||||||
*
|
*
|
||||||
* @param input Input
|
* @param input Input
|
||||||
* @param enumClass Enum class
|
* @param enumClass Enum class
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public EnumParseException(
|
public EnumParseException(
|
||||||
final @NonNull String input,
|
final @NonNull String input,
|
||||||
final @NonNull Class<? extends Enum<?>> enumClass
|
final @NonNull Class<? extends Enum<?>> enumClass,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
) {
|
) {
|
||||||
|
super(
|
||||||
|
EnumParser.class,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM,
|
||||||
|
CaptionVariable.of("input", input),
|
||||||
|
CaptionVariable.of("acceptableValues", join(enumClass))
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.enumClass = enumClass;
|
this.enumClass = enumClass;
|
||||||
}
|
}
|
||||||
|
|
@ -238,11 +250,6 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
||||||
return this.enumClass;
|
return this.enumClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("'%s' is not one of the following: %s", this.input, join(enumClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,22 @@ public final class FloatArgument<C> extends CommandArgument<C, Float> {
|
||||||
try {
|
try {
|
||||||
final float value = Float.parseFloat(input);
|
final float value = Float.parseFloat(input);
|
||||||
if (value < this.min || value > this.max) {
|
if (value < this.min || value > this.max) {
|
||||||
return ArgumentParseResult.failure(new FloatParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new FloatParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(new FloatParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new FloatParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,9 +247,21 @@ public final class FloatArgument<C> extends CommandArgument<C, Float> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param commandContext Command context
|
||||||
*/
|
*/
|
||||||
public FloatParseException(final @NonNull String input, final float min, final float max) {
|
public FloatParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final float min,
|
||||||
|
final float max,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
FloatParser.class,
|
||||||
|
commandContext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -223,12 +223,22 @@ public final class IntegerArgument<C> extends CommandArgument<C, Integer> {
|
||||||
try {
|
try {
|
||||||
final int value = Integer.parseInt(input);
|
final int value = Integer.parseInt(input);
|
||||||
if (value < this.min || value > this.max) {
|
if (value < this.min || value > this.max) {
|
||||||
return ArgumentParseResult.failure(new IntegerParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new IntegerParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(new IntegerParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new IntegerParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,9 +284,21 @@ public final class IntegerArgument<C> extends CommandArgument<C, Integer> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param commandContext Command context
|
||||||
*/
|
*/
|
||||||
public IntegerParseException(final @NonNull String input, final int min, final int max) {
|
public IntegerParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final int min,
|
||||||
|
final int max,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
IntegerParser.class,
|
||||||
|
commandContext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -188,12 +188,22 @@ public final class LongArgument<C> extends CommandArgument<C, Long> {
|
||||||
try {
|
try {
|
||||||
final long value = Long.parseLong(input);
|
final long value = Long.parseLong(input);
|
||||||
if (value < this.min || value > this.max) {
|
if (value < this.min || value > this.max) {
|
||||||
return ArgumentParseResult.failure(new LongParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new LongParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(new LongParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new LongParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,9 +231,21 @@ public final class LongArgument<C> extends CommandArgument<C, Long> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param commandContext Command context
|
||||||
*/
|
*/
|
||||||
public LongParseException(final @NonNull String input, final long min, final long max) {
|
public LongParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final long min,
|
||||||
|
final long max,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
LongParser.class,
|
||||||
|
commandContext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -194,12 +194,22 @@ public final class ShortArgument<C> extends CommandArgument<C, Short> {
|
||||||
try {
|
try {
|
||||||
final short value = Short.parseShort(input);
|
final short value = Short.parseShort(input);
|
||||||
if (value < this.min || value > this.max) {
|
if (value < this.min || value > this.max) {
|
||||||
return ArgumentParseResult.failure(new ShortParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new ShortParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(value);
|
return ArgumentParseResult.success(value);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ArgumentParseResult.failure(new ShortParseException(input, this.min, this.max));
|
return ArgumentParseResult.failure(new ShortParseException(
|
||||||
|
input,
|
||||||
|
this.min,
|
||||||
|
this.max,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,9 +255,21 @@ public final class ShortArgument<C> extends CommandArgument<C, Short> {
|
||||||
* @param input String input
|
* @param input String input
|
||||||
* @param min Minimum value
|
* @param min Minimum value
|
||||||
* @param max Maximum value
|
* @param max Maximum value
|
||||||
|
* @param commandContext Command context
|
||||||
*/
|
*/
|
||||||
public ShortParseException(final @NonNull String input, final short min, final short max) {
|
public ShortParseException(
|
||||||
super(input, min, max);
|
final @NonNull String input,
|
||||||
|
final short min,
|
||||||
|
final short max,
|
||||||
|
final @NonNull CommandContext<?> commandContext
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
input,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
ShortParser.class,
|
||||||
|
commandContext
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -342,7 +345,7 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stringMode == StringMode.QUOTED && (!started || !finished)) {
|
if (this.stringMode == StringMode.QUOTED && (!started || !finished)) {
|
||||||
return ArgumentParseResult.failure(new StringParseException(sj.toString(), StringMode.GREEDY));
|
return ArgumentParseResult.failure(new StringParseException(sj.toString(), StringMode.GREEDY, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.success(sj.toString());
|
return ArgumentParseResult.success(sj.toString());
|
||||||
|
|
@ -373,7 +376,7 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class StringParseException extends IllegalArgumentException {
|
public static final class StringParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
private final StringMode stringMode;
|
private final StringMode stringMode;
|
||||||
|
|
@ -383,8 +386,20 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
*
|
*
|
||||||
* @param input Input
|
* @param input Input
|
||||||
* @param stringMode String mode
|
* @param stringMode String mode
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public StringParseException(final @NonNull String input, final @NonNull StringMode stringMode) {
|
public StringParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull StringMode stringMode,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
StringParser.class,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_STRING,
|
||||||
|
CaptionVariable.of("input", input),
|
||||||
|
CaptionVariable.of("stringMode", stringMode.name())
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.stringMode = stringMode;
|
this.stringMode = stringMode;
|
||||||
}
|
}
|
||||||
|
|
@ -408,14 +423,6 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
return this.stringMode;
|
return this.stringMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
if (this.stringMode == StringMode.QUOTED) {
|
|
||||||
return "The string needs to be surrounded by quotation marks";
|
|
||||||
}
|
|
||||||
return String.format("'%s' is not a valid string", this.input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -133,7 +136,7 @@ public final class UUIDArgument<C> extends CommandArgument<C, UUID> {
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(uuid);
|
return ArgumentParseResult.success(uuid);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return ArgumentParseResult.failure(new UUIDParseException(input));
|
return ArgumentParseResult.failure(new UUIDParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +148,7 @@ public final class UUIDArgument<C> extends CommandArgument<C, UUID> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class UUIDParseException extends IllegalArgumentException {
|
public static final class UUIDParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -153,14 +156,28 @@ public final class UUIDArgument<C> extends CommandArgument<C, UUID> {
|
||||||
* Construct a new UUID parse exception
|
* Construct a new UUID parse exception
|
||||||
*
|
*
|
||||||
* @param input String input
|
* @param input String input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public UUIDParseException(final @NonNull String input) {
|
public UUIDParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
UUIDParser.class,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String getMessage() {
|
* Get the supplied input
|
||||||
return String.format("Could not parse UUID from '%s'.", input);
|
*
|
||||||
|
* @return String value
|
||||||
|
*/
|
||||||
|
public String getInput() {
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a reference to a caption and does not contain any message itself
|
||||||
|
*/
|
||||||
|
public final class Caption {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
private Caption(final @NonNull String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new caption with a given key
|
||||||
|
*
|
||||||
|
* @param key Caption key
|
||||||
|
* @return Created caption
|
||||||
|
*/
|
||||||
|
public static @NonNull Caption of(final @NonNull String key) {
|
||||||
|
return new Caption(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Caption caption = (Caption) o;
|
||||||
|
return Objects.equals(key, caption.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the caption key
|
||||||
|
*
|
||||||
|
* @return Caption key
|
||||||
|
*/
|
||||||
|
public @NonNull String getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format(
|
||||||
|
"Caption{key='%s'}",
|
||||||
|
this.key
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry that allows for messages to be configurable per-sender
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public interface CaptionRegistry<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a caption for a specific sender
|
||||||
|
*
|
||||||
|
* @param caption Caption key
|
||||||
|
* @param sender Sender
|
||||||
|
* @return Caption
|
||||||
|
*/
|
||||||
|
@NonNull String getCaption(@NonNull Caption caption, @NonNull C sender);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key-value pair used to replace variables in captions
|
||||||
|
*/
|
||||||
|
public final class CaptionVariable {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private CaptionVariable(final @NonNull String key, final @NonNull String value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new caption variable instance
|
||||||
|
*
|
||||||
|
* @param key Key
|
||||||
|
* @param value Replacement
|
||||||
|
* @return Created instance
|
||||||
|
*/
|
||||||
|
public static @NonNull CaptionVariable of(final @NonNull String key, final @NonNull String value) {
|
||||||
|
return new CaptionVariable(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the variable key
|
||||||
|
*
|
||||||
|
* @return Key
|
||||||
|
*/
|
||||||
|
public @NonNull String getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the variable value
|
||||||
|
*
|
||||||
|
* @return Value
|
||||||
|
*/
|
||||||
|
public @NonNull String getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility that replaces variables in captions
|
||||||
|
*/
|
||||||
|
public interface CaptionVariableReplacementHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the variables in a message and return the result
|
||||||
|
*
|
||||||
|
* @param string Message to replace variables in
|
||||||
|
* @param variables Variables
|
||||||
|
* @return Transformed message
|
||||||
|
*/
|
||||||
|
@NonNull String replaceVariables(@NonNull String string, @NonNull CaptionVariable... variables);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caption registry that delegates to factory methods
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public interface FactoryDelegatingCaptionRegistry<C> extends CaptionRegistry<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a message factory
|
||||||
|
*
|
||||||
|
* @param caption Caption key
|
||||||
|
* @param factory Message factory
|
||||||
|
*/
|
||||||
|
void registerMessageFactory(
|
||||||
|
@NonNull Caption caption,
|
||||||
|
@NonNull BiFunction<Caption, C, String> factory
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caption registry that uses bi-functions to produce messages
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public class SimpleCaptionRegistry<C> implements FactoryDelegatingCaptionRegistry<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_BOOLEAN}.
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_BOOLEAN = "Could not parse boolean from '{input}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_NUMBER}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_NUMBER = "'{input}' is not a valid number in the range {min} to {max}";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_CHAR}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_CHAR = "'{input}' is not a valid character";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_ENUM}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_ENUM = "'{input}' is not one of the following: {acceptableValues}";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_STRING}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_STRING = "'{input}' is not a valid string of type {stringMode}";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_UUID}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_UUID = "'{input}' is not a valid UUID";
|
||||||
|
|
||||||
|
private final Map<Caption, BiFunction<Caption, C, String>> messageFactories = new HashMap<>();
|
||||||
|
|
||||||
|
protected SimpleCaptionRegistry() {
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_BOOLEAN,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_BOOLEAN
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_NUMBER,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_NUMBER
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_CHAR,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_CHAR
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_ENUM
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_STRING,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_STRING
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_UUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final @NonNull String getCaption(
|
||||||
|
@NonNull final Caption caption,
|
||||||
|
@NonNull final C sender
|
||||||
|
) {
|
||||||
|
final BiFunction<Caption, C, String> messageFactory = this.messageFactories.get(caption);
|
||||||
|
if (messageFactory == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"There is no caption stored with key '%s'",
|
||||||
|
caption
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return messageFactory.apply(caption, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void registerMessageFactory(
|
||||||
|
final @NonNull Caption caption,
|
||||||
|
final @NonNull BiFunction<Caption, C, String> messageFactory
|
||||||
|
) {
|
||||||
|
this.messageFactories.put(caption, messageFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory creating {@link SimpleCaptionRegistry} instances
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public final class SimpleCaptionRegistryFactory<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new simple caption registry instance
|
||||||
|
*
|
||||||
|
* @return Created instance
|
||||||
|
*/
|
||||||
|
public @NonNull SimpleCaptionRegistry<C> create() {
|
||||||
|
return new SimpleCaptionRegistry<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of {@link CaptionVariableReplacementHandler}
|
||||||
|
*/
|
||||||
|
public final class SimpleCaptionVariableReplacementHandler implements CaptionVariableReplacementHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull String replaceVariables(
|
||||||
|
final @NonNull String string,
|
||||||
|
final @NonNull CaptionVariable... variables
|
||||||
|
) {
|
||||||
|
String replacedString = string;
|
||||||
|
for (final CaptionVariable variable : variables) {
|
||||||
|
replacedString = replacedString.replace(String.format("{%s}", variable.getKey()), variable.getValue());
|
||||||
|
}
|
||||||
|
return replacedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
//
|
||||||
|
// 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.captions;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Caption} instances for messages in cloud-core
|
||||||
|
*/
|
||||||
|
public final class StandardCaptionKeys {
|
||||||
|
|
||||||
|
private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_BOOLEAN = of("argument.parse.failure.boolean");
|
||||||
|
/**
|
||||||
|
* Variables: {input}, {min}, {max}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_NUMBER = of("argument.parse.failure.number");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_CHAR = of("argument.parse.failure.char");
|
||||||
|
/**
|
||||||
|
* Variables: {input}, {stringMode}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_STRING = of("argument.parse.failure.number");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_UUID = of("argument.parse.failure.number");
|
||||||
|
/**
|
||||||
|
* Variables: {input}, {acceptableValues}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_ENUM = of("argument.parse.failure.enum");
|
||||||
|
/**
|
||||||
|
* Variables: {input}, {pattern}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_REGEX = of("argument.parse.failure.regex");
|
||||||
|
|
||||||
|
private StandardCaptionKeys() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull Caption of(final @NonNull String key) {
|
||||||
|
final Caption caption = Caption.of(key);
|
||||||
|
RECOGNIZED_CAPTIONS.add(caption);
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an immutable collection containing all standard caption keys
|
||||||
|
*
|
||||||
|
* @return Immutable collection of keys
|
||||||
|
*/
|
||||||
|
public static @NonNull Collection<@NonNull Caption> getStandardCaptionKeys() {
|
||||||
|
return Collections.unmodifiableCollection(RECOGNIZED_CAPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classes allowing for the configuration of messages. Mainly used in parser
|
||||||
|
* exception messages
|
||||||
|
*/
|
||||||
|
package cloud.commandframework.captions;
|
||||||
|
|
@ -25,6 +25,11 @@ package cloud.commandframework.context;
|
||||||
|
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.flags.FlagContext;
|
import cloud.commandframework.arguments.flags.FlagContext;
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import cloud.commandframework.captions.CaptionRegistry;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.CaptionVariableReplacementHandler;
|
||||||
|
import cloud.commandframework.captions.SimpleCaptionVariableReplacementHandler;
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -41,19 +46,23 @@ import java.util.Optional;
|
||||||
*/
|
*/
|
||||||
public final class CommandContext<C> {
|
public final class CommandContext<C> {
|
||||||
|
|
||||||
|
private final CaptionVariableReplacementHandler captionVariableReplacementHandler =
|
||||||
|
new SimpleCaptionVariableReplacementHandler();
|
||||||
private final Map<CommandArgument<C, ?>, ArgumentTiming> argumentTimings = new HashMap<>();
|
private final Map<CommandArgument<C, ?>, ArgumentTiming> argumentTimings = new HashMap<>();
|
||||||
private final FlagContext flagContext = FlagContext.create();
|
private final FlagContext flagContext = FlagContext.create();
|
||||||
private final Map<String, Object> internalStorage = new HashMap<>();
|
private final Map<String, Object> internalStorage = new HashMap<>();
|
||||||
private final C commandSender;
|
private final C commandSender;
|
||||||
private final boolean suggestions;
|
private final boolean suggestions;
|
||||||
|
private final CaptionRegistry<C> captionRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command context instance
|
* Create a new command context instance
|
||||||
*
|
*
|
||||||
* @param commandSender Sender of the command
|
* @param commandSender Sender of the command
|
||||||
|
* @param captionRegistry Caption registry
|
||||||
*/
|
*/
|
||||||
public CommandContext(final @NonNull C commandSender) {
|
public CommandContext(final @NonNull C commandSender, final @NonNull CaptionRegistry<C> captionRegistry) {
|
||||||
this(false, commandSender);
|
this(false, commandSender, captionRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,13 +70,33 @@ public final class CommandContext<C> {
|
||||||
*
|
*
|
||||||
* @param suggestions Whether or not the context is created for command suggestions
|
* @param suggestions Whether or not the context is created for command suggestions
|
||||||
* @param commandSender Sender of the command
|
* @param commandSender Sender of the command
|
||||||
|
* @param captionRegistry Caption registry
|
||||||
*/
|
*/
|
||||||
public CommandContext(
|
public CommandContext(
|
||||||
final boolean suggestions,
|
final boolean suggestions,
|
||||||
final @NonNull C commandSender
|
final @NonNull C commandSender,
|
||||||
|
final @NonNull CaptionRegistry<C> captionRegistry
|
||||||
) {
|
) {
|
||||||
this.commandSender = commandSender;
|
this.commandSender = commandSender;
|
||||||
this.suggestions = suggestions;
|
this.suggestions = suggestions;
|
||||||
|
this.captionRegistry = captionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a caption
|
||||||
|
*
|
||||||
|
* @param caption Caption key
|
||||||
|
* @param variables Replacements
|
||||||
|
* @return Formatted message
|
||||||
|
*/
|
||||||
|
public @NonNull String formatMessage(
|
||||||
|
final @NonNull Caption caption,
|
||||||
|
final @NonNull CaptionVariable... variables
|
||||||
|
) {
|
||||||
|
return this.captionVariableReplacementHandler.replaceVariables(
|
||||||
|
this.captionRegistry.getCaption(caption, this.commandSender),
|
||||||
|
variables
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
//
|
//
|
||||||
package cloud.commandframework.context;
|
package cloud.commandframework.context;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.CaptionRegistry;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,8 +38,13 @@ public interface CommandContextFactory<C> {
|
||||||
*
|
*
|
||||||
* @param suggestions Whether or not the sender is requesting suggestions
|
* @param suggestions Whether or not the sender is requesting suggestions
|
||||||
* @param sender Command sender
|
* @param sender Command sender
|
||||||
|
* @param captionRegistry Caption registry
|
||||||
* @return Command context
|
* @return Command context
|
||||||
*/
|
*/
|
||||||
@NonNull CommandContext<C> create(boolean suggestions, @NonNull C sender);
|
@NonNull CommandContext<C> create(
|
||||||
|
boolean suggestions,
|
||||||
|
@NonNull C sender,
|
||||||
|
@NonNull CaptionRegistry<C> captionRegistry
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
//
|
//
|
||||||
package cloud.commandframework.context;
|
package cloud.commandframework.context;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.CaptionRegistry;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public final class StandardCommandContextFactory<C> implements CommandContextFactory<C> {
|
public final class StandardCommandContextFactory<C> implements CommandContextFactory<C> {
|
||||||
|
|
@ -32,11 +33,20 @@ public final class StandardCommandContextFactory<C> implements CommandContextFac
|
||||||
*
|
*
|
||||||
* @param suggestions Whether or not the sender is requesting suggestions
|
* @param suggestions Whether or not the sender is requesting suggestions
|
||||||
* @param sender Command sender
|
* @param sender Command sender
|
||||||
|
* @param captionRegistry Caption registry
|
||||||
* @return Created context
|
* @return Created context
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CommandContext<C> create(final boolean suggestions, final @NonNull C sender) {
|
public CommandContext<C> create(
|
||||||
return new CommandContext<>(suggestions, sender);
|
final boolean suggestions,
|
||||||
|
final @NonNull C sender,
|
||||||
|
final @NonNull CaptionRegistry<C> captionRegistry
|
||||||
|
) {
|
||||||
|
return new CommandContext<>(
|
||||||
|
suggestions,
|
||||||
|
sender,
|
||||||
|
captionRegistry
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,12 @@
|
||||||
//
|
//
|
||||||
package cloud.commandframework.exceptions.parsing;
|
package cloud.commandframework.exceptions.parsing;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
|
import cloud.commandframework.context.CommandContext;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
public abstract class NumberParseException extends IllegalArgumentException {
|
public abstract class NumberParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
private final Number min;
|
private final Number min;
|
||||||
|
|
@ -37,31 +40,29 @@ public abstract class NumberParseException extends IllegalArgumentException {
|
||||||
* @param input Input
|
* @param input Input
|
||||||
* @param min Maximum value
|
* @param min Maximum value
|
||||||
* @param max Minimum value
|
* @param max Minimum value
|
||||||
|
* @param parserClass Parser class
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public NumberParseException(
|
public NumberParseException(
|
||||||
final @NonNull String input,
|
final @NonNull String input,
|
||||||
final @NonNull Number min,
|
final @NonNull Number min,
|
||||||
final @NonNull Number max
|
final @NonNull Number max,
|
||||||
|
final @NonNull Class<?> parserClass,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
) {
|
) {
|
||||||
|
super(
|
||||||
|
parserClass,
|
||||||
|
context,
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_NUMBER,
|
||||||
|
CaptionVariable.of("input", input),
|
||||||
|
CaptionVariable.of("min", String.valueOf(min)),
|
||||||
|
CaptionVariable.of("max", String.valueOf(max))
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.min = min;
|
this.min = min;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final String getMessage() {
|
|
||||||
if (this.hasMin() && this.hasMax()) {
|
|
||||||
return "'" + this.input + "' is not a valid " + this.getNumberType() + " in the range ["
|
|
||||||
+ this.min + ", " + this.max + "]";
|
|
||||||
} else if (this.hasMin()) {
|
|
||||||
return "'" + this.input + "' is not a valid " + this.getNumberType() + " above " + this.min;
|
|
||||||
} else if (this.hasMax()) {
|
|
||||||
return "'" + this.input + "' is not a valid " + this.getNumberType() + " below " + this.max;
|
|
||||||
} else {
|
|
||||||
return String.format("'%s' is not a valid %s", this.input, this.getNumberType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number type
|
* Get the number type
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// 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.exceptions.parsing;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
public class ParserException extends IllegalArgumentException {
|
||||||
|
|
||||||
|
private final Class<?> argumentParser;
|
||||||
|
private final CommandContext<?> context;
|
||||||
|
private final Caption errorCaption;
|
||||||
|
private final CaptionVariable[] captionVariables;
|
||||||
|
|
||||||
|
protected ParserException(
|
||||||
|
final Class<?> argumentParser,
|
||||||
|
final @NonNull CommandContext<?> context,
|
||||||
|
final @NonNull Caption errorCaption,
|
||||||
|
final @NonNull CaptionVariable... captionVariables
|
||||||
|
) {
|
||||||
|
this.argumentParser = argumentParser;
|
||||||
|
this.context = context;
|
||||||
|
this.errorCaption = errorCaption;
|
||||||
|
this.captionVariables = captionVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getMessage() {
|
||||||
|
return this.context.formatMessage(
|
||||||
|
this.errorCaption,
|
||||||
|
this.captionVariables
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the argument parser
|
||||||
|
*
|
||||||
|
* @return Argument parser
|
||||||
|
*/
|
||||||
|
public final @NonNull Class<?> getArgumentParserClass() {
|
||||||
|
return this.argumentParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the command context
|
||||||
|
*
|
||||||
|
* @return Command context
|
||||||
|
*/
|
||||||
|
public final @NonNull CommandContext<?> getContext() {
|
||||||
|
return this.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -150,7 +150,9 @@ class CommandTreeTest {
|
||||||
final Pair<Command<TestCommandSender>, Exception> command = manager.getCommandTree()
|
final Pair<Command<TestCommandSender>, Exception> command = manager.getCommandTree()
|
||||||
.parse(
|
.parse(
|
||||||
new CommandContext<>(
|
new CommandContext<>(
|
||||||
new TestCommandSender()),
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
),
|
||||||
new LinkedList<>(
|
new LinkedList<>(
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
"test",
|
"test",
|
||||||
|
|
@ -161,31 +163,60 @@ class CommandTreeTest {
|
||||||
Assertions.assertEquals(NoPermissionException.class, manager.getCommandTree()
|
Assertions.assertEquals(NoPermissionException.class, manager.getCommandTree()
|
||||||
.parse(
|
.parse(
|
||||||
new CommandContext<>(
|
new CommandContext<>(
|
||||||
new TestCommandSender()),
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
),
|
||||||
new LinkedList<>(
|
new LinkedList<>(
|
||||||
Arrays.asList("test", "two"))
|
Arrays.asList("test", "two"))
|
||||||
)
|
)
|
||||||
.getSecond().getClass());
|
.getSecond().getClass());
|
||||||
manager.getCommandTree()
|
manager.getCommandTree()
|
||||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
|
.parse(
|
||||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||||
|
new LinkedList<>(Arrays.asList("test", "opt"))
|
||||||
|
)
|
||||||
|
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||||
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
));
|
||||||
manager.getCommandTree()
|
manager.getCommandTree()
|
||||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
|
.parse(
|
||||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||||
|
new LinkedList<>(Arrays.asList("test", "opt", "12"))
|
||||||
|
)
|
||||||
|
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||||
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAlias() {
|
void testAlias() {
|
||||||
manager.getCommandTree()
|
manager.getCommandTree()
|
||||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("other", "öpt", "12")))
|
.parse(
|
||||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
new CommandContext<>(
|
||||||
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
),
|
||||||
|
new LinkedList<>(Arrays.asList(
|
||||||
|
"other",
|
||||||
|
"öpt",
|
||||||
|
"12"
|
||||||
|
))
|
||||||
|
)
|
||||||
|
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||||
|
new TestCommandSender(),
|
||||||
|
manager.getCaptionRegistry()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getSuggestions() {
|
void getSuggestions() {
|
||||||
Assertions.assertFalse(
|
Assertions.assertFalse(
|
||||||
manager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
|
manager.getCommandTree().getSuggestions(
|
||||||
Collections.singletonList("test "))).isEmpty());
|
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||||
|
new LinkedList<>(Collections.singletonList("test "))
|
||||||
|
).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
//
|
||||||
|
// 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.bukkit;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Caption} instances for messages in cloud-bukkit
|
||||||
|
*/
|
||||||
|
public final class BukkitCaptionKeys {
|
||||||
|
private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_ENCHANTMENT = of("argument.parse.failure.enchantment");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_MATERIAL = of("argument.parse.failure.material");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER = of("argument.parse.failure.offlineplayer");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_PLAYER = of("argument.parse.failure.player");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_WORLD = of("argument.parse.failure.world");
|
||||||
|
|
||||||
|
private BukkitCaptionKeys() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull Caption of(final @NonNull String key) {
|
||||||
|
final Caption caption = Caption.of(key);
|
||||||
|
RECOGNIZED_CAPTIONS.add(caption);
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an immutable collection containing all standard caption keys
|
||||||
|
*
|
||||||
|
* @return Immutable collection of keys
|
||||||
|
*/
|
||||||
|
public static @NonNull Collection<@NonNull Caption> getBukkitCaptionKeys() {
|
||||||
|
return Collections.unmodifiableCollection(RECOGNIZED_CAPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.bukkit;
|
||||||
|
|
||||||
|
import cloud.commandframework.captions.SimpleCaptionRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caption registry that uses bi-functions to produce messages
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public class BukkitCaptionRegistry<C> extends SimpleCaptionRegistry<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_ENCHANTMENT = "'{input}' is not a valid enchantment";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_MATERIAL = "'{input}' is not a valid material name";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER = "No player found for input '{input}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_PLAYER = "No player found for input '{input}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_ENCHANTMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_WORLD = "'{input}' is not a valid Minecraft world";
|
||||||
|
|
||||||
|
protected BukkitCaptionRegistry() {
|
||||||
|
super();
|
||||||
|
this.registerMessageFactory(
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_ENCHANTMENT,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_ENCHANTMENT
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_MATERIAL,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_MATERIAL
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_PLAYER
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_WORLD,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_WORLD
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// 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.bukkit;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory creating {@link BukkitCaptionRegistry} instances
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public final class BukkitCaptionRegistryFactory<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new bukkit caption registry instance
|
||||||
|
*
|
||||||
|
* @return Created instance
|
||||||
|
*/
|
||||||
|
public @NonNull BukkitCaptionRegistry<C> create() {
|
||||||
|
return new BukkitCaptionRegistry<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -162,6 +162,8 @@ public class BukkitCommandManager<C> extends CommandManager<C> {
|
||||||
new CommandSuggestionsListener<>(this),
|
new CommandSuggestionsListener<>(this),
|
||||||
this.owningPlugin
|
this.owningPlugin
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.registerDefaultCaptions(new BukkitCaptionRegistryFactory<C>().create());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,10 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||||
this.commandManager = commandManager;
|
this.commandManager = commandManager;
|
||||||
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
||||||
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () ->
|
this.brigadierManager = new CloudBrigadierManager<>(commandManager, () ->
|
||||||
new CommandContext<>(commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender())));
|
new CommandContext<>(
|
||||||
|
commandManager.getCommandSenderMapper().apply(Bukkit.getConsoleSender()),
|
||||||
|
commandManager.getCaptionRegistry()
|
||||||
|
));
|
||||||
new BukkitBrigadierMapper<>(this.commandManager, this.brigadierManager);
|
new BukkitBrigadierMapper<>(this.commandManager, this.brigadierManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
@ -143,7 +146,7 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
||||||
|
|
||||||
final Enchantment enchantment = Enchantment.getByKey(key);
|
final Enchantment enchantment = Enchantment.getByKey(key);
|
||||||
if (enchantment == null) {
|
if (enchantment == null) {
|
||||||
return ArgumentParseResult.failure(new EnchantmentParseException(input));
|
return ArgumentParseResult.failure(new EnchantmentParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(enchantment);
|
return ArgumentParseResult.success(enchantment);
|
||||||
|
|
@ -168,7 +171,7 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class EnchantmentParseException extends IllegalArgumentException {
|
public static final class EnchantmentParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -176,8 +179,18 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
||||||
* Construct a new EnchantmentParseException
|
* Construct a new EnchantmentParseException
|
||||||
*
|
*
|
||||||
* @param input Input
|
* @param input Input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public EnchantmentParseException(final @NonNull String input) {
|
public EnchantmentParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
EnchantmentParser.class,
|
||||||
|
context,
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_ENCHANTMENT,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,11 +203,6 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
||||||
return this.input;
|
return this.input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("'%s' is not a valid enchantment", this.input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
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;
|
||||||
|
|
@ -136,7 +139,7 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(material);
|
return ArgumentParseResult.success(material);
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
return ArgumentParseResult.failure(new MaterialParseException(input));
|
return ArgumentParseResult.failure(new MaterialParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +158,7 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class MaterialParseException extends IllegalArgumentException {
|
public static final class MaterialParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -163,8 +166,18 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
||||||
* Construct a new MaterialParseException
|
* Construct a new MaterialParseException
|
||||||
*
|
*
|
||||||
* @param input Input
|
* @param input Input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public MaterialParseException(final @NonNull String input) {
|
public MaterialParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
MaterialParser.class,
|
||||||
|
context,
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_MATERIAL,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,11 +190,6 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
||||||
return this.input;
|
return this.input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("'%s' is not a valid material name", this.input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
@ -146,7 +149,7 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
||||||
OfflinePlayer player = Bukkit.getOfflinePlayer(input);
|
OfflinePlayer player = Bukkit.getOfflinePlayer(input);
|
||||||
|
|
||||||
if (player == null || (!player.hasPlayedBefore() && !player.isOnline())) {
|
if (player == null || (!player.hasPlayedBefore() && !player.isOnline())) {
|
||||||
return ArgumentParseResult.failure(new OfflinePlayerParseException(input));
|
return ArgumentParseResult.failure(new OfflinePlayerParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.success(player);
|
return ArgumentParseResult.success(player);
|
||||||
|
|
@ -172,7 +175,7 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
||||||
/**
|
/**
|
||||||
* OfflinePlayer parse exception
|
* OfflinePlayer parse exception
|
||||||
*/
|
*/
|
||||||
public static final class OfflinePlayerParseException extends IllegalArgumentException {
|
public static final class OfflinePlayerParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -180,8 +183,18 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
||||||
* Construct a new OfflinePlayer parse exception
|
* Construct a new OfflinePlayer parse exception
|
||||||
*
|
*
|
||||||
* @param input String input
|
* @param input String input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public OfflinePlayerParseException(final @NonNull String input) {
|
public OfflinePlayerParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
OfflinePlayerParser.class,
|
||||||
|
context,
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_OFFLINEPLAYER,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,11 +207,6 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("No player found for input '%s'.", input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
@ -140,7 +143,7 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
Player player = Bukkit.getPlayer(input);
|
Player player = Bukkit.getPlayer(input);
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return ArgumentParseResult.failure(new PlayerParseException(input));
|
return ArgumentParseResult.failure(new PlayerParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ArgumentParseResult.success(player);
|
return ArgumentParseResult.success(player);
|
||||||
|
|
@ -166,7 +169,7 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
/**
|
/**
|
||||||
* Player parse exception
|
* Player parse exception
|
||||||
*/
|
*/
|
||||||
public static final class PlayerParseException extends IllegalArgumentException {
|
public static final class PlayerParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -174,8 +177,18 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
* Construct a new Player parse exception
|
* Construct a new Player parse exception
|
||||||
*
|
*
|
||||||
* @param input String input
|
* @param input String input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public PlayerParseException(final @NonNull String input) {
|
public PlayerParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
PlayerParser.class,
|
||||||
|
context,
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,11 +201,6 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("No player found for input '%s'.", input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
||||||
import cloud.commandframework.arguments.CommandArgument;
|
import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
@ -130,7 +133,7 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
|
||||||
|
|
||||||
final World world = Bukkit.getWorld(input);
|
final World world = Bukkit.getWorld(input);
|
||||||
if (world == null) {
|
if (world == null) {
|
||||||
return ArgumentParseResult.failure(new WorldParseException(input));
|
return ArgumentParseResult.failure(new WorldParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
|
|
@ -145,7 +148,7 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class WorldParseException extends IllegalArgumentException {
|
public static final class WorldParseException extends ParserException {
|
||||||
|
|
||||||
private final String input;
|
private final String input;
|
||||||
|
|
||||||
|
|
@ -153,8 +156,18 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
|
||||||
* Construct a new WorldParseException
|
* Construct a new WorldParseException
|
||||||
*
|
*
|
||||||
* @param input Input
|
* @param input Input
|
||||||
|
* @param context Command context
|
||||||
*/
|
*/
|
||||||
public WorldParseException(final @NonNull String input) {
|
public WorldParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
WorldParser.class,
|
||||||
|
context,
|
||||||
|
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_WORLD,
|
||||||
|
CaptionVariable.of("input", input)
|
||||||
|
);
|
||||||
this.input = input;
|
this.input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +180,6 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
|
||||||
return this.input;
|
return this.input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return String.format("'%s' is not a valid Minecraft world", this.input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ public final class MultiplePlayerSelectorArgument<C> extends CommandArgument<C,
|
||||||
Player player = Bukkit.getPlayer(input);
|
Player player = Bukkit.getPlayer(input);
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input));
|
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
return ArgumentParseResult.success(new MultiplePlayerSelector(input, ImmutableList.of(player)));
|
return ArgumentParseResult.success(new MultiplePlayerSelector(input, ImmutableList.of(player)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
|
||||||
Player player = Bukkit.getPlayer(input);
|
Player player = Bukkit.getPlayer(input);
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input));
|
return ArgumentParseResult.failure(new PlayerArgument.PlayerParseException(input, commandContext));
|
||||||
}
|
}
|
||||||
return ArgumentParseResult.success(new SinglePlayerSelector(input, ImmutableList.of(player)));
|
return ArgumentParseResult.success(new SinglePlayerSelector(input, ImmutableList.of(player)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ class PaperBrigadierListener<C> implements Listener {
|
||||||
this.paperCommandManager,
|
this.paperCommandManager,
|
||||||
() -> new CommandContext<>(
|
() -> new CommandContext<>(
|
||||||
this.paperCommandManager.getCommandSenderMapper()
|
this.paperCommandManager.getCommandSenderMapper()
|
||||||
.apply(Bukkit.getConsoleSender()))
|
.apply(Bukkit.getConsoleSender()),
|
||||||
|
this.paperCommandManager.getCaptionRegistry()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
new BukkitBrigadierMapper<>(this.paperCommandManager, this.brigadierManager);
|
new BukkitBrigadierMapper<>(this.paperCommandManager, this.brigadierManager);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@ final class VelocityPluginRegistrationHandler<C> implements CommandRegistrationH
|
||||||
() -> new CommandContext<>(
|
() -> new CommandContext<>(
|
||||||
velocityCommandManager.getCommandSenderMapper()
|
velocityCommandManager.getCommandSenderMapper()
|
||||||
.apply(velocityCommandManager.getProxyServer()
|
.apply(velocityCommandManager.getProxyServer()
|
||||||
.getConsoleCommandSource()))
|
.getConsoleCommandSource()),
|
||||||
|
velocityCommandManager.getCaptionRegistry()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.MaterialArgument;
|
import cloud.commandframework.bukkit.parsers.MaterialArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.WorldArgument;
|
import cloud.commandframework.bukkit.parsers.WorldArgument;
|
||||||
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import cloud.commandframework.captions.SimpleCaptionRegistry;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
|
||||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||||
|
|
@ -409,6 +411,15 @@ public final class ExamplePlugin extends JavaPlugin {
|
||||||
context.getSender().sendMessage("You wrote: " + StringUtils.join(args, " "));
|
context.getSender().sendMessage("You wrote: " + StringUtils.join(args, " "));
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Register a custom regex caption */
|
||||||
|
final Caption moneyCaption = Caption.of("regex.money");
|
||||||
|
if (manager.getCaptionRegistry() instanceof SimpleCaptionRegistry) {
|
||||||
|
((SimpleCaptionRegistry<CommandSender>) manager.getCaptionRegistry()).registerMessageFactory(
|
||||||
|
moneyCaption,
|
||||||
|
(sender, key) -> "'{input}' is not very cash money of you"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandMethod("example help [query]")
|
@CommandMethod("example help [query]")
|
||||||
|
|
@ -466,7 +477,8 @@ public final class ExamplePlugin extends JavaPlugin {
|
||||||
@CommandDescription("Command to test the preprocessing system")
|
@CommandDescription("Command to test the preprocessing system")
|
||||||
private void commandPay(
|
private void commandPay(
|
||||||
final @NonNull CommandSender sender,
|
final @NonNull CommandSender sender,
|
||||||
final @Argument("money") @Regex("(?=.*?\\d)^\\$?(([1-9]\\d{0,2}(,\\d{3})*)|\\d+)?(\\.\\d{1,2})?$") String money
|
final @Argument("money") @Regex(value = "(?=.*?\\d)^\\$?(([1-9]\\d{0,2}(,\\d{3})*)|\\d+)?(\\.\\d{1,2})?$",
|
||||||
|
failureCaption = "regex.money") String money
|
||||||
) {
|
) {
|
||||||
bukkitAudiences.sender(sender).sendMessage(
|
bukkitAudiences.sender(sender).sendMessage(
|
||||||
Component.text().append(Component.text("You have been given ", NamedTextColor.AQUA))
|
Component.text().append(Component.text("You have been given ", NamedTextColor.AQUA))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue