bukkit/paper: Add NamespacedKeyArgument (#376)
This commit is contained in:
parent
a441f42666
commit
c250aa642f
12 changed files with 645 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ package cloud.commandframework.bukkit;
|
|||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.arguments.standard.UUIDArgument;
|
||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||
import cloud.commandframework.bukkit.argument.NamespacedKeyArgument;
|
||||
import cloud.commandframework.bukkit.internal.CommandBuildContextSupplier;
|
||||
import cloud.commandframework.bukkit.internal.MinecraftArgumentTypes;
|
||||
import cloud.commandframework.bukkit.parsers.BlockPredicateArgument;
|
||||
|
|
@ -85,6 +86,9 @@ public final class BukkitBrigadierMapper<C> {
|
|||
} catch (final IllegalArgumentException ignore) {
|
||||
// < 1.16
|
||||
}
|
||||
/* Map NamespacedKey */
|
||||
this.mapSimpleNMS(new TypeToken<NamespacedKeyArgument.Parser<C>>() {
|
||||
}, "resource_location", true);
|
||||
/* Map Enchantment */
|
||||
this.mapSimpleNMS(new TypeToken<EnchantmentArgument.EnchantmentParser<C>>() {
|
||||
}, "item_enchantment");
|
||||
|
|
|
|||
|
|
@ -89,6 +89,27 @@ public final class BukkitCaptionKeys {
|
|||
*/
|
||||
public static final Caption ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE = of(
|
||||
"argument.parse.failure.location.mixed_local_absolute");
|
||||
/**
|
||||
* Variables: {input}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final Caption ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE =
|
||||
of("argument.parse.failure.namespacedkey.namespace");
|
||||
/**
|
||||
* Variables: {input}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final Caption ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY =
|
||||
of("argument.parse.failure.namespacedkey.key");
|
||||
/**
|
||||
* Variables: {input}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final Caption ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NEED_NAMESPACE =
|
||||
of("argument.parse.failure.namespacedkey.need_namespace");
|
||||
|
||||
private BukkitCaptionKeys() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,28 @@ public class BukkitCaptionRegistry<C> extends SimpleCaptionRegistry<C> {
|
|||
*/
|
||||
public static final String ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE =
|
||||
"Cannot mix local and absolute coordinates. (either all coordinates use '^' or none do)";
|
||||
/**
|
||||
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final String ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE =
|
||||
"Invalid namespace '{input}'. Must be [a-z0-9._-]";
|
||||
/**
|
||||
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final String ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY =
|
||||
"Invalid key '{input}'. Must be [a-z0-9/._-]";
|
||||
/**
|
||||
* Default caption for {@link BukkitCaptionKeys#ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY}
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final String ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NEED_NAMESPACE =
|
||||
"Invalid input '{input}', requires an explicit namespace.";
|
||||
|
||||
|
||||
protected BukkitCaptionRegistry() {
|
||||
super();
|
||||
|
|
@ -134,6 +156,18 @@ public class BukkitCaptionRegistry<C> extends SimpleCaptionRegistry<C> {
|
|||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE,
|
||||
(caption, sender) -> ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE
|
||||
);
|
||||
this.registerMessageFactory(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE,
|
||||
(caption, sender) -> ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE
|
||||
);
|
||||
this.registerMessageFactory(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY,
|
||||
(caption, sender) -> ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY
|
||||
);
|
||||
this.registerMessageFactory(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NEED_NAMESPACE,
|
||||
(caption, sender) -> ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NEED_NAMESPACE
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,13 +26,18 @@ package cloud.commandframework.bukkit;
|
|||
import cloud.commandframework.CloudCapability;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.CommandTree;
|
||||
import cloud.commandframework.arguments.parser.ParserParameters;
|
||||
import cloud.commandframework.brigadier.BrigadierManagerHolder;
|
||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||
import cloud.commandframework.bukkit.annotation.specifier.DefaultNamespace;
|
||||
import cloud.commandframework.bukkit.annotation.specifier.RequireExplicitNamespace;
|
||||
import cloud.commandframework.bukkit.argument.NamespacedKeyArgument;
|
||||
import cloud.commandframework.bukkit.arguments.selector.MultipleEntitySelector;
|
||||
import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector;
|
||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
||||
import cloud.commandframework.bukkit.data.ProtoItemStack;
|
||||
import cloud.commandframework.bukkit.internal.CraftBukkitReflection;
|
||||
import cloud.commandframework.bukkit.parsers.BlockPredicateArgument;
|
||||
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||
import cloud.commandframework.bukkit.parsers.ItemStackArgument;
|
||||
|
|
@ -162,6 +167,18 @@ public class BukkitCommandManager<C> extends CommandManager<C> implements Brigad
|
|||
this.getParserRegistry().registerParserSupplier(TypeToken.get(MultiplePlayerSelector.class), parserParameters ->
|
||||
new MultiplePlayerSelectorArgument.MultiplePlayerSelectorParser<>());
|
||||
|
||||
if (CraftBukkitReflection.classExists("org.bukkit.NamespacedKey")) {
|
||||
this.registerParserSupplierFor(NamespacedKeyArgument.class);
|
||||
this.getParserRegistry().registerAnnotationMapper(
|
||||
RequireExplicitNamespace.class,
|
||||
(annotation, type) -> ParserParameters.single(BukkitParserParameters.REQUIRE_EXPLICIT_NAMESPACE, true)
|
||||
);
|
||||
this.getParserRegistry().registerAnnotationMapper(
|
||||
DefaultNamespace.class,
|
||||
(annotation, type) -> ParserParameters.single(BukkitParserParameters.DEFAULT_NAMESPACE, annotation.value())
|
||||
);
|
||||
}
|
||||
|
||||
/* Register MC 1.13+ parsers */
|
||||
if (this.hasCapability(CloudBukkitCapabilities.BRIGADIER)) {
|
||||
this.registerParserSupplierFor(ItemStackPredicateArgument.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021 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.arguments.parser.ParserParameter;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* {@link ParserParameter} keys for cloud-bukkit.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public final class BukkitParserParameters {
|
||||
|
||||
private BukkitParserParameters() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets to require explicit namespaces for {@link cloud.commandframework.bukkit.argument.NamespacedKeyArgument}
|
||||
* (i.e. 'test' will be rejected but 'test:test' will pass).
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final ParserParameter<Boolean> REQUIRE_EXPLICIT_NAMESPACE =
|
||||
create("require_explicit_namespace", TypeToken.get(Boolean.class));
|
||||
|
||||
/**
|
||||
* Sets a custom default namespace for {@link cloud.commandframework.bukkit.argument.NamespacedKeyArgument}.
|
||||
* Without this annotation the default is {@link org.bukkit.NamespacedKey#MINECRAFT}.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final ParserParameter<String> DEFAULT_NAMESPACE =
|
||||
create("default_namespace", TypeToken.get(String.class));
|
||||
|
||||
private static <T> @NonNull ParserParameter<T> create(
|
||||
final @NonNull String key,
|
||||
final @NonNull TypeToken<T> expectedType
|
||||
) {
|
||||
return new ParserParameter<>(key, expectedType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Annotations for cloud-bukkit.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
package cloud.commandframework.bukkit.annotation;
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021 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.annotation.specifier;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Annotation used to set a custom namespace for {@link cloud.commandframework.bukkit.argument.NamespacedKeyArgument}.
|
||||
* Without this annotation, the default namespace is {@link org.bukkit.NamespacedKey#MINECRAFT}.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultNamespace {
|
||||
|
||||
/**
|
||||
* Default namespace string.
|
||||
*
|
||||
* @return default namespace
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@NonNull String value();
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021 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.annotation.specifier;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation used to set {@link cloud.commandframework.bukkit.argument.NamespacedKeyArgument} to
|
||||
* require explicit namespaces.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface RequireExplicitNamespace {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Specifier annotations for cloud-bukkit.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
package cloud.commandframework.bukkit.annotation.specifier;
|
||||
|
|
@ -0,0 +1,370 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021 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.argument;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
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.bukkit.BukkitCommandManager;
|
||||
import cloud.commandframework.bukkit.BukkitParserParameters;
|
||||
import cloud.commandframework.captions.Caption;
|
||||
import cloud.commandframework.captions.CaptionVariable;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiFunction;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* cloud argument type that parses {@link NamespacedKey}s
|
||||
*
|
||||
* @param <C> sender type
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public final class NamespacedKeyArgument<C> extends CommandArgument<C, NamespacedKey> {
|
||||
|
||||
private NamespacedKeyArgument(
|
||||
final boolean required,
|
||||
final @NonNull String name,
|
||||
final @NonNull String defaultValue,
|
||||
final @Nullable BiFunction<@NonNull CommandContext<C>, @NonNull String,
|
||||
@NonNull List<@NonNull String>> suggestionsProvider,
|
||||
final @NonNull ArgumentDescription defaultDescription,
|
||||
final boolean requireExplicitNamespace,
|
||||
final String defaultNamespace
|
||||
) {
|
||||
super(
|
||||
required,
|
||||
name,
|
||||
new Parser<>(requireExplicitNamespace, defaultNamespace),
|
||||
defaultValue,
|
||||
NamespacedKey.class,
|
||||
suggestionsProvider,
|
||||
defaultDescription
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Builder}.
|
||||
*
|
||||
* @param name argument name
|
||||
* @param <C> sender type
|
||||
* @return builder instance
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static <C> @NonNull Builder<C> builder(final @NonNull String name) {
|
||||
return new NamespacedKeyArgument.Builder<>(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new required {@link NamespacedKeyArgument}.
|
||||
*
|
||||
* @param name argument name
|
||||
* @param <C> sender type
|
||||
* @return argument instance
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static <C> @NonNull NamespacedKeyArgument<C> of(final @NonNull String name) {
|
||||
return NamespacedKeyArgument.<C>builder(name).asRequired().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new optional {@link NamespacedKeyArgument}.
|
||||
*
|
||||
* @param name argument name
|
||||
* @param <C> sender type
|
||||
* @return argument instance
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static <C> @NonNull NamespacedKeyArgument<C> optional(final @NonNull String name) {
|
||||
return NamespacedKeyArgument.<C>builder(name).asOptional().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new optional {@link NamespacedKeyArgument} using the provided default value.
|
||||
*
|
||||
* @param name argument name
|
||||
* @param defulatValue default name
|
||||
* @param <C> sender type
|
||||
* @return argument instance
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static <C> @NonNull NamespacedKeyArgument<C> optional(
|
||||
final @NonNull String name,
|
||||
final @NonNull NamespacedKey defulatValue
|
||||
) {
|
||||
return NamespacedKeyArgument.<C>builder(name).asOptionalWithDefault(defulatValue).build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder for {@link NamespacedKeyArgument}.
|
||||
*
|
||||
* @param <C> sender type
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final class Builder<C> extends CommandArgument.TypedBuilder<C, NamespacedKey, Builder<C>> {
|
||||
|
||||
private boolean requireExplicitNamespace = false;
|
||||
private String defaultNamespace = NamespacedKey.MINECRAFT;
|
||||
|
||||
private Builder(final @NonNull String name) {
|
||||
super(NamespacedKey.class, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to require explicit namespaces (i.e. 'test' will be rejected but 'test:test' will pass).
|
||||
*
|
||||
* @return this builder
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public Builder<C> requireExplicitNamespace() {
|
||||
return this.requireExplicitNamespace(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to require explicit namespaces (i.e. 'test' will be rejected but 'test:test' will pass).
|
||||
*
|
||||
* @param requireExplicitNamespace whether to require explicit namespaces
|
||||
* @return this builder
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public Builder<C> requireExplicitNamespace(final boolean requireExplicitNamespace) {
|
||||
this.requireExplicitNamespace = requireExplicitNamespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom default namespace. By default, it is {@link NamespacedKey#MINECRAFT}.
|
||||
*
|
||||
* @param defaultNamespace default namespace
|
||||
* @return this builder
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public Builder<C> defaultNamespace(final String defaultNamespace) {
|
||||
this.defaultNamespace = defaultNamespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command argument to be optional, with the specified default value.
|
||||
*
|
||||
* @param defaultValue default value
|
||||
* @return this builder
|
||||
* @see CommandArgument.Builder#asOptionalWithDefault(String)
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public Builder<C> asOptionalWithDefault(final NamespacedKey defaultValue) {
|
||||
return this.asOptionalWithDefault(defaultValue.getNamespace() + ':' + defaultValue.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull NamespacedKeyArgument<C> build() {
|
||||
return new NamespacedKeyArgument<>(
|
||||
this.isRequired(),
|
||||
this.getName(),
|
||||
this.getDefaultValue(),
|
||||
this.getSuggestionsProvider(),
|
||||
this.getDefaultDescription(),
|
||||
this.requireExplicitNamespace,
|
||||
this.defaultNamespace
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser for {@link NamespacedKey}.
|
||||
*
|
||||
* @param <C> sender type
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final class Parser<C> implements ArgumentParser<C, NamespacedKey> {
|
||||
|
||||
private final boolean requireExplicitNamespace;
|
||||
private final String defaultNamespace;
|
||||
|
||||
/**
|
||||
* Create a new {@link Parser}.
|
||||
*
|
||||
* @param requireExplicitNamespace whether to require an explicit namespace
|
||||
* @param defaultNamespace default namespace
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public Parser(
|
||||
final boolean requireExplicitNamespace,
|
||||
final String defaultNamespace
|
||||
) {
|
||||
this.requireExplicitNamespace = requireExplicitNamespace;
|
||||
this.defaultNamespace = defaultNamespace;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public @NonNull ArgumentParseResult<NamespacedKey> parse(
|
||||
final @NonNull CommandContext<C> commandContext,
|
||||
final @NonNull Queue<@NonNull String> inputQueue
|
||||
) {
|
||||
final String input = inputQueue.peek();
|
||||
final String[] split = input.split(":");
|
||||
final int maxSemi = split.length > 1 ? 1 : 0;
|
||||
if (input.length() - input.replace(":", "").length() > maxSemi) {
|
||||
// Wrong number of ':'
|
||||
return ArgumentParseResult.failure(new NamespacedKeyParseException(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY, input, commandContext
|
||||
));
|
||||
}
|
||||
try {
|
||||
final NamespacedKey ret;
|
||||
if (split.length == 1) {
|
||||
if (this.requireExplicitNamespace) {
|
||||
// Did not provide explicit namespace when option was enabled
|
||||
return ArgumentParseResult.failure(new NamespacedKeyParseException(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NEED_NAMESPACE, input, commandContext
|
||||
));
|
||||
}
|
||||
ret = new NamespacedKey(this.defaultNamespace, split[0]);
|
||||
} else if (split.length == 2) {
|
||||
ret = new NamespacedKey(split[0], split[1]);
|
||||
} else {
|
||||
// Too many parts, ie not:valid:input
|
||||
return ArgumentParseResult.failure(new NamespacedKeyParseException(
|
||||
BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY, input, commandContext
|
||||
));
|
||||
}
|
||||
|
||||
// Success!
|
||||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(ret);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
final Caption caption = ex.getMessage().contains("namespace") // stupid but works
|
||||
? BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_NAMESPACE
|
||||
// this will also get used if someone puts >256 chars
|
||||
: BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_NAMESPACED_KEY_KEY;
|
||||
return ArgumentParseResult.failure(new NamespacedKeyParseException(caption, input, commandContext));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<@NonNull String> suggestions(
|
||||
final @NonNull CommandContext<C> commandContext,
|
||||
final @NonNull String input
|
||||
) {
|
||||
final List<String> ret = new ArrayList<>();
|
||||
ret.add(this.defaultNamespace + ":");
|
||||
if (!input.contains(":") && !input.isEmpty()) {
|
||||
ret.add(input + ":");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exception used when {@link Parser} fails.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static final class NamespacedKeyParseException extends ParserException {
|
||||
|
||||
private static final long serialVersionUID = -482592639358941441L;
|
||||
private final String input;
|
||||
private final Caption caption;
|
||||
|
||||
/**
|
||||
* Creates a new {@link NamespacedKeyParseException}.
|
||||
*
|
||||
* @param caption caption
|
||||
* @param input input
|
||||
* @param context command context
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public NamespacedKeyParseException(
|
||||
final @NonNull Caption caption,
|
||||
final @NonNull String input,
|
||||
final @NonNull CommandContext<?> context
|
||||
) {
|
||||
super(
|
||||
Parser.class,
|
||||
context,
|
||||
caption,
|
||||
CaptionVariable.of("input", input)
|
||||
);
|
||||
this.caption = caption;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public @NonNull String getInput() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || this.getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final NamespacedKeyParseException that = (NamespacedKeyParseException) o;
|
||||
return this.input.equals(that.input) && this.caption.equals(that.caption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.input, this.caption);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called reflectively by {@link BukkitCommandManager}.
|
||||
*
|
||||
* @param commandManager command manager
|
||||
* @param <C> sender type
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static <C> void registerParserSupplier(final @NonNull BukkitCommandManager<C> commandManager) {
|
||||
commandManager.getParserRegistry()
|
||||
.registerParserSupplier(TypeToken.get(NamespacedKey.class), params -> new Parser<>(
|
||||
params.has(BukkitParserParameters.REQUIRE_EXPLICIT_NAMESPACE),
|
||||
params.get(BukkitParserParameters.DEFAULT_NAMESPACE, NamespacedKey.MINECRAFT)
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Command argument types for the Bukkit platform.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
package cloud.commandframework.bukkit.argument;
|
||||
|
|
@ -44,6 +44,7 @@ import cloud.commandframework.arguments.standard.IntegerArgument;
|
|||
import cloud.commandframework.arguments.standard.StringArrayArgument;
|
||||
import cloud.commandframework.bukkit.BukkitCommandManager;
|
||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||
import cloud.commandframework.bukkit.argument.NamespacedKeyArgument;
|
||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||
import cloud.commandframework.bukkit.data.ProtoItemStack;
|
||||
import cloud.commandframework.bukkit.parsers.EnchantmentArgument;
|
||||
|
|
@ -89,6 +90,7 @@ import org.bukkit.ChatColor;
|
|||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
|
@ -393,6 +395,8 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
new Mc113(this.manager).registerCommands();
|
||||
}
|
||||
|
||||
this.registerNamespacedKeyUsingCommand();
|
||||
|
||||
//
|
||||
// Create a Bukkit-like command
|
||||
//
|
||||
|
|
@ -457,6 +461,28 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
}));
|
||||
}
|
||||
|
||||
private void registerNamespacedKeyUsingCommand() {
|
||||
boolean nsk = true;
|
||||
try {
|
||||
Class.forName("org.bukkit.NamespacedKey");
|
||||
} catch (final ClassNotFoundException e) {
|
||||
nsk = false;
|
||||
}
|
||||
|
||||
if (!nsk) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.manager.command(this.manager.commandBuilder("example")
|
||||
.literal("namespacedkey")
|
||||
.argument(NamespacedKeyArgument.of("key"))
|
||||
.handler(ctx -> {
|
||||
final NamespacedKey namespacedKey = ctx.get("key");
|
||||
final String key = namespacedKey.getNamespace() + ":" + namespacedKey.getKey();
|
||||
ctx.getSender().sendMessage("The key you typed is '" + key + "'.");
|
||||
}));
|
||||
}
|
||||
|
||||
@CommandMethod("example|e|ex help [query]")
|
||||
@CommandDescription("Help menu")
|
||||
public void commandHelp(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue