diff --git a/build.gradle.kts b/build.gradle.kts index a90a25a1..a55ce519 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ import xyz.jpenilla.runpaper.task.RunServer plugins { java + idea alias(libs.plugins.shadow) alias(libs.plugins.indra.licenser.spotless) alias(libs.plugins.runPaper) @@ -96,6 +97,13 @@ indraSpotlessLicenser { } } +idea { + module { + isDownloadJavadoc = true + isDownloadSources = true + } +} + tasks { assemble { dependsOn(shadowJar) @@ -143,7 +151,7 @@ tasks { } listOf( - "cloud.commandframework", // cloud + "org.incendo", // cloud "com.fasterxml.jackson", // jackson "com.github.benmanes", // caffeine "com.google.inject", // guice diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ce92d6d6..e53060a1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ minecraft = "1.20.4" mm-mirror = "0.1.2" mm-lectern = "0.3.0" # deprecated -cloud = "1.8.4" +cloud = "2.0.0-beta.2" bstats = "3.0.2" moonshine = "2.0.4" guice = "5.1.0" @@ -32,8 +32,8 @@ runPaper = "2.2.2" mm-mirror = { module = "me.machinemaker.mirror:mirror-paper", version.ref = "mm-mirror" } mm-lectern = { module = "me.machinemaker.lectern:lectern-yaml", version.ref = "mm-lectern" } # deprecated -cloud-paper = { module = "cloud.commandframework:cloud-paper", version.ref = "cloud" } -cloud-extras = { module = "cloud.commandframework:cloud-minecraft-extras", version.ref = "cloud" } +cloud-paper = { module = "org.incendo:cloud-paper", version.ref = "cloud" } +cloud-extras = { module = "org.incendo:cloud-minecraft-extras", version.ref = "cloud" } guice = { module = "com.google.inject:guice", version.ref = "guice" } guice-assistedInject = { module = "com.google.inject.extensions:guice-assistedinject", version.ref = "guice" } diff --git a/src/main/java/me/machinemaker/papertweaks/GlobalListener.java b/src/main/java/me/machinemaker/papertweaks/GlobalListener.java index 2d029daa..09a40481 100644 --- a/src/main/java/me/machinemaker/papertweaks/GlobalListener.java +++ b/src/main/java/me/machinemaker/papertweaks/GlobalListener.java @@ -19,8 +19,8 @@ */ package me.machinemaker.papertweaks; -import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.paper.PaperCommandManager; +import org.incendo.cloud.bukkit.CloudBukkitCapabilities; +import org.incendo.cloud.paper.PaperCommandManager; import com.google.inject.Inject; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ModuleManager; diff --git a/src/main/java/me/machinemaker/papertweaks/RootCommand.java b/src/main/java/me/machinemaker/papertweaks/RootCommand.java index 3938bc92..fb4a3e21 100644 --- a/src/main/java/me/machinemaker/papertweaks/RootCommand.java +++ b/src/main/java/me/machinemaker/papertweaks/RootCommand.java @@ -19,11 +19,6 @@ */ package me.machinemaker.papertweaks; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.IntegerArgument; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.inject.Inject; import com.google.inject.name.Named; import java.util.ArrayList; @@ -32,7 +27,6 @@ import me.machinemaker.lectern.ConfigurationNode; import me.machinemaker.papertweaks.adventure.Components; import me.machinemaker.papertweaks.cloud.PaperTweaksCommand; -import me.machinemaker.papertweaks.cloud.arguments.ModuleArgument; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.menus.AbstractConfigurationMenu; import me.machinemaker.papertweaks.modules.ModuleBase; @@ -49,7 +43,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import org.incendo.cloud.Command; +import org.incendo.cloud.component.DefaultValue; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.minecraft.extras.RichDescription; +import static me.machinemaker.papertweaks.cloud.parsers.ParserFactory.moduleDescriptor; import static net.kyori.adventure.text.Component.join; import static net.kyori.adventure.text.Component.newline; import static net.kyori.adventure.text.Component.space; @@ -65,11 +65,14 @@ import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; import static net.kyori.adventure.text.format.TextColor.color; +import static org.incendo.cloud.key.CloudKey.cloudKey; +import static org.incendo.cloud.parser.standard.IntegerParser.integerParser; @DefaultQualifier(NonNull.class) public class RootCommand extends PaperTweaksCommand { private static final int PAGE_SIZE = 6; + private static final CloudKey MODULE_BASE_KEY = cloudKey("module", ModuleBase.class); private final ModuleManager moduleManager; private final ConfigurationNode modulesConfig; @@ -92,25 +95,25 @@ public void registerCommands() { .handler(this.sync(this::reloadEverything)) ).command(this.simple("reload") .literal("module") - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, translatable("commands.reload.module")) // Override default meta from #simple(String) - .argument(this.argumentFactory.module(true)) - .handler(this.sync(context -> context.getSender().sendMessage(this.moduleManager.reloadModule(ModuleArgument.getModule(context).getName())))) + .commandDescription(RichDescription.translatable("commands.reload.module")) // Override default meta from #simple(String) + .required(MODULE_BASE_KEY, moduleDescriptor(this.argumentFactory, true)) + .handler(this.sync(context -> context.sender().sendMessage(this.moduleManager.reloadModule(context.get(MODULE_BASE_KEY).getName())))) ).command(this.simple("enable") - .argument(this.argumentFactory.module(false)) + .required(MODULE_BASE_KEY, moduleDescriptor(this.argumentFactory, false)) .handler(this.sync(context -> { - final Component enableMsg = this.moduleManager.enableModule(ModuleArgument.getModule(context).getName()); - context.getSender().sendMessage(enableMsg); + final Component enableMsg = this.moduleManager.enableModule(context.get(MODULE_BASE_KEY).getName()); + context.sender().sendMessage(enableMsg); this.console.sendMessage(Components.join(PaperTweaks.PLUGIN_PREFIX, enableMsg)); })) ).command(this.simple("disable") - .argument(this.argumentFactory.module(true)) + .required(MODULE_BASE_KEY, moduleDescriptor(this.argumentFactory, true)) .handler(this.sync(context -> { - final Component disableMsg = this.moduleManager.disableModule(ModuleArgument.getModule(context).getName()); - context.getSender().sendMessage(disableMsg); + final Component disableMsg = this.moduleManager.disableModule(context.get(MODULE_BASE_KEY).getName()); + context.sender().sendMessage(disableMsg); this.console.sendMessage(Components.join(PaperTweaks.PLUGIN_PREFIX, disableMsg)); })) ).command(this.simple("list") - .argument(IntegerArgument.builder("page").withMin(1).withMax(this.maxPageCount).asOptionalWithDefault(1)) + .optional("page", integerParser(1, this.maxPageCount), DefaultValue.constant(1)) .handler(this::sendModuleList) ).command(this.simple("version") .handler(this::showVersion) @@ -118,11 +121,11 @@ public void registerCommands() { } private Command.Builder simple(final String name) { - return this.builder.literal(name).meta(MinecraftExtrasMetaKeys.DESCRIPTION, translatable("commands." + name)).permission("vanillatweaks.main." + name); + return this.builder.literal(name).commandDescription(RichDescription.translatable("commands." + name)).permission("vanillatweaks.main." + name); } private void reloadEverything(final CommandContext context) { - final Audience audience = context.getSender(); + final Audience audience = context.sender(); this.modulesConfig.reloadAndSave(); // TODO reload more stuff final ModuleManager.ReloadResult result = this.moduleManager.reloadModules(); @@ -145,7 +148,7 @@ private void reloadEverything(final CommandContext context) { } private void sendModuleList(final @NonNull CommandContext context) { - final boolean showAll = context.getSender().hasPermission("vanillatweaks.main.list.all"); + final boolean showAll = context.sender().hasPermission("vanillatweaks.main.list.all"); final int page = context.get("page"); final TextComponent.Builder list = text(); final List modules = this.moduleManager.getModules().values().stream().filter(module -> showAll || this.moduleManager.getLifecycle(module.getName()).orElseThrow().getState().isRunning()).toList(); @@ -157,7 +160,7 @@ private void sendModuleList(final @NonNull CommandContext con final ModuleState state = lifecycle.get().getState(); if (showAll || state.isRunning()) { final TextComponent.Builder builder = text().color(color(0x8F8F8F)).append(text(" - ")); - if ((state.isRunning() && context.getSender().hasPermission("vanillatweaks.main.disable")) || (!state.isRunning() && context.getSender().hasPermission("vanillatweaks.main.enable"))) { + if ((state.isRunning() && context.sender().hasPermission("vanillatweaks.main.disable")) || (!state.isRunning() && context.sender().hasPermission("vanillatweaks.main.enable"))) { builder.append( text("[" + (state.isRunning() ? "■" : "▶") + "]", state.isRunning() ? RED : GREEN) .hoverEvent(showText(translatable("commands.config.bool-toggle." + state.isRunning(), state.isRunning() ? RED : GREEN, text(moduleBase.getName(), GOLD)))) @@ -172,7 +175,7 @@ private void sendModuleList(final @NonNull CommandContext con list.append(builder).append(newline()); } } - context.getSender().sendMessage(join(JoinConfiguration.noSeparators(), header, list, AbstractConfigurationMenu.END_LINE)); + context.sender().sendMessage(join(JoinConfiguration.noSeparators(), header, list, AbstractConfigurationMenu.END_LINE)); } private ComponentLike createHeader(final int page, final List modules) { @@ -194,7 +197,7 @@ private void showVersion(final CommandContext context) { .hoverEvent(showText(translatable("commands.version.success.hover", GRAY))) .clickEvent(copyToClipboard(PaperTweaks.class.getPackage().getImplementationVersion())) ); - context.getSender().sendMessage(component); + context.sender().sendMessage(component); } } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/CloudModule.java b/src/main/java/me/machinemaker/papertweaks/cloud/CloudModule.java index 40bcae3d..e0cc1b81 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/CloudModule.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/CloudModule.java @@ -19,15 +19,6 @@ */ package me.machinemaker.papertweaks.cloud; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; -import cloud.commandframework.arguments.StaticArgument; -import cloud.commandframework.brigadier.CloudBrigadierManager; -import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator; -import cloud.commandframework.minecraft.extras.AudienceProvider; -import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; -import cloud.commandframework.paper.PaperCommandManager; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; import com.google.inject.AbstractModule; @@ -46,18 +37,25 @@ import me.machinemaker.mirror.MethodInvoker; import me.machinemaker.mirror.Mirror; import me.machinemaker.mirror.paper.PaperMirror; -import me.machinemaker.papertweaks.cloud.arguments.ArgumentFactory; -import me.machinemaker.papertweaks.cloud.arguments.PseudoEnumArgument; +import me.machinemaker.papertweaks.cloud.parsers.ParserFactory; import me.machinemaker.papertweaks.cloud.cooldown.CommandCooldownManager; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcherFactory; -import me.machinemaker.papertweaks.cloud.processors.SimpleSuggestionProcessor; +import me.machinemaker.papertweaks.cloud.parsers.PseudoEnumParser; +import me.machinemaker.papertweaks.cloud.processors.ConditionalCaseInsensitiveSuggestionProcessor; import me.machinemaker.papertweaks.cloud.processors.post.GamemodePostprocessor; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.SimpleCommandMap; import org.bukkit.plugin.java.JavaPlugin; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.SenderMapper; +import org.incendo.cloud.brigadier.CloudBrigadierManager; +import org.incendo.cloud.bukkit.CloudBukkitCapabilities; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.minecraft.extras.MinecraftExceptionHandler; +import org.incendo.cloud.paper.PaperCommandManager; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.format.NamedTextColor.RED; @@ -82,7 +80,7 @@ private static Map getCommandMap() { @Override protected void configure() { - this.install(new FactoryModuleBuilder().build(ArgumentFactory.class)); + this.install(new FactoryModuleBuilder().build(ParserFactory.class)); } @Provides @@ -90,7 +88,7 @@ protected void configure() { CommandCooldownManager commandCooldownManager() { return CommandCooldownManager.create( CommandDispatcher::getUUID, - (context, cooldown, secondsLeft) -> context.getCommandContext().getSender().sendMessage(text("Cooling down", RED)), + (context, cooldown, secondsLeft) -> context.commandContext().sender().sendMessage(text("Cooling down", RED)), this.executorService); } @@ -101,25 +99,25 @@ PaperCommandManager paperCommandManager(final CommandDispatch final MinecraftExceptionHandler minecraftExceptionHandler) { final LoadingCache senderCache = CacheBuilder.newBuilder().expireAfterAccess(20, TimeUnit.MINUTES).build(commandDispatcherFactory); try { - final PaperCommandManager manager = new PaperCommandManager<>( + final PaperCommandManager manager = new PaperCommandManager( this.plugin, - AsynchronousCommandExecutionCoordinator.builder().build(), - commandSender -> { - try { - return senderCache.get(commandSender); - } catch (final ExecutionException e) { - throw new IllegalArgumentException("Error mapping command sender", e); - } - }, - CommandDispatcher::sender + ExecutionCoordinator.asyncCoordinator(), + SenderMapper.create( + commandSender -> { + try { + return senderCache.get(commandSender); + } catch (final ExecutionException e) { + throw new IllegalArgumentException("Error mapping command sender", e); + } + }, + CommandDispatcher::sender + ) ) { @Override - public CommandManager command(final Command command) { - if (command.getArguments().get(0) instanceof final StaticArgument staticArgument) { - final String main = staticArgument.getName(); - if (VANILLA_COMMAND_WRAPPER_CLASS.isInstance(getCommandMap().get(main))) { - getCommandMap().remove(main); - } + public CommandManager command(final Command command) { + final String main = command.rootComponent().name(); + if (VANILLA_COMMAND_WRAPPER_CLASS.isInstance(getCommandMap().get(main))) { + getCommandMap().remove(main); } return super.command(command); } @@ -132,21 +130,19 @@ public CommandManager command(final Command brigManager = manager.brigadierManager(); - if (brigManager != null) { - brigManager.registerMapping(new TypeToken>() {}, builder -> { - builder.cloudSuggestions().to(argument -> switch (argument.getStringMode()) { - case QUOTED -> StringArgumentType.string(); - case GREEDY -> StringArgumentType.greedyString(); - default -> StringArgumentType.word(); - }); + final CloudBrigadierManager brigManager = manager.brigadierManager(); + brigManager.registerMapping(new TypeToken>() {}, builder -> { + builder.cloudSuggestions().to(argument -> switch (argument.getStringMode()) { + case QUOTED -> StringArgumentType.string(); + case GREEDY -> StringArgumentType.greedyString(); + default -> StringArgumentType.word(); }); - } + }); return manager; } catch (final Exception e) { @@ -157,11 +153,11 @@ public CommandManager command(final Command minecraftExceptionHandler() { - return new MinecraftExceptionHandler() - .withArgumentParsingHandler() - .withCommandExecutionHandler() - .withInvalidSenderHandler() - .withInvalidSyntaxHandler() - .withNoPermissionHandler(); + return MinecraftExceptionHandler.createNative() + .defaultArgumentParsingHandler() + .defaultCommandExecutionHandler() + .defaultInvalidSenderHandler() + .defaultInvalidSyntaxHandler() + .defaultNoPermissionHandler(); } } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/MetaKeys.java b/src/main/java/me/machinemaker/papertweaks/cloud/MetaKeys.java index 8c085bf4..14ab09e8 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/MetaKeys.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/MetaKeys.java @@ -19,12 +19,24 @@ */ package me.machinemaker.papertweaks.cloud; -import cloud.commandframework.meta.CommandMeta; import org.bukkit.GameMode; +import org.incendo.cloud.Command; +import org.incendo.cloud.key.CloudKey; + +import static org.incendo.cloud.key.CloudKey.cloudKey; public final class MetaKeys { - public static final CommandMeta.Key GAMEMODE_KEY = CommandMeta.Key.of(GameMode.class, "papertweaks:gamemode"); + public static final CloudKey HIDDEN = cloudKey("papertweaks:hidden"); + + public static Command.Builder.Applicable hiddenCommand() { + return builder -> { + builder.meta(HIDDEN, null); + return builder; + }; + } + + public static final CloudKey GAMEMODE_KEY = cloudKey("papertweaks:gamemode", GameMode.class); private MetaKeys() { } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/ModulePermission.java b/src/main/java/me/machinemaker/papertweaks/cloud/ModulePermission.java index a098c99b..1e1f7169 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/ModulePermission.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/ModulePermission.java @@ -19,27 +19,26 @@ */ package me.machinemaker.papertweaks.cloud; -import cloud.commandframework.keys.SimpleCloudKey; -import cloud.commandframework.permission.AndPermission; -import cloud.commandframework.permission.CommandPermission; -import cloud.commandframework.permission.Permission; -import cloud.commandframework.permission.PredicatePermission; import java.util.Set; import me.machinemaker.papertweaks.modules.ModuleLifecycle; +import org.incendo.cloud.permission.Permission; +import org.incendo.cloud.permission.PredicatePermission; + +import static org.incendo.cloud.key.CloudKey.cloudKey; public final class ModulePermission { private ModulePermission() { } - public static CommandPermission of(final ModuleLifecycle lifecycle, final String permission) { - return AndPermission.of(Set.of( + public static Permission of(final ModuleLifecycle lifecycle, final String permission) { + return Permission.allOf(Set.of( Permission.of(permission), of(lifecycle) )); } - public static CommandPermission of(final ModuleLifecycle lifecycle) { - return PredicatePermission.of(SimpleCloudKey.of(lifecycle.moduleInfo().name() + "-lifecycle"), ignored -> lifecycle.getState().isRunning()); + public static Permission of(final ModuleLifecycle lifecycle) { + return PredicatePermission.of(cloudKey(lifecycle.moduleInfo().name() + "-lifecycle"), ignored -> lifecycle.getState().isRunning()); } } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/PaperTweaksCommand.java b/src/main/java/me/machinemaker/papertweaks/cloud/PaperTweaksCommand.java index c6dc7b74..16b9d83e 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/PaperTweaksCommand.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/PaperTweaksCommand.java @@ -19,17 +19,18 @@ */ package me.machinemaker.papertweaks.cloud; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.execution.CommandExecutionHandler; -import cloud.commandframework.paper.PaperCommandManager; -import cloud.commandframework.tasks.TaskConsumer; import com.google.inject.Inject; import java.util.function.BiConsumer; -import me.machinemaker.papertweaks.cloud.arguments.ArgumentFactory; +import java.util.function.Consumer; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.cloud.parsers.ParserFactory; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.execution.CommandExecutionHandler; +import org.incendo.cloud.paper.PaperCommandManager; /** * Various utility methods for commands to utilize @@ -39,20 +40,24 @@ public abstract class PaperTweaksCommand { @Inject protected PaperCommandManager manager; @Inject - protected ArgumentFactory argumentFactory; + protected ParserFactory argumentFactory; protected final CommandExecutionHandler sync(final BiConsumer, Player> playerTaskConsumer) { - return commandContext -> this.manager.taskRecipe().begin(commandContext).synchronous(context -> { - final Player player = PlayerCommandDispatcher.from(context); - playerTaskConsumer.accept(context, player); - }).execute(); + return context -> { + Bukkit.getScheduler().runTask(this.manager.owningPlugin(), () -> { + final Player player = PlayerCommandDispatcher.from(context); + playerTaskConsumer.accept(context, player); + }); + }; } - protected final CommandExecutionHandler sync(final TaskConsumer> taskConsumer) { - return commandContext -> this.manager.taskRecipe().begin(commandContext).synchronous(taskConsumer).execute(); + protected final CommandExecutionHandler sync(final Consumer> taskConsumer) { + return context -> { + Bukkit.getScheduler().runTask(this.manager.owningPlugin(), () -> taskConsumer.accept(context)); + }; } - protected final void register(final Command.Builder builder) { + protected final void register(final Command.Builder builder) { this.manager.command(builder); } } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/SuggestionProviders.java b/src/main/java/me/machinemaker/papertweaks/cloud/SuggestionProviders.java index 8fad670c..bd35d86d 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/SuggestionProviders.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/SuggestionProviders.java @@ -19,18 +19,19 @@ */ package me.machinemaker.papertweaks.cloud; -import cloud.commandframework.bukkit.parsers.PlayerArgument; -import cloud.commandframework.context.CommandContext; +import com.google.common.collect.Iterables; import java.util.Collections; import java.util.List; import java.util.function.BiFunction; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import org.bukkit.entity.Player; +import org.incendo.cloud.bukkit.parser.PlayerParser; +import org.incendo.cloud.suggestion.BlockingSuggestionProvider; public final class SuggestionProviders { private static final BiFunction> EMPTY = (c, s) -> Collections.emptyList(); - private static final PlayerArgument.PlayerParser DUMMY_PLAYER_PARSER = new PlayerArgument.PlayerParser<>(); + private static final PlayerParser DUMMY_PLAYER_PARSER = new PlayerParser<>(); private SuggestionProviders() { } @@ -40,12 +41,12 @@ public static BiFunction> empty() { return (BiFunction>) EMPTY; } - public static BiFunction, String, List> playersWithoutSelf() { - return (context, s) -> { - if (context.getSender().sender() instanceof final Player player) { - return DUMMY_PLAYER_PARSER.suggestions(context, s).stream().filter(name -> !name.equals(player.getName())).toList(); + public static BlockingSuggestionProvider playersWithoutSelf() { + return (context, input) -> { + if (context.sender().sender() instanceof final Player player) { + return Iterables.filter(DUMMY_PLAYER_PARSER.suggestions(context, input), name -> !name.suggestion().equals(player.getName())); } - return DUMMY_PLAYER_PARSER.suggestions(context, s); + return DUMMY_PLAYER_PARSER.suggestions(context, input); }; } } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/HomeArgument.java b/src/main/java/me/machinemaker/papertweaks/cloud/arguments/HomeArgument.java deleted file mode 100644 index f4470035..00000000 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/HomeArgument.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.cloud.arguments; - -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.parsing.NoInputProvidedException; -import cloud.commandframework.minecraft.extras.RichDescription; -import com.google.inject.Inject; -import com.google.inject.assistedinject.Assisted; -import java.util.Collections; -import java.util.List; -import java.util.Queue; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; -import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; -import me.machinemaker.papertweaks.db.dao.teleportation.homes.HomesDAO; -import me.machinemaker.papertweaks.db.model.teleportation.homes.Home; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class HomeArgument extends CommandArgument { - - @Inject - HomeArgument(final HomesDAO homesDAO, @Assisted final boolean required, @Assisted final String name) { - super(required, name, new Parser(homesDAO), "home", Home.class, null, RichDescription.translatable("modules.homes.commands.arguments.home")); - } - - private record Parser(HomesDAO homesDAO) implements ArgumentParser { - - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final @Nullable String input = inputQueue.peek(); - if (input == null || input.isBlank()) { - return ArgumentParseResult.failure(new NoInputProvidedException(Parser.class, commandContext)); - } - if (!commandContext.getSender().isPlayer()) { - return ArgumentParseResult.failure(new IllegalStateException("Must be player")); - } - final Home home = this.homesDAO.getPlayerHome(commandContext.getSender().getUUID(), input); - if (home == null) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " is not a valid home")); - } - - inputQueue.remove(); - return ArgumentParseResult.success(home); - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - if (commandContext.getSender() instanceof final PlayerCommandDispatcher playerCommandDispatcher) { - return List.copyOf(this.homesDAO.getHomesForPlayer(playerCommandDispatcher.getUUID()).keySet()); - } - return Collections.emptyList(); - } - } -} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/ModuleArgument.java b/src/main/java/me/machinemaker/papertweaks/cloud/arguments/ModuleArgument.java deleted file mode 100644 index 090d2614..00000000 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/ModuleArgument.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.cloud.arguments; - -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.minecraft.extras.RichDescription; -import com.google.inject.Inject; -import com.google.inject.assistedinject.Assisted; -import java.util.ArrayList; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Queue; -import java.util.function.Predicate; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; -import me.machinemaker.papertweaks.cloud.processors.SimpleSuggestionProcessor; -import me.machinemaker.papertweaks.modules.ModuleBase; -import me.machinemaker.papertweaks.modules.ModuleLifecycle; -import me.machinemaker.papertweaks.modules.ModuleManager; -import org.checkerframework.checker.nullness.qual.Nullable; - -import static java.util.Objects.requireNonNull; - -public class ModuleArgument extends CommandArgument { - - private static final String ARGUMENT_NAME = "module"; - - @Inject - private ModuleArgument(final ModuleManager manager, @Assisted final @Nullable Boolean enabled) { - super(true, ARGUMENT_NAME, new Parser(enabled, manager), "", ModuleBase.class, null, RichDescription.translatable("commands.arguments.module")); - } - - public static ModuleBase getModule(final CommandContext context) { - return context.get(ARGUMENT_NAME); - } - - private static Predicate predicateFor(final @Nullable Boolean enabled) { - if (enabled == null) { - return lifecycle -> true; - } else if (enabled) { - return lifecycle -> lifecycle.getState().isRunning(); - } else { - return lifecycle -> !lifecycle.getState().isRunning(); - } - } - - private record Parser(@Nullable Boolean enabled, ModuleManager manager) implements ArgumentParser { - - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final String input = requireNonNull(inputQueue.peek()); - final Optional lifecycle = this.manager.getLifecycle(input); - if (lifecycle.isEmpty()) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " is not a valid module")); // TODO lang - } - if (this.enabled != null) { - if (this.enabled && !lifecycle.get().getState().isRunning()) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " must be enabled!")); // TODO lang - } - if (!this.enabled && lifecycle.get().getState().isRunning()) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " must be disabled!")); // TODO lang - } - } - inputQueue.remove(); - try { - return ArgumentParseResult.success(this.manager.getModule(input).orElseThrow()); - } catch (final NoSuchElementException exception) { - return ArgumentParseResult.failure(exception); - } - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - commandContext.set(SimpleSuggestionProcessor.IGNORE_CASE, true); - final List modules = new ArrayList<>(); - final Predicate lifecyclePredicate = predicateFor(this.enabled); - for (final ModuleBase module : this.manager.getModules().values()) { - this.manager.getLifecycle(module.getName()).ifPresent(lifecycle -> { - if (lifecyclePredicate.test(lifecycle)) { - modules.add(module.getName()); - } - }); - } - return modules; - } - } -} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/PseudoEnumArgument.java b/src/main/java/me/machinemaker/papertweaks/cloud/arguments/PseudoEnumArgument.java deleted file mode 100644 index 2fda677c..00000000 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/PseudoEnumArgument.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.cloud.arguments; - -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.captions.CaptionVariable; -import cloud.commandframework.captions.StandardCaptionKeys; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.parsing.NoInputProvidedException; -import cloud.commandframework.exceptions.parsing.ParserException; -import java.io.Serial; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.function.BiFunction; -import org.checkerframework.checker.nullness.qual.Nullable; - -public class PseudoEnumArgument extends CommandArgument { - - private final StringArgument.StringMode stringMode; - - protected PseudoEnumArgument(final boolean required, final String name, final StringArgument.StringMode stringMode, final String defaultValue, final Set allowedValues, final @Nullable BiFunction, String, List> suggestionsProvider, final ArgumentDescription defaultDescription) { - super(required, name, new PseudoEnumParser<>(stringMode, allowedValues), defaultValue, String.class, suggestionsProvider, defaultDescription); - this.stringMode = stringMode; - } - - /** - * Create a new builder - * - * @param name Name of the argument - * @param allowedValues Allowed values - * @param Command sender type - * @return Created builder - * @since 1.6.0 - */ - public static PseudoEnumArgument.Builder builder(final String name, final Set allowedValues) { - return new Builder<>(name, allowedValues); - } - - /** - * Create a new required single string command argument - * - * @param name Argument name - * @param allowedValues Allowed values - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument of(final String name, final Set allowedValues) { - return PseudoEnumArgument.builder(name, allowedValues).single().asRequired().build(); - } - - /** - * Create a new required command argument - * - * @param name Argument name - * @param allowedValues Allowed values - * @param stringMode String mode - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument of(final String name, final Set allowedValues, final StringArgument.StringMode stringMode) { - return PseudoEnumArgument.builder(name, allowedValues).withMode(stringMode).asRequired().build(); - } - - /** - * Create a new optional single string command argument - * - * @param name Argument name - * @param allowedValues Allowed values - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument optional(final String name, final Set allowedValues) { - return PseudoEnumArgument.builder(name, allowedValues).single().asOptional().build(); - } - - /** - * Create a new optional command argument - * - * @param name Argument name - * @param allowedValues Allowed values - * @param stringMode String mode - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument optional(final String name, final Set allowedValues, final StringArgument.StringMode stringMode) { - return PseudoEnumArgument.builder(name, allowedValues).withMode(stringMode).asOptional().build(); - } - - /** - * Create a new required command argument with a default value - * - * @param name Argument name - * @param allowedValues Allowed values - * @param defaultString Default string - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument optional(final String name, final Set allowedValues, final String defaultString) { - return PseudoEnumArgument.builder(name, allowedValues).asOptionalWithDefault(defaultString).build(); - } - - /** - * Create a new required command argument with the 'single' parsing mode - * - * @param name Argument name - * @param allowedValues Allowed values - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument single(final String name, final Set allowedValues) { - return of(name, allowedValues, StringArgument.StringMode.SINGLE); - } - - /** - * Create a new required command argument with the 'greedy' parsing mode - * - * @param name Argument name - * @param allowedValues Allowed values - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument greedy(final String name, final Set allowedValues) { - return of(name, allowedValues, StringArgument.StringMode.GREEDY); - } - - /** - * Create a new required command argument with the 'quoted' parsing mode - * - * @param name Argument name - * @param allowedValues Allowed values - * @param Command sender type - * @return Created argument - * @since 1.6.0 - */ - public static CommandArgument quoted(final String name, final Set allowedValues) { - return of(name, allowedValues, StringArgument.StringMode.QUOTED); - } - - /** - * Get the string mode - * - * @return String mode - * @since 1.6.0 - */ - public StringArgument.StringMode getStringMode() { - return this.stringMode; - } - - - /** - * Builder for {@link PseudoEnumArgument}. - * - * @param Command sender type - * @since 1.6.0 - */ - public static final class Builder extends CommandArgument.TypedBuilder> { - - private final Set allowedValues; - private StringArgument.StringMode stringMode = StringArgument.StringMode.SINGLE; - - private Builder(final String name, final Set allowedValues) { - super(String.class, name); - this.allowedValues = allowedValues; - } - - /** - * Set the String mode - * - * @param stringMode String mode to parse with - * @return Builder instance - * @since 1.6.0 - */ - private Builder withMode(final StringArgument.StringMode stringMode) { - this.stringMode = stringMode; - return this; - } - - /** - * Set the string mode to greedy - * - * @return Builder instance - * @since 1.6.0 - */ - public Builder greedy() { - this.stringMode = StringArgument.StringMode.GREEDY; - return this; - } - - /** - * Set the string mode to single - * - * @return Builder instance - * @since 1.6.0 - */ - public Builder single() { - this.stringMode = StringArgument.StringMode.SINGLE; - return this; - } - - /** - * Set the string mode to greedy - * - * @return Builder instance - * @since 1.6.0 - */ - public Builder quoted() { - this.stringMode = StringArgument.StringMode.QUOTED; - return this; - } - - /** - * Builder a new string argument - * - * @return Constructed argument - * @since 1.6.0 - */ - @Override - public PseudoEnumArgument build() { - return new PseudoEnumArgument<>(this.isRequired(), this.getName(), this.stringMode, - this.getDefaultValue(), this.allowedValues, this.getSuggestionsProvider(), this.getDefaultDescription() - ); - } - - } - - - /** - * Parser for pseudo-enums. - * - * @param Command sender type - * @since 1.6.0 - */ - public static final class PseudoEnumParser implements ArgumentParser { - - private final Set allowedValues; - private final StringArgument.StringParser stringParser; - - public PseudoEnumParser(final StringArgument.StringMode stringMode, final Set allowedValues) { - this.stringParser = new StringArgument.StringParser<>(stringMode, (context, s) -> new ArrayList<>(allowedValues)); - this.allowedValues = allowedValues; - } - - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final ArgumentParseResult result = this.stringParser.parse(commandContext, inputQueue); - if (result.getFailure().isPresent()) { - return result; - } else if (result.getParsedValue().isPresent()) { - final String input = result.getParsedValue().get(); - if (!this.allowedValues.contains(input)) { - return ArgumentParseResult.failure(new PseudoEnumParseException(input, this.allowedValues, commandContext)); - } else { - return result; - } - } else { - return ArgumentParseResult.failure(new NoInputProvidedException(PseudoEnumParser.class, commandContext)); - } - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - return this.stringParser.suggestions(commandContext, input); - } - - @Override - public boolean isContextFree() { - return true; - } - - /** - * Get the string mode - * - * @return String mode - * @since 1.6.0 - */ - public StringArgument.StringMode getStringMode() { - return this.stringParser.getStringMode(); - } - } - - - public static final class PseudoEnumParseException extends ParserException { - - @Serial - private static final long serialVersionUID = 5198435213837796433L; - private final String input; - private final Set acceptableValues; - - /** - * Construct a new pseudo-enum parse exception - * - * @param input Input - * @param acceptableValues Acceptable values - * @param context Command context - * @since 1.6.0 - */ - public PseudoEnumParseException(final String input, final Set acceptableValues, final CommandContext context) { - super(PseudoEnumParser.class, context, StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM, CaptionVariable.of("input", input), CaptionVariable.of("acceptableValues", String.join(", ", acceptableValues))); - this.input = input; - this.acceptableValues = Collections.unmodifiableSet(acceptableValues); - } - - /** - * Get the input provided by the sender - * - * @return Input - * @since 1.6.0 - */ - public String getInput() { - return this.input; - } - - /** - * Get the acceptable values for this argument - * - * @return The acceptable values - * @since 1.6.0 - */ - public Set getAcceptableValues() { - return this.acceptableValues; - } - - } - -} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/SettingArgument.java b/src/main/java/me/machinemaker/papertweaks/cloud/arguments/SettingArgument.java deleted file mode 100644 index bc3ae8a4..00000000 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/SettingArgument.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.cloud.arguments; - -import cloud.commandframework.Command; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.compound.ArgumentPair; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.parsing.NoInputProvidedException; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; -import cloud.commandframework.minecraft.extras.RichDescription; -import cloud.commandframework.types.tuples.Pair; -import com.google.common.collect.Lists; -import io.leangen.geantyref.GenericTypeReflector; -import io.leangen.geantyref.TypeToken; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.Queue; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; -import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; -import me.machinemaker.papertweaks.modules.MenuModuleConfig; -import me.machinemaker.papertweaks.settings.ModuleSetting; -import me.machinemaker.papertweaks.settings.ModuleSettings; -import me.machinemaker.papertweaks.settings.Setting; -import me.machinemaker.papertweaks.settings.types.ConfigSetting; -import me.machinemaker.papertweaks.settings.types.PlayerSetting; -import org.bukkit.entity.Player; -import org.checkerframework.checker.nullness.qual.Nullable; - -import static net.kyori.adventure.text.Component.translatable; -import static net.kyori.adventure.text.format.NamedTextColor.GREEN; - -@SuppressWarnings("Convert2Diamond") -public class SettingArgument> extends ArgumentPair> { - - public static final String SETTING_CHANGE_KEY_STRING = "setting"; - public static final CloudKey>> PLAYER_SETTING_CHANGE_KEY = SimpleCloudKey.of(SETTING_CHANGE_KEY_STRING, new TypeToken>>() {}); - private static final TypeToken> PLAYER_SETTING_TYPE_TOKEN = new TypeToken>() {}; - - protected SettingArgument(final Pair, ArgumentParser> parsers, final Class classOfS, final TypeToken> settingChangeTypeToken) { - super(true, SETTING_CHANGE_KEY_STRING, Pair.of("key", "value"), Pair.of(classOfS, Object.class), parsers, (sender, pair) -> of(pair), settingChangeTypeToken); - } - - public static > Builder newBuilder(final TypeToken> settingsChangeTypeToken, final Map settings, final TypeToken settingsTypeToken) { - return new Builder<>(settingsChangeTypeToken, settings, settingsTypeToken); - } - - public static SettingArgument> playerSettings(final Map> settings) { - return newBuilder(PLAYER_SETTING_CHANGE_KEY.getType(), settings, PLAYER_SETTING_TYPE_TOKEN).hideSuggestions().build(); - } - - public static > SettingArgument> configSettings(final CloudKey>> settingsChangeCloudKey, final Map> settings) { - return newBuilder(settingsChangeCloudKey.getType(), settings, new TypeToken>() {}).hideSuggestions().build(); // the C generic won't be resolved here - } - - private static > SettingChange of(final Pair pair) { - return new SettingChange<>(pair.getFirst(), pair.getSecond()); - } - - public static > Command.Builder resetPlayerSettings(final Command.Builder builder, final String translationKey, final ModuleSettings settings) { - return builder - .literal("reset", RichDescription.translatable(translationKey)) - .handler(context -> { - final Player player = PlayerCommandDispatcher.from(context); - for (final S setting : settings.index().values()) { - if (setting instanceof final PlayerSetting playerSetting) { - playerSetting.reset(player); - } - } - context.getSender().sendMessage(translatable(translationKey + ".success", GREEN)); - }); - } - - public static final class Builder> extends CommandArgument.Builder> { - - private final Map settings; - private final TypeToken settingsTypeToken; - private boolean hideSuggestions = false; - - private Builder(final TypeToken> settingsChangeTypeToken, final Map settings, final TypeToken settingsTypeToken) { - super(settingsChangeTypeToken, SETTING_CHANGE_KEY_STRING); - this.settings = settings; - this.settingsTypeToken = settingsTypeToken; - } - - /** - * Only affects setting key suggestions. Setting - * value suggestions are left for editable options. - */ - public Builder hideSuggestions() { - this.hideSuggestions = true; - return this; - } - - @SuppressWarnings("unchecked") - @Override - public SettingArgument build() { - final CloudKey key = SimpleCloudKey.of("specifiedSetting", this.settingsTypeToken); - final SettingParser settingParser = new SettingParser(this.settings, key, this.hideSuggestions); - final Pair, ArgumentParser> parsers = Pair.of(settingParser, new SettingValueParser<>(settingParser, key)); - return new SettingArgument<>(parsers, (Class) GenericTypeReflector.erase(this.settingsTypeToken.getType()), this.getValueType()); - } - } - - record SettingParser>( - Map settings, CloudKey key, - boolean hideSuggestions - ) implements ArgumentParser { - - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final @Nullable String string = inputQueue.peek(); - if (string == null) { - return ArgumentParseResult.failure(new NoInputProvidedException(SettingParser.class, commandContext)); - } - final S value = this.settings.get(string.toLowerCase(Locale.ENGLISH)); - if (value == null) { - return ArgumentParseResult.failure(new IllegalArgumentException(string)); - } - inputQueue.remove(); - commandContext.store(this.key, value); - - return ArgumentParseResult.success(value); - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - if (this.hideSuggestions) { - return Collections.emptyList(); - } - return this.settings.keySet().stream().toList(); - } - } - - record SettingValueParser>( - SettingParser settingParser, - CloudKey key - ) implements ArgumentParser { - - @SuppressWarnings("unchecked") - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final @Nullable String string = inputQueue.peek(); - if (string == null) { - return ArgumentParseResult.failure(new NoInputProvidedException(SettingValueParser.class, commandContext)); - } - final Optional setting = commandContext.getOptional(this.key); - return setting.map(s -> (ArgumentParseResult) s.argumentParser().parse(commandContext, inputQueue)).orElseGet(() -> ArgumentParseResult.failure(new IllegalStateException(string + " isn't preceded by a setting"))); - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - final List rawInput = commandContext.getRawInput(); - final ArgumentParseResult parseResult = this.settingParser.parse(commandContext, Lists.newLinkedList(rawInput.subList(rawInput.size() - 2, rawInput.size() - 1))); - final Optional setting = parseResult.getParsedValue(); - if (parseResult.getFailure().isPresent() || setting.isEmpty()) { - return Collections.emptyList(); - } - return setting.get().argumentParser().suggestions(commandContext, input); - } - } - - public record SettingChange>(S setting, Object value) { - - public void apply(final C holder) { - this.setting.setObject(holder, this.value); - } - } -} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldown.java b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldown.java index 964afbf1..fe854307 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldown.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldown.java @@ -19,14 +19,14 @@ */ package me.machinemaker.papertweaks.cloud.cooldown; -import cloud.commandframework.Command; -import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; -import cloud.commandframework.meta.CommandMeta; import io.leangen.geantyref.TypeToken; import java.time.Duration; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.execution.postprocessor.CommandPostprocessingContext; +import org.incendo.cloud.key.CloudKey; + +import static org.incendo.cloud.key.CloudKey.cloudKey; /** * A command cooldown which can be applied to one or more {@link Command.Builder}s. @@ -37,7 +37,7 @@ */ public interface CommandCooldown extends Command.Builder.Applicable { - CommandMeta.Key> COMMAND_META_KEY = CommandMeta.Key.of(new TypeToken<>() {}, "papertweaks:command_cooldown"); + CloudKey> COMMAND_META_KEY = cloudKey("papertweaks:command_cooldown", new TypeToken>() {}); /** * Get the {@link CloudKey} for this cooldown. @@ -122,7 +122,7 @@ interface Builder { * @return this builder */ default Builder key(final String cooldownKey) { - return this.key(SimpleCloudKey.of(cooldownKey)); + return this.key(cloudKey(cooldownKey)); } /** diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownImpl.java b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownImpl.java index 0719b0f1..3a9a15ec 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownImpl.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownImpl.java @@ -19,12 +19,13 @@ */ package me.machinemaker.papertweaks.cloud.cooldown; -import cloud.commandframework.Command; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; import java.util.UUID; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.key.CloudKey; + +import static org.incendo.cloud.key.CloudKey.cloudKey; record CommandCooldownImpl(CloudKey key, CommandCooldown.DurationFunction duration, CommandCooldown.@Nullable Notifier notifier) implements CommandCooldown { @@ -58,7 +59,7 @@ public CommandCooldown.Builder key(final CloudKey cooldownKey) { private CloudKey getOrCreateKey() { @Nullable CloudKey key = this.cooldownKey; if (key == null) { - key = SimpleCloudKey.of(UUID.randomUUID().toString()); + key = cloudKey(UUID.randomUUID().toString()); } return key; } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownManager.java b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownManager.java index 081d894a..349f206d 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownManager.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/cooldown/CommandCooldownManager.java @@ -19,12 +19,12 @@ */ package me.machinemaker.papertweaks.cloud.cooldown; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; -import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; -import cloud.commandframework.execution.postprocessor.CommandPostprocessor; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.services.types.ConsumerService; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.execution.postprocessor.CommandPostprocessingContext; +import org.incendo.cloud.execution.postprocessor.CommandPostprocessor; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.services.type.ConsumerService; import java.time.Duration; import java.util.Collections; import java.util.Map; @@ -85,7 +85,7 @@ public void registerCooldownManager(final CommandManager manager) { } public synchronized void invalidate(final I id, final Command command) { - command.getCommandMeta().get(CommandCooldown.COMMAND_META_KEY) + command.commandMeta().optional(CommandCooldown.COMMAND_META_KEY) .ifPresent(cooldown -> this.invalidate(id, cooldown.key())); } @@ -104,13 +104,13 @@ private final class CommandCooldownPostprocessor implements CommandPostprocessor @SuppressWarnings("unchecked") @Override public void accept(final CommandPostprocessingContext context) { - final I id = this.mapToId(context.getCommandContext().getSender()); + final I id = this.mapToId(context.commandContext().sender()); if (id == null) { return; } final Optional cooldownDuration = this.cooldownDuration(context); if (cooldownDuration.isPresent() && !cooldownDuration.get().isZero()) { - final CommandCooldown commandCooldown = (CommandCooldown) context.getCommand().getCommandMeta().get(CommandCooldown.COMMAND_META_KEY).orElseThrow(); + final CommandCooldown commandCooldown = (CommandCooldown) context.command().commandMeta().optional(CommandCooldown.COMMAND_META_KEY).orElseThrow(); final CloudKey commandCooldownKey = commandCooldown.key(); final long cooldownMillis = cooldownDuration.get().toMillis(); final long currentMillis = System.currentTimeMillis(); @@ -128,12 +128,12 @@ public void accept(final CommandPostprocessingContext context) { } } else { senderCooldownMap.put(commandCooldownKey, currentMillis + cooldownMillis); - this.setupEntryRemoval(id, context.getCommand(), cooldownMillis); + this.setupEntryRemoval(id, context.command(), cooldownMillis); } } else { final Map, Long> map = new ConcurrentHashMap<>(Map.of(commandCooldownKey, currentMillis + cooldownMillis)); CommandCooldownManager.this.commandsOnCooldown.put(id, map); - this.setupEntryRemoval(id, context.getCommand(), cooldownMillis); + this.setupEntryRemoval(id, context.command(), cooldownMillis); } } } @@ -148,8 +148,8 @@ private void setupEntryRemoval(final I identity, final Command command, final @SuppressWarnings({"rawtypes", "unchecked"}) private Optional cooldownDuration(final CommandPostprocessingContext context) { - return context.getCommand().getCommandMeta() - .get(CommandCooldown.COMMAND_META_KEY) + return context.command().commandMeta() + .optional(CommandCooldown.COMMAND_META_KEY) .map(cooldown -> cooldown.duration().getDuration((CommandPostprocessingContext) context)); } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/dispatchers/PlayerCommandDispatcher.java b/src/main/java/me/machinemaker/papertweaks/cloud/dispatchers/PlayerCommandDispatcher.java index 88d156f3..5b55f7f1 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/dispatchers/PlayerCommandDispatcher.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/dispatchers/PlayerCommandDispatcher.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.cloud.dispatchers; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.context.CommandContext; import java.util.Locale; import java.util.UUID; import java.util.function.Function; @@ -46,7 +46,7 @@ public PlayerCommandDispatcher(final Player player, final Function context) { - if (context.getSender() instanceof final PlayerCommandDispatcher playerCommandDispatcher) { + if (context.sender() instanceof final PlayerCommandDispatcher playerCommandDispatcher) { return playerCommandDispatcher.sender(); } throw new IllegalArgumentException("Not a PlayerCommandDispatcher"); @@ -71,7 +71,7 @@ public PersistentDataContainer getPersistentDataContainer() { } @Override - public @Nullable UUID getUUID() { + public UUID getUUID() { return this.player.getUniqueId(); } diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/HomeParser.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/HomeParser.java new file mode 100644 index 00000000..fa50207d --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/HomeParser.java @@ -0,0 +1,70 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers; + +import com.google.inject.Inject; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.db.dao.teleportation.homes.HomesDAO; +import me.machinemaker.papertweaks.db.model.teleportation.homes.Home; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +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.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProvider; + +public class HomeParser implements ArgumentParser { + + private final HomesDAO homesDAO; + + @Inject + HomeParser(final HomesDAO homesDAO) { + this.homesDAO = homesDAO; + } + + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String input = commandInput.readString(); + if (!(commandContext.sender() instanceof final PlayerCommandDispatcher playerDispatcher)) { + return ArgumentParseResult.failure(new IllegalStateException("Must be player")); + } + final @Nullable Home home = this.homesDAO.getPlayerHome(playerDispatcher.getUUID(), input); + if (home == null) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " is not a valid home")); + } + + return ArgumentParseResult.success(home); + } + + @Override + public @NonNull SuggestionProvider suggestionProvider() { + return (context, input) -> { + if (context.sender() instanceof final PlayerCommandDispatcher playerCommandDispatcher) { + return CompletableFuture.supplyAsync(() -> this.homesDAO.getHomesForPlayer(playerCommandDispatcher.getUUID()).keySet().stream().map(Suggestion::simple).toList()); + } + return CompletableFuture.completedFuture(Collections.emptyList()); + }; + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ModuleParser.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ModuleParser.java new file mode 100644 index 00000000..a607c77f --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ModuleParser.java @@ -0,0 +1,102 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.function.Predicate; +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.cloud.processors.ConditionalCaseInsensitiveSuggestionProcessor; +import me.machinemaker.papertweaks.modules.ModuleBase; +import me.machinemaker.papertweaks.modules.ModuleLifecycle; +import me.machinemaker.papertweaks.modules.ModuleManager; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +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.suggestion.BlockingSuggestionProvider; +import org.incendo.cloud.suggestion.SuggestionProvider; + +public class ModuleParser implements ArgumentParser { + + private final ModuleManager manager; + private final @Nullable Boolean enabled; + + @Inject + ModuleParser(final ModuleManager manager, @Assisted final @Nullable Boolean enabled) { + this.manager = manager; + this.enabled = enabled; + } + + private static Predicate predicateFor(final @Nullable Boolean enabled) { + if (enabled == null) { + return lifecycle -> true; + } else if (enabled) { + return lifecycle -> lifecycle.getState().isRunning(); + } else { + return lifecycle -> !lifecycle.getState().isRunning(); + } + } + + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String input = commandInput.readString(); + final Optional lifecycle = this.manager.getLifecycle(input); + if (lifecycle.isEmpty()) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " is not a valid module")); // TODO lang + } + if (this.enabled != null) { + if (this.enabled && !lifecycle.get().getState().isRunning()) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " must be enabled!")); // TODO lang + } + if (!this.enabled && lifecycle.get().getState().isRunning()) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " must be disabled!")); // TODO lang + } + } + try { + return ArgumentParseResult.success(this.manager.getModule(input).orElseThrow()); + } catch (final NoSuchElementException exception) { + return ArgumentParseResult.failure(exception); + } + } + + @Override + public @NonNull SuggestionProvider suggestionProvider() { + return (BlockingSuggestionProvider.Strings) (context, input) -> { + context.set(ConditionalCaseInsensitiveSuggestionProcessor.IGNORE_CASE, true); + final List modules = new ArrayList<>(); + final Predicate lifecyclePredicate = predicateFor(this.enabled); + for (final ModuleBase module : this.manager.getModules().values()) { + this.manager.getLifecycle(module.getName()).ifPresent(lifecycle -> { + if (lifecyclePredicate.test(lifecycle)) { + modules.add(module.getName()); + } + }); + } + return modules; + }; + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ParserFactory.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ParserFactory.java new file mode 100644 index 00000000..749cbd41 --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/ParserFactory.java @@ -0,0 +1,45 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2021-2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers; + +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.db.model.teleportation.homes.Home; +import me.machinemaker.papertweaks.modules.ModuleBase; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.parser.ParserDescriptor; + +import static org.incendo.cloud.key.CloudKey.cloudKey; +import static org.incendo.cloud.parser.ParserDescriptor.parserDescriptor; + +public interface ParserFactory { + + static ParserDescriptor homeDescriptor(final ParserFactory factory) { + return parserDescriptor(factory.home(), Home.class); + } + + static ParserDescriptor moduleDescriptor(final ParserFactory factory, final @Nullable Boolean enabled) { + return parserDescriptor(factory.module(enabled), ModuleBase.class); + } + + HomeParser home(); + + ModuleParser module(@Nullable Boolean enabled); +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/PseudoEnumParser.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/PseudoEnumParser.java new file mode 100644 index 00000000..b4499ceb --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/PseudoEnumParser.java @@ -0,0 +1,151 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers; + +import com.google.common.collect.Iterables; +import java.io.Serial; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.caption.CaptionVariable; +import org.incendo.cloud.caption.StandardCaptionKeys; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.exception.parsing.ParserException; +import org.incendo.cloud.parser.ArgumentParseResult; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.ParserDescriptor; +import org.incendo.cloud.parser.standard.StringParser; +import org.incendo.cloud.suggestion.SuggestionProvider; + +import static org.incendo.cloud.parser.ParserDescriptor.parserDescriptor; + +/** + * Parser for pseudo-enums. + * + * @param Command sender type + * @since 1.6.0 + */ +public class PseudoEnumParser implements ArgumentParser { + + public static ParserDescriptor singlePseudoEnumParser(final Iterable allowedValues) { + return pseudoEnumParser(StringParser.StringMode.SINGLE, allowedValues); + } + + public static ParserDescriptor quotedPseudoEnumParser(final Iterable allowedValues) { + return pseudoEnumParser(StringParser.StringMode.QUOTED, allowedValues); + } + + public static ParserDescriptor greedyFlagYieldingPseudoEnumParser(final Iterable allowedValues) { + return pseudoEnumParser(StringParser.StringMode.GREEDY_FLAG_YIELDING, allowedValues); + } + + public static ParserDescriptor greedyPseudoEnumParser(final Iterable allowedValues) { + return pseudoEnumParser(StringParser.StringMode.GREEDY, allowedValues); + } + + private static ParserDescriptor pseudoEnumParser(final StringParser.StringMode stringMode, final Iterable allowedValues) { + return parserDescriptor(new PseudoEnumParser<>(stringMode, allowedValues), String.class); + } + + private final Set allowedValues; + private final StringParser stringParser; + + public PseudoEnumParser(final StringParser.StringMode stringMode, final Iterable allowedValues) { + this.stringParser = new StringParser<>(stringMode); + final Set allowedValuesSet = new HashSet<>(); + Iterables.addAll(allowedValuesSet, allowedValues); + this.allowedValues = Set.copyOf(allowedValuesSet); + } + + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final ArgumentParseResult result = this.stringParser.parse(commandContext, commandInput); + if (result.failure().isPresent()) { + return result; + } else { + final String input = result.parsedValue().orElseThrow(); + if (!this.allowedValues.contains(input)) { + return ArgumentParseResult.failure(new PseudoEnumParseException(input, this.allowedValues, commandContext)); + } else { + return result; + } + } + } + + @Override + public @NonNull SuggestionProvider suggestionProvider() { + return SuggestionProvider.suggestingStrings(this.allowedValues); + } + + /** + * Get the string mode + * + * @return String mode + * @since 1.6.0 + */ + public StringParser.StringMode getStringMode() { + return this.stringParser.stringMode(); + } + + public static final class PseudoEnumParseException extends ParserException { + + @Serial + private static final long serialVersionUID = 5198435213837796433L; + private final String input; + private final Set acceptableValues; + + /** + * Construct a new pseudo-enum parse exception + * + * @param input Input + * @param acceptableValues Acceptable values + * @param context Command context + * @since 1.6.0 + */ + public PseudoEnumParseException(final String input, final Set acceptableValues, final CommandContext context) { + super(PseudoEnumParser.class, context, StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM, CaptionVariable.of("input", input), CaptionVariable.of("acceptableValues", String.join(", ", acceptableValues))); + this.input = input; + this.acceptableValues = Collections.unmodifiableSet(acceptableValues); + } + + /** + * Get the input provided by the sender + * + * @return Input + * @since 1.6.0 + */ + public String getInput() { + return this.input; + } + + /** + * Get the acceptable values for this argument + * + * @return The acceptable values + * @since 1.6.0 + */ + public Set getAcceptableValues() { + return this.acceptableValues; + } + + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/package-info.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/package-info.java similarity index 90% rename from src/main/java/me/machinemaker/papertweaks/cloud/arguments/package-info.java rename to src/main/java/me/machinemaker/papertweaks/cloud/parsers/package-info.java index cdb7dc64..fbc1edd0 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/package-info.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/package-info.java @@ -3,7 +3,7 @@ * * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. * - * Copyright (C) 2022-2024 Machine_Maker + * Copyright (C) 2024 Machine_Maker * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ * along with this program. If not, see . */ @DefaultQualifier(NonNull.class) -package me.machinemaker.papertweaks.cloud.arguments; +package me.machinemaker.papertweaks.cloud.parsers; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingArgumentPair.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingArgumentPair.java new file mode 100644 index 00000000..f049c129 --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingArgumentPair.java @@ -0,0 +1,102 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers.setting; + +import io.leangen.geantyref.GenericTypeReflector; +import io.leangen.geantyref.TypeToken; +import java.util.Map; +import java.util.function.Supplier; +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.modules.MenuModuleConfig; +import me.machinemaker.papertweaks.settings.ModuleSetting; +import me.machinemaker.papertweaks.settings.ModuleSettings; +import me.machinemaker.papertweaks.settings.Setting; +import me.machinemaker.papertweaks.settings.types.ConfigSetting; +import me.machinemaker.papertweaks.settings.types.PlayerSetting; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.minecraft.extras.RichDescription; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.compound.ArgumentPair; +import org.incendo.cloud.type.tuple.Pair; + +import static net.kyori.adventure.text.Component.translatable; +import static net.kyori.adventure.text.format.NamedTextColor.GREEN; +import static org.incendo.cloud.key.CloudKey.cloudKey; + +@SuppressWarnings("Convert2Diamond") +public class SettingArgumentPair> extends ArgumentPair> { + + private static final TypeToken> PLAYER_SETTING_TYPE_TOKEN = new TypeToken>() {}; + public static final String SETTING_CHANGE_KEY_STRING = "setting"; + public static final CloudKey>> PLAYER_SETTING_CHANGE_KEY = cloudKey(SETTING_CHANGE_KEY_STRING, new TypeToken>>() {}); + + @SuppressWarnings("unchecked") + protected SettingArgumentPair(final TypeToken> settingsChangeTypeToken, final Map settings, final TypeToken settingsTypeToken, final boolean hideSuggestions) { + super( + Pair.of("key", "value"), + Pair.of((Class) GenericTypeReflector.erase(settingsTypeToken.getType()), Object.class), + ((Supplier, ArgumentParser>>) () -> { + final CloudKey key = cloudKey("specifiedSetting", settingsTypeToken); + return Pair.of( + new SettingParser<>(settings, key, hideSuggestions), + new SettingValueParser<>(key) + ); + }).get(), + SettingArgumentPair::mapper, + settingsChangeTypeToken + ); + } + + public static SettingArgumentPair> playerSettings(final Map> settings) { + return new SettingArgumentPair<>(PLAYER_SETTING_CHANGE_KEY.type(), settings, PLAYER_SETTING_TYPE_TOKEN, false); + } + + public static > SettingArgumentPair> configSettings(final CloudKey>> settingsChangeCloudKey, final Map> settings) { + return new SettingArgumentPair>(settingsChangeCloudKey.type(), settings, new TypeToken>() {}, false); + } + + public static > Command.Builder resetPlayerSettings(final Command.Builder builder, final String translationKey, final ModuleSettings settings) { + return builder + .literal("reset", RichDescription.translatable(translationKey)) + .handler(context -> { + final Player player = PlayerCommandDispatcher.from(context); + for (final S setting : settings.index().values()) { + if (setting instanceof final PlayerSetting playerSetting) { + playerSetting.reset(player); + } + } + context.sender().sendMessage(translatable(translationKey + ".success", GREEN)); + }); + } + + private static > SettingChange mapper(final CommandDispatcher sender, final Pair pair) { + return new SettingChange<>(pair.first(), pair.second()); + } + + public record SettingChange>(S setting, Object value) { + + public void apply(final C holder) { + this.setting.setObject(holder, this.value); + } + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingParser.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingParser.java new file mode 100644 index 00000000..432f2429 --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingParser.java @@ -0,0 +1,65 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers.setting; + +import java.util.Locale; +import java.util.Map; +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.settings.Setting; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.parser.ArgumentParseResult; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.suggestion.SuggestionProvider; + +class SettingParser> implements ArgumentParser { + + private final Map settings; + private final CloudKey key; + private final boolean hideSuggestions; + + SettingParser(final Map settings, final CloudKey key, final boolean hideSuggestions) { + this.settings = settings; + this.key = key; + this.hideSuggestions = hideSuggestions; + } + + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String string = commandInput.readString(); + final S value = this.settings.get(string.toLowerCase(Locale.ENGLISH)); + if (value == null) { + return ArgumentParseResult.failure(new IllegalArgumentException(string)); + } + commandContext.store(this.key, value); + + return ArgumentParseResult.success(value); + } + + @Override + public @NonNull SuggestionProvider suggestionProvider() { + if (this.hideSuggestions) { + return SuggestionProvider.noSuggestions(); + } + return SuggestionProvider.suggestingStrings(this.settings.keySet()); + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingValueParser.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingValueParser.java new file mode 100644 index 00000000..1732f198 --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/SettingValueParser.java @@ -0,0 +1,60 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.parsers.setting; + +import java.util.Collections; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.settings.Setting; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.parser.ArgumentParseResult; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.suggestion.SuggestionProvider; + +class SettingValueParser> implements ArgumentParser { + + private final CloudKey key; + + SettingValueParser(final CloudKey key) { + this.key = key; + } + + @SuppressWarnings("unchecked") + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String string = commandInput.peekString(); // don't consume, as it will be consumed by the delegated parser + final Optional setting = commandContext.optional(this.key); + return setting.map(s -> (ArgumentParseResult) s.argumentParser().parse(commandContext, commandInput)).orElseGet(() -> ArgumentParseResult.failure(new IllegalStateException(string + " isn't preceded by a setting"))); + } + + @Override + public @NonNull SuggestionProvider suggestionProvider() { + return(context, input) -> { + final Optional setting = context.optional(this.key); + return setting + .map(s -> s.argumentParser().suggestionProvider().suggestionsFuture(context, input)) + .orElseGet(() -> CompletableFuture.completedFuture(Collections.emptyList())); + }; + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/ArgumentFactory.java b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/package-info.java similarity index 70% rename from src/main/java/me/machinemaker/papertweaks/cloud/arguments/ArgumentFactory.java rename to src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/package-info.java index ab02316a..6fd1754b 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/arguments/ArgumentFactory.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/parsers/setting/package-info.java @@ -3,7 +3,7 @@ * * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. * - * Copyright (C) 2021-2024 Machine_Maker + * Copyright (C) 2024 Machine_Maker * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,13 +17,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package me.machinemaker.papertweaks.cloud.arguments; +@DefaultQualifier(NonNull.class) +package me.machinemaker.papertweaks.cloud.parsers.setting; -import org.checkerframework.checker.nullness.qual.Nullable; - -public interface ArgumentFactory { - - HomeArgument home(boolean required, String name); - - ModuleArgument module(@Nullable Boolean enabled); -} +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/processors/ConditionalCaseInsensitiveSuggestionProcessor.java b/src/main/java/me/machinemaker/papertweaks/cloud/processors/ConditionalCaseInsensitiveSuggestionProcessor.java new file mode 100644 index 00000000..a23ab91d --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/cloud/processors/ConditionalCaseInsensitiveSuggestionProcessor.java @@ -0,0 +1,52 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.cloud.processors; + +import java.util.stream.Stream; +import org.incendo.cloud.execution.preprocessor.CommandPreprocessingContext; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.suggestion.FilteringSuggestionProcessor; +import org.incendo.cloud.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProcessor; + +import static org.incendo.cloud.key.CloudKey.cloudKey; +import static org.incendo.cloud.suggestion.FilteringSuggestionProcessor.Filter.partialTokenMatches; + +public class ConditionalCaseInsensitiveSuggestionProcessor implements SuggestionProcessor { + + private static final ConditionalCaseInsensitiveSuggestionProcessor INSTANCE = new ConditionalCaseInsensitiveSuggestionProcessor<>(); + + @SuppressWarnings("unchecked") + public static ConditionalCaseInsensitiveSuggestionProcessor instance() { + return (ConditionalCaseInsensitiveSuggestionProcessor) INSTANCE; + } + + public static final CloudKey IGNORE_CASE = cloudKey("papertweaks:suggestions/ignore_case", Boolean.class); + + private final SuggestionProcessor caseSensitive = new FilteringSuggestionProcessor<>(partialTokenMatches(false)); + private final SuggestionProcessor caseInsensitive = new FilteringSuggestionProcessor<>(partialTokenMatches(true)); + + @Override + public Stream process(final CommandPreprocessingContext context, final Stream suggestions) { + final boolean ignoreCase = Boolean.TRUE.equals(context.commandContext().getOrDefault(IGNORE_CASE, false)); + final SuggestionProcessor delegate = ignoreCase ? this.caseInsensitive : this.caseSensitive; + return delegate.process(context, suggestions); + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/processors/SimpleSuggestionProcessor.java b/src/main/java/me/machinemaker/papertweaks/cloud/processors/SimpleSuggestionProcessor.java deleted file mode 100644 index bd243e6b..00000000 --- a/src/main/java/me/machinemaker/papertweaks/cloud/processors/SimpleSuggestionProcessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.cloud.processors; - -import cloud.commandframework.execution.CommandSuggestionProcessor; -import cloud.commandframework.execution.preprocessor.CommandPreprocessingContext; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; -import io.leangen.geantyref.TypeToken; -import java.util.LinkedList; -import java.util.List; -import java.util.function.BiPredicate; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; -import org.apache.commons.lang3.StringUtils; - -public final class SimpleSuggestionProcessor implements CommandSuggestionProcessor { - - public static final CloudKey IGNORE_CASE = SimpleCloudKey.of("papertweaks:suggestions/ignore_case", TypeToken.get(Boolean.class)); - - @Override - public List apply(final CommandPreprocessingContext context, final List strings) { - final boolean ignoreCase = Boolean.TRUE.equals(context.getCommandContext().getOrDefault(IGNORE_CASE, false)); - final BiPredicate predicate = ignoreCase ? StringUtils::startsWithIgnoreCase : StringUtils::startsWith; - final String input; - if (context.getInputQueue().isEmpty()) { - input = ""; - } else { - input = context.getInputQueue().peek(); - } - - final List suggestions = new LinkedList<>(); - for (final String suggestion : strings) { - if (predicate.test(suggestion, input)) { - suggestions.add(suggestion); - } - } - return suggestions; - } -} diff --git a/src/main/java/me/machinemaker/papertweaks/cloud/processors/post/GamemodePostprocessor.java b/src/main/java/me/machinemaker/papertweaks/cloud/processors/post/GamemodePostprocessor.java index 2a13f565..29cea14a 100644 --- a/src/main/java/me/machinemaker/papertweaks/cloud/processors/post/GamemodePostprocessor.java +++ b/src/main/java/me/machinemaker/papertweaks/cloud/processors/post/GamemodePostprocessor.java @@ -19,15 +19,15 @@ */ package me.machinemaker.papertweaks.cloud.processors.post; -import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; -import cloud.commandframework.execution.postprocessor.CommandPostprocessor; -import cloud.commandframework.services.types.ConsumerService; +import org.incendo.cloud.execution.postprocessor.CommandPostprocessingContext; +import org.incendo.cloud.execution.postprocessor.CommandPostprocessor; import java.util.Optional; import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; import org.bukkit.GameMode; import org.bukkit.entity.Player; +import org.incendo.cloud.services.type.ConsumerService; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -37,14 +37,14 @@ public class GamemodePostprocessor implements CommandPostprocessor context) { - final Optional gameMode = context.getCommand().getCommandMeta().get(MetaKeys.GAMEMODE_KEY); + final Optional gameMode = context.command().commandMeta().optional(MetaKeys.GAMEMODE_KEY); if (gameMode.isPresent()) { - if (!(context.getCommandContext().getSender() instanceof PlayerCommandDispatcher)) { + if (!(context.commandContext().sender() instanceof PlayerCommandDispatcher)) { ConsumerService.interrupt(); } - final Player player = PlayerCommandDispatcher.from(context.getCommandContext()); + final Player player = PlayerCommandDispatcher.from(context.commandContext()); if (player.getGameMode() != gameMode.get()) { - context.getCommandContext().getSender().sendMessage(translatable("commands.condition.gamemode", RED, text(gameMode.get().name()))); + context.commandContext().sender().sendMessage(translatable("commands.condition.gamemode", RED, text(gameMode.get().name()))); ConsumerService.interrupt(); } } diff --git a/src/main/java/me/machinemaker/papertweaks/db/dao/teleportation/homes/HomesDAO.java b/src/main/java/me/machinemaker/papertweaks/db/dao/teleportation/homes/HomesDAO.java index 2a8ee49f..dc8bda7b 100644 --- a/src/main/java/me/machinemaker/papertweaks/db/dao/teleportation/homes/HomesDAO.java +++ b/src/main/java/me/machinemaker/papertweaks/db/dao/teleportation/homes/HomesDAO.java @@ -20,6 +20,7 @@ package me.machinemaker.papertweaks.db.dao.teleportation.homes; import me.machinemaker.papertweaks.db.model.teleportation.homes.Home; +import org.checkerframework.checker.nullness.qual.Nullable; import org.jdbi.v3.sqlobject.config.KeyColumn; import org.jdbi.v3.sqlobject.config.RegisterConstructorMapper; import org.jdbi.v3.sqlobject.customizer.BindBean; @@ -38,7 +39,7 @@ public interface HomesDAO { LinkedHashMap getHomesForPlayer(UUID playerUUID); @SqlQuery("SELECT * FROM homes WHERE player = :playerUUID AND name = :name") - Home getPlayerHome(UUID playerUUID, String name); + @Nullable Home getPlayerHome(UUID playerUUID, String name); @SqlUpdate("INSERT INTO homes (player, world, name, x, y, z) VALUES ( :player, :world, :name, :x, :y, :z )") void insertHome(@BindBean Home home); diff --git a/src/main/java/me/machinemaker/papertweaks/menus/ConfigurationMenu.java b/src/main/java/me/machinemaker/papertweaks/menus/ConfigurationMenu.java index 30ffa8f8..2fac13a5 100644 --- a/src/main/java/me/machinemaker/papertweaks/menus/ConfigurationMenu.java +++ b/src/main/java/me/machinemaker/papertweaks/menus/ConfigurationMenu.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.menus; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.context.CommandContext; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.ComponentLike; @@ -33,7 +33,7 @@ public interface ConfigurationMenu extends BuildablePart { ComponentLike[] buildFooter(S object); default void send(final CommandContext context, final S object) { - this.send(context.getSender(), object); + this.send(context.sender(), object); } void send(Audience audience, S object); diff --git a/src/main/java/me/machinemaker/papertweaks/menus/PlayerConfigurationMenu.java b/src/main/java/me/machinemaker/papertweaks/menus/PlayerConfigurationMenu.java index a27c6221..282d9689 100644 --- a/src/main/java/me/machinemaker/papertweaks/menus/PlayerConfigurationMenu.java +++ b/src/main/java/me/machinemaker/papertweaks/menus/PlayerConfigurationMenu.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.menus; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.context.CommandContext; import java.util.List; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; @@ -35,7 +35,7 @@ public PlayerConfigurationMenu(final Component title, final String commandPrefix } public void send(final CommandContext context) { - this.send(context.getSender(), PlayerCommandDispatcher.from(context)); + this.send(context.sender(), PlayerCommandDispatcher.from(context)); } @Override diff --git a/src/main/java/me/machinemaker/papertweaks/menus/ReferenceConfigurationMenu.java b/src/main/java/me/machinemaker/papertweaks/menus/ReferenceConfigurationMenu.java index 9092a772..36e1a274 100644 --- a/src/main/java/me/machinemaker/papertweaks/menus/ReferenceConfigurationMenu.java +++ b/src/main/java/me/machinemaker/papertweaks/menus/ReferenceConfigurationMenu.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.menus; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.context.CommandContext; import java.util.List; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; @@ -38,7 +38,7 @@ public ReferenceConfigurationMenu(final Component title, final String commandPre } public void send(final CommandContext context) { - this.send(context.getSender(), this.reference); + this.send(context.sender(), this.reference); } @Override diff --git a/src/main/java/me/machinemaker/papertweaks/modules/ConfiguredModuleCommand.java b/src/main/java/me/machinemaker/papertweaks/modules/ConfiguredModuleCommand.java index c2453b7d..d541caf4 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/ConfiguredModuleCommand.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/ConfiguredModuleCommand.java @@ -19,16 +19,15 @@ */ package me.machinemaker.papertweaks.modules; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.Command; -import cloud.commandframework.meta.CommandMeta; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.common.base.Preconditions; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import org.incendo.cloud.Command; +import org.incendo.cloud.description.Description; +import org.incendo.cloud.minecraft.extras.RichDescription; import static net.kyori.adventure.text.Component.text; +import static org.incendo.cloud.description.Description.description; public abstract class ConfiguredModuleCommand extends ModuleCommand { @@ -41,7 +40,7 @@ void checkValid() { } protected final Command.Builder literal(final Command.Builder parent, final String name) { - final ArgumentDescription literalDescription = this.buildSimpleDescription(name); + final Description literalDescription = this.buildSimpleDescription(name); final Command.Builder builder = parent .literal(name, literalDescription) .permission(this.modulePermission(this.permValue(name))); @@ -49,7 +48,7 @@ protected final Command.Builder literal(final Command.Builder parent, } protected final Command.Builder adminLiteral(final Command.Builder parent, final String name) { - final ArgumentDescription literalDescription = this.buildSimpleDescription(ADMIN + "." + name); + final Description literalDescription = this.buildSimpleDescription(ADMIN + "." + name); final Command.Builder builder = parent .literal(ADMIN, RichDescription.translatable("commands.admin", text(this.moduleBase.getName()))) .literal(name, literalDescription) @@ -58,19 +57,18 @@ protected final Command.Builder adminLiteral(final Command.Builder par } protected final Command.Builder builder(final String name, final String... aliases) { - final ArgumentDescription literalDescription = this.buildSimpleDescription(name); + final Description literalDescription = this.buildSimpleDescription(name); final Command.Builder builder = this.manager() .commandBuilder(name, this.buildRootMeta(), literalDescription, aliases) .permission(this.modulePermission(this.permValue(name))); return this.addDescription(builder, literalDescription); } - protected final Command.Builder addDescription(final Command.Builder builder, final ArgumentDescription description) { - builder.meta(CommandMeta.DESCRIPTION, ""); // clear existing description + protected final Command.Builder addDescription(final Command.Builder builder, final Description description) { if (this.commandInfo.miniMessage()) { - return builder.meta(CommandMeta.DESCRIPTION, description.getDescription()); + return builder.commandDescription(description(description.textDescription())); } else { - return builder.meta(MinecraftExtrasMetaKeys.DESCRIPTION, ((RichDescription) description).getContents()); + return builder.commandDescription(description); } } @@ -78,16 +76,16 @@ protected final Command.Builder player(final String name, fin return this.builder(name, aliases).senderType(PlayerCommandDispatcher.class); } - final ArgumentDescription buildSimpleDescription(final String name) { + final Description buildSimpleDescription(final String name) { return this.buildDescription(this.i18nValue(name)); } - final ArgumentDescription buildDescription(final String i18nKey) { + final Description buildDescription(final String i18nKey) { return translatableDescriptionFactory(this.commandInfo.miniMessage()).apply(i18nKey); } @Override - ArgumentDescription buildRootDescription() { + Description buildRootDescription() { return this.buildSimpleDescription("root"); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/MenuModuleConfig.java b/src/main/java/me/machinemaker/papertweaks/modules/MenuModuleConfig.java index 3ab6c1c2..a21d2621 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/MenuModuleConfig.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/MenuModuleConfig.java @@ -19,11 +19,6 @@ */ package me.machinemaker.papertweaks.modules; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; import io.leangen.geantyref.TypeToken; import java.nio.file.Path; import java.util.ArrayList; @@ -37,9 +32,10 @@ import me.machinemaker.lectern.annotations.validations.numbers.Min; import me.machinemaker.lectern.collection.ConfigField; import me.machinemaker.papertweaks.adventure.TranslationRegistry; -import me.machinemaker.papertweaks.cloud.arguments.SettingArgument; +import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair; import me.machinemaker.papertweaks.menus.ConfigurationMenu; import me.machinemaker.papertweaks.menus.Menu; import me.machinemaker.papertweaks.menus.config.ConfigMenuOptionBuilder; @@ -55,13 +51,19 @@ import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.description.Description; +import org.incendo.cloud.key.CloudKey; import static me.machinemaker.papertweaks.adventure.Components.join; +import static me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair.configSettings; import static net.kyori.adventure.text.Component.newline; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GRAY; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; +import static org.incendo.cloud.key.CloudKey.cloudKey; public abstract class MenuModuleConfig, M extends ConfigurationMenu> extends ModuleConfig { @@ -80,7 +82,7 @@ public abstract class MenuModuleConfig, M exten private final Map> settings = new HashMap<>(); @SuppressWarnings("Convert2Diamond") - private final CloudKey>> settingChangeCloudKey = SimpleCloudKey.of(SettingArgument.SETTING_CHANGE_KEY_STRING, new TypeToken>>() {}); + private final CloudKey>> settingChangeCloudKey = cloudKey(SettingArgumentPair.SETTING_CHANGE_KEY_STRING, new TypeToken>>() {}); private @MonotonicNonNull M menu; private static void registerOptionBuilder(final ConfigMenuOptionBuilder builder) { @@ -160,11 +162,12 @@ protected final ValueNode setupValueNodeSchema(final SectionNode sectionN public void createCommands(final ConfiguredModuleCommand command, final Command.Builder builder) { final Command.Builder configBuilder = command.adminLiteral(builder, CONFIG_COMMAND_NAME).senderType(PlayerCommandDispatcher.class); - final ArgumentDescription resetDescription = command.buildDescription(command.i18nValue("admin." + CONFIG_COMMAND_NAME) + ".reset"); + final Description resetDescription = command.buildDescription(command.i18nValue("admin." + CONFIG_COMMAND_NAME) + ".reset"); command.manager() .command(configBuilder.handler(this::sendMenu)) - .command(configBuilder.hidden() - .argument(SettingArgument.configSettings(this.settingChangeCloudKey, this.settings)) + .command(configBuilder + .apply(MetaKeys.hiddenCommand()) + .required(this.settingChangeCloudKey, configSettings(this.settingChangeCloudKey, this.settings)) .handler(context -> { context.get(this.settingChangeCloudKey).apply(this.self()); this.save(); @@ -176,7 +179,7 @@ public void createCommands(final ConfiguredModuleCommand command, final Command. .handler(context -> { this.settings.values().forEach(setting -> setting.reset(this.self())); this.save(); - context.getSender().sendMessage(translatable(command.i18nValue("admin." + CONFIG_COMMAND_NAME) + ".reset.success", GREEN)); + context.sender().sendMessage(translatable(command.i18nValue("admin." + CONFIG_COMMAND_NAME) + ".reset.success", GREEN)); }) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/ModuleCommand.java b/src/main/java/me/machinemaker/papertweaks/modules/ModuleCommand.java index e31c2556..65c5125e 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/ModuleCommand.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/ModuleCommand.java @@ -19,17 +19,6 @@ */ package me.machinemaker.papertweaks.modules; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.execution.CommandExecutionHandler; -import cloud.commandframework.meta.CommandMeta; -import cloud.commandframework.meta.SimpleCommandMeta; -import cloud.commandframework.minecraft.extras.MinecraftExtrasMetaKeys; -import cloud.commandframework.minecraft.extras.MinecraftHelp; -import cloud.commandframework.minecraft.extras.RichDescription; -import cloud.commandframework.paper.PaperCommandManager; -import cloud.commandframework.permission.CommandPermission; import com.google.common.base.Functions; import com.google.common.base.Preconditions; import com.google.inject.Inject; @@ -41,6 +30,7 @@ import java.util.Objects; import java.util.function.Function; import me.machinemaker.papertweaks.adventure.TranslationRegistry; +import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.ModulePermission; import me.machinemaker.papertweaks.cloud.PaperTweaksCommand; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; @@ -53,9 +43,22 @@ import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.BukkitCommandMeta; +import org.incendo.cloud.description.Description; +import org.incendo.cloud.execution.CommandExecutionHandler; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.meta.CommandMeta; +import org.incendo.cloud.minecraft.extras.AudienceProvider; +import org.incendo.cloud.minecraft.extras.MinecraftHelp; +import org.incendo.cloud.minecraft.extras.RichDescription; +import org.incendo.cloud.paper.PaperCommandManager; +import org.incendo.cloud.parser.standard.StringParser; +import org.incendo.cloud.permission.Permission; import org.intellij.lang.annotations.Pattern; import static me.machinemaker.papertweaks.adventure.Components.CLOSE_BRACKET; @@ -72,11 +75,13 @@ import static net.kyori.adventure.text.format.NamedTextColor.WHITE; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; import static net.kyori.adventure.text.format.TextColor.color; +import static org.incendo.cloud.description.Description.description; +import static org.incendo.cloud.key.CloudKey.cloudKey; public abstract class ModuleCommand extends PaperTweaksCommand { - private static final CommandMeta.Key MODULE_OWNER = CommandMeta.Key.of(ModuleBase.class, "papertweaks:commands/module_owner"); - private static final MinecraftHelp.HelpColors MODULE_HELP_COLORS = MinecraftHelp.HelpColors.of( + private static final CloudKey MODULE_OWNER = cloudKey("papertweaks:commands/module_owner", ModuleBase.class); + private static final MinecraftHelp.HelpColors MODULE_HELP_COLORS = MinecraftHelp.helpColors( color(0x70B3B3), AQUA, color(0x5290FA), @@ -91,15 +96,14 @@ public abstract class ModuleCommand extends PaperTweaksCommand { private Command.@MonotonicNonNull Builder rootBuilder; private static CommandExecutionHandler createHelpHandler(final MinecraftHelp help) { - return context -> help.queryCommands(Objects.requireNonNull(context.getOrDefault("query", ""), "must supply a help query"), context.getSender()); + return context -> help.queryCommands(Objects.requireNonNull(context.getOrDefault("query", ""), "must supply a help query"), context.sender()); } // MiniMessage descriptions will use the MinecraftHelp description decorator to parse - static Function translatableDescriptionFactory(final boolean usesMiniMessage) { - return usesMiniMessage ? ArgumentDescription::of : RichDescription::translatable; + static Function translatableDescriptionFactory(final boolean usesMiniMessage) { + return usesMiniMessage ? Description::description : RichDescription::translatable; } - final void registerCommands0(final ModuleLifecycle lifecycle) { Objects.requireNonNull(this.commandInfo, this + " is not annotated with @ModuleCommand.Info"); this.checkValid(); @@ -119,29 +123,28 @@ void checkValid() { @EnsuresNonNull("rootBuilder") private void setupRootBuilder() { - this.rootBuilder = this.manager.commandBuilder(this.commandInfo.value(), this.buildRootMeta(), this.buildRootDescription(), this.commandInfo.aliases()); + this.rootBuilder = this.manager.commandBuilder(this.commandInfo.value(), this.buildRootMeta(), this.commandInfo.aliases()); + if (this.commandInfo.miniMessage()) { + // if the command uses minimessage translations, set the verbose description to the minimessage translation key + this.rootBuilder = this.rootBuilder.commandDescription(this.buildRootDescription(), description(this.buildRootDescription().textDescription())); + } } protected CommandMeta buildRootMeta() { - final SimpleCommandMeta.Builder builder = CommandMeta.simple() - .with(MODULE_OWNER, this.moduleBase); - if (this.commandInfo.miniMessage()) { // mini message requires the mini message i18n key to be in this description - builder.with(CommandMeta.DESCRIPTION, this.buildRootDescription().getDescription()); - } else { - builder.with(CommandMeta.DESCRIPTION, "§cUse \"/" + this.commandInfo.value() + "\" for help") - .with(MinecraftExtrasMetaKeys.DESCRIPTION, ((RichDescription) this.buildRootDescription()).getContents()); - } - return builder.build(); + return CommandMeta.builder() + .with(MODULE_OWNER, this.moduleBase) + .with(BukkitCommandMeta.BUKKIT_DESCRIPTION, LegacyComponentSerializer.legacySection().serialize(text("Use \"%s\" for help".formatted(this.commandInfo.value()), RED))) + .build(); } private void createInfoCommand() { Objects.requireNonNull(this.rootBuilder, "Must create info command after root builder"); Command.Builder builder = this.rootBuilder.permission(ModulePermission.of(this.lifecycle)) - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, translatable("commands.info.hover", text(this.moduleBase.getName(), GOLD))); + .commandDescription(RichDescription.translatable("commands.info.hover", text(this.moduleBase.getName(), GOLD))); if (!this.commandInfo.infoOnRoot()) { builder = builder.literal("info"); } - this.manager.command(builder.handler(context -> context.getSender().sendMessage(this.buildInfoComponent(context.getSender().sender())))); + this.manager.command(builder.handler(context -> context.sender().sendMessage(this.buildInfoComponent(context.sender().sender())))); } @EnsuresNonNull("infoComponent") @@ -192,18 +195,21 @@ private Component buildInfoComponent(final CommandSender audience) { void setupHelp() { Objects.requireNonNull(this.rootBuilder, "Must configure help after root builder"); if (this.commandInfo.help()) { - final MinecraftHelp help = MinecraftHelp.createNative("/" + this.commandInfo.value() + " help", this.manager); - help.descriptionDecorator((dispatcher, key) -> TranslationRegistry.translate(key, dispatcher.locale()).map(MiniMessage.miniMessage()::deserialize).orElseThrow()); - help.setHelpColors(MODULE_HELP_COLORS); - help.commandFilter(command -> { - final boolean isOwnedByThis = command.getCommandMeta().get(MODULE_OWNER).map(Functions.forPredicate(module -> module == this.moduleBase)).orElse(false); - return isOwnedByThis && !command.isHidden(); - }); + final MinecraftHelp help = MinecraftHelp.builder() + .commandManager(this.manager) + .audienceProvider(AudienceProvider.nativeAudience()) + .commandPrefix("/" + this.commandInfo.value() + " help") + .colors(MODULE_HELP_COLORS) + .descriptionDecorator((dispatcher, key) -> TranslationRegistry.translate(key, dispatcher.locale()).map(MiniMessage.miniMessage()::deserialize).orElseThrow()) + .commandFilter(command -> { + final boolean isOwnedByThis = command.commandMeta().optional(MODULE_OWNER).map(Functions.forPredicate(module -> module == this.moduleBase)).orElse(false); + return isOwnedByThis && !command.commandMeta().contains(MetaKeys.HIDDEN); + }).build(); this.manager.command(this.rootBuilder .literal("help") .permission(ModulePermission.of(this.lifecycle)) - .argument(StringArgument.builder("query").greedy().asOptional().withDefaultDescription(RichDescription.translatable("commands.help.query"))) - .meta(MinecraftExtrasMetaKeys.DESCRIPTION, translatable("commands.help", text(this.moduleBase.getName()))) + .commandDescription(RichDescription.translatable("commands.help", text(this.moduleBase.getName()))) + .argument(StringParser.stringComponent(StringParser.StringMode.GREEDY).name("query").optional().description(RichDescription.translatable("commands.help.query"))) .handler(createHelpHandler(help))); } } @@ -219,7 +225,7 @@ PaperCommandManager manager() { return this.manager; } - protected final CommandPermission modulePermission(final String permission) { + protected final Permission modulePermission(final String permission) { return ModulePermission.of(this.lifecycle(), permission); } @@ -239,7 +245,7 @@ protected final Command.Builder console() { return this.rootBuilder.senderType(ConsoleCommandDispatcher.class); } - ArgumentDescription buildRootDescription() { + Description buildRootDescription() { return translatableDescriptionFactory(this.commandInfo.miniMessage()).apply(this.commandInfo.descriptionKey()); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/ModuleLifecycle.java b/src/main/java/me/machinemaker/papertweaks/modules/ModuleLifecycle.java index cde0b8b4..6793d11d 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/ModuleLifecycle.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/ModuleLifecycle.java @@ -19,8 +19,6 @@ */ package me.machinemaker.papertweaks.modules; -import cloud.commandframework.CommandManager; -import cloud.commandframework.paper.PaperCommandManager; import com.google.inject.Inject; import java.util.Map; import java.util.Set; @@ -34,6 +32,8 @@ import org.bukkit.event.HandlerList; import org.bukkit.inventory.Recipe; import org.bukkit.plugin.java.JavaPlugin; +import org.incendo.cloud.paper.PaperCommandManager; +import org.incendo.cloud.setting.ManagerSetting; public abstract class ModuleLifecycle { @@ -128,9 +128,9 @@ final void reload() { } private void enableCommands() { - this.commandManager.setSetting(CommandManager.ManagerSettings.ALLOW_UNSAFE_REGISTRATION, true); + this.commandManager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true); this.commands.stream().filter(Predicate.not(ModuleCommand::isRegistered)).forEach(moduleCommand -> moduleCommand.registerCommands0(this)); - this.commandManager.setSetting(CommandManager.ManagerSettings.ALLOW_UNSAFE_REGISTRATION, false); + this.commandManager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, false); } private void registerListeners() { diff --git a/src/main/java/me/machinemaker/papertweaks/modules/SimpleMenuModuleConfig.java b/src/main/java/me/machinemaker/papertweaks/modules/SimpleMenuModuleConfig.java index 94eb58ff..21859f8e 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/SimpleMenuModuleConfig.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/SimpleMenuModuleConfig.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.modules; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.context.CommandContext; import java.util.List; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.menus.ReferenceConfigurationMenu; diff --git a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/gemvillagers/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/gemvillagers/Commands.java index 44457c1c..0e073290 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/gemvillagers/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/gemvillagers/Commands.java @@ -19,17 +19,19 @@ */ package me.machinemaker.papertweaks.modules.hermitcraft.gemvillagers; -import cloud.commandframework.bukkit.parsers.location.LocationArgument; import com.google.inject.Inject; -import me.machinemaker.papertweaks.cloud.arguments.PseudoEnumArgument; +import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.cloud.parsers.PseudoEnumParser; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; import org.bukkit.Location; +import org.incendo.cloud.bukkit.parser.location.LocationParser; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.component.DefaultValue.dynamic; @ModuleCommand.Info(value = "gemvillagers", aliases = {"gvillagers", "gv"}, i18n = "gem-villagers", perm = "gemvillagers") class Commands extends ConfiguredModuleCommand { @@ -45,13 +47,14 @@ class Commands extends ConfiguredModuleCommand { protected void registerCommands() { this.register( this.literal(this.player(), "spawn") - .argument(PseudoEnumArgument.single("villager", this.gemVillagers.villagers.keySet())) - .argument(LocationArgument.optional("loc")) + .senderType(PlayerCommandDispatcher.class) + .required("villager", PseudoEnumParser.singlePseudoEnumParser(this.gemVillagers.villagers.keySet())) + .optional("loc", LocationParser.locationParser(), dynamic(ctx -> ctx.sender().sender().getLocation())) .handler(this.sync((context, player) -> { final String villager = context.get("villager"); - final Location loc = context.getOptional("loc").orElse(player.getLocation()); + final Location loc = context.get("loc"); this.gemVillagers.villagers.get(villager).spawnVillager(loc.getWorld(), loc); - context.getSender().sendMessage(translatable("modules.gem-villagers.commands.spawn.success", YELLOW, text(villager, GOLD))); + context.sender().sendMessage(translatable("modules.gem-villagers.commands.spawn.success", YELLOW, text(villager, GOLD))); })) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/tag/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/tag/Commands.java index 065e5f05..cd4d3b54 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/tag/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/tag/Commands.java @@ -19,10 +19,6 @@ */ package me.machinemaker.papertweaks.modules.hermitcraft.tag; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.EnumArgument; -import cloud.commandframework.bukkit.parsers.PlayerArgument; -import cloud.commandframework.execution.CommandExecutionHandler; import com.google.inject.Inject; import java.util.Locale; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; @@ -32,6 +28,8 @@ import me.machinemaker.papertweaks.utils.boards.DisplaySlot; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.execution.CommandExecutionHandler; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -39,6 +37,8 @@ import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.bukkit.parser.PlayerParser.playerParser; +import static org.incendo.cloud.parser.standard.EnumParser.enumParser; @ModuleCommand.Info(value = "tag", i18n = "tag", perm = "tag") class Commands extends ConfiguredModuleCommand { @@ -58,7 +58,7 @@ protected void registerCommands() { final Command.Builder giveTagBuilder = this.literal(builder, "givetag").handler(this.giveTag()); this.register(giveTagBuilder.senderType(PlayerCommandDispatcher.class)); - this.register(giveTagBuilder.argument(PlayerArgument.of("player"))); + this.register(giveTagBuilder.required("player", playerParser())); this.register( this.literal(builder, "reset") .handler(this.sync(context -> { @@ -67,24 +67,24 @@ protected void registerCommands() { if (Tag.IT.has(player)) { removed = true; this.tagManager.removeAsIt(player); - context.getSender().sendMessage(translatable("modules.tag.commands.reset.success", GREEN, text(player.getName(), GOLD))); + context.sender().sendMessage(translatable("modules.tag.commands.reset.success", GREEN, text(player.getName(), GOLD))); } } if (!removed) { - context.getSender().sendMessage(translatable("modules.tag.commands.reset.fail")); + context.sender().sendMessage(translatable("modules.tag.commands.reset.fail")); } })) ); this.register( this.literal(builder, "counter") - .argument(EnumArgument.of(DisplaySlot.class, "slot")) + .required("slot", enumParser(DisplaySlot.class)) .handler(this.sync(context -> { final DisplaySlot slot = context.get("slot"); if (slot.isDisplayedOn(this.tagManager.tagCounter)) { - context.getSender().sendMessage(translatable("modules.tag.commands.counter.fail", RED)); + context.sender().sendMessage(translatable("modules.tag.commands.counter.fail", RED)); } else { slot.changeFor(this.tagManager.tagCounter); - context.getSender().sendMessage(translatable("modules.tag.commands.counter.success", GREEN, text(slot.name().toLowerCase(Locale.ENGLISH), GOLD))); + context.sender().sendMessage(translatable("modules.tag.commands.counter.success", GREEN, text(slot.name().toLowerCase(Locale.ENGLISH), GOLD))); } })) ); @@ -95,8 +95,8 @@ protected void registerCommands() { private CommandExecutionHandler giveTag() { return this.sync(context -> { final Player player = context.getOrSupplyDefault("player", () -> PlayerCommandDispatcher.from(context)); - if (this.tagManager.setAsIt(context.getSender().sender(), player) && this.config.showMessages) { - Bukkit.getServer().sendMessage(translatable("modules.tag.tag.success", YELLOW, text(context.getSender().sender().getName()), text(player.getName()))); + if (this.tagManager.setAsIt(context.sender().sender(), player) && this.config.showMessages) { + Bukkit.getServer().sendMessage(translatable("modules.tag.tag.success", YELLOW, text(context.sender().sender().getName()), text(player.getName()))); } }); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/thundershrine/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/thundershrine/Commands.java index 810bad30..fba65845 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/thundershrine/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/thundershrine/Commands.java @@ -19,7 +19,6 @@ */ package me.machinemaker.papertweaks.modules.hermitcraft.thundershrine; -import cloud.commandframework.Command; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; @@ -30,6 +29,7 @@ import org.bukkit.entity.AreaEffectCloud; import org.bukkit.entity.ArmorStand; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.RED; @@ -47,7 +47,7 @@ protected void registerCommands() { .handler(this.sync((context, player) -> { final @Nullable ArmorStand stand = Entities.getSingleNearbyEntityOfType(ArmorStand.class, player.getLocation(), 3, 3, 3); if (stand == null) { - context.getSender().sendMessage(translatable("modules.thunder-shrine.commands.create.fail.no-stands", RED)); + context.sender().sendMessage(translatable("modules.thunder-shrine.commands.create.fail.no-stands", RED)); } else { stand.getWorld().spawnParticle(Particle.TOTEM, stand.getLocation(), 100, 0, 0, 0, 0.5); stand.getWorld().playSound(stand.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.MASTER, 1.0f, 0.75f); @@ -59,7 +59,7 @@ protected void registerCommands() { ThunderShrine.SHRINE.setTo(cloud, player.getUniqueId()); }); stand.remove(); - context.getSender().sendMessage(translatable("modules.thunder-shrine.commands.create.success", YELLOW)); + context.sender().sendMessage(translatable("modules.thunder-shrine.commands.create.success", YELLOW)); } })) ); @@ -68,10 +68,10 @@ protected void registerCommands() { .handler(this.sync((context, player) -> { final @Nullable AreaEffectCloud cloud = Entities.getSingleNearbyEntityOfType(AreaEffectCloud.class, player.getLocation(), 3, 3, 3, c -> player.getUniqueId().equals(ThunderShrine.SHRINE.getFrom(c))); if (cloud == null) { - context.getSender().sendMessage(translatable("modules.thunder-shrine.commands.remove.fail.no-stands", RED)); + context.sender().sendMessage(translatable("modules.thunder-shrine.commands.remove.fail.no-stands", RED)); } else { cloud.remove(); - context.getSender().sendMessage(translatable("modules.thunder-shrine.commands.remove.success", YELLOW)); + context.sender().sendMessage(translatable("modules.thunder-shrine.commands.remove.success", YELLOW)); } })) ); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/treasuregems/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/treasuregems/Commands.java index d7b3ec17..8f391018 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/treasuregems/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/hermitcraft/treasuregems/Commands.java @@ -19,14 +19,16 @@ */ package me.machinemaker.papertweaks.modules.hermitcraft.treasuregems; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.IntegerArgument; import com.google.inject.Inject; -import me.machinemaker.papertweaks.cloud.arguments.PseudoEnumArgument; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; import org.bukkit.inventory.ItemStack; +import org.incendo.cloud.Command; + +import static me.machinemaker.papertweaks.cloud.parsers.PseudoEnumParser.singlePseudoEnumParser; +import static org.incendo.cloud.component.DefaultValue.constant; +import static org.incendo.cloud.parser.standard.IntegerParser.integerParser; @ModuleCommand.Info(value = "treasuregems", aliases = {"tgems"}, i18n = "treasure-gems", perm = "treasuregems") class Commands extends ConfiguredModuleCommand { @@ -44,8 +46,8 @@ protected void registerCommands() { this.register( this.literal(builder, "give") - .argument(PseudoEnumArgument.single("head", this.treasureGems.heads.keySet())) - .argument(IntegerArgument.builder("count").asOptionalWithDefault(1).withMin(1)) + .required("head", singlePseudoEnumParser(this.treasureGems.heads.keySet())) + .optional("count", integerParser(1), constant(1)) .handler(this.sync((context, player) -> { final ItemStack head = this.treasureGems.heads.get((String) context.get("head")).clone(); head.setAmount(context.get("count")); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/mobs/countmobdeaths/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/mobs/countmobdeaths/Commands.java index 37a0d3f2..0e58db45 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/mobs/countmobdeaths/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/mobs/countmobdeaths/Commands.java @@ -19,15 +19,15 @@ */ package me.machinemaker.papertweaks.modules.mobs.countmobdeaths; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.execution.CommandExecutionHandler; import com.google.inject.Inject; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; import me.machinemaker.papertweaks.utils.boards.Scoreboards; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.execution.CommandExecutionHandler; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; @@ -52,21 +52,21 @@ protected void registerCommands() { .handler(this.sync((player, context, countingBoard) -> { countingBoard.setCounting(true); player.setScoreboard(countingBoard.scoreboard()); - context.getSender().sendMessage(translatable("modules.mob-death-count.started", GREEN)); + context.sender().sendMessage(translatable("modules.mob-death-count.started", GREEN)); })) ); this.register( this.literal(builder, "stop") .handler(this.sync((player, context, countingBoard) -> { countingBoard.setCounting(false); - context.getSender().sendMessage(translatable("modules.mob-death-count.stopped", YELLOW)); + context.sender().sendMessage(translatable("modules.mob-death-count.stopped", YELLOW)); })) ); this.register( this.literal(builder, "reset") .handler(this.sync((player, context, countingBoard) -> { countingBoard.scoreboard().getEntries().forEach(countingBoard.scoreboard()::resetScores); - context.getSender().sendMessage(translatable("modules.mob-death-count.reset", GREEN)); + context.sender().sendMessage(translatable("modules.mob-death-count.reset", GREEN)); })) ); this.register( diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/coordinateshud/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/coordinateshud/Commands.java index b1222642..c512630f 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/coordinateshud/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/coordinateshud/Commands.java @@ -19,12 +19,12 @@ */ package me.machinemaker.papertweaks.modules.survival.coordinateshud; -import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector; -import cloud.commandframework.bukkit.parsers.selector.MultiplePlayerSelectorArgument; import com.google.inject.Inject; import me.machinemaker.papertweaks.modules.ModuleCommand; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; +import org.incendo.cloud.bukkit.data.MultiplePlayerSelector; +import org.incendo.cloud.bukkit.parser.selector.MultiplePlayerSelectorParser; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -50,22 +50,22 @@ protected void registerCommands() { .handler(this.sync((context, player) -> { if (this.hudRunnable.contains(player)) { this.hudRunnable.setAndRemove(player); - context.getSender().sendMessage(translatable("modules.coordinates-hud.hud-off", GREEN)); - context.getSender().sendActionBar(Component.empty()); + context.sender().sendMessage(translatable("modules.coordinates-hud.hud-off", GREEN)); + context.sender().sendActionBar(Component.empty()); } else { this.hudRunnable.setAndAdd(player); - context.getSender().sendMessage(translatable("modules.coordinates-hud.hud-on", GREEN)); + context.sender().sendMessage(translatable("modules.coordinates-hud.hud-on", GREEN)); } })) ); this.register(this.builder() .literal("player") - .argument(MultiplePlayerSelectorArgument.of("players")) + .required("players", MultiplePlayerSelectorParser.multiplePlayerSelectorParser(false)) .permission(this.modulePermission("vanillatweaks.coordinateshud.togglehud.others")) .handler(this.sync(context -> { final MultiplePlayerSelector players = context.get("players"); - for (final Player player : players.getPlayers()) { + for (final Player player : players.values()) { if (this.hudRunnable.contains(player)) { this.hudRunnable.setAndRemove(player); player.sendActionBar(Component.empty()); @@ -73,7 +73,7 @@ protected void registerCommands() { this.hudRunnable.setAndAdd(player); } } - context.getSender().sendMessage(translatable("modules.coordinates-hud.hud-toggled-for", style(GRAY, ITALIC), text(players.getPlayers().size()))); + context.sender().sendMessage(translatable("modules.coordinates-hud.hud-toggled-for", style(GRAY, ITALIC), text(players.values().size()))); })) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/durabilityping/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/durabilityping/Commands.java index d88a4985..808bfffa 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/durabilityping/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/durabilityping/Commands.java @@ -19,12 +19,11 @@ */ package me.machinemaker.papertweaks.modules.survival.durabilityping; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.EnumArgument; import com.google.inject.Inject; import java.util.List; -import me.machinemaker.papertweaks.cloud.arguments.SettingArgument; +import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; +import me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair; import me.machinemaker.papertweaks.menus.PlayerConfigurationMenu; import me.machinemaker.papertweaks.menus.options.BooleanMenuOption; import me.machinemaker.papertweaks.menus.options.SelectableEnumMenuOption; @@ -35,10 +34,14 @@ import net.kyori.adventure.text.event.ClickEvent; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; import static me.machinemaker.papertweaks.adventure.Components.join; +import static me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair.playerSettings; +import static me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair.resetPlayerSettings; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.format.NamedTextColor.GRAY; +import static org.incendo.cloud.parser.standard.EnumParser.enumParser; @ModuleCommand.Info(value = "durabilityping", aliases = {"dping", "dp"}, i18n = "durability-ping", perm = "durabilityping") class Commands extends ConfiguredModuleCommand { @@ -76,25 +79,28 @@ protected void registerCommands() { final Command.Builder configBuilder = this.literal(builder, "config"); this.register(configBuilder.handler(this.menu::send)); - this.register(configBuilder.hidden() + this.register(configBuilder + .apply(MetaKeys.hiddenCommand()) .literal("preview_display") - .argument(EnumArgument.of(Settings.DisplaySetting.class, "displaySetting")) - .handler(context -> context.get("displaySetting").sendMessage(context.getSender(), this.listener.createNotification(Material.ELYTRA, Material.ELYTRA.getMaxDurability() / 2))) + .required("displaySetting", enumParser(Settings.DisplaySetting.class)) + .handler(context -> context.get("displaySetting").sendMessage(context.sender(), this.listener.createNotification(Material.ELYTRA, Material.ELYTRA.getMaxDurability() / 2))) ); - this.register(configBuilder.hidden() + this.register(configBuilder + .apply(MetaKeys.hiddenCommand()) .literal("preview_sound") - .handler((context -> context.getSender().playSound(DurabilityPing.SOUND, Sound.Emitter.self()))) + .handler(context -> context.sender().playSound(DurabilityPing.SOUND, Sound.Emitter.self())) ); - this.register(configBuilder.hidden() - .argument(SettingArgument.playerSettings(this.settings.index())) + this.register(configBuilder + .apply(MetaKeys.hiddenCommand()) + .required(SettingArgumentPair.PLAYER_SETTING_CHANGE_KEY, playerSettings(this.settings.index())) .handler(this.sync((context, player) -> { - final SettingArgument.SettingChange> change = context.get(SettingArgument.PLAYER_SETTING_CHANGE_KEY); + final SettingArgumentPair.SettingChange> change = context.get(SettingArgumentPair.PLAYER_SETTING_CHANGE_KEY); change.apply(player); this.listener.settingsCache.invalidate(player.getUniqueId()); this.menu.send(context); })) ); - this.register(SettingArgument.resetPlayerSettings(configBuilder, "modules.durability-ping.commands.config.reset", this.settings)); + this.register(resetPlayerSettings(configBuilder, "modules.durability-ping.commands.config.reset", this.settings)); this.config.createCommands(this, builder); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/Commands.java index da5dc3a7..8362a703 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/Commands.java @@ -19,12 +19,10 @@ */ package me.machinemaker.papertweaks.modules.survival.graves; -import cloud.commandframework.Command; -import cloud.commandframework.bukkit.arguments.selector.MultiplePlayerSelector; -import cloud.commandframework.bukkit.parsers.selector.MultiplePlayerSelectorArgument; import com.google.common.base.Preconditions; import com.google.inject.Inject; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,8 +42,9 @@ import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.data.MultiplePlayerSelector; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -54,6 +53,7 @@ import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; import static net.kyori.adventure.text.format.TextDecoration.ITALIC; +import static org.incendo.cloud.bukkit.parser.selector.MultiplePlayerSelectorParser.multiplePlayerSelectorParser; @ModuleCommand.Info(value = "graves", i18n = "graves", perm = "graves") class Commands extends ConfiguredModuleCommand { @@ -87,35 +87,35 @@ protected void registerCommands() { this.literal(builder, "locate") .handler(this.sync((context, player) -> { if (!this.config.graveLocating) { - context.getSender().sendMessage(translatable("modules.graves.commands.locate.disabled", RED)); + context.sender().sendMessage(translatable("modules.graves.commands.locate.disabled", RED)); return; } final @Nullable Location location = player.getPersistentDataContainer().get(PlayerListener.LAST_GRAVE_LOCATION, DataTypes.LOCATION); if (location == null) { - context.getSender().sendMessage(translatable("modules.graves.commands.locate.none-found", RED)); + context.sender().sendMessage(translatable("modules.graves.commands.locate.none-found", RED)); } else { final Component loc = formatLocation(location, false); final Component world = location.getWorld() != null ? text(location.getWorld().getName(), YELLOW) : text("unknown world"); - context.getSender().sendMessage(translatable("modules.graves.last-grave-location", GOLD, loc, world)); + context.sender().sendMessage(translatable("modules.graves.last-grave-location", GOLD, loc, world)); } })) ); this.register(this.adminLiteral(builder, "grave-key").handler(this.sync((context, player) -> player.getInventory().addItem(GRAVE_KEY)))); this.register(this.adminLiteral(builder, "locate") - .argument(MultiplePlayerSelectorArgument.builder("targets").allowEmpty(false)) + .required("targets", multiplePlayerSelectorParser(false)) .handler(this.sync((context) -> { final MultiplePlayerSelector selector = context.get("targets"); - final List<@NonNull Player> players = selector.getPlayers(); + final Collection players = selector.values(); for (final Player target : players) { final Map> locations = locateGravesFor(target); if (locations.isEmpty()) { - context.getSender().sendMessage(translatable("modules.graves.commands.admin.locate.none-found", target.displayName())); + context.sender().sendMessage(translatable("modules.graves.commands.admin.locate.none-found", target.displayName())); } else { locations.forEach((world, locs) -> { - context.getSender().sendMessage(translatable("modules.graves.commands.admin.locate.found.header", target.displayName(), text(world.key().asString()))); + context.sender().sendMessage(translatable("modules.graves.commands.admin.locate.found.header", target.displayName(), text(world.key().asString()))); for (final Location loc : locs) { - context.getSender().sendMessage(formatLocation(loc, true)); + context.sender().sendMessage(formatLocation(loc, true)); } }); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/PlayerListener.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/PlayerListener.java index 4d2c361a..4b465ab1 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/PlayerListener.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/graves/PlayerListener.java @@ -19,7 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.graves; -import cloud.commandframework.types.tuples.Pair; import com.google.inject.Inject; import java.util.Arrays; import java.util.Collection; @@ -60,6 +59,7 @@ import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.type.tuple.Pair; import static java.util.Objects.requireNonNull; import static me.machinemaker.papertweaks.utils.Entities.getNearbyEntitiesOfType; @@ -316,11 +316,11 @@ static class GravePair extends Pair { } ArmorStand getHeadstone() { - return this.getFirst(); + return this.first(); } ArmorStand getBase() { - return this.getSecond(); + return this.second(); } void remove() { diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Commands.java index aaa0c0e5..afc0c50f 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Commands.java @@ -19,14 +19,13 @@ */ package me.machinemaker.papertweaks.modules.survival.multiplayersleep; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.EnumArgument; import com.google.inject.Inject; import java.util.List; import me.machinemaker.papertweaks.adventure.Components; -import me.machinemaker.papertweaks.cloud.arguments.SettingArgument; +import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; +import me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair; import me.machinemaker.papertweaks.menus.PlayerConfigurationMenu; import me.machinemaker.papertweaks.menus.options.SelectableEnumMenuOption; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; @@ -35,7 +34,10 @@ import net.kyori.adventure.text.Component; import org.bukkit.World; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import static me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair.playerSettings; +import static me.machinemaker.papertweaks.cloud.parsers.setting.SettingArgumentPair.resetPlayerSettings; import static net.kyori.adventure.text.Component.join; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; @@ -45,6 +47,7 @@ import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.WHITE; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.parser.standard.EnumParser.enumParser; @ModuleCommand.Info(value = "multiplayersleep", aliases = {"mpsleep", "mps"}, i18n = "multiplayer-sleep", perm = "multiplayersleep") class Commands extends ConfiguredModuleCommand { @@ -87,30 +90,30 @@ protected void registerCommands() { } else { almostAsleep = translatable("modules.multiplayer-sleep.commands.sleeping.almost-asleep.empty", RED); } - context.getSender().sendMessage(translatable("modules.multiplayer-sleep.commands.sleeping.fully-asleep", GREEN, fullyAsleep)); - context.getSender().sendMessage(translatable("modules.multiplayer-sleep.commands.sleeping.almost-asleep", YELLOW, almostAsleep)); + context.sender().sendMessage(translatable("modules.multiplayer-sleep.commands.sleeping.fully-asleep", GREEN, fullyAsleep)); + context.sender().sendMessage(translatable("modules.multiplayer-sleep.commands.sleeping.almost-asleep", YELLOW, almostAsleep)); }) ); this.register(configBuilder.handler(this.menu::send)); this.register(configBuilder - .hidden() + .apply(MetaKeys.hiddenCommand()) .literal("preview_display") - .argument(EnumArgument.of(Settings.DisplaySetting.class, "displaySetting")) + .required("displaySetting", enumParser(Settings.DisplaySetting.class)) .handler(context -> { context.get("displaySetting").preview(PlayerCommandDispatcher.from(context)); }) ); this.register(configBuilder - .hidden() - .argument(SettingArgument.playerSettings(this.settings.index())) + .apply(MetaKeys.hiddenCommand()) + .required(SettingArgumentPair.PLAYER_SETTING_CHANGE_KEY, playerSettings(this.settings.index())) .handler(context -> { - final SettingArgument.SettingChange> change = context.get(SettingArgument.PLAYER_SETTING_CHANGE_KEY); + final SettingArgumentPair.SettingChange> change = context.get(SettingArgumentPair.PLAYER_SETTING_CHANGE_KEY); final Player player = PlayerCommandDispatcher.from(context); change.apply(player); this.menu.send(context); }) ); - this.register(SettingArgument.resetPlayerSettings(configBuilder, "modules.multiplayer-sleep.commands.config.reset", this.settings)); + this.register(resetPlayerSettings(configBuilder, "modules.multiplayer-sleep.commands.config.reset", this.settings)); // TODO if set to action bar or boss bar, don't wait for SleepContext#recalculate to send notifications this.config.createCommands(this, builder); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Config.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Config.java index 4874b769..d99cbe8d 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Config.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/multiplayersleep/Config.java @@ -19,7 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.multiplayersleep; -import cloud.commandframework.context.CommandContext; import java.util.List; import java.util.Map; import java.util.Objects; @@ -46,6 +45,7 @@ import org.bukkit.GameRule; import org.bukkit.World; import org.bukkit.entity.Player; +import org.incendo.cloud.context.CommandContext; import static net.kyori.adventure.text.Component.text; @@ -102,7 +102,7 @@ protected MergedMenus.Menu1 createMenu(final Component title, fin @Override protected void sendMenu(final CommandContext context) { final Player player = PlayerCommandDispatcher.from(context); - context.getSender().sendMessage(this.menu().build(this, player.getWorld())); + context.sender().sendMessage(this.menu().build(this, player.getWorld())); } @Override diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/netherportalcoords/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/netherportalcoords/Commands.java index 245e4866..c4ad9d4e 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/netherportalcoords/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/netherportalcoords/Commands.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.modules.survival.netherportalcoords; -import cloud.commandframework.Command; +import org.incendo.cloud.Command; import com.google.inject.Inject; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.cloud.dispatchers.PlayerCommandDispatcher; @@ -49,11 +49,11 @@ protected void registerCommands() { final Player player = PlayerCommandDispatcher.from(context); final Location loc = player.getLocation(); if (this.config.overWorlds().contains(player.getWorld())) { - this.messageService.coordinatesMsg(context.getSender(), new MessageService.CoordinatesComponent(loc, i -> i / 8), "Nether"); // TODO use coord scale from DimensionType + this.messageService.coordinatesMsg(context.sender(), new MessageService.CoordinatesComponent(loc, i -> i / 8), "Nether"); // TODO use coord scale from DimensionType } else if (this.config.netherWorlds().contains(player.getWorld())) { - this.messageService.coordinatesMsg(context.getSender(), new MessageService.CoordinatesComponent(loc, i -> i * 8), "Overworld"); // TODO use coord scale from DimensionType + this.messageService.coordinatesMsg(context.sender(), new MessageService.CoordinatesComponent(loc, i -> i * 8), "Overworld"); // TODO use coord scale from DimensionType } else { - this.messageService.invalidWorld(context.getSender()); + this.messageService.invalidWorld(context.sender()); } }) ); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/pillagertools/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/pillagertools/Commands.java index b1607d91..37000ec0 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/pillagertools/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/pillagertools/Commands.java @@ -19,13 +19,13 @@ */ package me.machinemaker.papertweaks.modules.survival.pillagertools; -import cloud.commandframework.Command; import com.google.inject.Inject; import java.util.Locale; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; import net.kyori.adventure.text.TextComponent; +import org.incendo.cloud.Command; import static net.kyori.adventure.text.Component.newline; import static net.kyori.adventure.text.Component.text; @@ -61,7 +61,7 @@ protected void registerCommands() { translatable("commands.config.default-value.bool." + this.config.getSettingValue(option), GREEN) )); } - context.getSender().sendMessage(txtBuilder); + context.sender().sendMessage(txtBuilder); }) ); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/realtimeclock/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/realtimeclock/Commands.java index 81d8d129..8ba9a7ca 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/realtimeclock/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/realtimeclock/Commands.java @@ -19,9 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.realtimeclock; -import cloud.commandframework.Command; -import cloud.commandframework.bukkit.parsers.WorldArgument; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.inject.Inject; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -31,6 +28,10 @@ import net.kyori.adventure.audience.Audience; import org.bukkit.World; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.minecraft.extras.RichDescription; + +import static org.incendo.cloud.bukkit.parser.WorldParser.worldParser; @ModuleCommand.Info(value = "gametime", aliases = {"gtime", "gt"}, descriptionKey = "modules.real-time-clock.commands.root", miniMessage = true, infoOnRoot = false) class Commands extends ModuleCommand { @@ -52,16 +53,16 @@ protected void registerCommands() { .handler(context -> { final Player player = PlayerCommandDispatcher.from(context); final Duration duration = Duration.of(player.getWorld().getGameTime() / 20, ChronoUnit.SECONDS); - this.sendGameTime(context.getSender(), duration, player.getWorld()); + this.sendGameTime(context.sender(), duration, player.getWorld()); }) ); this.register(builder .permission(this.modulePermission("vanillatweaks.realtimeclock.other")) - .argument(WorldArgument.of("world"), RichDescription.translatable("modules.real-time-clock.commands.specific-world")) + .required("world", worldParser(), RichDescription.translatable("modules.real-time-clock.commands.specific-world")) .handler(context -> { final World world = context.get("world"); final Duration duration = Duration.of(world.getGameTime() / 20, ChronoUnit.SECONDS); - this.sendGameTime(context.getSender(), duration, world); + this.sendGameTime(context.sender(), duration, world); }) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Commands.java index 612b709c..568b1dfa 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Commands.java @@ -19,7 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.trackrawstats; -import cloud.commandframework.Command; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; @@ -27,10 +26,13 @@ import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.minecraft.extras.RichDescription; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.parser.ParserDescriptor.parserDescriptor; @ModuleCommand.Info(value = "trackrawstats", aliases = {"trackrs", "trs"}, i18n = "track-raw-stats", perm = "trackrawstats") class Commands extends ConfiguredModuleCommand { @@ -41,15 +43,15 @@ protected void registerCommands() { this.register( this.literal(builder, "display") - .argument(ObjectiveArgument.of("objective")) + .required("objective", parserDescriptor(new ObjectiveParser<>(), Tracked.class), RichDescription.translatable("modules.track-raw-stats.commands.arguments.objective")) .handler(this.sync((context, player) -> { player.setScoreboard(Scoreboards.main()); final Tracked tracked = context.get("objective"); if (tracked.objective().getDisplaySlot() == DisplaySlot.SIDEBAR) { - context.getSender().sendMessage(translatable("modules.track-raw-stats.commands.display.already-displayed", YELLOW, tracked)); + context.sender().sendMessage(translatable("modules.track-raw-stats.commands.display.already-displayed", YELLOW, tracked)); } else { tracked.objective().setDisplaySlot(DisplaySlot.SIDEBAR); - context.getSender().sendMessage(translatable("modules.track-raw-stats.commands.display.success", GREEN, tracked)); + context.sender().sendMessage(translatable("modules.track-raw-stats.commands.display.success", GREEN, tracked)); } })) ); @@ -58,10 +60,10 @@ protected void registerCommands() { .handler(this.sync(context -> { final @Nullable Objective currentlyDisplayed = Scoreboards.main().getObjective(DisplaySlot.SIDEBAR); if (currentlyDisplayed == null || !RawStats.OBJECTIVE_DATA.containsKey(currentlyDisplayed.getName())) { - context.getSender().sendMessage(translatable("modules.track-raw-stats.commands.clear.no-display", YELLOW)); + context.sender().sendMessage(translatable("modules.track-raw-stats.commands.clear.no-display", YELLOW)); } else { currentlyDisplayed.setDisplaySlot(null); - context.getSender().sendMessage(translatable("modules.track-raw-stats.commands.clear.success", GREEN, RawStats.OBJECTIVE_DATA.get(currentlyDisplayed.getName()))); + context.sender().sendMessage(translatable("modules.track-raw-stats.commands.clear.success", GREEN, RawStats.OBJECTIVE_DATA.get(currentlyDisplayed.getName()))); } })) ); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveArgument.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveArgument.java deleted file mode 100644 index a13acb29..00000000 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveArgument.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GNU General Public License v3 - * - * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. - * - * Copyright (C) 2021-2024 Machine_Maker - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.machinemaker.papertweaks.modules.survival.trackrawstats; - -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.minecraft.extras.RichDescription; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; -import me.machinemaker.papertweaks.utils.boards.Scoreboards; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.checkerframework.checker.nullness.qual.Nullable; - -class ObjectiveArgument extends CommandArgument { - - private ObjectiveArgument(final String name) { - super(true, name, new Parser(), "", Tracked.class, null, RichDescription.translatable("modules.track-raw-stats.commands.arguments.objective")); - } - - static ObjectiveArgument of(final String name) { - return new ObjectiveArgument(name); - } - - private static class Parser implements ArgumentParser { - - private static final Set SUGGESTIONS = Collections.unmodifiableSet(RawStats.OBJECTIVE_DATA.keySet()); - - @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final @Nullable String input = inputQueue.peek(); - if (!RawStats.OBJECTIVE_DATA.containsKey(input) || input == null) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " does not match a valid criteria")); - } - final @Nullable Objective objective = Scoreboards.main().getObjective(input); - if (objective == null) { - return ArgumentParseResult.failure(new IllegalArgumentException(input + " does not match a valid criteria")); - } - inputQueue.remove(); - return ArgumentParseResult.success(RawStats.OBJECTIVE_DATA.get(input)); - } - - @Override - public List suggestions(final CommandContext commandContext, final String input) { - final @Nullable Objective currentObjective = Scoreboards.main().getObjective(DisplaySlot.SIDEBAR); - final Set suggestions; - if (currentObjective != null && SUGGESTIONS.contains(currentObjective.getName())) { - suggestions = new LinkedHashSet<>(SUGGESTIONS); - suggestions.remove(currentObjective.getName()); - } else { - suggestions = SUGGESTIONS; - } - return new ArrayList<>(suggestions); - } - - @Override - public boolean isContextFree() { - return true; - } - } -} diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveParser.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveParser.java new file mode 100644 index 00000000..d991e760 --- /dev/null +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/ObjectiveParser.java @@ -0,0 +1,65 @@ +/* + * GNU General Public License v3 + * + * PaperTweaks, a performant replacement for the VanillaTweaks datapacks. + * + * Copyright (C) 2024 Machine_Maker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.machinemaker.papertweaks.modules.survival.trackrawstats; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import me.machinemaker.papertweaks.utils.boards.Scoreboards; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.checkerframework.checker.nullness.qual.Nullable; +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.suggestion.BlockingSuggestionProvider; + +class ObjectiveParser implements ArgumentParser, BlockingSuggestionProvider.Strings { + + private static final Set SUGGESTIONS = Collections.unmodifiableSet(RawStats.OBJECTIVE_DATA.keySet()); + + @Override + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String input = commandInput.readString(); + if (!RawStats.OBJECTIVE_DATA.containsKey(input)) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " does not match a valid criteria")); + } + final @Nullable Objective objective = Scoreboards.main().getObjective(input); + if (objective == null) { + return ArgumentParseResult.failure(new IllegalArgumentException(input + " does not match a valid criteria")); + } + return ArgumentParseResult.success(RawStats.OBJECTIVE_DATA.get(input)); + } + + @Override + public Iterable stringSuggestions(final CommandContext commandContext, final CommandInput input) { + final @Nullable Objective currentObjective = Scoreboards.main().getObjective(DisplaySlot.SIDEBAR); + final Set suggestions; + if (currentObjective != null && SUGGESTIONS.contains(currentObjective.getName())) { + suggestions = new LinkedHashSet<>(SUGGESTIONS); + suggestions.remove(currentObjective.getName()); + } else { + suggestions = SUGGESTIONS; + } + return new ArrayList<>(suggestions); + } +} diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Tracked.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Tracked.java index 8e371519..96929a44 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Tracked.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackrawstats/Tracked.java @@ -19,7 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.trackrawstats; -import cloud.commandframework.types.tuples.Pair; import com.google.common.base.Preconditions; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -32,6 +31,7 @@ import org.bukkit.scoreboard.Scoreboard; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.type.tuple.Pair; import static me.machinemaker.papertweaks.adventure.Components.join; import static net.kyori.adventure.text.Component.text; @@ -163,9 +163,9 @@ public Component asComponent() { }; return join( - translatable(typeKey.getFirst()), + translatable(typeKey.first()), text(": "), - translatable(typeKey.getSecond() + this.value) + translatable(typeKey.second() + this.value) ).color(GOLD); } } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/CalculatedStatParser.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/CalculatedStatParser.java index 65768579..b02e2bc2 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/CalculatedStatParser.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/CalculatedStatParser.java @@ -19,34 +19,28 @@ */ package me.machinemaker.papertweaks.modules.survival.trackstats; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.parsing.NoInputProvidedException; -import java.util.List; -import java.util.Queue; -import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import org.checkerframework.checker.nullness.qual.Nullable; +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.suggestion.BlockingSuggestionProvider; -public class CalculatedStatParser implements ArgumentParser { +class CalculatedStatParser implements ArgumentParser, BlockingSuggestionProvider.Strings { @Override - public ArgumentParseResult parse(final CommandContext commandContext, final Queue inputQueue) { - final @Nullable String input = inputQueue.peek(); - if (input == null) { - return ArgumentParseResult.failure(new NoInputProvidedException(CalculatedStatParser.class, commandContext)); - } + public ArgumentParseResult parse(final CommandContext commandContext, final CommandInput commandInput) { + final String input = commandInput.readString(); final @Nullable CalculatedStat stat = Stats.REGISTRY.get(input); if (stat == null) { return ArgumentParseResult.failure(new IllegalArgumentException(input + " is not a valid stat")); } else { - inputQueue.remove(); return ArgumentParseResult.success(stat); } } @Override - public List suggestions(final CommandContext commandContext, final String input) { - return List.copyOf(Stats.REGISTRY.keySet()); + public Iterable stringSuggestions(final CommandContext commandContext, final CommandInput input) { + return Stats.REGISTRY.keySet(); } } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/Commands.java index e2c903ea..7c7b1749 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/trackstats/Commands.java @@ -19,9 +19,6 @@ */ package me.machinemaker.papertweaks.modules.survival.trackstats; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.inject.Inject; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; @@ -30,11 +27,14 @@ import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.minecraft.extras.RichDescription; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.parser.ParserDescriptor.parserDescriptor; @ModuleCommand.Info(value = "trackstats", aliases = {"tstats", "ts"}, i18n = "track-stats", perm = "trackstats") class Commands extends ConfiguredModuleCommand { @@ -52,15 +52,15 @@ protected void registerCommands() { this.register( this.literal(builder, "show") - .argument(CommandArgument.ofType(CalculatedStat.class, "stat").withParser(new CalculatedStatParser()), RichDescription.translatable("modules.track-stats.commands.arguments.stat")) + .required("stat", parserDescriptor(new CalculatedStatParser<>(), CalculatedStat.class), RichDescription.translatable("modules.track-stats.commands.arguments.stat")) .handler(this.sync((context, player) -> { player.setScoreboard(this.board); final CalculatedStat stat = context.get("stat"); if (stat.getObjective(this.board).getDisplaySlot() == DisplaySlot.SIDEBAR) { - context.getSender().sendMessage(translatable("modules.track-stats.commands.show.already-displayed", YELLOW, translatable(stat, GOLD))); + context.sender().sendMessage(translatable("modules.track-stats.commands.show.already-displayed", YELLOW, translatable(stat, GOLD))); } else { stat.getObjective(this.board).setDisplaySlot(DisplaySlot.SIDEBAR); - context.getSender().sendMessage(translatable("modules.track-stats.commands.show.success", GREEN, translatable(stat, GOLD))); + context.sender().sendMessage(translatable("modules.track-stats.commands.show.success", GREEN, translatable(stat, GOLD))); } })) ); @@ -69,10 +69,10 @@ protected void registerCommands() { .handler(this.sync((context, player) -> { final @Nullable Objective currentlyDisplayed = this.board.getObjective(DisplaySlot.SIDEBAR); if (currentlyDisplayed == null || !Stats.REGISTRY.containsKey(currentlyDisplayed.getName())) { - context.getSender().sendMessage(translatable("modules.track-stats.commands.clear.no-display", YELLOW)); + context.sender().sendMessage(translatable("modules.track-stats.commands.clear.no-display", YELLOW)); } else { currentlyDisplayed.setDisplaySlot(null); - context.getSender().sendMessage(translatable("modules.track-stats.commands.clear.success", GREEN, translatable(Stats.REGISTRY.get(currentlyDisplayed.getName()), GOLD))); + context.sender().sendMessage(translatable("modules.track-stats.commands.clear.success", GREEN, translatable(Stats.REGISTRY.get(currentlyDisplayed.getName()), GOLD))); } })) ); diff --git a/src/main/java/me/machinemaker/papertweaks/modules/survival/workstationhighlights/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/survival/workstationhighlights/Commands.java index 27eefc71..4923922b 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/survival/workstationhighlights/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/survival/workstationhighlights/Commands.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.modules.survival.workstationhighlights; -import cloud.commandframework.Command; +import org.incendo.cloud.Command; import com.google.inject.Inject; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ModuleCommand; @@ -53,12 +53,12 @@ protected void registerCommands() { .handler(this.sync((context, player) -> { final @Nullable Villager villager = Entities.getSingleNearbyEntityOfType(Villager.class, player.getLocation(), 3, 3, 3); if (villager == null) { - this.messageService.noVillagerNearby(context.getSender()); + this.messageService.noVillagerNearby(context.sender()); return; } final @Nullable Location work = villager.getMemory(MemoryKey.JOB_SITE); if (work == null || work.getWorld() == null) { - this.messageService.noWorkstationFound(context.getSender()); + this.messageService.noWorkstationFound(context.sender()); return; } villager.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 200, 0)); @@ -70,7 +70,7 @@ protected void registerCommands() { cloud.setRadiusOnUse(0f); cloud.setDuration(200); }); - this.messageService.workstationLocatedAt(context.getSender(), work.getBlockX(), work.getBlockY(), work.getBlockZ()); + this.messageService.workstationLocatedAt(context.sender(), work.getBlockX(), work.getBlockY(), work.getBlockZ()); })) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/back/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/back/Commands.java index eaf13f72..8cb12be3 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/back/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/back/Commands.java @@ -19,9 +19,6 @@ */ package me.machinemaker.papertweaks.modules.teleportation.back; -import cloud.commandframework.Command; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; import com.google.inject.Inject; import java.time.Duration; import me.machinemaker.papertweaks.cloud.cooldown.CommandCooldown; @@ -31,16 +28,19 @@ import me.machinemaker.papertweaks.utils.PTUtils; import org.bukkit.Location; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.key.CloudKey; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.RED; +import static org.incendo.cloud.key.CloudKey.cloudKey; @ModuleCommand.Info(value = "back", i18n = "back", perm = "back", infoOnRoot = false) class Commands extends ConfiguredModuleCommand { - static final CloudKey BACK_COMMAND_COOLDOWN_KEY = SimpleCloudKey.of("papertweaks:back_cmd_cooldown"); + static final CloudKey BACK_COMMAND_COOLDOWN_KEY = cloudKey("papertweaks:back_cmd_cooldown"); private final Config config; @@ -55,7 +55,7 @@ protected void registerCommands() { final CommandCooldown backCooldown = CommandCooldown.builder(context -> Duration.ofSeconds(this.config.cooldown)) .key(BACK_COMMAND_COOLDOWN_KEY) - .notifier((context, cooldown, secondsLeft) -> context.getCommandContext().getSender().sendMessage(translatable("modules.back.commands.root.cooldown", RED, text(secondsLeft)))) + .notifier((context, cooldown, secondsLeft) -> context.commandContext().sender().sendMessage(translatable("modules.back.commands.root.cooldown", RED, text(secondsLeft)))) .build(); this.register(builder @@ -67,13 +67,13 @@ protected void registerCommands() { } @Nullable Location loc = Back.BACK_LOCATION.getFrom(player); if (loc == null) { - context.getSender().sendMessage(translatable("modules.back.commands.root.fail.no-loc", RED)); + context.sender().sendMessage(translatable("modules.back.commands.root.fail.no-loc", RED)); return; } loc = PTUtils.toCenter(loc, false); - context.getSender().sendMessage(translatable("modules.back.commands.root.success", GOLD)); + context.sender().sendMessage(translatable("modules.back.commands.root.success", GOLD)); if (this.config.delay > 0) { - new BackTeleportRunnable(player, loc, this.config.delay * 20L, context.getSender()).start(); + new BackTeleportRunnable(player, loc, this.config.delay * 20L, context.sender()).start(); } else { Back.setBackLocation(player, player.getLocation()); if (loc.getChunk().isLoaded()) { diff --git a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/homes/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/homes/Commands.java index e0de5e7e..14467495 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/homes/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/homes/Commands.java @@ -19,10 +19,6 @@ */ package me.machinemaker.papertweaks.modules.teleportation.homes; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.StringArgument; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; import com.google.inject.Inject; import java.time.Duration; import java.util.List; @@ -40,18 +36,25 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.Command; +import org.incendo.cloud.key.CloudKey; +import static me.machinemaker.papertweaks.cloud.parsers.ParserFactory.homeDescriptor; import static net.kyori.adventure.text.Component.newline; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.NamedTextColor.YELLOW; +import static org.incendo.cloud.component.DefaultValue.constant; +import static org.incendo.cloud.component.DefaultValue.parsed; +import static org.incendo.cloud.key.CloudKey.cloudKey; +import static org.incendo.cloud.parser.standard.StringParser.quotedStringParser; @ModuleCommand.Info(value = "homes", i18n = "homes", perm = "homes") class Commands extends ConfiguredModuleCommand { - static final CloudKey HOME_COMMAND_COOLDOWN_KEY = SimpleCloudKey.of("papertweaks:home_cmd_cooldown"); + static final CloudKey HOME_COMMAND_COOLDOWN_KEY = cloudKey("papertweaks:home_cmd_cooldown"); private final HomesDAO homesDAO; private final Config config; @@ -68,63 +71,63 @@ protected void registerCommands() { final CommandCooldown homeCooldown = CommandCooldown.builder(context -> Duration.ofSeconds(this.config.sethomeCooldown)) .key(HOME_COMMAND_COOLDOWN_KEY) - .notifier((context, cooldown, secondsLeft) -> context.getCommandContext().getSender().sendMessage(translatable("modules.homes.commands.home.cooldown", RED, text(secondsLeft)))) + .notifier((context, cooldown, secondsLeft) -> context.commandContext().sender().sendMessage(translatable("modules.homes.commands.home.cooldown", RED, text(secondsLeft)))) .build(); this.register( this.literal(builder, "sethome") - .argument(StringArgument.optional("homeName", "home")) + .optional("homeName", quotedStringParser(), constant("home")) .handler(context -> { final Player player = PlayerCommandDispatcher.from(context); final Map homes = this.homesDAO.getHomesForPlayer(player.getUniqueId()); if (homes.size() + 1 > this.config.defaultSetHomeLimit) { - context.getSender().sendMessage(translatable("modules.homes.commands.sethome.too-many-homes", RED, text(this.config.defaultSetHomeLimit, YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.sethome.too-many-homes", RED, text(this.config.defaultSetHomeLimit, YELLOW))); return; } final String homeName = context.get("homeName"); if (homes.containsKey(homeName)) { - context.getSender().sendMessage(translatable("modules.homes.commands.sethome.duplicate-name", TextColor.color(249, 104, 3), text(homeName, YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.sethome.duplicate-name", TextColor.color(249, 104, 3), text(homeName, YELLOW))); return; } this.homesDAO.insertHome(new Home(player.getUniqueId(), homeName, player.getLocation())); - context.getSender().sendMessage(translatable("modules.homes.commands.sethome.success", GOLD, text(homeName, YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.sethome.success", GOLD, text(homeName, YELLOW))); }) ); this.register( this.literal(builder, "delhome") - .argument(this.argumentFactory.home(false, "home")) + .optional("home", homeDescriptor(this.argumentFactory), parsed("home")) .handler(context -> { final Home home = context.get("home"); this.homesDAO.deleteHome(home); - context.getSender().sendMessage(translatable("modules.homes.commands.delhome.success", GOLD, text(home.getName(), YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.delhome.success", GOLD, text(home.getName(), YELLOW))); }) ); this.register( this.literal(builder, "rename") - .argument(this.argumentFactory.home(true, "home")) - .argument(StringArgument.single("newName")) + .required("home", homeDescriptor(this.argumentFactory)) + .required("newName", quotedStringParser()) .handler(context -> { final Player player = PlayerCommandDispatcher.from(context); final Home home = context.get("home"); final String newName = context.get("newName"); final String oldName = home.getName(); - final Home possibleExisting = this.homesDAO.getPlayerHome(player.getUniqueId(), newName); + final @Nullable Home possibleExisting = this.homesDAO.getPlayerHome(player.getUniqueId(), newName); if (possibleExisting != null) { - context.getSender().sendMessage(translatable("modules.homes.commands.rename.duplicate-name", TextColor.color(249, 104, 3), text(newName, YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.rename.duplicate-name", TextColor.color(249, 104, 3), text(newName, YELLOW))); return; } home.setName(newName); this.homesDAO.updateHome(home); - context.getSender().sendMessage(translatable("modules.homes.commands.rename.success", GOLD, text(oldName, YELLOW), text(newName, YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.rename.success", GOLD, text(oldName, YELLOW), text(newName, YELLOW))); }) ); this.register( this.literal(builder, "list") .senderType(PlayerCommandDispatcher.class) .handler(context -> { - final Map homes = this.homesDAO.getHomesForPlayer(context.getSender().getUUID()); + final Map homes = this.homesDAO.getHomesForPlayer(context.sender().getUUID()); if (homes.isEmpty()) { - context.getSender().sendMessage(translatable("modules.homes.commands.list.no-homes", RED)); + context.sender().sendMessage(translatable("modules.homes.commands.list.no-homes", RED)); return; } final List names = List.copyOf(homes.keySet()); @@ -141,13 +144,13 @@ protected void registerCommands() { component.append(translatable("modules.homes.commands.list.success", GOLD, text(i + 1), text(names.get(i), YELLOW), text(loc.getBlockX()), text(loc.getBlockY()), text(loc.getBlockZ()), text(loc.getWorld().getName()))); } } - context.getSender().sendMessage(component); + context.sender().sendMessage(component); }) ); this.register( this.player("home") .apply(homeCooldown) - .argument(this.argumentFactory.home(false, "home")) + .optional("home", homeDescriptor(this.argumentFactory), parsed("home")) .handler(this.sync((context, player) -> { if (HomeTeleportRunnable.AWAITING_TELEPORT.containsKey(player.getUniqueId())) { return; @@ -155,16 +158,16 @@ protected void registerCommands() { final Home home = context.get("home"); if (home.getLocation() == null) { this.homesDAO.deleteHome(home); - context.getSender().sendMessage(translatable("modules.homes.commands.arguments.home.invalid", RED)); + context.sender().sendMessage(translatable("modules.homes.commands.arguments.home.invalid", RED)); return; } if (!this.config.allowAcrossDimension && home.getLocation().getWorld() != player.getWorld()) { - context.getSender().sendMessage(translatable("modules.homes.commands.home.fail.across-dimensions", RED)); + context.sender().sendMessage(translatable("modules.homes.commands.home.fail.across-dimensions", RED)); return; } - context.getSender().sendMessage(translatable("modules.homes.commands.home.success", GOLD, text(home.getName(), YELLOW))); + context.sender().sendMessage(translatable("modules.homes.commands.home.success", GOLD, text(home.getName(), YELLOW))); if (this.config.sethomeDelay > 0) { - new HomeTeleportRunnable(player, home.getLocation(), this.config.sethomeDelay * 20, context.getSender()).start(); + new HomeTeleportRunnable(player, home.getLocation(), this.config.sethomeDelay * 20, context.sender()).start(); } else { Back.setBackLocation(player, player.getLocation()); // Store back location if (home.getLocation().getChunk().isLoaded()) { diff --git a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/spawn/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/spawn/Commands.java index b3a908aa..3b1021d1 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/spawn/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/spawn/Commands.java @@ -19,13 +19,6 @@ */ package me.machinemaker.papertweaks.modules.teleportation.spawn; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.bukkit.parsers.WorldArgument; -import cloud.commandframework.execution.CommandExecutionHandler; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; -import cloud.commandframework.minecraft.extras.RichDescription; import com.google.inject.Inject; import java.time.Duration; import me.machinemaker.papertweaks.cloud.cooldown.CommandCooldown; @@ -35,17 +28,22 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.incendo.cloud.Command; +import org.incendo.cloud.execution.CommandExecutionHandler; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.minecraft.extras.RichDescription; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.RED; +import static org.incendo.cloud.bukkit.parser.WorldParser.worldParser; +import static org.incendo.cloud.key.CloudKey.cloudKey; @ModuleCommand.Info(value = "spawn", descriptionKey = "modules.spawn.commands.root", infoOnRoot = false) class Commands extends ModuleCommand { - static final CloudKey SPAWN_CMD_COOLDOWN_KEY = SimpleCloudKey.of("papertweaks:spawn_cmd_cooldown"); - private static final CommandArgument WORLD_ARG = WorldArgument.of("world"); + static final CloudKey SPAWN_CMD_COOLDOWN_KEY = cloudKey("papertweaks:spawn_cmd_cooldown"); private final Config config; @Inject @@ -59,7 +57,7 @@ protected void registerCommands() { final CommandCooldown commandCooldown = CommandCooldown.builder(context -> Duration.ofSeconds(this.config.cooldown)) .key(SPAWN_CMD_COOLDOWN_KEY) - .notifier((context, cooldown, secondsLeft) -> context.getCommandContext().getSender().sendMessage(translatable("modules.spawn.teleporting.cooldown", RED, text(secondsLeft)))) + .notifier((context, cooldown, secondsLeft) -> context.commandContext().sender().sendMessage(translatable("modules.spawn.teleporting.cooldown", RED, text(secondsLeft)))) .build(); @@ -71,7 +69,7 @@ protected void registerCommands() { this.register(builder .apply(commandCooldown) .permission(this.modulePermission("vanillatweaks.spawn.other")) - .argument(WORLD_ARG, RichDescription.translatable("modules.spawn.commands.other")) + .required("world", worldParser(), RichDescription.translatable("modules.spawn.commands.other")) .handler(this.handleSpawnCmd()) ); } @@ -81,10 +79,10 @@ private CommandExecutionHandler handleSpawnCmd() { if (SpawnTeleportRunnable.AWAITING_TELEPORT.containsKey(player.getUniqueId())) { return; } - final Location spawnLoc = context.getOptional(WORLD_ARG).orElse(this.config.defaultsToMainWorld ? Bukkit.getWorlds().get(0) : player.getWorld()).getSpawnLocation(); - context.getSender().sendMessage(translatable("modules.spawn.teleporting", GOLD)); + final Location spawnLoc = context.optional("world").orElse(this.config.defaultsToMainWorld ? Bukkit.getWorlds().get(0) : player.getWorld()).getSpawnLocation(); + context.sender().sendMessage(translatable("modules.spawn.teleporting", GOLD)); if (this.config.delay > 0) { - new SpawnTeleportRunnable(player, context.getSender(), spawnLoc, this.config.delay * 20).start(); + new SpawnTeleportRunnable(player, context.sender(), spawnLoc, this.config.delay * 20).start(); } else { Back.setBackLocation(player, player.getLocation()); // Set back location if (spawnLoc.getChunk().isLoaded()) { diff --git a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/tpa/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/tpa/Commands.java index d71c04b4..b54cdfb7 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/teleportation/tpa/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/teleportation/tpa/Commands.java @@ -19,45 +19,44 @@ */ package me.machinemaker.papertweaks.modules.teleportation.tpa; -import cloud.commandframework.Command; -import cloud.commandframework.bukkit.parsers.PlayerArgument; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; -import cloud.commandframework.keys.SimpleCloudKey; import com.google.inject.Inject; import java.time.Duration; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Optional; -import java.util.function.BiFunction; -import me.machinemaker.papertweaks.cloud.SuggestionProviders; import me.machinemaker.papertweaks.cloud.cooldown.CommandCooldown; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; import me.machinemaker.papertweaks.modules.ModuleCommand; import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.parser.PlayerParser; +import org.incendo.cloud.key.CloudKey; +import org.incendo.cloud.suggestion.BlockingSuggestionProvider; +import static me.machinemaker.papertweaks.cloud.SuggestionProviders.playersWithoutSelf; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.RED; +import static org.incendo.cloud.bukkit.parser.PlayerParser.playerParser; +import static org.incendo.cloud.key.CloudKey.cloudKey; @ModuleCommand.Info(value = "tpa", i18n = "tpa", perm = "tpa") class Commands extends ConfiguredModuleCommand { - static final CloudKey TPA_REQUEST_COOLDOWN_KEY = SimpleCloudKey.of("papertweaks:tpa_request_cmd_cooldown"); + static final CloudKey TPA_REQUEST_COOLDOWN_KEY = cloudKey("papertweaks:tpa_request_cmd_cooldown"); private final TPAManager tpaManager; private final Config config; - private final BiFunction, String, List> requestSuggestions; + private final BlockingSuggestionProvider.Strings requestSuggestions; @Inject Commands(final TPAManager tpaManager, final Config config) { this.tpaManager = tpaManager; this.config = config; - this.requestSuggestions = (context, s) -> { - if (this.tpaManager.requestsByTarget.containsKey(context.getSender().getUUID())) { - final Collection requests = this.tpaManager.requestsByTarget.get(context.getSender().getUUID()); + this.requestSuggestions = (context, input) -> { + if (this.tpaManager.requestsByTarget.containsKey(context.sender().getUUID())) { + final Collection requests = this.tpaManager.requestsByTarget.get(context.sender().getUUID()); return requests.stream().map(Request::playerFrom).filter(Optional::isPresent).map(Optional::get).map(Player::getName).toList(); } return Collections.emptyList(); @@ -70,17 +69,17 @@ protected void registerCommands() { final CommandCooldown requestCooldown = CommandCooldown.builder(context -> Duration.ofSeconds(this.config.cooldown)) .key(TPA_REQUEST_COOLDOWN_KEY) - .notifier((context, cooldown, secondsLeft) -> context.getCommandContext().getSender().sendMessage(translatable("modules.tpa.commands.request.cooldown", RED, text(secondsLeft)))) + .notifier((context, cooldown, secondsLeft) -> context.commandContext().sender().sendMessage(translatable("modules.tpa.commands.request.cooldown", RED, text(secondsLeft)))) .build(); this.register( this.literal(builder, "request") .apply(requestCooldown) - .argument(PlayerArgument.builder("target").withSuggestionsProvider(SuggestionProviders.playersWithoutSelf())) + .required("target", playerParser(), playersWithoutSelf()) .handler(this.sync((context, player) -> { final Player target = context.get("target"); if (player == target) { - context.getSender().sendMessage(translatable("modules.tpa.commands.request.fail.same-player", RED)); + context.sender().sendMessage(translatable("modules.tpa.commands.request.fail.same-player", RED)); return; } this.tpaManager.startRequest(player, target); @@ -92,14 +91,15 @@ protected void registerCommands() { ); this.register( this.literal(builder, "accept") - .argument(PlayerArgument.builder("from").asOptional().withSuggestionsProvider(this.requestSuggestions)) + .optional("from", playerParser(), this.requestSuggestions) + .argument(PlayerParser.playerComponent().name("from").optional().suggestionProvider(this.requestSuggestions)) .handler(this.sync((context, player) -> { this.tpaManager.acceptRequest(player, context.getOrDefault("from", null)); })) ); this.register( this.literal(builder, "deny") - .argument(PlayerArgument.builder("from").asOptional().withSuggestionsProvider(this.requestSuggestions)) + .optional("from", playerParser(), this.requestSuggestions) .handler(this.sync((context, player) -> { this.tpaManager.denyRequest(player, context.getOrDefault("from", null)); })) diff --git a/src/main/java/me/machinemaker/papertweaks/modules/utilities/killemptyboats/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/utilities/killemptyboats/Commands.java index 11f4f7e8..9220132d 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/utilities/killemptyboats/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/utilities/killemptyboats/Commands.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.modules.utilities.killemptyboats; -import cloud.commandframework.Command; +import org.incendo.cloud.Command; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ModuleCommand; import org.bukkit.Bukkit; @@ -50,7 +50,7 @@ protected void registerCommands() { } } } - context.getSender().sendMessage(translatable("modules.kill-empty-boats.removed-boats", count > 0 ? YELLOW : RED, text(count))); + context.sender().sendMessage(translatable("modules.kill-empty-boats.removed-boats", count > 0 ? YELLOW : RED, text(count))); })) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/utilities/spawningspheres/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/utilities/spawningspheres/Commands.java index 687edc0f..e50cb760 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/utilities/spawningspheres/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/utilities/spawningspheres/Commands.java @@ -19,8 +19,6 @@ */ package me.machinemaker.papertweaks.modules.utilities.spawningspheres; -import cloud.commandframework.Command; -import cloud.commandframework.arguments.standard.EnumArgument; import java.util.Collection; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ConfiguredModuleCommand; @@ -39,12 +37,14 @@ import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; +import org.incendo.cloud.Command; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.Component.translatable; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.RED; import static net.kyori.adventure.text.format.TextDecoration.ITALIC; +import static org.incendo.cloud.parser.standard.EnumParser.enumParser; @ModuleCommand.Info(value = "spawningspheres", aliases = {"spawnsphere", "ss"}, i18n = "spawning-spheres", perm = "spawningspheres") class Commands extends ConfiguredModuleCommand { @@ -73,12 +73,12 @@ protected void registerCommands() { this.register( this.literal(builder, "add") - .argument(EnumArgument.of(Color.class, "color")) + .required("color", enumParser(Color.class)) .handler(this.sync((context, player) -> { final Color color = context.get("color"); final Collection stands = Entities.getEntitiesOfType(ArmorStand.class, player.getWorld(), stand -> color == COLOR_KEY.getFrom(stand)); if (!stands.isEmpty()) { - context.getSender().sendMessage(translatable("modules.spawning-spheres.commands.add.fail", RED, color)); + context.sender().sendMessage(translatable("modules.spawning-spheres.commands.add.fail", RED, color)); return; } final Location center = PTUtils.toBlockLoc(player.getLocation()).add(0.5, 0, 0.5); @@ -89,21 +89,21 @@ protected void registerCommands() { }); this.fibonacciSphere(player.getWorld(), center, DESPAWN_DISTANCES.hard(player.getWorld()), 1500, color, color.outer); this.fibonacciSphere(player.getWorld(), center, DESPAWN_DISTANCES.soft(player.getWorld()), 200, color, color.inner); - context.getSender().sendMessage(translatable("modules.spawning-spheres.commands.add.succeed", GREEN, color)); + context.sender().sendMessage(translatable("modules.spawning-spheres.commands.add.succeed", GREEN, color)); })) ); this.register( this.literal(builder, "remove") - .argument(EnumArgument.of(Color.class, "color")) + .required("color", enumParser(Color.class)) .handler(this.sync((context, player) -> { final Color color = context.get("color"); final Collection sphereStands = Entities.getEntitiesOfType(ArmorStand.class, player.getWorld(), stand -> color == COLOR_KEY.getFrom(stand)); if (sphereStands.isEmpty()) { - context.getSender().sendMessage(translatable("modules.spawning-spheres.commands.remove.fail", RED, color)); + context.sender().sendMessage(translatable("modules.spawning-spheres.commands.remove.fail", RED, color)); return; } sphereStands.forEach(Entity::remove); - context.getSender().sendMessage(translatable("modules.spawning-spheres.commands.remove.succeed", GREEN, color)); + context.sender().sendMessage(translatable("modules.spawning-spheres.commands.remove.succeed", GREEN, color)); })) ); } diff --git a/src/main/java/me/machinemaker/papertweaks/modules/utilities/spectatoreffects/Commands.java b/src/main/java/me/machinemaker/papertweaks/modules/utilities/spectatoreffects/Commands.java index e656bc8e..16316471 100644 --- a/src/main/java/me/machinemaker/papertweaks/modules/utilities/spectatoreffects/Commands.java +++ b/src/main/java/me/machinemaker/papertweaks/modules/utilities/spectatoreffects/Commands.java @@ -19,7 +19,7 @@ */ package me.machinemaker.papertweaks.modules.utilities.spectatoreffects; -import cloud.commandframework.Command; +import org.incendo.cloud.Command; import me.machinemaker.papertweaks.cloud.MetaKeys; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.modules.ModuleCommand; diff --git a/src/main/java/me/machinemaker/papertweaks/settings/Setting.java b/src/main/java/me/machinemaker/papertweaks/settings/Setting.java index bff4a3bd..595531fc 100644 --- a/src/main/java/me/machinemaker/papertweaks/settings/Setting.java +++ b/src/main/java/me/machinemaker/papertweaks/settings/Setting.java @@ -19,10 +19,10 @@ */ package me.machinemaker.papertweaks.settings; -import cloud.commandframework.arguments.parser.ArgumentParser; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.parser.ArgumentParser; public interface Setting { diff --git a/src/main/java/me/machinemaker/papertweaks/settings/types/ConfigSetting.java b/src/main/java/me/machinemaker/papertweaks/settings/types/ConfigSetting.java index e537b0a7..147967f6 100644 --- a/src/main/java/me/machinemaker/papertweaks/settings/types/ConfigSetting.java +++ b/src/main/java/me/machinemaker/papertweaks/settings/types/ConfigSetting.java @@ -19,11 +19,11 @@ */ package me.machinemaker.papertweaks.settings.types; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.arguments.standard.BooleanArgument; -import cloud.commandframework.arguments.standard.DoubleArgument; -import cloud.commandframework.arguments.standard.EnumArgument; -import cloud.commandframework.arguments.standard.IntegerArgument; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.standard.BooleanParser; +import org.incendo.cloud.parser.standard.DoubleParser; +import org.incendo.cloud.parser.standard.EnumParser; +import org.incendo.cloud.parser.standard.IntegerParser; import com.fasterxml.jackson.databind.type.TypeFactory; import io.leangen.geantyref.GenericTypeReflector; import me.machinemaker.lectern.ValueNode; @@ -46,19 +46,19 @@ public ConfigSetting(final ValueNode node, final ArgumentParser> ConfigSetting ofBoolean(final ValueNode valueNode) { - return new ConfigSetting<>((ValueNode) valueNode, new BooleanArgument.BooleanParser<>(false)); + return new ConfigSetting<>((ValueNode) valueNode, new BooleanParser<>(false)); } public static , C extends MenuModuleConfig> ConfigSetting ofEnum(final ValueNode valueNode, final Class classOfE) { - return new ConfigSetting<>((ValueNode) valueNode, new EnumArgument.EnumParser<>(classOfE)); + return new ConfigSetting<>((ValueNode) valueNode, new EnumParser<>(classOfE)); } public static > ConfigSetting ofInt(final ValueNode valueNode) { - return new ConfigSetting<>((ValueNode) valueNode, new IntegerArgument.IntegerParser<>(Integer.parseInt(valueNode.meta().getOrDefault("min", IntegerArgument.IntegerParser.DEFAULT_MINIMUM).toString()), Integer.parseInt(valueNode.meta().getOrDefault("max", IntegerArgument.IntegerParser.DEFAULT_MAXIMUM).toString()))); + return new ConfigSetting<>((ValueNode) valueNode, new IntegerParser<>(Integer.parseInt(valueNode.meta().getOrDefault("min", IntegerParser.DEFAULT_MINIMUM).toString()), Integer.parseInt(valueNode.meta().getOrDefault("max", IntegerParser.DEFAULT_MAXIMUM).toString()))); } public static > ConfigSetting ofDouble(final ValueNode valueNode) { - return new ConfigSetting<>((ValueNode) valueNode, new DoubleArgument.DoubleParser<>(Double.parseDouble(valueNode.meta().getOrDefault("min", DoubleArgument.DoubleParser.DEFAULT_MINIMUM).toString()), Double.parseDouble(valueNode.meta().getOrDefault("max", DoubleArgument.DoubleParser.DEFAULT_MAXIMUM).toString()))); + return new ConfigSetting<>((ValueNode) valueNode, new DoubleParser<>(Double.parseDouble(valueNode.meta().getOrDefault("min", DoubleParser.DEFAULT_MINIMUM).toString()), Double.parseDouble(valueNode.meta().getOrDefault("max", DoubleParser.DEFAULT_MAXIMUM).toString()))); } private static Component createValidations(final ValueNode valueNode) { diff --git a/src/main/java/me/machinemaker/papertweaks/settings/types/GameRuleSetting.java b/src/main/java/me/machinemaker/papertweaks/settings/types/GameRuleSetting.java index d73cc346..b2366046 100644 --- a/src/main/java/me/machinemaker/papertweaks/settings/types/GameRuleSetting.java +++ b/src/main/java/me/machinemaker/papertweaks/settings/types/GameRuleSetting.java @@ -19,9 +19,6 @@ */ package me.machinemaker.papertweaks.settings.types; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.arguments.standard.BooleanArgument; -import cloud.commandframework.arguments.standard.IntegerArgument; import java.util.Objects; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.settings.Setting; @@ -29,17 +26,20 @@ import org.bukkit.GameRule; import org.bukkit.World; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.standard.BooleanParser; +import org.incendo.cloud.parser.standard.IntegerParser; public record GameRuleSetting(GameRule gameRule, ArgumentParser argumentParser) implements Setting { private static final World OVERWORLD = Objects.requireNonNull(Bukkit.getWorlds().get(0), "no overworld found"); public static GameRuleSetting ofBoolean(final GameRule gameRule) { - return new GameRuleSetting<>(gameRule, new BooleanArgument.BooleanParser<>(false)); + return new GameRuleSetting<>(gameRule, new BooleanParser<>(false)); } public static GameRuleSetting ofInt(final GameRule gameRule, final int min, final int max) { - return new GameRuleSetting<>(gameRule, new IntegerArgument.IntegerParser<>(min, max)); + return new GameRuleSetting<>(gameRule, new IntegerParser<>(min, max)); } public static GameRuleSetting ofInt(final GameRule gameRule, final int min) { diff --git a/src/main/java/me/machinemaker/papertweaks/settings/types/PlayerSetting.java b/src/main/java/me/machinemaker/papertweaks/settings/types/PlayerSetting.java index e6fec830..b3fb20fd 100644 --- a/src/main/java/me/machinemaker/papertweaks/settings/types/PlayerSetting.java +++ b/src/main/java/me/machinemaker/papertweaks/settings/types/PlayerSetting.java @@ -19,9 +19,6 @@ */ package me.machinemaker.papertweaks.settings.types; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.arguments.standard.BooleanArgument; -import cloud.commandframework.arguments.standard.EnumArgument; import java.util.function.Supplier; import me.machinemaker.papertweaks.cloud.dispatchers.CommandDispatcher; import me.machinemaker.papertweaks.pdc.DataTypes; @@ -32,15 +29,18 @@ import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.standard.BooleanParser; +import org.incendo.cloud.parser.standard.EnumParser; public record PlayerSetting(SettingKey settingKey, PersistentDataType dataType, Supplier defaultSupplier, ArgumentParser argumentParser) implements ModuleSetting { public static PlayerSetting ofBoolean(final SettingKey key, final Supplier supplier) { - return of(key, DataTypes.BOOLEAN, supplier, new BooleanArgument.BooleanParser<>(false)); + return of(key, DataTypes.BOOLEAN, supplier, new BooleanParser<>(false)); } public static > PlayerSetting ofEnum(final SettingKey key, final Class classOfE, final Supplier defaultSupplier) { - return of(key, EnumDataType.of(classOfE), defaultSupplier, new EnumArgument.EnumParser<>(classOfE)); + return of(key, EnumDataType.of(classOfE), defaultSupplier, new EnumParser<>(classOfE)); } private static PlayerSetting of(final SettingKey key, final PersistentDataType dataType, final Supplier defaultSupplier, final ArgumentParser argumentParser) {