✨ 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.StandardParameters;
|
||||
import cloud.commandframework.arguments.preprocessor.RegexPreprocessor;
|
||||
import cloud.commandframework.captions.Caption;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
||||
|
|
@ -97,7 +98,10 @@ public final class AnnotationParser<C> {
|
|||
this.flagExtractor = new FlagExtractor(manager);
|
||||
this.registerAnnotationMapper(CommandDescription.class, d ->
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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.ParserRegistry;
|
||||
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.CommandContextFactory;
|
||||
import cloud.commandframework.context.StandardCommandContextFactory;
|
||||
|
|
@ -92,6 +94,7 @@ public abstract class CommandManager<C> {
|
|||
private CommandSyntaxFormatter<C> commandSyntaxFormatter = new StandardCommandSyntaxFormatter<>();
|
||||
private CommandSuggestionProcessor<C> commandSuggestionProcessor = new FilteringCommandSuggestionProcessor<>();
|
||||
private CommandRegistrationHandler commandRegistrationHandler;
|
||||
private CaptionRegistry<C> captionRegistry;
|
||||
|
||||
/**
|
||||
* Create a new command manager instance
|
||||
|
|
@ -111,6 +114,7 @@ public abstract class CommandManager<C> {
|
|||
}, new AcceptingCommandPreprocessor<>());
|
||||
this.servicePipeline.registerServiceType(new TypeToken<CommandPostprocessor<C>>() {
|
||||
}, new AcceptingCommandPostprocessor<>());
|
||||
this.captionRegistry = new SimpleCaptionRegistryFactory<C>().create();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,7 +128,11 @@ public abstract class CommandManager<C> {
|
|||
final @NonNull C commandSender,
|
||||
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();
|
||||
try {
|
||||
if (this.preprocessContext(context, inputQueue) == State.ACCEPTED) {
|
||||
|
|
@ -153,7 +161,8 @@ public abstract class CommandManager<C> {
|
|||
) {
|
||||
final CommandContext<C> context = this.commandContextFactory.create(
|
||||
true,
|
||||
commandSender
|
||||
commandSender,
|
||||
this.captionRegistry
|
||||
);
|
||||
return this.commandSuggestionEngine.getSuggestions(context, input);
|
||||
}
|
||||
|
|
@ -240,6 +249,33 @@ public abstract class CommandManager<C> {
|
|||
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
|
||||
* empty, this should return {@code true}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
package cloud.commandframework.arguments.preprocessor;
|
||||
|
||||
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 org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
|
|
@ -42,21 +45,42 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
|||
|
||||
private final String rawPattern;
|
||||
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.predicate = Pattern.compile(pattern).asPredicate();
|
||||
this.failureCaption = failureCaption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new preprocessor
|
||||
* 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 new RegexPreprocessor<>(pattern);
|
||||
return of(pattern, StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new preprocessor
|
||||
*
|
||||
* @param pattern Regular expression
|
||||
* @param <C> Command sender type
|
||||
* @param failureCaption Caption sent when the input is invalid
|
||||
* @return Preprocessor instance
|
||||
*/
|
||||
public static <C> @NonNull RegexPreprocessor<C> of(
|
||||
final @NonNull String pattern,
|
||||
final @NonNull Caption failureCaption
|
||||
) {
|
||||
return new RegexPreprocessor<>(pattern, failureCaption);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -73,7 +97,9 @@ public final class RegexPreprocessor<C> implements BiFunction<@NonNull CommandCo
|
|||
return ArgumentParseResult.failure(
|
||||
new RegexValidationException(
|
||||
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 failedString;
|
||||
private final Caption failureCaption;
|
||||
private final CommandContext<?> commandContext;
|
||||
|
||||
private RegexValidationException(
|
||||
@NonNull final String pattern,
|
||||
@NonNull final String failedString
|
||||
final @NonNull String pattern,
|
||||
final @NonNull String failedString,
|
||||
final @NonNull Caption failureCaption,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
this.pattern = pattern;
|
||||
this.failedString = failedString;
|
||||
this.failureCaption = failureCaption;
|
||||
this.commandContext = commandContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format(
|
||||
"Input '%s' does not match the required pattern '%s'",
|
||||
failedString,
|
||||
pattern
|
||||
return this.commandContext.formatMessage(
|
||||
this.failureCaption,
|
||||
CaptionVariable.of(
|
||||
"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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
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.failure(new BooleanParseException(input, false));
|
||||
return ArgumentParseResult.failure(new BooleanParseException(input, false, commandContext));
|
||||
}
|
||||
|
||||
final String uppercaseInput = input.toUpperCase();
|
||||
|
|
@ -196,7 +199,7 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
|||
return ArgumentParseResult.success(false);
|
||||
}
|
||||
|
||||
return ArgumentParseResult.failure(new BooleanParseException(input, true));
|
||||
return ArgumentParseResult.failure(new BooleanParseException(input, true, commandContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -222,7 +225,7 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
|||
/**
|
||||
* Boolean parse exception
|
||||
*/
|
||||
public static final class BooleanParseException extends IllegalArgumentException {
|
||||
public static final class BooleanParseException extends ParserException {
|
||||
|
||||
private final String input;
|
||||
private final boolean liberal;
|
||||
|
|
@ -230,17 +233,26 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
|||
/**
|
||||
* Construct a new boolean parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param liberal Liberal value
|
||||
* @param input Input
|
||||
* @param liberal Whether or not the parser allows truthy and falsy values, or strictly true/false
|
||||
* @param context Command context
|
||||
*/
|
||||
public BooleanParseException(
|
||||
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.liberal = liberal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the supplied input
|
||||
*
|
||||
|
|
@ -259,11 +271,6 @@ public final class BooleanArgument<C> extends CommandArgument<C, Boolean> {
|
|||
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(
|
||||
input,
|
||||
this.min,
|
||||
this.max
|
||||
this.max,
|
||||
commandContext
|
||||
));
|
||||
}
|
||||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(value);
|
||||
} catch (final Exception e) {
|
||||
return ArgumentParseResult.failure(
|
||||
new ByteParseException(input, this.min,
|
||||
this.max
|
||||
new ByteParseException(
|
||||
input,
|
||||
this.min,
|
||||
this.max,
|
||||
commandContext
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -253,12 +257,24 @@ public final class ByteArgument<C> extends CommandArgument<C, Byte> {
|
|||
/**
|
||||
* Construct a new byte parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param context Command context
|
||||
*/
|
||||
public ByteParseException(final @NonNull String input, final byte min, final byte max) {
|
||||
super(input, min, max);
|
||||
public ByteParseException(
|
||||
final @NonNull String input,
|
||||
final byte min,
|
||||
final byte max,
|
||||
final @NonNull CommandContext<?> context
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
ByteParser.class,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
|||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
|
|
@ -130,7 +133,7 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
|||
}
|
||||
|
||||
if (input.length() != 1) {
|
||||
return ArgumentParseResult.failure(new CharParseException(input));
|
||||
return ArgumentParseResult.failure(new CharParseException(input, commandContext));
|
||||
}
|
||||
|
||||
return ArgumentParseResult.success(input.charAt(0));
|
||||
|
|
@ -147,16 +150,23 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
|||
/**
|
||||
* Char parse exception
|
||||
*/
|
||||
public static final class CharParseException extends IllegalArgumentException {
|
||||
public static final class CharParseException extends ParserException {
|
||||
|
||||
private final String input;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -169,11 +179,6 @@ public final class CharArgument<C> extends CommandArgument<C, Character> {
|
|||
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 {
|
||||
final double value = Double.parseDouble(input);
|
||||
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();
|
||||
return ArgumentParseResult.success(value);
|
||||
} 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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,12 +244,24 @@ public final class DoubleArgument<C> extends CommandArgument<C, Double> {
|
|||
/**
|
||||
* Construct a new double parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
public DoubleParseException(final @NonNull String input, final double min, final double max) {
|
||||
super(input, min, max);
|
||||
public DoubleParseException(
|
||||
final @NonNull String input,
|
||||
final double min,
|
||||
final double max,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
DoubleParser.class,
|
||||
commandContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
|||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
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
|
||||
|
|
@ -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 Class<? extends Enum<?>> enumClass;
|
||||
|
|
@ -203,11 +206,20 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
|||
*
|
||||
* @param input Input
|
||||
* @param enumClass Enum class
|
||||
* @param context Command context
|
||||
*/
|
||||
public EnumParseException(
|
||||
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.enumClass = enumClass;
|
||||
}
|
||||
|
|
@ -238,11 +250,6 @@ public class EnumArgument<C, E extends Enum<E>> extends CommandArgument<C, E> {
|
|||
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 {
|
||||
final float value = Float.parseFloat(input);
|
||||
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();
|
||||
return ArgumentParseResult.success(value);
|
||||
} 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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,12 +244,24 @@ public final class FloatArgument<C> extends CommandArgument<C, Float> {
|
|||
/**
|
||||
* Construct a new float parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
public FloatParseException(final @NonNull String input, final float min, final float max) {
|
||||
super(input, min, max);
|
||||
public FloatParseException(
|
||||
final @NonNull String input,
|
||||
final float min,
|
||||
final float max,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
FloatParser.class,
|
||||
commandContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -223,12 +223,22 @@ public final class IntegerArgument<C> extends CommandArgument<C, Integer> {
|
|||
try {
|
||||
final int value = Integer.parseInt(input);
|
||||
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();
|
||||
return ArgumentParseResult.success(value);
|
||||
} 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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,12 +281,24 @@ public final class IntegerArgument<C> extends CommandArgument<C, Integer> {
|
|||
/**
|
||||
* Construct a new integer parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
public IntegerParseException(final @NonNull String input, final int min, final int max) {
|
||||
super(input, min, max);
|
||||
public IntegerParseException(
|
||||
final @NonNull String input,
|
||||
final int min,
|
||||
final int max,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
IntegerParser.class,
|
||||
commandContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -188,12 +188,22 @@ public final class LongArgument<C> extends CommandArgument<C, Long> {
|
|||
try {
|
||||
final long value = Long.parseLong(input);
|
||||
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();
|
||||
return ArgumentParseResult.success(value);
|
||||
} 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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,12 +228,24 @@ public final class LongArgument<C> extends CommandArgument<C, Long> {
|
|||
/**
|
||||
* Construct a new long parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
public LongParseException(final @NonNull String input, final long min, final long max) {
|
||||
super(input, min, max);
|
||||
public LongParseException(
|
||||
final @NonNull String input,
|
||||
final long min,
|
||||
final long max,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
LongParser.class,
|
||||
commandContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -194,12 +194,22 @@ public final class ShortArgument<C> extends CommandArgument<C, Short> {
|
|||
try {
|
||||
final short value = Short.parseShort(input);
|
||||
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();
|
||||
return ArgumentParseResult.success(value);
|
||||
} 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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,12 +252,24 @@ public final class ShortArgument<C> extends CommandArgument<C, Short> {
|
|||
/**
|
||||
* Construct a new short parse exception
|
||||
*
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param input String input
|
||||
* @param min Minimum value
|
||||
* @param max Maximum value
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
public ShortParseException(final @NonNull String input, final short min, final short max) {
|
||||
super(input, min, max);
|
||||
public ShortParseException(
|
||||
final @NonNull String input,
|
||||
final short min,
|
||||
final short max,
|
||||
final @NonNull CommandContext<?> commandContext
|
||||
) {
|
||||
super(
|
||||
input,
|
||||
min,
|
||||
max,
|
||||
ShortParser.class,
|
||||
commandContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.arguments.standard;
|
|||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -342,7 +345,7 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
|||
}
|
||||
|
||||
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());
|
||||
|
|
@ -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 StringMode stringMode;
|
||||
|
|
@ -383,8 +386,20 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
|||
*
|
||||
* @param input Input
|
||||
* @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.stringMode = stringMode;
|
||||
}
|
||||
|
|
@ -408,14 +423,6 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
|||
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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
|
|
@ -133,7 +136,7 @@ public final class UUIDArgument<C> extends CommandArgument<C, UUID> {
|
|||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(uuid);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ArgumentParseResult.failure(new UUIDParseException(input));
|
||||
return ArgumentParseResult.failure(new UUIDParseException(input, commandContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,22 +148,36 @@ 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("Could not parse UUID from '%s'.", input);
|
||||
/**
|
||||
* Get the supplied 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.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.Nullable;
|
||||
|
||||
|
|
@ -41,33 +46,57 @@ import java.util.Optional;
|
|||
*/
|
||||
public final class CommandContext<C> {
|
||||
|
||||
private final CaptionVariableReplacementHandler captionVariableReplacementHandler =
|
||||
new SimpleCaptionVariableReplacementHandler();
|
||||
private final Map<CommandArgument<C, ?>, ArgumentTiming> argumentTimings = new HashMap<>();
|
||||
private final FlagContext flagContext = FlagContext.create();
|
||||
private final Map<String, Object> internalStorage = new HashMap<>();
|
||||
private final C commandSender;
|
||||
private final boolean suggestions;
|
||||
private final CaptionRegistry<C> captionRegistry;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this(false, commandSender);
|
||||
public CommandContext(final @NonNull C commandSender, final @NonNull CaptionRegistry<C> captionRegistry) {
|
||||
this(false, commandSender, captionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new command context instance
|
||||
*
|
||||
* @param suggestions Whether or not the context is created for command suggestions
|
||||
* @param commandSender Sender of the command
|
||||
* @param suggestions Whether or not the context is created for command suggestions
|
||||
* @param commandSender Sender of the command
|
||||
* @param captionRegistry Caption registry
|
||||
*/
|
||||
public CommandContext(
|
||||
final boolean suggestions,
|
||||
final @NonNull C commandSender
|
||||
final @NonNull C commandSender,
|
||||
final @NonNull CaptionRegistry<C> captionRegistry
|
||||
) {
|
||||
this.commandSender = commandSender;
|
||||
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;
|
||||
|
||||
import cloud.commandframework.captions.CaptionRegistry;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
|
|
@ -35,10 +36,15 @@ public interface CommandContextFactory<C> {
|
|||
/**
|
||||
* Create a new command context
|
||||
*
|
||||
* @param suggestions Whether or not the sender is requesting suggestions
|
||||
* @param sender Command sender
|
||||
* @param suggestions Whether or not the sender is requesting suggestions
|
||||
* @param sender Command sender
|
||||
* @param captionRegistry Caption registry
|
||||
* @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;
|
||||
|
||||
import cloud.commandframework.captions.CaptionRegistry;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public final class StandardCommandContextFactory<C> implements CommandContextFactory<C> {
|
||||
|
|
@ -30,13 +31,22 @@ public final class StandardCommandContextFactory<C> implements CommandContextFac
|
|||
/**
|
||||
* Construct a new command context
|
||||
*
|
||||
* @param suggestions Whether or not the sender is requesting suggestions
|
||||
* @param sender Command sender
|
||||
* @param suggestions Whether or not the sender is requesting suggestions
|
||||
* @param sender Command sender
|
||||
* @param captionRegistry Caption registry
|
||||
* @return Created context
|
||||
*/
|
||||
@Override
|
||||
public CommandContext<C> create(final boolean suggestions, final @NonNull C sender) {
|
||||
return new CommandContext<>(suggestions, sender);
|
||||
public CommandContext<C> create(
|
||||
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;
|
||||
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
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 Number min;
|
||||
|
|
@ -34,34 +37,32 @@ public abstract class NumberParseException extends IllegalArgumentException {
|
|||
/**
|
||||
* Construct a new number parse exception
|
||||
*
|
||||
* @param input Input
|
||||
* @param min Maximum value
|
||||
* @param max Minimum value
|
||||
* @param input Input
|
||||
* @param min Maximum value
|
||||
* @param max Minimum value
|
||||
* @param parserClass Parser class
|
||||
* @param context Command context
|
||||
*/
|
||||
public NumberParseException(
|
||||
final @NonNull String input,
|
||||
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.min = min;
|
||||
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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender()),
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
),
|
||||
new LinkedList<>(
|
||||
Arrays.asList(
|
||||
"test",
|
||||
|
|
@ -161,31 +163,60 @@ class CommandTreeTest {
|
|||
Assertions.assertEquals(NoPermissionException.class, manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender()),
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
),
|
||||
new LinkedList<>(
|
||||
Arrays.asList("test", "two"))
|
||||
)
|
||||
.getSecond().getClass());
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
||||
.parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||
new LinkedList<>(Arrays.asList("test", "opt"))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
));
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
||||
.parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||
new LinkedList<>(Arrays.asList("test", "opt", "12"))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlias() {
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("other", "öpt", "12")))
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender()));
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
),
|
||||
new LinkedList<>(Arrays.asList(
|
||||
"other",
|
||||
"öpt",
|
||||
"12"
|
||||
))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager.getCaptionRegistry()
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSuggestions() {
|
||||
Assertions.assertFalse(
|
||||
manager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
|
||||
Collections.singletonList("test "))).isEmpty());
|
||||
manager.getCommandTree().getSuggestions(
|
||||
new CommandContext<>(new TestCommandSender(), manager.getCaptionRegistry()),
|
||||
new LinkedList<>(Collections.singletonList("test "))
|
||||
).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -263,11 +294,11 @@ class CommandTreeTest {
|
|||
|
||||
@Test
|
||||
void testPreprocessors() {
|
||||
manager.executeCommand(new TestCommandSender(), "preprocess abc").join();
|
||||
Assertions.assertThrows(
|
||||
CompletionException.class,
|
||||
() -> manager.executeCommand(new TestCommandSender(), "preprocess ab").join()
|
||||
);
|
||||
manager.executeCommand(new TestCommandSender(), "preprocess abc").join();
|
||||
Assertions.assertThrows(
|
||||
CompletionException.class,
|
||||
() -> manager.executeCommand(new TestCommandSender(), "preprocess ab").join()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
this.owningPlugin
|
||||
);
|
||||
|
||||
this.registerDefaultCaptions(new BukkitCaptionRegistryFactory<C>().create());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
|||
this.commandManager = commandManager;
|
||||
this.commodore = CommodoreProvider.getCommodore(commandManager.getOwningPlugin());
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ package cloud.commandframework.bukkit.parsers;
|
|||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
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);
|
||||
if (enchantment == null) {
|
||||
return ArgumentParseResult.failure(new EnchantmentParseException(input));
|
||||
return ArgumentParseResult.failure(new EnchantmentParseException(input, commandContext));
|
||||
}
|
||||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(enchantment);
|
||||
|
|
@ -168,16 +171,26 @@ 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -190,11 +203,6 @@ public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
|||
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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.bukkit.Material;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
|
@ -136,7 +139,7 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
|||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(material);
|
||||
} catch (final IllegalArgumentException exception) {
|
||||
return ArgumentParseResult.failure(new MaterialParseException(input));
|
||||
return ArgumentParseResult.failure(new MaterialParseException(input, commandContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,16 +158,26 @@ 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -177,11 +190,6 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
|||
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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -146,7 +149,7 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
|||
OfflinePlayer player = Bukkit.getOfflinePlayer(input);
|
||||
|
||||
if (player == null || (!player.hasPlayedBefore() && !player.isOnline())) {
|
||||
return ArgumentParseResult.failure(new OfflinePlayerParseException(input));
|
||||
return ArgumentParseResult.failure(new OfflinePlayerParseException(input, commandContext));
|
||||
}
|
||||
|
||||
return ArgumentParseResult.success(player);
|
||||
|
|
@ -172,16 +175,26 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
|||
/**
|
||||
* OfflinePlayer parse exception
|
||||
*/
|
||||
public static final class OfflinePlayerParseException extends IllegalArgumentException {
|
||||
public static final class OfflinePlayerParseException extends ParserException {
|
||||
|
||||
private final String input;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -194,11 +207,6 @@ public final class OfflinePlayerArgument<C> extends CommandArgument<C, OfflinePl
|
|||
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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
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);
|
||||
|
||||
if (player == null) {
|
||||
return ArgumentParseResult.failure(new PlayerParseException(input));
|
||||
return ArgumentParseResult.failure(new PlayerParseException(input, commandContext));
|
||||
}
|
||||
|
||||
return ArgumentParseResult.success(player);
|
||||
|
|
@ -166,16 +169,26 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
|||
/**
|
||||
* Player parse exception
|
||||
*/
|
||||
public static final class PlayerParseException extends IllegalArgumentException {
|
||||
public static final class PlayerParseException extends ParserException {
|
||||
|
||||
private final String input;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -188,11 +201,6 @@ public final class PlayerArgument<C> extends CommandArgument<C, Player> {
|
|||
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.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.bukkit.BukkitCaptionKeys;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
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);
|
||||
if (world == null) {
|
||||
return ArgumentParseResult.failure(new WorldParseException(input));
|
||||
return ArgumentParseResult.failure(new WorldParseException(input, commandContext));
|
||||
}
|
||||
|
||||
inputQueue.remove();
|
||||
|
|
@ -145,16 +148,26 @@ 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -167,11 +180,6 @@ public class WorldArgument<C> extends CommandArgument<C, World> {
|
|||
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);
|
||||
|
||||
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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ public final class SinglePlayerSelectorArgument<C> extends CommandArgument<C, Si
|
|||
Player player = Bukkit.getPlayer(input);
|
||||
|
||||
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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ class PaperBrigadierListener<C> implements Listener {
|
|||
this.paperCommandManager,
|
||||
() -> new CommandContext<>(
|
||||
this.paperCommandManager.getCommandSenderMapper()
|
||||
.apply(Bukkit.getConsoleSender()))
|
||||
.apply(Bukkit.getConsoleSender()),
|
||||
this.paperCommandManager.getCaptionRegistry()
|
||||
)
|
||||
);
|
||||
new BukkitBrigadierMapper<>(this.paperCommandManager, this.brigadierManager);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ final class VelocityPluginRegistrationHandler<C> implements CommandRegistrationH
|
|||
() -> new CommandContext<>(
|
||||
velocityCommandManager.getCommandSenderMapper()
|
||||
.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.WorldArgument;
|
||||
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.execution.AsynchronousCommandExecutionCoordinator;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
|
|
@ -409,6 +411,15 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
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]")
|
||||
|
|
@ -466,7 +477,8 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
@CommandDescription("Command to test the preprocessing system")
|
||||
private void commandPay(
|
||||
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(
|
||||
Component.text().append(Component.text("You have been given ", NamedTextColor.AQUA))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue