✨ Implement EnchantmentArgument, remove inaccurate brig mappings.
This commit is contained in:
parent
1f3c3f2bd9
commit
c3d679d5ec
7 changed files with 244 additions and 34 deletions
|
|
@ -30,9 +30,7 @@ import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
|||
import cloud.commandframework.bukkit.arguments.selector.SinglePlayerSelector;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
|
@ -81,10 +79,6 @@ public final class BukkitBrigadierMapper<C> {
|
|||
}
|
||||
/* Map Enchantment */
|
||||
this.mapSimpleNMS(Enchantment.class, this.getNMSArgument("Enchantment").getConstructor());
|
||||
/* Map EntityType */
|
||||
this.mapSimpleNMS(EntityType.class, this.getNMSArgument("EntitySummon").getConstructor());
|
||||
/* Map Material */
|
||||
this.mapSimpleNMS(Material.class, this.getNMSArgument("ItemStack").getConstructor());
|
||||
/* Map Entity Selectors */
|
||||
this.mapComplexNMS(SingleEntitySelector.class, this.getEntitySelectorArgument(true, false));
|
||||
this.mapComplexNMS(SinglePlayerSelector.class, this.getEntitySelectorArgument(true, true));
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ 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.parsers.EnchantmentArgument;
|
||||
import cloud.commandframework.bukkit.parsers.MaterialArgument;
|
||||
import cloud.commandframework.bukkit.parsers.OfflinePlayerArgument;
|
||||
import cloud.commandframework.bukkit.parsers.PlayerArgument;
|
||||
|
|
@ -46,6 +47,7 @@ import org.bukkit.Material;
|
|||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
|
@ -135,18 +137,16 @@ public class BukkitCommandManager<C> extends CommandManager<C> {
|
|||
this.registerCommandPreProcessor(new BukkitCommandPreprocessor<>(this));
|
||||
|
||||
/* Register Bukkit Parsers */
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(World.class), params -> new WorldArgument.WorldParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(
|
||||
TypeToken.get(Material.class),
|
||||
params -> new MaterialArgument.MaterialParser<>()
|
||||
);
|
||||
this.getParserRegistry()
|
||||
.registerParserSupplier(TypeToken.get(Player.class), params -> new PlayerArgument.PlayerParser<>());
|
||||
this.getParserRegistry()
|
||||
.registerParserSupplier(
|
||||
TypeToken.get(OfflinePlayer.class),
|
||||
params -> new OfflinePlayerArgument.OfflinePlayerParser<>()
|
||||
);
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(World.class), parserParameters ->
|
||||
new WorldArgument.WorldParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(Material.class), parserParameters ->
|
||||
new MaterialArgument.MaterialParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(Player.class), parserParameters ->
|
||||
new PlayerArgument.PlayerParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(OfflinePlayer.class), parserParameters ->
|
||||
new OfflinePlayerArgument.OfflinePlayerParser<>());
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(Enchantment.class), parserParameters ->
|
||||
new EnchantmentArgument.EnchantmentParser<>());
|
||||
/* Register Entity Selector Parsers */
|
||||
this.getParserRegistry().registerParserSupplier(TypeToken.get(SingleEntitySelector.class), parserParameters ->
|
||||
new SingleEntitySelectorArgument.SingleEntitySelectorParser<>());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,190 @@
|
|||
//
|
||||
// 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.parsers;
|
||||
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* cloud argument type that parses Bukkit {@link Enchantment enchantments}
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
public class EnchantmentArgument<C> extends CommandArgument<C, Enchantment> {
|
||||
|
||||
protected EnchantmentArgument(
|
||||
final boolean required,
|
||||
final @NonNull String name,
|
||||
final @NonNull String defaultValue,
|
||||
final @Nullable BiFunction<@NonNull CommandContext<C>, @NonNull String,
|
||||
@NonNull List<@NonNull String>> suggestionsProvider
|
||||
) {
|
||||
super(required, name, new EnchantmentParser<>(), defaultValue, Enchantment.class, suggestionsProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new builder
|
||||
*
|
||||
* @param name Name of the argument
|
||||
* @param <C> Command sender type
|
||||
* @return Created builder
|
||||
*/
|
||||
public static <C> EnchantmentArgument.@NonNull Builder<C> newBuilder(final @NonNull String name) {
|
||||
return new EnchantmentArgument.Builder<>(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new required argument
|
||||
*
|
||||
* @param name Argument name
|
||||
* @param <C> Command sender type
|
||||
* @return Created argument
|
||||
*/
|
||||
public static <C> @NonNull CommandArgument<C, Enchantment> of(final @NonNull String name) {
|
||||
return EnchantmentArgument.<C>newBuilder(name).asRequired().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new optional argument
|
||||
*
|
||||
* @param name Argument name
|
||||
* @param <C> Command sender type
|
||||
* @return Created argument
|
||||
*/
|
||||
public static <C> @NonNull CommandArgument<C, Enchantment> optional(final @NonNull String name) {
|
||||
return EnchantmentArgument.<C>newBuilder(name).asOptional().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new optional argument with a default value
|
||||
*
|
||||
* @param name Argument name
|
||||
* @param enchantment Default value
|
||||
* @param <C> Command sender type
|
||||
* @return Created argument
|
||||
*/
|
||||
public static <C> @NonNull CommandArgument<C, Enchantment> optional(
|
||||
final @NonNull String name,
|
||||
final @NonNull Enchantment enchantment
|
||||
) {
|
||||
return EnchantmentArgument.<C>newBuilder(name).asOptionalWithDefault(enchantment.getKey().toString()).build();
|
||||
}
|
||||
|
||||
public static final class Builder<C> extends CommandArgument.Builder<C, Enchantment> {
|
||||
|
||||
protected Builder(final @NonNull String name) {
|
||||
super(Enchantment.class, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class EnchantmentParser<C> implements ArgumentParser<C, Enchantment> {
|
||||
|
||||
@Override
|
||||
public @NonNull ArgumentParseResult<Enchantment> parse(
|
||||
final @NonNull CommandContext<C> commandContext,
|
||||
final @NonNull Queue<@NonNull String> inputQueue
|
||||
) {
|
||||
final String input = inputQueue.peek();
|
||||
if (input == null) {
|
||||
return ArgumentParseResult.failure(new NullPointerException("No input was provided"));
|
||||
}
|
||||
|
||||
final NamespacedKey key;
|
||||
if (input.contains(":")) {
|
||||
final String[] splitInput = input.split(":");
|
||||
//noinspection deprecation
|
||||
key = new NamespacedKey(splitInput[0], splitInput[1]);
|
||||
} else {
|
||||
key = NamespacedKey.minecraft(input);
|
||||
}
|
||||
|
||||
final Enchantment enchantment = Enchantment.getByKey(key);
|
||||
if (enchantment == null) {
|
||||
return ArgumentParseResult.failure(new EnchantmentParseException(input));
|
||||
}
|
||||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(enchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<@NonNull String> suggestions(
|
||||
final @NonNull CommandContext<C> commandContext,
|
||||
final @NonNull String input
|
||||
) {
|
||||
final List<String> completions = new ArrayList<>();
|
||||
for (Enchantment value : Enchantment.values()) {
|
||||
if (value.getKey().getNamespace().equals(NamespacedKey.MINECRAFT)) {
|
||||
completions.add(value.getKey().getKey());
|
||||
} else {
|
||||
completions.add(value.getKey().toString());
|
||||
}
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static final class EnchantmentParseException extends IllegalArgumentException {
|
||||
|
||||
private final String input;
|
||||
|
||||
/**
|
||||
* Construct a new EnchantmentParseException
|
||||
*
|
||||
* @param input Input
|
||||
*/
|
||||
public EnchantmentParseException(final @NonNull String input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public @NonNull String getInput() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("'%s' is not a valid enchantment", this.input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ import org.bukkit.Material;
|
|||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiFunction;
|
||||
|
|
@ -108,7 +109,6 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public static final class MaterialParser<C> implements ArgumentParser<C, Material> {
|
||||
|
||||
@Override
|
||||
|
|
@ -121,21 +121,27 @@ public class MaterialArgument<C> extends CommandArgument<C, Material> {
|
|||
return ArgumentParseResult.failure(new NullPointerException("No input was provided"));
|
||||
}
|
||||
|
||||
/* Pre-process input */
|
||||
if (input.contains("minecraft:")) {
|
||||
input = input.substring("minecraft:".length());
|
||||
}
|
||||
input = input.toUpperCase();
|
||||
|
||||
try {
|
||||
final Material material = Material.valueOf(input);
|
||||
final Material material = Material.valueOf(input.toUpperCase());
|
||||
inputQueue.remove();
|
||||
return ArgumentParseResult.success(material);
|
||||
} catch (final IllegalArgumentException exception) {
|
||||
return ArgumentParseResult.failure(new MaterialParseException(inputQueue.peek()));
|
||||
return ArgumentParseResult.failure(new MaterialParseException(input));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<@NonNull String> suggestions(
|
||||
final @NonNull CommandContext<C> commandContext,
|
||||
final @NonNull String input
|
||||
) {
|
||||
final List<String> completions = new ArrayList<>();
|
||||
for (Material value : Material.values()) {
|
||||
completions.add(value.name().toLowerCase());
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
dependencies {
|
||||
api 'net.kyori:adventure-api:4.0.0-SNAPSHOT'
|
||||
api project(':cloud-core')
|
||||
api 'net.kyori:adventure-text-minimessage:4.0.0-SNAPSHOT'
|
||||
api 'net.kyori:adventure-api:4.0.0-SNAPSHOT'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,8 @@ public class PaperCommandManager<C> extends BukkitCommandManager<C> {
|
|||
CommandExecutionCoordinator<C>> commandExecutionCoordinator,
|
||||
final @NonNull Function<CommandSender, C> commandSenderMapper,
|
||||
final @NonNull Function<C, CommandSender> backwardsCommandSenderMapper
|
||||
) throws
|
||||
Exception {
|
||||
) throws Exception {
|
||||
super(owningPlugin, commandExecutionCoordinator, commandSenderMapper, backwardsCommandSenderMapper);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ import cloud.commandframework.bukkit.BukkitCommandManager;
|
|||
import cloud.commandframework.bukkit.BukkitCommandMetaBuilder;
|
||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||
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.context.CommandContext;
|
||||
|
|
@ -71,6 +73,8 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
|
@ -287,7 +291,7 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
));
|
||||
manager.command(manager.commandBuilder("give")
|
||||
.senderType(Player.class)
|
||||
.argument(EnumArgument.of(Material.class, "material"))
|
||||
.argument(MaterialArgument.of("material"))
|
||||
.argument(IntegerArgument.of("amount"))
|
||||
.handler(c -> {
|
||||
final Material material = c.get("material");
|
||||
|
|
@ -296,6 +300,21 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
((Player) c.getSender()).getInventory().addItem(itemStack);
|
||||
c.getSender().sendMessage("You've been given stuff, bro.");
|
||||
}));
|
||||
manager.command(builder.literal("summon")
|
||||
.senderType(Player.class)
|
||||
.argument(EnumArgument.of(EntityType.class, "type"))
|
||||
.handler(c -> manager.taskRecipe().begin(c).synchronous(ctx -> {
|
||||
final Location loc = ((Player) ctx.getSender()).getLocation();
|
||||
loc.getWorld().spawnEntity(loc, ctx.get("type"));
|
||||
}).execute()));
|
||||
manager.command(builder.literal("enchant")
|
||||
.senderType(Player.class)
|
||||
.argument(EnchantmentArgument.of("enchant"))
|
||||
.argument(IntegerArgument.of("level"))
|
||||
.handler(c -> manager.taskRecipe().begin(c).synchronous(ctx -> {
|
||||
final Player player = ((Player) ctx.getSender());
|
||||
player.getInventory().getItemInHand().addEnchantment(ctx.get("enchant"), ctx.get("level"));
|
||||
}).execute()));
|
||||
|
||||
//
|
||||
// An Argument Parser for TextColor that accepts NamedTextColor names or RGB colors in the format 'RRGGBB'
|
||||
|
|
@ -419,7 +438,8 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
final @NonNull Player player,
|
||||
final @NonNull @Argument("material") Material material,
|
||||
final @Argument("amount") int number,
|
||||
final @Nullable @Flag("color") ChatColor nameColor
|
||||
final @Nullable @Flag("color") ChatColor nameColor,
|
||||
final @Nullable @Flag("enchant") Enchantment enchant
|
||||
) {
|
||||
final ItemStack itemStack = new ItemStack(material, number);
|
||||
String itemName = String.format(
|
||||
|
|
@ -437,6 +457,9 @@ public final class ExamplePlugin extends JavaPlugin {
|
|||
meta.setDisplayName(itemName);
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
if (enchant != null) {
|
||||
itemStack.addUnsafeEnchantment(enchant, 10);
|
||||
}
|
||||
player.getInventory().addItem(itemStack);
|
||||
player.sendMessage(ChatColor.GREEN + String.format("You have been given %d x %s", number, material));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue