From 96ebd22b8027ae39118ebd11db330cbfa4af0fb5 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:43:35 -0700 Subject: [PATCH] Cloud 2 (#227) * Cloud 2 * Use cloud-translations * Use AudienceLocaleExtractor * Update dependencies * Update cloud * Update cloud * merge service files --- build.gradle.kts | 21 ++-- .../wanderingtrades/command/BaseCommand.java | 4 +- .../wanderingtrades/command/Commands.java | 91 ++++++---------- .../command/ExceptionHandler.java | 103 +++++------------- .../command/argument/TradeConfigArgument.java | 84 -------------- .../command/argument/TradeConfigParser.java | 46 ++++++++ .../command/commands/AboutCommand.java | 9 +- .../command/commands/ConfigCommands.java | 55 +++++----- .../command/commands/HelpCommand.java | 98 ++++++++--------- .../command/commands/ReloadCommand.java | 11 +- .../command/commands/SummonCommands.java | 70 ++++++------ .../command/commands/TradeCommands.java | 30 ++--- .../wanderingtrades/config/Messages.java | 43 +------- src/main/resources/lang/de_DE.yml | 26 ----- src/main/resources/lang/en_US.yml | 23 ---- src/main/resources/lang/ro_RO.yml | 23 ---- src/main/resources/lang/ru_RU.yml | 24 ---- src/main/resources/lang/zh_CN.yml | 20 ---- 18 files changed, 258 insertions(+), 523 deletions(-) delete mode 100644 src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigArgument.java create mode 100644 src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigParser.java diff --git a/build.gradle.kts b/build.gradle.kts index fb439ee..5f1caba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ group = "xyz.jpenilla" version = "1.8.4-SNAPSHOT".decorateVersion() description = "Customizable trades for Wandering Traders." -val mcVersion = "1.20.2" +val mcVersion = "1.20.4" repositories { mavenCentral() @@ -37,12 +37,16 @@ dependencies { compileOnly("io.papermc.paper", "paper-api", "1.20.1-R0.1-SNAPSHOT") implementation("io.papermc", "paperlib", "1.0.8") - implementation("xyz.jpenilla", "legacy-plugin-base", "0.0.1+106-SNAPSHOT") + implementation("xyz.jpenilla", "legacy-plugin-base", "0.0.1+108-SNAPSHOT") implementation("org.bstats", "bstats-bukkit", "3.0.2") - implementation(platform("cloud.commandframework:cloud-bom:1.8.4")) - implementation("cloud.commandframework", "cloud-paper") - implementation("cloud.commandframework", "cloud-minecraft-extras") + implementation(platform("org.incendo:cloud-bom:2.0.0-beta.4")) + implementation(platform("org.incendo:cloud-minecraft-bom:2.0.0-beta.5")) + implementation("org.incendo:cloud-paper") + implementation("org.incendo:cloud-minecraft-extras") + implementation(platform("org.incendo:cloud-translations-bom:1.0.0-SNAPSHOT")) + implementation("org.incendo:cloud-translations-bukkit") + implementation("org.incendo:cloud-translations-minecraft-extras") implementation("org.incendo.interfaces", "interfaces-paper", "1.0.0-SNAPSHOT") @@ -90,15 +94,15 @@ tasks { archiveFileName.set("${project.name}-${project.version}.jar") sequenceOf( "org.bstats", - "cloud.commandframework", + "org.incendo", "xyz.jpenilla.pluginbase", "net.kyori", "io.papermc.lib", "io.leangen.geantyref", - "org.incendo.interfaces", ).forEach { relocate(it, "xyz.jpenilla.wanderingtrades.lib.$it") } + mergeServiceFiles() } processResources { val tokens = mapOf( @@ -116,6 +120,9 @@ tasks { } } } + compileJava { + options.compilerArgs.add("-Xlint:-classfile,-processing") + } } fun lastCommitHash(): String = indraGit.commit()?.name?.substring(0, 7) diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/BaseCommand.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/BaseCommand.java index b219adf..cc6f727 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/BaseCommand.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/BaseCommand.java @@ -1,9 +1,9 @@ package xyz.jpenilla.wanderingtrades.command; -import cloud.commandframework.paper.PaperCommandManager; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.CommandManager; import xyz.jpenilla.pluginbase.legacy.Chat; import xyz.jpenilla.wanderingtrades.WanderingTrades; @@ -11,7 +11,7 @@ public abstract class BaseCommand { protected final WanderingTrades plugin; protected final Commands commands; - protected final PaperCommandManager commandManager; + protected final CommandManager commandManager; protected final Chat chat; protected BaseCommand(final WanderingTrades plugin, final Commands commands) { diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/Commands.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/Commands.java index 07811bb..c9d5b6a 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/Commands.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/Commands.java @@ -1,40 +1,38 @@ package xyz.jpenilla.wanderingtrades.command; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.flags.CommandFlag; -import cloud.commandframework.brigadier.CloudBrigadierManager; -import cloud.commandframework.bukkit.BukkitCaptionKeys; -import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.captions.SimpleCaptionRegistry; -import cloud.commandframework.captions.StandardCaptionKeys; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.execution.FilteringCommandSuggestionProcessor; -import cloud.commandframework.execution.preprocessor.CommandPreprocessingContext; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; -import cloud.commandframework.paper.PaperCommandManager; import io.leangen.geantyref.TypeToken; import java.util.HashMap; import java.util.List; import java.util.Map; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.bukkit.CloudBukkitCapabilities; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.execution.preprocessor.CommandPreprocessingContext; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.paper.PaperCommandManager; +import org.incendo.cloud.parser.flag.CommandFlag; +import org.incendo.cloud.translations.LocaleExtractor; import xyz.jpenilla.wanderingtrades.WanderingTrades; -import xyz.jpenilla.wanderingtrades.command.argument.TradeConfigArgument; +import xyz.jpenilla.wanderingtrades.command.argument.TradeConfigParser; import xyz.jpenilla.wanderingtrades.command.commands.AboutCommand; import xyz.jpenilla.wanderingtrades.command.commands.ConfigCommands; import xyz.jpenilla.wanderingtrades.command.commands.HelpCommand; import xyz.jpenilla.wanderingtrades.command.commands.ReloadCommand; import xyz.jpenilla.wanderingtrades.command.commands.SummonCommands; import xyz.jpenilla.wanderingtrades.command.commands.TradeCommands; -import xyz.jpenilla.wanderingtrades.config.Messages; -import xyz.jpenilla.wanderingtrades.config.TradeConfig; + +import static org.incendo.cloud.translations.TranslationBundle.core; +import static org.incendo.cloud.translations.bukkit.BukkitTranslationBundle.bukkit; +import static org.incendo.cloud.translations.minecraft.extras.AudienceLocaleExtractor.audienceLocaleExtractor; +import static org.incendo.cloud.translations.minecraft.extras.MinecraftExtrasTranslationBundle.minecraftExtras; @DefaultQualifier(NonNull.class) public final class Commands { - public static final CloudKey PLUGIN = SimpleCloudKey.of("wt:plugin", TypeToken.get(WanderingTrades.class)); + public static final CloudKey PLUGIN = CloudKey.of("wt:plugin", TypeToken.get(WanderingTrades.class)); private final WanderingTrades plugin; private final PaperCommandManager commandManager; @@ -44,17 +42,12 @@ private Commands(final WanderingTrades plugin, final PaperCommandManager( - FilteringCommandSuggestionProcessor.Filter.contains(true).andTrimBeforeLastSpace() - )); new ExceptionHandler(plugin, commandManager).register(); - this.registerMessageFactories(); + this.registerCaptions(); if (this.commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { this.commandManager.registerBrigadier(); - final @Nullable CloudBrigadierManager brigManager = this.commandManager.brigadierManager(); - if (brigManager != null) { - brigManager.setNativeNumberSuggestions(false); - } + } else if (this.commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { + this.commandManager.registerAsynchronousCompletions(); } this.registerParsers(); this.commandManager.registerCommandPreProcessor(this::preProcessContext); @@ -73,37 +66,24 @@ private void registerCommands() { commands.forEach(BaseCommand::register); } - public PaperCommandManager commandManager() { + public CommandManager commandManager() { return this.commandManager; } - private void registerMessageFactories() { - if (!(this.commandManager.captionRegistry() instanceof final SimpleCaptionRegistry registry)) { - return; - } - registry.registerMessageFactory( - StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM, - (caption, sender) -> Messages.COMMAND_ARGUMENT_PARSE_FAILURE_ENUM.message() - ); - registry.registerMessageFactory( - BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE, - (caption, sender) -> Messages.COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE.message() - ); - registry.registerMessageFactory( - BukkitCaptionKeys.ARGUMENT_PARSE_FAILURE_LOCATION_INVALID_FORMAT, - (caption, sender) -> Messages.COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_INVALID_FORMAT.message() - ); + private void registerCaptions() { + final LocaleExtractor extractor = audienceLocaleExtractor(this.plugin.audiences()::sender); + this.commandManager.captionRegistry() + .registerProvider(minecraftExtras(extractor)) + .registerProvider(bukkit(extractor)) + .registerProvider(core(extractor)); } private void registerParsers() { - this.commandManager.parserRegistry().registerParserSupplier( - TypeToken.get(TradeConfig.class), - parameters -> new TradeConfigArgument.Parser() - ); + this.commandManager.parserRegistry().registerParser(TradeConfigParser.tradeConfigParser()); } private void preProcessContext(final CommandPreprocessingContext context) { - context.getCommandContext().store(PLUGIN, this.plugin); + context.commandContext().store(PLUGIN, this.plugin); } public CommandFlag.Builder getFlag(final String name) { @@ -114,20 +94,15 @@ public void registerFlag(final String name, final CommandFlag.Builder flagBui this.flagRegistry.put(name, flagBuilder); } - public void register(final List> commands) { + public void register(final List> commands) { commands.forEach(this.commandManager::command); } public static void setup(final WanderingTrades plugin) { - final PaperCommandManager manager; - try { - manager = PaperCommandManager.createNative( - plugin, - CommandExecutionCoordinator.simpleCoordinator() - ); - } catch (final Exception ex) { - throw new RuntimeException("Failed to initialize command manager", ex); - } + final PaperCommandManager manager = PaperCommandManager.createNative( + plugin, + ExecutionCoordinator.simpleCoordinator() + ); new Commands(plugin, manager); } } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/ExceptionHandler.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/ExceptionHandler.java index ac5b721..1c8eaf8 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/ExceptionHandler.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/ExceptionHandler.java @@ -1,98 +1,51 @@ package xyz.jpenilla.wanderingtrades.command; -import cloud.commandframework.CommandManager; -import cloud.commandframework.exceptions.ArgumentParseException; -import cloud.commandframework.exceptions.InvalidCommandSenderException; -import cloud.commandframework.exceptions.InvalidSyntaxException; -import cloud.commandframework.exceptions.NoPermissionException; -import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; -import java.util.Objects; -import java.util.regex.Pattern; +import java.util.logging.Level; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.util.ComponentMessageThrowable; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.exception.ArgumentParseException; +import org.incendo.cloud.exception.CommandExecutionException; +import org.incendo.cloud.exception.InvalidCommandSenderException; +import org.incendo.cloud.exception.InvalidSyntaxException; +import org.incendo.cloud.exception.NoPermissionException; +import org.incendo.cloud.minecraft.extras.MinecraftExceptionHandler; import xyz.jpenilla.wanderingtrades.WanderingTrades; -import xyz.jpenilla.wanderingtrades.config.Messages; -import xyz.jpenilla.wanderingtrades.util.Components; import xyz.jpenilla.wanderingtrades.util.Constants; +import static org.incendo.cloud.exception.handling.ExceptionHandler.unwrappingHandler; + @DefaultQualifier(NonNull.class) final class ExceptionHandler { - private static final Pattern SYNTAX_HIGHLIGHT_PATTERN = Pattern.compile("[^\\s\\w\\-]"); private final WanderingTrades plugin; private final CommandManager commandManager; - ExceptionHandler(final WanderingTrades plugin, final CommandManager commandManager) { + ExceptionHandler( + final WanderingTrades plugin, + final CommandManager commandManager + ) { this.plugin = plugin; this.commandManager = commandManager; } void register() { - new MinecraftExceptionHandler() - .withHandler(MinecraftExceptionHandler.ExceptionType.NO_PERMISSION, ExceptionHandler::noPermission) - .withHandler(MinecraftExceptionHandler.ExceptionType.INVALID_SYNTAX, this::invalidSyntax) - .withHandler(MinecraftExceptionHandler.ExceptionType.INVALID_SENDER, this::invalidSender) - .withHandler(MinecraftExceptionHandler.ExceptionType.ARGUMENT_PARSING, this::argumentParsing) - .withHandler(MinecraftExceptionHandler.ExceptionType.COMMAND_EXECUTION, this::commandExecution) - .withDecorator(ExceptionHandler::decorate) - .apply(this.commandManager, this.plugin.audiences()::sender); - } - - private Component commandExecution(final CommandSender commandSender, final Exception ex) { - final Throwable cause = ex.getCause(); - - if (cause instanceof NoPermissionException noPermissionException) { - return noPermission(noPermissionException); - } else if (cause instanceof InvalidSyntaxException invalidSyntaxException) { - return this.invalidSyntax(invalidSyntaxException); - } else if (cause instanceof InvalidCommandSenderException invalidCommandSenderException) { - return this.invalidSender(invalidCommandSenderException); - } else if (cause instanceof ArgumentParseException argumentParseException) { - return this.argumentParsing(argumentParseException); - } - - return MinecraftExceptionHandler.DEFAULT_COMMAND_EXECUTION_FUNCTION.apply(ex); - } - - private Component invalidSyntax(final Exception ex) { - final InvalidSyntaxException exception = (InvalidSyntaxException) ex; - final Component correctSyntaxMessage = Component.text( - String.format("/%s", exception.getCorrectSyntax()), - NamedTextColor.GRAY - ).replaceText(config -> { - config.match(SYNTAX_HIGHLIGHT_PATTERN); - config.replacement(builder -> builder.color(NamedTextColor.WHITE)); - }); - return Messages.COMMAND_INVALID_SYNTAX.withPlaceholders( - Components.placeholder("syntax", correctSyntaxMessage) - ); - } - - private Component invalidSender(final Exception ex) { - final InvalidCommandSenderException exception = (InvalidCommandSenderException) ex; - return Messages.COMMAND_INVALID_SENDER.withPlaceholders( - Components.placeholder("type", exception.getRequiredSender().getSimpleName()) - ); - } - - private Component argumentParsing(final Exception ex) { - final Component causeMessage = Objects.requireNonNull(ComponentMessageThrowable.getOrConvertMessage(ex.getCause())) - .colorIfAbsent(NamedTextColor.GRAY); - return Messages.COMMAND_INVALID_ARGUMENT.withPlaceholders( - Components.placeholder("error", causeMessage) - ); - } - - private static Component noPermission(final Exception e) { - return Component.translatable("commands.help.failed", NamedTextColor.RED); - } - - private static Component decorate(final ComponentLike component) { - return Component.textOfChildren(Constants.PREFIX_COMPONENT, component); + MinecraftExceptionHandler.create(this.plugin.audiences()::sender) + .handler(NoPermissionException.class, (formatter, ctx) -> Component.translatable("commands.help.failed", NamedTextColor.RED)) + .defaultInvalidSyntaxHandler() + .defaultInvalidSenderHandler() + .defaultArgumentParsingHandler() + .defaultCommandExecutionHandler(ctx -> this.plugin.getLogger().log(Level.WARNING, "Unexpected exception during command execution", ctx.exception().getCause())) + .decorator(msg -> Component.textOfChildren(Constants.PREFIX_COMPONENT, msg)) + .registerTo(this.commandManager); + + this.commandManager.exceptionController() + .registerHandler(CommandExecutionException.class, unwrappingHandler(NoPermissionException.class)) + .registerHandler(CommandExecutionException.class, unwrappingHandler(InvalidSyntaxException.class)) + .registerHandler(CommandExecutionException.class, unwrappingHandler(InvalidCommandSenderException.class)) + .registerHandler(CommandExecutionException.class, unwrappingHandler(ArgumentParseException.class)); } } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigArgument.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigArgument.java deleted file mode 100644 index 5956187..0000000 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigArgument.java +++ /dev/null @@ -1,84 +0,0 @@ -package xyz.jpenilla.wanderingtrades.command.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.context.CommandContext; -import java.util.List; -import java.util.Queue; -import java.util.function.BiFunction; -import org.bukkit.command.CommandSender; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.framework.qual.DefaultQualifier; -import xyz.jpenilla.wanderingtrades.WanderingTrades; -import xyz.jpenilla.wanderingtrades.command.Commands; -import xyz.jpenilla.wanderingtrades.config.Messages; -import xyz.jpenilla.wanderingtrades.config.TradeConfig; - -@DefaultQualifier(NonNull.class) -public final class TradeConfigArgument extends CommandArgument { - private TradeConfigArgument( - final boolean required, - final String name, - final String defaultValue, - final @Nullable BiFunction, String, List> suggestionsProvider, - final ArgumentDescription defaultDescription - ) { - super(required, name, new Parser(), defaultValue, TradeConfig.class, suggestionsProvider, defaultDescription); - } - - public static TradeConfigArgument of(final String name) { - return builder(name).build(); - } - - public static TradeConfigArgument optional(final String name) { - return builder(name).asOptional().build(); - } - - public static Builder builder(final String name) { - return new Builder(name); - } - - public static final class Parser implements ArgumentParser { - @Override - public ArgumentParseResult parse( - final CommandContext commandContext, - final Queue inputQueue - ) { - final WanderingTrades plugin = commandContext.get(Commands.PLUGIN); - final @Nullable TradeConfig tradeConfig = plugin.configManager().tradeConfigs().get(inputQueue.peek()); - if (tradeConfig != null) { - inputQueue.remove(); - return ArgumentParseResult.success(tradeConfig); - } - return ArgumentParseResult.failure(new IllegalArgumentException(Messages.COMMAND_PARSE_EXCEPTION_NO_TRADE_CONFIG.message())); - } - - @Override - public List suggestions( - final CommandContext commandContext, - final String input - ) { - return List.copyOf(commandContext.get(Commands.PLUGIN).configManager().tradeConfigs().keySet()); - } - } - - public static final class Builder extends TypedBuilder { - private Builder(final String name) { - super(TradeConfig.class, name); - } - - @Override - public TradeConfigArgument build() { - return new TradeConfigArgument( - this.isRequired(), - this.getName(), - this.getDefaultValue(), - this.getSuggestionsProvider(), - this.getDefaultDescription() - ); - } - } -} diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigParser.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigParser.java new file mode 100644 index 0000000..6e4ac58 --- /dev/null +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/argument/TradeConfigParser.java @@ -0,0 +1,46 @@ +package xyz.jpenilla.wanderingtrades.command.argument; + +import java.util.List; +import org.bukkit.command.CommandSender; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.ArgumentParseResult; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.ParserDescriptor; +import org.incendo.cloud.suggestion.BlockingSuggestionProvider; +import xyz.jpenilla.wanderingtrades.WanderingTrades; +import xyz.jpenilla.wanderingtrades.command.Commands; +import xyz.jpenilla.wanderingtrades.config.Messages; +import xyz.jpenilla.wanderingtrades.config.TradeConfig; + +@DefaultQualifier(NonNull.class) +public final class TradeConfigParser implements ArgumentParser, BlockingSuggestionProvider.Strings { + + public static ParserDescriptor tradeConfigParser() { + return ParserDescriptor.of(new TradeConfigParser(), TradeConfig.class); + } + + @Override + public ArgumentParseResult parse( + final CommandContext commandContext, + final CommandInput input + ) { + final WanderingTrades plugin = commandContext.get(Commands.PLUGIN); + final @Nullable TradeConfig tradeConfig = plugin.configManager().tradeConfigs().get(input.readString()); + if (tradeConfig != null) { + return ArgumentParseResult.success(tradeConfig); + } + return ArgumentParseResult.failure(new IllegalArgumentException(Messages.COMMAND_PARSE_EXCEPTION_NO_TRADE_CONFIG.message())); + } + + @Override + public Iterable stringSuggestions( + final CommandContext commandContext, + final CommandInput input + ) { + return List.copyOf(commandContext.get(Commands.PLUGIN).configManager().tradeConfigs().keySet()); + } +} diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/AboutCommand.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/AboutCommand.java index 45510da..0219b32 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/AboutCommand.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/AboutCommand.java @@ -1,12 +1,11 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; import java.util.stream.Stream; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; import xyz.jpenilla.pluginbase.legacy.Chat; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; @@ -22,7 +21,7 @@ public AboutCommand(final WanderingTrades plugin, final Commands commands) { @Override public void register() { final Command about = this.commandManager.commandBuilder("wt") - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_ABOUT_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_ABOUT_DESCRIPTION.asDescription()) .literal("about") .handler(this::execute) .build(); @@ -36,6 +35,6 @@ private void execute(final CommandContext context) { "click me!'>" + this.plugin.getName() + " " + this.plugin.getDescription().getVersion(), "By jmp", "--------------------------" - ).map(Chat::getCenteredMessage).forEach(string -> this.chat.send(context.getSender(), string)); + ).map(Chat::getCenteredMessage).forEach(string -> this.chat.send(context.sender(), string)); } } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ConfigCommands.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ConfigCommands.java index 32f625b..fcf9e8a 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ConfigCommands.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ConfigCommands.java @@ -1,11 +1,5 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.meta.CommandMeta; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -14,11 +8,13 @@ import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.description.Description; import xyz.jpenilla.pluginbase.legacy.itembuilder.ItemBuilder; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; import xyz.jpenilla.wanderingtrades.command.Commands; -import xyz.jpenilla.wanderingtrades.command.argument.TradeConfigArgument; import xyz.jpenilla.wanderingtrades.config.Messages; import xyz.jpenilla.wanderingtrades.config.TradeConfig; import xyz.jpenilla.wanderingtrades.gui.ListTradeConfigsInterface; @@ -28,6 +24,8 @@ import xyz.jpenilla.wanderingtrades.util.Constants; import static net.kyori.adventure.text.Component.text; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; +import static xyz.jpenilla.wanderingtrades.command.argument.TradeConfigParser.tradeConfigParser; public final class ConfigCommands extends BaseCommand { public ConfigCommands(final WanderingTrades plugin, final Commands commands) { @@ -40,55 +38,55 @@ public void register() { /* List Trade Configs Command */ final Command list = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_LIST_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_LIST_DESCRIPTION.asDescription()) .literal("list") .permission("wanderingtrades.list") .handler(this::executeList) .build(); /* Trade Config Edit Command */ - final Command edit = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_EDIT_DESCRIPTION.asComponent()) + final Command edit = wt + .commandDescription(Messages.COMMAND_EDIT_DESCRIPTION.asDescription()) .literal("edit") - .argument(TradeConfigArgument.optional("trade_config")) + .optional("trade_config", tradeConfigParser()) .permission("wanderingtrades.edit") .senderType(Player.class) .handler(context -> { - final TradeConfig config = context.getOptional("trade_config").orElse(null); + final TradeConfig config = context.optional("trade_config").orElse(null); if (config == null) { - new ListTradeConfigsInterface(this.plugin).open((Player) context.getSender()); + new ListTradeConfigsInterface(this.plugin).open(context.sender()); } else { - new ListTradesInterface(this.plugin, config).open((Player) context.getSender()); + new ListTradesInterface(this.plugin, config).open(context.sender()); } }) .build(); /* Plugin Config Edit Command */ - final Command editConfig = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_EDITCONFIG_DESCRIPTION.asComponent()) + final Command editConfig = wt + .commandDescription(Messages.COMMAND_EDITCONFIG_DESCRIPTION.asDescription()) .literal("editconfig") .permission("wanderingtrades.edit") .senderType(Player.class) - .handler(context -> new MainConfigInterface(this.plugin).open((Player) context.getSender())) + .handler(context -> new MainConfigInterface(this.plugin).open(context.sender())) .build(); /* Player Head Config Edit Command */ - final Command editPlayerHeadConfig = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_EDITPLAYERHEADS_DESCRIPTION.asComponent()) + final Command editPlayerHeadConfig = wt + .commandDescription(Messages.COMMAND_EDITPLAYERHEADS_DESCRIPTION.asDescription()) .literal("editplayerheads") .permission("wanderingtrades.edit") .senderType(Player.class) - .handler(context -> new PlayerHeadConfigInterface(this.plugin).open((Player) context.getSender())) + .handler(context -> new PlayerHeadConfigInterface(this.plugin).open(context.sender())) .build(); // Needed for 1.19+ as run_command click events can no longer be used to send chat messages this.commandManager.command(wt .literal("accept-input") - .argument(StringArgument.greedy("input")) + .required("input", greedyStringParser()) .permission("wanderingtrades.edit") .senderType(Player.class) .handler(context -> { - final Player player = (Player) context.getSender(); + final Player player = context.sender(); if (!player.isConversing()) { this.plugin.audiences().player(player).sendMessage(text("Error. This command is meant for use by click events.", NamedTextColor.RED)); return; @@ -97,14 +95,13 @@ public void register() { })); /* Held ItemStack Rename Command */ - final Command nameHeldItem = this.commandManager.commandBuilder("namehelditem") - .meta(CommandMeta.DESCRIPTION, "Sets the display name of the held ItemStack.") - .argument(StringArgument.of("name", StringArgument.StringMode.GREEDY), - ArgumentDescription.of("The MiniMessage string to use as a name.")) + final Command nameHeldItem = this.commandManager.commandBuilder("namehelditem") + .commandDescription(Description.of("Sets the display name of the held ItemStack.")) + .required("name", greedyStringParser(), Description.of("The MiniMessage string to use as a name.")) .permission("wanderingtrades.namehand") .senderType(Player.class) .handler(context -> { - final Player player = (Player) context.getSender(); + final Player player = context.sender(); if (player.getInventory().getItemInMainHand().getType() != Material.AIR) { player.getInventory().setItemInMainHand( ItemBuilder.create(player.getInventory().getItemInMainHand()) @@ -121,7 +118,7 @@ public void register() { private void executeList(final CommandContext context) { this.chat.send( - context.getSender(), + context.sender(), Component.textOfChildren(Constants.PREFIX_COMPONENT, Messages.COMMAND_LIST_LOADED) ); final List toSort = new ArrayList<>(this.plugin.configManager().tradeConfigs().values()); @@ -130,7 +127,7 @@ private void executeList(final CommandContext context) { for (final TradeConfig cfg : toSort) { final String color = cfg.enabled() ? "green" : "red"; this.chat.send( - context.getSender(), + context.sender(), String.format(" %s. Click to edit'><%s>%s", index++, cfg.configName(), color, cfg.configName()) ); } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/HelpCommand.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/HelpCommand.java index be1eb84..020d69c 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/HelpCommand.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/HelpCommand.java @@ -1,95 +1,91 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.Command; -import cloud.commandframework.CommandHelpHandler; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; -import cloud.commandframework.minecraft.extras.MinecraftHelp; +import java.util.Map; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.component.CommandComponent; +import org.incendo.cloud.component.DefaultValue; +import org.incendo.cloud.component.TypedCommandComponent; +import org.incendo.cloud.help.HelpHandler; +import org.incendo.cloud.help.result.CommandEntry; +import org.incendo.cloud.help.result.IndexCommandResult; +import org.incendo.cloud.minecraft.extras.MinecraftHelp; +import org.incendo.cloud.minecraft.extras.caption.ComponentCaptionFormatter; +import org.incendo.cloud.suggestion.SuggestionProvider; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; import xyz.jpenilla.wanderingtrades.command.Commands; import xyz.jpenilla.wanderingtrades.config.Messages; -import xyz.jpenilla.wanderingtrades.util.Components; + +import static org.incendo.cloud.minecraft.extras.MinecraftHelp.helpColors; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; @DefaultQualifier(NonNull.class) public final class HelpCommand extends BaseCommand { private final MinecraftHelp minecraftHelp; - private final CommandHelpHandler commandHelpHandler; + private final HelpHandler commandHelpHandler; public HelpCommand(final WanderingTrades plugin, final Commands commands) { super(plugin, commands); this.minecraftHelp = this.createMinecraftHelp(); - this.commandHelpHandler = this.commandManager.createCommandHelpHandler(); + this.commandHelpHandler = this.commandManager.createHelpHandler(); } @Override public void register() { /* Help Query Argument */ - final CommandArgument helpQueryArgument = StringArgument.builder("query") - .greedy() - .asOptional() - .withSuggestionsProvider((context, input) -> { - final CommandHelpHandler.IndexHelpTopic indexHelpTopic = - (CommandHelpHandler.IndexHelpTopic) this.commandHelpHandler.queryHelp(context.getSender(), ""); - return indexHelpTopic.getEntries() + final TypedCommandComponent helpQueryArgument = CommandComponent.ofType(String.class, "query") + .parser(greedyStringParser()) + .optional() + .suggestionProvider(SuggestionProvider.blockingStrings((context, input) -> { + final IndexCommandResult indexHelpTopic = this.commandHelpHandler.queryRootIndex(context.sender()); + return indexHelpTopic.entries() .stream() - .map(CommandHelpHandler.VerboseHelpEntry::getSyntaxString) + .map(CommandEntry::syntax) .toList(); - }) + })) + .description(Messages.COMMAND_ARGUMENT_HELP_QUERY.asDescription()) + .defaultValue(DefaultValue.constant("")) .build(); /* Help Command */ final Command help = this.commandManager.commandBuilder("wt", "wanderingtrades") - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_HELP_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_HELP_DESCRIPTION.asDescription()) .literal("help") - .argument(helpQueryArgument, Messages.COMMAND_ARGUMENT_HELP_QUERY.asDescription()) - .handler(context -> this.minecraftHelp.queryCommands( - context.getOptional(helpQueryArgument).orElse(""), - context.getSender() - )) + .argument(helpQueryArgument) + .handler(context -> this.minecraftHelp.queryCommands(context.get(helpQueryArgument), context.sender())) .build(); this.commandManager.command(help); } private MinecraftHelp createMinecraftHelp() { - final MinecraftHelp minecraftHelp = new MinecraftHelp<>( - "/wanderingtrades help", - this.plugin.audiences()::sender, - this.commandManager - ); - minecraftHelp.setHelpColors(MinecraftHelp.HelpColors.of( - TextColor.color(0x00a3ff), - NamedTextColor.WHITE, - TextColor.color(0x284fff), - NamedTextColor.GRAY, - NamedTextColor.DARK_GRAY - )); - minecraftHelp.messageProvider(this::helpMessage); - return minecraftHelp; + return MinecraftHelp.builder() + .commandManager(this.commandManager) + .audienceProvider(this.plugin.audiences()::sender) + .commandPrefix("/wanderingtrades help") + .messageProvider(this::helpMessage) + .colors(helpColors( + TextColor.color(0x00a3ff), + NamedTextColor.WHITE, + TextColor.color(0x284fff), + NamedTextColor.GRAY, + NamedTextColor.DARK_GRAY + )) + .build(); } - private Component helpMessage(final CommandSender sender, final String key, final String... args) { - // Hack but works - final TagResolver[] placeholders; - if (args.length == 0) { - placeholders = new TagResolver[]{}; - } else { - placeholders = new TagResolver[]{ - Components.placeholder("page", args[0]), - Components.placeholder("max_pages", args[1]) - }; + private Component helpMessage(final CommandSender sender, final String key, final Map args) { + if (key.equals("help")) { + return Messages.COMMAND_HELP_DESCRIPTION.asComponent(); } - return ((Messages.SingleMessage) Messages.get("command.help.message." + key.replace("_", "-"))) - .withPlaceholders(placeholders); + return MinecraftHelp.captionMessageProvider(this.commandManager.captionRegistry(), ComponentCaptionFormatter.miniMessage()) + .provide(sender, key, args); } } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ReloadCommand.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ReloadCommand.java index c5ff649..e63493a 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ReloadCommand.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/ReloadCommand.java @@ -1,11 +1,10 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; import xyz.jpenilla.pluginbase.legacy.Chat; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; @@ -21,7 +20,7 @@ public ReloadCommand(final WanderingTrades plugin, final Commands commands) { @Override public void register() { final Command reload = this.commandManager.commandBuilder("wt") - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_RELOAD_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_RELOAD_DESCRIPTION.asDescription()) .literal("reload") .permission("wanderingtrades.reload") .handler(this::execute) @@ -31,8 +30,8 @@ public void register() { } private void execute(final CommandContext context) { - this.chat.send(context.getSender(), Chat.getCenteredMessage(Messages.COMMAND_RELOAD.message())); + this.chat.send(context.sender(), Chat.getCenteredMessage(Messages.COMMAND_RELOAD.message())); this.plugin.reload(); - this.chat.send(context.getSender(), Chat.getCenteredMessage(Messages.COMMAND_RELOAD_DONE.message())); + this.chat.send(context.sender(), Chat.getCenteredMessage(Messages.COMMAND_RELOAD_DONE.message())); } } diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/SummonCommands.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/SummonCommands.java index f4dda2c..a4645d1 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/SummonCommands.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/SummonCommands.java @@ -1,17 +1,5 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.EnumArgument; -import cloud.commandframework.arguments.standard.IntegerArgument; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector; -import cloud.commandframework.bukkit.parsers.WorldArgument; -import cloud.commandframework.bukkit.parsers.location.LocationArgument; -import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.meta.CommandMeta; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; import io.papermc.lib.PaperLib; import java.lang.reflect.Method; import java.util.List; @@ -30,16 +18,27 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.data.SingleEntitySelector; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.description.Description; import xyz.jpenilla.pluginbase.legacy.MiniMessageUtil; import xyz.jpenilla.pluginbase.legacy.PaperComponentUtil; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; import xyz.jpenilla.wanderingtrades.command.Commands; -import xyz.jpenilla.wanderingtrades.command.argument.TradeConfigArgument; import xyz.jpenilla.wanderingtrades.config.Messages; import xyz.jpenilla.wanderingtrades.config.TradeConfig; import xyz.jpenilla.wanderingtrades.util.Constants; +import static org.incendo.cloud.bukkit.parser.WorldParser.worldParser; +import static org.incendo.cloud.bukkit.parser.location.LocationParser.locationParser; +import static org.incendo.cloud.bukkit.parser.selector.SingleEntitySelectorParser.singleEntitySelectorParser; +import static org.incendo.cloud.parser.standard.EnumParser.enumParser; +import static org.incendo.cloud.parser.standard.IntegerParser.integerParser; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; +import static xyz.jpenilla.wanderingtrades.command.argument.TradeConfigParser.tradeConfigParser; + @DefaultQualifier(NonNull.class) public final class SummonCommands extends BaseCommand { public SummonCommands( @@ -51,17 +50,17 @@ public SummonCommands( commands.registerFlag( "pitch", this.commandManager.flagBuilder("pitch") - .withArgument(IntegerArgument.builder("pitch").withMin(-180).withMax(180)) + .withComponent(integerParser(-180, 180)) ); commands.registerFlag( "yaw", this.commandManager.flagBuilder("yaw") - .withArgument(IntegerArgument.builder("yaw").withMin(-90).withMax(90)) + .withComponent(integerParser(-90, 90)) ); commands.registerFlag( "world", this.commandManager.flagBuilder("world") - .withArgument(WorldArgument.of("world")) + .withComponent(worldParser()) ); } @@ -70,9 +69,9 @@ public void register() { final Command.Builder wt = this.commandManager.commandBuilder("wt"); final Command summonNatural = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_SUMMONNATURAL_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_SUMMONNATURAL_DESCRIPTION.asDescription()) .literal("summonnatural") - .argument(LocationArgument.of("location")) + .required("location", locationParser()) .flag(this.commands.getFlag("world")) .flag(this.commands.getFlag("pitch")) .flag(this.commands.getFlag("yaw")) @@ -91,17 +90,17 @@ public void register() { .build(); final Command summon = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_SUMMON_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_SUMMON_DESCRIPTION.asDescription()) .literal("summon") - .argument(TradeConfigArgument.of("trade_config")) - .argument(LocationArgument.of("location")) + .required("trade_config", tradeConfigParser()) + .required("location", locationParser()) .flag(this.commands.getFlag("world")) .flag(this.commands.getFlag("pitch")) .flag(this.commands.getFlag("yaw")) .flag(this.commandManager.flagBuilder("noai")) .permission("wanderingtrades.summon") .handler(context -> this.summonTrader( - context.getSender(), + context.sender(), context.get("trade_config"), resolveLocation(context), context.flags().isPresent("noai") @@ -109,19 +108,19 @@ public void register() { .build(); final Command summonVillager = wt - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, Messages.COMMAND_SUMMONVILLAGER_DESCRIPTION.asComponent()) + .commandDescription(Messages.COMMAND_SUMMONVILLAGER_DESCRIPTION.asDescription()) .literal("summonvillager") - .argument(TradeConfigArgument.of("trade_config")) - .argument(EnumArgument.of(Villager.Type.class, "type")) - .argument(EnumArgument.of(Villager.Profession.class, "profession")) - .argument(LocationArgument.of("location")) + .required("trade_config", tradeConfigParser()) + .required("type", enumParser(Villager.Type.class)) + .required("profession", enumParser(Villager.Profession.class)) + .required("location", locationParser()) .flag(this.commands.getFlag("world")) .flag(this.commands.getFlag("pitch")) .flag(this.commands.getFlag("yaw")) .flag(this.commandManager.flagBuilder("noai")) .permission("wanderingtrades.villager") .handler(context -> this.summonVillagerTrader( - context.getSender(), + context.sender(), context.get("trade_config"), resolveLocation(context), context.get("type"), @@ -131,21 +130,20 @@ public void register() { .build(); /* Entity Rename Command */ - final Command nameEntity = this.commandManager.commandBuilder("nameentity") - .meta(CommandMeta.DESCRIPTION, "Sets the name of an entity.") - .argument(SingleEntitySelectorArgument.of("entity")) - .argument(StringArgument.of("name", StringArgument.StringMode.GREEDY), - ArgumentDescription.of("The MiniMessage string to use as a name.")) + final Command nameEntity = this.commandManager.commandBuilder("nameentity") + .commandDescription(Description.of("Sets the name of an entity.")) + .required("entity", singleEntitySelectorParser()) + .required("name", greedyStringParser(), Description.of("The MiniMessage string to use as a name.")) .permission("wanderingtrades.name") .senderType(Player.class) .handler(context -> { - final @Nullable Entity entity = context.get("entity").getEntity(); + final @Nullable Entity entity = context.get("entity").single(); if (entity != null && !(entity instanceof Player)) { this.setCustomName(entity, context.get("name")); entity.setCustomNameVisible(true); - this.chat.send(context.getSender(), "Named entity: " + context.get("name")); + this.chat.send(context.sender(), "Named entity: " + context.get("name")); } else { - this.chat.send(context.getSender(), "Cannot name player or non-living entity."); + this.chat.send(context.sender(), "Cannot name player or non-living entity."); } }) .build(); diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/TradeCommands.java b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/TradeCommands.java index 0ce0c8c..43c6723 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/TradeCommands.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/command/commands/TradeCommands.java @@ -1,11 +1,7 @@ package xyz.jpenilla.wanderingtrades.command.commands; -import cloud.commandframework.Command; -import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector; -import cloud.commandframework.bukkit.parsers.selector.MultiplePlayerSelectorArgument; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.InvalidCommandSenderException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import net.kyori.adventure.text.Component; import org.bukkit.command.CommandSender; @@ -17,14 +13,20 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.data.MultiplePlayerSelector; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.exception.InvalidCommandSenderException; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.command.BaseCommand; import xyz.jpenilla.wanderingtrades.command.Commands; -import xyz.jpenilla.wanderingtrades.command.argument.TradeConfigArgument; import xyz.jpenilla.wanderingtrades.config.TradeConfig; import xyz.jpenilla.wanderingtrades.util.Constants; import xyz.jpenilla.wanderingtrades.util.InventoryFactory; +import static org.incendo.cloud.bukkit.parser.selector.MultiplePlayerSelectorParser.multiplePlayerSelectorParser; +import static xyz.jpenilla.wanderingtrades.command.argument.TradeConfigParser.tradeConfigParser; + @DefaultQualifier(NonNull.class) public final class TradeCommands extends BaseCommand { public TradeCommands(final WanderingTrades plugin, final Commands commands) { @@ -39,13 +41,13 @@ public void register() { final Command.Builder config = trade .literal("config") - .argument(TradeConfigArgument.of("config")) + .required("config", tradeConfigParser()) .permission("wanderingtrades.tradecommand") .handler(this::tradeConfig); this.commandManager.command(config); this.commandManager.command(config .permission("wanderingtrades.tradecommand.others") - .argument(MultiplePlayerSelectorArgument.of("players"))); + .required("players", multiplePlayerSelectorParser())); final Command.Builder natural = trade .literal("natural") @@ -54,7 +56,7 @@ public void register() { this.commandManager.command(natural); this.commandManager.command(natural .permission("wanderingtrades.tradenaturalcommand.others") - .argument(MultiplePlayerSelectorArgument.of("players"))); + .required("players", multiplePlayerSelectorParser())); } private void tradeConfig(final CommandContext ctx) { @@ -104,15 +106,15 @@ private void tradeNatural(final Player player) { }); } - private static List players(final CommandContext ctx) { - @Nullable List players = ctx.getOptional("players") - .map(MultiplePlayerSelector::getPlayers) + private static Collection players(final CommandContext ctx) { + @Nullable Collection players = ctx.optional("players") + .map(MultiplePlayerSelector::values) .orElse(null); if (players == null) { - if (ctx.getSender() instanceof Player player) { + if (ctx.sender() instanceof Player player) { players = List.of(player); } else { - throw new InvalidCommandSenderException(ctx.getSender(), Player.class, null); + throw new InvalidCommandSenderException(ctx.sender(), Player.class, null); } } return players; diff --git a/src/main/java/xyz/jpenilla/wanderingtrades/config/Messages.java b/src/main/java/xyz/jpenilla/wanderingtrades/config/Messages.java index 4b3c205..31fe10c 100644 --- a/src/main/java/xyz/jpenilla/wanderingtrades/config/Messages.java +++ b/src/main/java/xyz/jpenilla/wanderingtrades/config/Messages.java @@ -1,6 +1,5 @@ package xyz.jpenilla.wanderingtrades.config; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.common.base.Suppliers; import java.io.File; import java.io.IOException; @@ -25,6 +24,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.description.Description; +import org.incendo.cloud.minecraft.extras.RichDescription; import xyz.jpenilla.wanderingtrades.WanderingTrades; import xyz.jpenilla.wanderingtrades.util.Logging; @@ -40,12 +41,6 @@ public final class Messages { public static SingleMessage COMMAND_ABOUT_DESCRIPTION; @Key(value = "command.argument.help-query", legacyKey = "COMMAND_ARGUMENT_HELP_QUERY") public static SingleMessage COMMAND_ARGUMENT_HELP_QUERY; - @Key(value = "command.exception.parse.failure-enum", legacyKey = "COMMAND_ARGUMENT_PARSE_FAILURE_ENUM") - public static SingleMessage COMMAND_ARGUMENT_PARSE_FAILURE_ENUM; - @Key(value = "command.exception.parse.failure-location-invalid-format", legacyKey = "COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_INVALID_FORMAT") - public static SingleMessage COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_INVALID_FORMAT; - @Key(value = "command.exception.parse.failure-location-mixed-local-absolute", legacyKey = "COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE") - public static SingleMessage COMMAND_ARGUMENT_PARSE_FAILURE_LOCATION_MIXED_LOCAL_ABSOLUTE; @Key(value = "command.editconfig.description", legacyKey = "COMMAND_WT_CONFIG") public static SingleMessage COMMAND_EDITCONFIG_DESCRIPTION; @Key(value = "command.editplayerheads.description", legacyKey = "COMMAND_WT_PH_CONFIG") @@ -54,38 +49,6 @@ public final class Messages { public static SingleMessage COMMAND_EDIT_DESCRIPTION; @Key(value = "command.help.description", legacyKey = "COMMAND_WT_HELP") public static SingleMessage COMMAND_HELP_DESCRIPTION; - @Key(value = "command.help.message.arguments", legacyKey = "HELP_ARGUMENTS") - public static SingleMessage COMMAND_HELP_MESSAGE_ARGUMENTS; - @Key(value = "command.help.message.available-commands", legacyKey = "HELP_AVAILABLE_COMMANDS") - public static SingleMessage COMMAND_HELP_MESSAGE_AVAILABLE_COMMANDS; - @Key(value = "command.help.message.click-for-next-page", legacyKey = "HELP_CLICK_FOR_NEXT_PAGE") - public static SingleMessage COMMAND_HELP_MESSAGE_CLICK_FOR_NEXT_PAGE; - @Key(value = "command.help.message.click-for-previous-page", legacyKey = "HELP_CLICK_FOR_PREVIOUS_PAGE") - public static SingleMessage COMMAND_HELP_MESSAGE_CLICK_FOR_PREVIOUS_PAGE; - @Key(value = "command.help.message.click-to-show-help", legacyKey = "HELP_CLICK_TO_SHOW_HELP") - public static SingleMessage COMMAND_HELP_MESSAGE_CLICK_TO_SHOW_HELP; - @Key(value = "command.help.message.command", legacyKey = "HELP_COMMAND") - public static SingleMessage COMMAND_HELP_MESSAGE_COMMAND; - @Key(value = "command.help.message.description", legacyKey = "HELP_DESCRIPTION") - public static SingleMessage COMMAND_HELP_MESSAGE_DESCRIPTION; - @Key(value = "command.help.message.help", legacyKey = "HELP_HELP") - public static SingleMessage COMMAND_HELP_MESSAGE_HELP; - @Key(value = "command.help.message.no-description", legacyKey = "HELP_NO_DESCRIPTION") - public static SingleMessage COMMAND_HELP_MESSAGE_NO_DESCRIPTION; - @Key(value = "command.help.message.no-results-for-query", legacyKey = "HELP_NO_RESULTS_FOR_QUERY") - public static SingleMessage COMMAND_HELP_MESSAGE_NO_RESULTS_FOR_QUERY; - @Key(value = "command.help.message.optional", legacyKey = "HELP_OPTIONAL") - public static SingleMessage COMMAND_HELP_MESSAGE_OPTIONAL; - @Key(value = "command.help.message.page-out-of-range", legacyKey = "HELP_PAGE_OUT_OF_RANGE") - public static SingleMessage COMMAND_HELP_MESSAGE_PAGE_OUT_OF_RANGE; - @Key(value = "command.help.message.showing-results-for-query", legacyKey = "HELP_SHOWING_RESULTS_FOR_QUERY") - public static SingleMessage COMMAND_HELP_MESSAGE_SHOWING_RESULTS_FOR_QUERY; - @Key(value = "command.exception.invalid-argument", legacyKey = "COMMAND_INVALID_ARGUMENT") - public static SingleMessage COMMAND_INVALID_ARGUMENT; - @Key(value = "command.exception.invalid-sender", legacyKey = "COMMAND_INVALID_SENDER") - public static SingleMessage COMMAND_INVALID_SENDER; - @Key(value = "command.exception.invalid-syntax", legacyKey = "COMMAND_INVALID_SYNTAX") - public static SingleMessage COMMAND_INVALID_SYNTAX; @Key(value = "command.exception.malformed-config", legacyKey = "COMMAND_SUMMON_MALFORMED_CONFIG") public static SingleMessage COMMAND_EXCEPTION_MALFORMED_CONFIG; @Key(value = "command.list.description", legacyKey = "COMMAND_WT_LIST") @@ -450,7 +413,7 @@ static SingleMessage create(final String message) { return new SingleMessage(message); } - default RichDescription asDescription() { + default Description asDescription() { return RichDescription.of(this.asComponent()); } } diff --git a/src/main/resources/lang/de_DE.yml b/src/main/resources/lang/de_DE.yml index f018875..eecdeb7 100644 --- a/src/main/resources/lang/de_DE.yml +++ b/src/main/resources/lang/de_DE.yml @@ -6,18 +6,7 @@ command: help-query: Abfragehilfe exception: parse: - failure-enum: '''{input}'' ist keine von den folgenden: {acceptableValues}' - failure-location-invalid-format: '''{input}'' ist kein gültiger Ort. Erforderliches - Format ist '' ''' - failure-location-mixed-local-absolute: Absolute und relative Koordinaten können - nicht gemischt werden. (Entweder alle Koordinaten nutzen '^' oder keine tut - es.) no-trade-config: Es sind keine Angebots-Konfigurationen mit diesem Namen geladen. - invalid-argument: 'Ungültiges Befehlsargument: ' - invalid-sender: Ungültiger Befehlseingabeort. Du musst vom Typ - sein. - invalid-syntax: 'Ungültige Befehlseingabe. Die korrekte Befehlssyntax lautet: - ' malformed-config: Diese Konfiguration enthält fehler. Stelle sicher, dass die Rezepte mindestens ein Item enthalten. editconfig: @@ -30,21 +19,6 @@ command: bearbeiten. help: description: WanderingTrades Hilfe - message: - arguments: Argumente - available-commands: Verfügbare Befehle - click-for-next-page: Klicken für die nächste Seite - click-for-previous-page: Klicken für die vorherige Seite - click-to-show-help: Klicken um Hilfe für diesen Befehl anzuzeigen. - command: Befehl - description: Beschreibung - help: WanderingTrades Hilfe - no-description: Keine Beschreibung - no-results-for-query: Keine Ergebnisse für die Abfrage. - optional: Optional - page-out-of-range: 'Fehler: Seite ist nicht in Reichweite. Sie muss sich - innerhalb der Reichweite befinden. [1, ]' - showing-results-for-query: Zeigt die Ergebnisse der Abfrage. list: description: Zeigt die geladenen Angebots-Konfigurationen an. message: 'Geladene Angebots-Konfigurationen:' diff --git a/src/main/resources/lang/en_US.yml b/src/main/resources/lang/en_US.yml index 788b818..21094e9 100644 --- a/src/main/resources/lang/en_US.yml +++ b/src/main/resources/lang/en_US.yml @@ -6,15 +6,7 @@ command: help-query: Help Query exception: parse: - failure-enum: '''{input}'' is not one of the following: {acceptableValues}' - failure-location-invalid-format: '''{input}'' is not a valid location. Required - format is '' ''' - failure-location-mixed-local-absolute: Cannot mix local and absolute coordinates. - (either all coordinates use '^' or none do) no-trade-config: There are no trade configs with that name loaded. - invalid-argument: 'Invalid command argument: ' - invalid-sender: Invalid command sender. You must be of type . - invalid-syntax: 'Invalid command syntax. Correct command syntax is: ' malformed-config: Config is malformed. Make sure recipes have at least one ingredient. editconfig: @@ -25,21 +17,6 @@ command: description: Opens a GUI menu to edit and create trade configs help: description: WanderingTrades Help - message: - arguments: Arguments - available-commands: Available Commands - click-for-next-page: Click for next page - click-for-previous-page: Click for previous page - click-to-show-help: Click to show help for this command - command: Command - description: Description - help: WanderingTrades Help - no-description: No description - no-results-for-query: No results for query - optional: Optional - page-out-of-range: 'Error: Page is not in range. Must be in range [1, - ]' - showing-results-for-query: Showing search results for query list: description: Lists the loaded trade configs. message: 'Loaded Trade Configs:' diff --git a/src/main/resources/lang/ro_RO.yml b/src/main/resources/lang/ro_RO.yml index a5edda8..df829e3 100644 --- a/src/main/resources/lang/ro_RO.yml +++ b/src/main/resources/lang/ro_RO.yml @@ -6,15 +6,7 @@ command: help-query: Help Query exception: parse: - failure-enum: '„{input}” nu este în mulțimea: {acceptableValues}' - failure-location-invalid-format: „{input}” nu este o locație validă. Formatul - cerut este „ ” - failure-location-mixed-local-absolute: Nu poate conține și coordonate absolute - și coordonate locale (Ori folosesc toate coordonatele „^” sau niciuna) no-trade-config: Nu există nicio configurație încărcată cu numele acela. - invalid-argument: 'Parametru invalid pentru comandă: ' - invalid-sender: Command sender invalid. Trebuie să fii un - invalid-syntax: 'Sintaxă invalidă. Sintaxa corectă a comenzii este: ' malformed-config: Această configurație nu este formatată corect. Verifică dacă schimburile au măcar un obiect. editconfig: @@ -25,21 +17,6 @@ command: description: Deschide un meniu pentru a crea si edita schimburi. help: description: WanderingTrades Help - message: - arguments: Parametrii - available-commands: Comenzi disponibile - click-for-next-page: Dă click pentru pagina următoare - click-for-previous-page: Dă click pentru pagina precedentă - click-to-show-help: Dă click pentru a primi ajutor în folosirea comenzii - command: Comandă - description: Descriere - help: WanderingTrades Help - no-description: Nicio descriere - no-results-for-query: Niciun rezultat pentru căutare - optional: Opțional - page-out-of-range: 'Eroare: Pagina nu este în interval. Trebuie să fie - în intervalul [1, ]' - showing-results-for-query: Rezultatele căutării list: description: Enumeră toate configurațiile de schimb încărcate. message: 'Configurațiile de schimburi au fost încărcate:' diff --git a/src/main/resources/lang/ru_RU.yml b/src/main/resources/lang/ru_RU.yml index 17721cd..92657c5 100644 --- a/src/main/resources/lang/ru_RU.yml +++ b/src/main/resources/lang/ru_RU.yml @@ -6,16 +6,7 @@ command: help-query: Справка exception: parse: - failure-enum: '''{input}'' не является одним из: {acceptableValues}' - failure-location-invalid-format: '''{input}'' не является допустимым местоположением. - Требуемый формат '' ''' - failure-location-mixed-local-absolute: Невозможно смешивать локальные и абсолютные - координаты. (либо все координаты используют '^', либо ни одна не использует) no-trade-config: Не существует конфигурации торгов с таким именем. - invalid-argument: 'Недопустимый аргумент команды: ' - invalid-sender: Неверный отправитель команды. Вы должны быть - invalid-syntax: 'Неправильный синтаксис команды. Правильный синтаксис команды: - ' malformed-config: Эта конфигурация неправильно сформирована. Убедитесь, что в рецептах есть хотя бы один ингредиент. editconfig: @@ -26,21 +17,6 @@ command: description: Открывает меню для редактирования и создания торговых конфигураций help: description: Помощь WanderingTrades - message: - arguments: Аргументы - available-commands: Доступные команды - click-for-next-page: Нажмите для перехода на следующую страницу - click-for-previous-page: Нажмите для просмотра предыдущей страницы - click-to-show-help: Нажмите, чтобы показать справку для этой команды - command: Команда - description: Описание - help: Помощь WanderingTrades - no-description: Нет описания - no-results-for-query: Нет результатов по запросу - optional: Опционально - page-out-of-range: 'Ошибка: Страница не находится в диапазоне. Должна - быть в диапазоне [1, ]' - showing-results-for-query: Показаны результаты поиска по запросу list: description: Список загруженных конфигураций торгов. message: 'Загруженные конфигурации торгов:' diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 88fad47..f600b75 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -6,13 +6,7 @@ command: help-query: 帮助查询 exception: parse: - failure-enum: '''{input}''不属于下列情况: {acceptableValues}' - failure-location-invalid-format: '''{input}''不是有效的位置坐标,所需格式为'' ''' - failure-location-mixed-local-absolute: 不能混合使用本地坐标和绝对坐标(所有坐标都使用'^'或不使用) no-trade-config: 没有加载该名称的交易配置 - invalid-argument: 无效的命令参数: - invalid-sender: 使用此命令您必须是 - invalid-syntax: 无效的命令语法。正确的命令语法是: malformed-config: 配置格式不正确,请确保食谱至少拥有一种成分 editconfig: description: 打开GUI以编辑 config.yml 配置 @@ -22,20 +16,6 @@ command: description: 打开GUI以编辑和创建交易配置 help: description: WanderingTrades 帮助 - message: - arguments: 参数 - available-commands: 可用命令 - click-for-next-page: 点击进入下一页 - click-for-previous-page: 点击进入上一页 - click-to-show-help: 单击此处显示此命令的帮助 - command: 命令 - description: 描述 - help: WanderingTrades帮助 - no-description: 无描述 - no-results-for-query: 无查询结果 - optional: 可选 - page-out-of-range: '错误: 第页不在范围内。可用范围[1, ]' - showing-results-for-query: 显示查询的搜索结果 list: description: 列出已加载的交易配置 message: '已加载交易配置:'