From 6088dd8409b1e074696e4bd9648d186797f824a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 31 Dec 2023 20:55:49 +0100 Subject: [PATCH 01/13] feature: use cloud v2 for commands --- Bukkit/build.gradle.kts | 4 + .../plotsquared/bukkit/BukkitPlatform.java | 7 + .../bukkit/inject/CloudModule.java | 86 ++++++++ Core/build.gradle.kts | 4 + .../core/commands/CommandRequirement.java | 28 +++ .../commands/CommonCommandRequirement.java | 50 +++++ .../commands/PlotSquaredCaptionProvider.java | 32 +++ .../core/commands/PlotSquaredCommandBean.java | 47 +++++ .../commands/PlotSquaredCommandManager.java | 56 +++++ .../core/commands/PlotSquaredCommandMeta.java | 18 ++ .../command/setting/flag/FlagSetCommand.java | 196 ++++++++++++++++++ .../core/commands/injection/PlotInjector.java | 24 +++ .../core/commands/parser/PlotFlagParser.java | 81 ++++++++ .../CommandRequirementPostprocessor.java | 63 ++++++ .../FlagValueSuggestionProvider.java | 66 ++++++ .../caption/TranslatableCaption.java | 8 +- .../core/inject/modules/CommandModule.java | 20 ++ build.gradle.kts | 1 + gradle/libs.versions.toml | 4 + 19 files changed, 794 insertions(+), 1 deletion(-) create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java create mode 100644 Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java diff --git a/Bukkit/build.gradle.kts b/Bukkit/build.gradle.kts index 19e48b218..04a2db3fa 100644 --- a/Bukkit/build.gradle.kts +++ b/Bukkit/build.gradle.kts @@ -53,6 +53,9 @@ dependencies { // Adventure implementation(libs.adventureBukkit) + + // Cloud + implementation(libs.cloudPaper) } tasks.processResources { @@ -77,6 +80,7 @@ tasks.named("shadowJar") { relocate("com.google.inject", "com.plotsquared.google") relocate("org.aopalliance", "com.plotsquared.core.aopalliance") relocate("cloud.commandframework.services", "com.plotsquared.core.services") + relocate("cloud.commandframework", "com.plotsquared.commands") relocate("io.leangen.geantyref", "com.plotsquared.core.geantyref") relocate("com.intellectualsites.arkitektonika", "com.plotsquared.core.arkitektonika") relocate("com.intellectualsites.http", "com.plotsquared.core.http") diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java index ad332176e..a28d82656 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java @@ -28,6 +28,7 @@ import com.google.inject.TypeLiteral; import com.plotsquared.bukkit.generator.BukkitPlotGenerator; import com.plotsquared.bukkit.inject.BackupModule; import com.plotsquared.bukkit.inject.BukkitModule; +import com.plotsquared.bukkit.inject.CloudModule; import com.plotsquared.bukkit.inject.PermissionModule; import com.plotsquared.bukkit.inject.WorldManagerModule; import com.plotsquared.bukkit.listener.BlockEventListener; @@ -64,6 +65,7 @@ import com.plotsquared.bukkit.uuid.SquirrelIdUUIDService; import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.backup.BackupManager; +import com.plotsquared.core.commands.PlotSquaredCommandManager; import com.plotsquared.core.components.ComponentPresetManager; import com.plotsquared.core.configuration.ConfigurationNode; import com.plotsquared.core.configuration.ConfigurationSection; @@ -83,6 +85,7 @@ import com.plotsquared.core.inject.annotations.DefaultGenerator; import com.plotsquared.core.inject.annotations.ImpromptuPipeline; import com.plotsquared.core.inject.annotations.WorldConfig; import com.plotsquared.core.inject.annotations.WorldFile; +import com.plotsquared.core.inject.modules.CommandModule; import com.plotsquared.core.inject.modules.PlotSquaredModule; import com.plotsquared.core.listener.PlotListener; import com.plotsquared.core.listener.WESubscriber; @@ -293,6 +296,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl new PermissionModule(), new WorldManagerModule(), new PlotSquaredModule(), + new CommandModule(), + new CloudModule(this), new BukkitModule(this), new BackupModule() ); @@ -388,6 +393,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl // Commands if (Settings.Enabled_Components.COMMANDS) { this.registerCommands(); + // Register the commands. + this.injector().getInstance(PlotSquaredCommandManager.class).registerDefaultCommands(); } // Permissions diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java new file mode 100644 index 000000000..87d437b4a --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -0,0 +1,86 @@ +package com.plotsquared.bukkit.inject; + +import cloud.commandframework.CloudCapability; +import cloud.commandframework.CommandManager; +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.inject.AbstractModule; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.plotsquared.bukkit.BukkitPlatform; +import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.core.commands.CommonCommandRequirement; +import com.plotsquared.core.commands.PlotSquaredCaptionProvider; +import com.plotsquared.core.commands.processing.CommandRequirementPostprocessor; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.ConsolePlayer; +import com.plotsquared.core.player.PlotPlayer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; + +public class CloudModule extends AbstractModule { + + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + CloudModule.class.getSimpleName()); + + private static @NonNull CommandSender convert(final @NonNull PlotPlayer player) { + if (player instanceof ConsolePlayer) { + return Bukkit.getConsoleSender(); + } + return (Player) player.getPlatformPlayer(); + } + + private static @NonNull PlotPlayer convert (final @NonNull CommandSender sender) { + if (sender instanceof Player player) { + return BukkitUtil.adapt(player); + } + return ConsolePlayer.getConsole(); + } + + private final BukkitPlatform bukkitPlatform; + + public CloudModule(final @NonNull BukkitPlatform bukkitPlatform) { + this.bukkitPlatform = bukkitPlatform; + } + + @Override + protected void configure() { + try { + final PaperCommandManager> commandManager = new PaperCommandManager>( + this.bukkitPlatform, + AsynchronousCommandExecutionCoordinator.>builder().withAsynchronousParsing().build(), + CloudModule::convert, + CloudModule::convert + ); + commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider()); + if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { + commandManager.registerAsynchronousCompletions(); + } + if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { + commandManager.registerBrigadier(); + } + + final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); + requirementPostprocessor.registerRequirements(CommonCommandRequirement.values()); + commandManager.registerCommandPostProcessor(requirementPostprocessor); + + // TODO(City): Override parsing errors using MM parsing. + MinecraftExceptionHandler.>create(PlotPlayer::getAudience) + .defaultHandlers() + .decorator((ctx, component) -> TranslatableCaption.of("core.prefix"). + toComponent(ctx.context().sender()) + .append(component)) + .registerTo(commandManager); + + bind(Key.get(new TypeLiteral>>() {})).toInstance(commandManager); + } catch (final Exception e) { + LOGGER.error("Failed to configure command manager", e); + } + } +} diff --git a/Core/build.gradle.kts b/Core/build.gradle.kts index a12fe2ad2..3ea85bff0 100644 --- a/Core/build.gradle.kts +++ b/Core/build.gradle.kts @@ -15,6 +15,10 @@ dependencies { api(libs.adventureApi) api(libs.adventureMiniMessage) + // Cloud + api(libs.cloud) + api(libs.cloudMinecraftExtras) + // Guice api(libs.guice) { exclude(group = "com.google.guava") diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java new file mode 100644 index 000000000..4129fb182 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -0,0 +1,28 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKeyHolder; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * Something that is required for a command to be executed. + */ +public interface CommandRequirement extends CloudKeyHolder { + + /** + * Returns the caption sent when the requirement is not met. + * + * @return the caption + */ + @NonNull TranslatableCaption failureCaption(); + + /** + * Evaluates whether the requirement is met. + * + * @param context command context to evaluate + * @return {@code true} if the requirement is met, else {@code false} + */ + boolean evaluate(final @NonNull CommandContext> context); +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java new file mode 100644 index 000000000..ae0135a05 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -0,0 +1,50 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.function.Predicate; + +/** + * Common {@link CommandRequirement command requirements}. + */ +public enum CommonCommandRequirement implements CommandRequirement { + /** + * Requires that the command sender is currently in a plot. + */ + REQUIRES_PLOT(TranslatableCaption.of("errors.not_in_plot"), ctx -> ctx.sender().getCurrentPlot() != null), + /** + * Requires that the command sender is in a claimed plot. + */ + REQUIRES_OWNER(TranslatableCaption.of("working.plot_not_claimed"), + ctx -> ctx.sender().getCurrentPlot() != null && ctx.sender().getCurrentPlot().hasOwner() + ); + + private final TranslatableCaption failureCaption; + private final Predicate>> predicate; + + CommonCommandRequirement( + final @NonNull TranslatableCaption failureCaption, + final @NonNull Predicate>> predicate + ) { + this.failureCaption = failureCaption; + this.predicate = predicate; + } + + public @NonNull TranslatableCaption failureCaption() { + return this.failureCaption; + } + + @Override + public boolean evaluate(final @NonNull CommandContext> context) { + return this.predicate.test(context); + } + + @Override + public @NonNull CloudKey key() { + return CloudKey.of(String.format("requirement_%s", this.name()), Boolean.class); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java new file mode 100644 index 000000000..2222ff4ff --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java @@ -0,0 +1,32 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.captions.Caption; +import cloud.commandframework.captions.CaptionProvider; +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.configuration.caption.CaptionMap; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * {@link CaptionProvider} that retrieves caption values from the {@link CaptionMap caption map}. + */ +public final class PlotSquaredCaptionProvider implements CaptionProvider> { + + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlotSquaredCaptionProvider.class.getSimpleName()); + + @Override + public @Nullable String provide(final @NonNull Caption caption, final @NonNull PlotPlayer recipient) { + try { + return PlotSquared.get() + .getCaptionMap(TranslatableCaption.DEFAULT_NAMESPACE) + .getMessage(TranslatableCaption.of(caption.key()), recipient); + } catch (final CaptionMap.NoSuchCaptionException ignored) { + LOGGER.warn("Missing caption '{}', will attempt to fall back on Cloud defaults", caption.key()); + return null; + } + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java new file mode 100644 index 000000000..6c604d61b --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -0,0 +1,47 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.Command; +import cloud.commandframework.CommandBean; +import cloud.commandframework.CommandProperties; +import com.plotsquared.core.command.CommandCategory; +import com.plotsquared.core.player.PlotPlayer; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Set; + +public abstract class PlotSquaredCommandBean extends CommandBean> { + + /** + * Returns the category of the command. + * + * @return the category + */ + public abstract @NonNull CommandCategory category(); + + /** + * Returns the requirements for the command to be executable. + * + * @return the requirements + */ + public abstract @NonNull Set<@NonNull CommandRequirement> requirements(); + + @Override + protected final @NonNull CommandProperties properties() { + return CommandProperties.of("platsquared", "plat"); + } + + @Override + protected final Command.@NonNull Builder> configure(final Command.@NonNull Builder> builder) { + Command.@NonNull Builder> intermediaryBuilder = + this.configurePlotCommand(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, + this.category())); + for (final CommandRequirement requirement : this.requirements()) { + intermediaryBuilder = intermediaryBuilder.meta(requirement.key(), true); + } + return intermediaryBuilder; + } + + protected abstract Command.@NonNull Builder> configurePlotCommand( + Command.@NonNull Builder> builder + ); +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java new file mode 100644 index 000000000..324ffcc9c --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java @@ -0,0 +1,56 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.CommandManager; +import cloud.commandframework.annotations.injection.GuiceInjectionService; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.Singleton; +import com.google.inject.TypeLiteral; +import com.plotsquared.core.commands.injection.PlotInjector; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Set; + +@Singleton +public final class PlotSquaredCommandManager { + + private final CommandManager> commandManager; + private final Injector injector; + + @Inject + public PlotSquaredCommandManager( + final @NonNull CommandManager> commandManager, + final @NonNull Injector injector + ) { + this.commandManager = commandManager; + this.injector = injector; + this.registerInjectors(); + } + + /** + * Registers the commands that are shipped with PlotSquared. + */ + public void registerDefaultCommands() { + final Set commands = + this.injector.getInstance(Key.get(new TypeLiteral>() {})); + commands.forEach(command -> this.commandManager().command(command)); + } + + /** + * Returns the command manager. + * + * @return the command manager + */ + public @NonNull CommandManager> commandManager() { + return this.commandManager; + } + + private void registerInjectors() { + this.commandManager.parameterInjectorRegistry().registerInjector(Plot.class, + this.injector.getInstance(PlotInjector.class)); + this.commandManager.parameterInjectorRegistry().registerInjectionService(GuiceInjectionService.create(this.injector)); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java new file mode 100644 index 000000000..f182d4069 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java @@ -0,0 +1,18 @@ +package com.plotsquared.core.commands; + +import cloud.commandframework.keys.CloudKey; +import com.plotsquared.core.command.CommandCategory; + +/** + * Shared {@link cloud.commandframework.meta.CommandMeta command meta} keys. + */ +public final class PlotSquaredCommandMeta { + + /** + * Key that determines what {@link CommandCategory category} a command belongs to. + */ + public static final CloudKey META_CATEGORY = CloudKey.of("category", CommandCategory.class); + + private PlotSquaredCommandMeta() { + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java new file mode 100644 index 000000000..2a4d243ab --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java @@ -0,0 +1,196 @@ +package com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; +import com.google.inject.Inject; +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.command.CommandCategory; +import com.plotsquared.core.commands.CommandRequirement; +import com.plotsquared.core.commands.CommonCommandRequirement; +import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; +import com.plotsquared.core.configuration.Settings; +import com.plotsquared.core.configuration.caption.CaptionUtility; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.events.PlotFlagAddEvent; +import com.plotsquared.core.events.Result; +import com.plotsquared.core.permissions.Permission; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.flag.FlagParseException; +import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.plot.flag.types.IntegerFlag; +import com.plotsquared.core.plot.flag.types.ListFlag; +import com.plotsquared.core.util.EventDispatcher; +import com.plotsquared.core.util.MathMan; +import io.leangen.geantyref.TypeToken; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.List; +import java.util.Set; + +import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; +import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; + +public final class FlagSetCommand extends PlotSquaredCommandBean { + + private static final CloudKey> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken>() {}); + private static final CloudKey COMPONENT_VALUE = CloudKey.of("value", String.class); + + private static boolean checkPermValue( + final @NonNull PlotPlayer player, + final @NonNull PlotFlag flag, @NonNull String key, @NonNull String value + ) { + key = key.toLowerCase(); + value = value.toLowerCase(); + String perm = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format(key.toLowerCase(), value.toLowerCase()); + if (flag instanceof IntegerFlag && MathMan.isInteger(value)) { + try { + int numeric = Integer.parseInt(value); + // Getting full permission without "." at the end + perm = perm.substring(0, perm.length() - value.length() - 1); + boolean result = false; + if (numeric >= 0) { + int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ? + numeric : + Settings.Limit.MAX_PLOTS; + result = player.hasPermissionRange(perm, checkRange) >= numeric; + } + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver( + "node", + Tag.inserting(Component.text(perm + "." + numeric)) + ) + ); + } + return result; + } catch (NumberFormatException ignore) { + } + } else if (flag instanceof final ListFlag listFlag) { + try { + PlotFlag, ?> parsedFlag = listFlag.parse(value); + for (final Object entry : parsedFlag.getValue()) { + final String permission = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format( + key.toLowerCase(), + entry.toString().toLowerCase() + ); + final boolean result = player.hasPermission(permission); + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver("node", Tag.inserting(Component.text(permission))) + ); + return false; + } + } + } catch (final FlagParseException e) { + player.sendMessage( + TranslatableCaption.of("flag.flag_parse_error"), + TagResolver.builder() + .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) + .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) + .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) + .build() + ); + return false; + } catch (final Exception e) { + return false; + } + return true; + } + boolean result; + String basePerm = Permission.PERMISSION_SET_FLAG_KEY.format(key.toLowerCase()); + if (flag.isValuedPermission()) { + result = player.hasKeyedPermission(basePerm, value); + } else { + result = player.hasPermission(basePerm); + perm = basePerm; + } + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver("node", Tag.inserting(Component.text(perm))) + ); + } + return result; + } + + private final EventDispatcher eventDispatcher; + + @Inject + public FlagSetCommand(final @NonNull EventDispatcher eventDispatcher) { + this.eventDispatcher = eventDispatcher; + } + + @Override + public @NonNull CommandCategory category() { + return CommandCategory.SETTINGS; + } + + @Override + public @NonNull Set<@NonNull CommandRequirement> requirements() { + // TODO: Figure out how to handle the override permission check :) + return Set.of(CommonCommandRequirement.REQUIRES_PLOT, CommonCommandRequirement.REQUIRES_OWNER); + } + + @Override + protected Command.@NonNull Builder> configurePlotCommand( + final Command.@NonNull Builder> builder + ) { + return builder.literal("flag") + .literal("set") + .required(COMPONENT_FLAG, plotFlagParser()) + .required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG)); + } + + @Override + public void execute(final @NonNull CommandContext> commandContext) { + final PlotPlayer player = commandContext.sender(); + final Plot plot = commandContext.inject(Plot.class).orElseThrow(); + final PlotFlag flag = commandContext.get(COMPONENT_FLAG); + final String flagValue = commandContext.get(COMPONENT_VALUE); + + final PlotFlagAddEvent event = this.eventDispatcher.callFlagAdd(flag, plot); + if (event.getEventResult() == Result.DENY) { + player.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver("value", Tag.inserting(Component.text("Flag set"))) + ); + return; + } + if (event.getEventResult() != Result.FORCE && !checkPermValue(player, flag, flag.getName(), flagValue)) { + return; + } + + final String sanitizedValue = CaptionUtility.stripClickEvents(flag, flagValue); + final PlotFlag parsedFlag; + try { + parsedFlag = flag.parse(flagValue); + } catch (final FlagParseException e) { + player.sendMessage( + TranslatableCaption.of("flag.flag_parse_error"), + TagResolver.builder() + .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) + .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) + .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) + .build() + ); + return; + } + + plot.setFlag(parsedFlag); + player.sendMessage( + TranslatableCaption.of("flag.flag_added"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text(flag.getName()))) + .tag("value", Tag.inserting(Component.text(parsedFlag.toString()))) + .build() + ); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java new file mode 100644 index 000000000..b420bb040 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java @@ -0,0 +1,24 @@ +package com.plotsquared.core.commands.injection; + +import cloud.commandframework.annotations.AnnotationAccessor; +import cloud.commandframework.annotations.injection.ParameterInjector; +import cloud.commandframework.context.CommandContext; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * {@link ParameterInjector} that returns the current plot of the player. + */ +public final class PlotInjector implements ParameterInjector, Plot> { + + @Override + public @Nullable Plot create( + final @NonNull CommandContext> context, + final @NonNull AnnotationAccessor annotationAccessor + ) { + // TODO: Allow for overriding for console. + return context.sender().getCurrentPlot(); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java new file mode 100644 index 000000000..b477f8df0 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java @@ -0,0 +1,81 @@ +package com.plotsquared.core.commands.parser; + +import cloud.commandframework.arguments.parser.ArgumentParseResult; +import cloud.commandframework.arguments.parser.ArgumentParser; +import cloud.commandframework.arguments.parser.ParserDescriptor; +import cloud.commandframework.arguments.suggestion.BlockingSuggestionProvider; +import cloud.commandframework.arguments.suggestion.Suggestion; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.context.CommandInput; +import cloud.commandframework.exceptions.parsing.ParserException; +import com.plotsquared.core.configuration.caption.LocaleHolder; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.flag.GlobalFlagContainer; +import com.plotsquared.core.plot.flag.InternalFlag; +import com.plotsquared.core.plot.flag.PlotFlag; +import io.leangen.geantyref.TypeToken; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.util.ComponentMessageThrowable; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.Nullable; + +/** + * Parser that parses and suggests {@link PlotFlag plot flags}. + */ +public final class PlotFlagParser implements ArgumentParser, PlotFlag>, + BlockingSuggestionProvider> { + + /** + * Returns a new parser that parses {@link PlotFlag plot flags}. + * + * @return the parser + */ + public static @NonNull ParserDescriptor, PlotFlag> plotFlagParser() { + return ParserDescriptor.of(new PlotFlagParser(), new TypeToken>() { + }); + } + + @Override + public @NonNull ArgumentParseResult<@NonNull PlotFlag> parse( + final @NonNull CommandContext<@NonNull PlotPlayer> commandContext, + final @NonNull CommandInput commandInput + ) { + final String flagName = commandInput.readString(); + final PlotFlag flag = GlobalFlagContainer.getInstance().getFlagFromString(flagName); + if (flag == null) { + return ArgumentParseResult.failure(new PlotFlagParseException(commandContext)); + } + return ArgumentParseResult.success(flag); + } + + @Override + public @NonNull Iterable<@NonNull Suggestion> suggestions( + final @NonNull CommandContext> context, + final @NonNull CommandInput input + ) { + return GlobalFlagContainer.getInstance() + .getRecognizedPlotFlags() + .stream() + .filter(flag -> (!(flag instanceof InternalFlag))) + .map(PlotFlag::getName) + .map(Suggestion::simple) + .toList(); + } + + /** + * Exception thrown when an invalid flag name is supplied. + */ + public static final class PlotFlagParseException extends ParserException implements ComponentMessageThrowable { + + private PlotFlagParseException(final @NonNull CommandContext context) { + super(PlotFlagParser.class, context, TranslatableCaption.of("flag.not_valid_flag")); + } + + @Override + public @NonNull Component componentMessage() { + // TODO(City): This sucks... + return ((TranslatableCaption) this.errorCaption()).toComponent(LocaleHolder.console()); + } + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java new file mode 100644 index 000000000..c10603fd4 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java @@ -0,0 +1,63 @@ +package com.plotsquared.core.commands.processing; + +import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; +import cloud.commandframework.execution.postprocessor.CommandPostprocessor; +import cloud.commandframework.services.types.ConsumerService; +import com.plotsquared.core.commands.CommandRequirement; +import com.plotsquared.core.player.PlotPlayer; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +/** + * Processor that evaluates registered {@link CommandRequirement command requirements} before a command is executed. + */ +public final class CommandRequirementPostprocessor implements CommandPostprocessor> { + + private final Collection<@NonNull CommandRequirement> requirements = new ArrayList<>(); + + /** + * Requires a single requirement. + * + * @param requirement the requirement + */ + public void registerRequirement(final @NonNull CommandRequirement requirement) { + this.requirements.add(Objects.requireNonNull(requirement, "requirement")); + } + + /** + * Registers the given {@code requirements}. + * + * @param requirements the requirements + */ + public void registerRequirements(final @NonNull Collection<@NonNull CommandRequirement> requirements) { + requirements.forEach(this::registerRequirement); + } + + /** + * Registers the given {@code requirements}. + * + * @param requirements the requirements + */ + public void registerRequirements(final @NonNull CommandRequirement @NonNull... requirements) { + this.registerRequirements(Arrays.asList(requirements)); + } + + @Override + public void accept(final @NonNull CommandPostprocessingContext> processingContext) { + for (final CommandRequirement requirement : this.requirements) { + if (!processingContext.command().commandMeta().getOrDefault(requirement.key(), false)) { + continue; + } + if (requirement.evaluate(processingContext.commandContext())) { + continue; + } + processingContext.commandContext().sender().sendMessage(requirement.failureCaption()); + // Not allowed :( + ConsumerService.interrupt(); + } + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java new file mode 100644 index 000000000..372240252 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java @@ -0,0 +1,66 @@ +package com.plotsquared.core.commands.suggestions; + +import cloud.commandframework.arguments.suggestion.BlockingSuggestionProvider; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.context.CommandInput; +import cloud.commandframework.keys.CloudKey; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.plot.flag.types.ListFlag; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Objects; + +/** + * Suggestion provider that provides context-aware {@link PlotFlag plot flag} value suggestions using + * {@link PlotFlag#getTabCompletions()}. + */ +public final class FlagValueSuggestionProvider implements BlockingSuggestionProvider.Strings> { + + private final CloudKey> flagKey; + + /** + * Creates a new suggestion provider. + * + * @param flagKey the key of the argument that contains the flag to provide value suggestions for + */ + public FlagValueSuggestionProvider(final @NonNull CloudKey> flagKey) { + this.flagKey = Objects.requireNonNull(flagKey, "flagKey"); + } + + @Override + public @NonNull Iterable<@NonNull String> stringSuggestions( + @NonNull final CommandContext> context, + @NonNull final CommandInput input + ) { + final PlotFlag plotFlag = context.getOrDefault(this.flagKey, null); + if (plotFlag == null) { + return List.of(); + } + final Collection completions = plotFlag.getTabCompletions(); + if (plotFlag instanceof ListFlag && input.peekString().contains(",")) { + final String[] split = input.peekString().split(","); + final StringBuilder prefix = new StringBuilder(); + for (int i = 0; i < split.length - i; i++) { + prefix.append(split[i]).append(","); + } + + final String cmp; + if (!input.peekString().endsWith(",")) { + cmp = split[split.length - 1]; + } else { + prefix.append(split[split.length - 1]).append(","); + cmp = ""; + } + + return completions.stream() + .filter(value -> value.startsWith(cmp.toLowerCase(Locale.ENGLISH))) + .map(value -> prefix + value) + .toList(); + } + return completions; + } +} diff --git a/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java b/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java index 18a2c9fca..a8193e271 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java @@ -18,6 +18,7 @@ */ package com.plotsquared.core.configuration.caption; +import cloud.commandframework.captions.Caption; import com.google.common.base.Objects; import com.plotsquared.core.PlotSquared; import net.kyori.adventure.text.Component; @@ -33,7 +34,7 @@ import java.util.regex.Pattern; /** * Caption that is user modifiable */ -public final class TranslatableCaption implements NamespacedCaption { +public final class TranslatableCaption implements NamespacedCaption, Caption { /** * Default caption namespace @@ -72,6 +73,11 @@ public final class TranslatableCaption implements NamespacedCaption { ); } + @Override + public @NonNull String key() { + return this.getKey(); + } + /** * Get a new {@link TranslatableCaption} instance * diff --git a/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java new file mode 100644 index 000000000..0b72a9724 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java @@ -0,0 +1,20 @@ +package com.plotsquared.core.inject.modules; + +import com.google.inject.AbstractModule; +import com.google.inject.Scopes; +import com.google.inject.multibindings.Multibinder; +import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.commands.command.setting.flag.FlagSetCommand; + +public final class CommandModule extends AbstractModule { + + @Override + protected void configure() { + final Multibinder commands = Multibinder.newSetBinder( + this.binder(), + PlotSquaredCommandBean.class + ); + + commands.addBinding().to(FlagSetCommand.class).in(Scopes.SINGLETON); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index dd52cc123..55ba0b292 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,6 +39,7 @@ subprojects { version = rootProject.version repositories { + mavenLocal() // TODO(City): Remove once Cloud 2 is on central. mavenCentral() maven { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f891c19d7..a5a7ccab0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,6 +31,7 @@ paperlib = "1.0.8" informative-annotations = "1.4" vault = "1.7.1" serverlib = "2.3.4" +cloud = "2.0.0-SNAPSHOT" # Gradle plugins shadow = "8.1.1" @@ -77,6 +78,9 @@ informativeAnnotations = { group = "com.intellectualsites.informative-annotation paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } +cloud = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" } +cloudPaper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" } +cloudMinecraftExtras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" } [plugins] shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } From 2ac2f6648ebe320dde36fcd48f448e3243800988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 31 Dec 2023 21:46:33 +0100 Subject: [PATCH 02/13] port over `flag remove` --- .../core/commands/PlotSquaredCommandBean.java | 16 +- .../command/setting/flag/FlagCommandBean.java | 123 ++++++++++++++ .../setting/flag/FlagRemoveCommand.java | 153 ++++++++++++++++++ .../command/setting/flag/FlagSetCommand.java | 112 +------------ .../core/commands/parser/PlotFlagParser.java | 68 +++++++- .../core/inject/modules/CommandModule.java | 2 + 6 files changed, 360 insertions(+), 114 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index 6c604d61b..46da2f099 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -25,6 +25,19 @@ public abstract class PlotSquaredCommandBean extends CommandBean> */ public abstract @NonNull Set<@NonNull CommandRequirement> requirements(); + /** + * Prepares the given {@code builder}. + * + *

This should be implemented by abstract classes that extend {@link PlotSquaredCommandBean} to offer shared behavior + * for a subset of plot commands.

+ * + * @param builder the builder + * @return the prepared builder + */ + protected Command.@NonNull Builder> prepare(final Command.@NonNull Builder> builder) { + return builder; + } + @Override protected final @NonNull CommandProperties properties() { return CommandProperties.of("platsquared", "plat"); @@ -33,8 +46,7 @@ public abstract class PlotSquaredCommandBean extends CommandBean> @Override protected final Command.@NonNull Builder> configure(final Command.@NonNull Builder> builder) { Command.@NonNull Builder> intermediaryBuilder = - this.configurePlotCommand(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, - this.category())); + this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category()))); for (final CommandRequirement requirement : this.requirements()) { intermediaryBuilder = intermediaryBuilder.meta(requirement.key(), true); } diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java new file mode 100644 index 000000000..664efe794 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java @@ -0,0 +1,123 @@ +package com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.command.CommandCategory; +import com.plotsquared.core.commands.CommandRequirement; +import com.plotsquared.core.commands.CommonCommandRequirement; +import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.configuration.Settings; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.permissions.Permission; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.flag.FlagParseException; +import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.plot.flag.types.IntegerFlag; +import com.plotsquared.core.plot.flag.types.ListFlag; +import com.plotsquared.core.util.MathMan; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.List; +import java.util.Set; + +public abstract class FlagCommandBean extends PlotSquaredCommandBean { + + protected static boolean checkPermValue( + final @NonNull PlotPlayer player, + final @NonNull PlotFlag flag, @NonNull String key, @NonNull String value + ) { + key = key.toLowerCase(); + value = value.toLowerCase(); + String perm = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format(key.toLowerCase(), value.toLowerCase()); + if (flag instanceof IntegerFlag && MathMan.isInteger(value)) { + try { + int numeric = Integer.parseInt(value); + // Getting full permission without "." at the end + perm = perm.substring(0, perm.length() - value.length() - 1); + boolean result = false; + if (numeric >= 0) { + int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ? + numeric : + Settings.Limit.MAX_PLOTS; + result = player.hasPermissionRange(perm, checkRange) >= numeric; + } + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver( + "node", + Tag.inserting(Component.text(perm + "." + numeric)) + ) + ); + } + return result; + } catch (NumberFormatException ignore) { + } + } else if (flag instanceof final ListFlag listFlag) { + try { + PlotFlag, ?> parsedFlag = listFlag.parse(value); + for (final Object entry : parsedFlag.getValue()) { + final String permission = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format( + key.toLowerCase(), + entry.toString().toLowerCase() + ); + final boolean result = player.hasPermission(permission); + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver("node", Tag.inserting(Component.text(permission))) + ); + return false; + } + } + } catch (final FlagParseException e) { + player.sendMessage( + TranslatableCaption.of("flag.flag_parse_error"), + TagResolver.builder() + .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) + .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) + .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) + .build() + ); + return false; + } catch (final Exception e) { + return false; + } + return true; + } + boolean result; + String basePerm = Permission.PERMISSION_SET_FLAG_KEY.format(key.toLowerCase()); + if (flag.isValuedPermission()) { + result = player.hasKeyedPermission(basePerm, value); + } else { + result = player.hasPermission(basePerm); + perm = basePerm; + } + if (!result) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver("node", Tag.inserting(Component.text(perm))) + ); + } + return result; + } + + @Override + public final @NonNull CommandCategory category() { + return CommandCategory.SETTINGS; + } + + @Override + public @NonNull Set<@NonNull CommandRequirement> requirements() { + // TODO: Figure out how to handle the override permission check :) + return Set.of(CommonCommandRequirement.REQUIRES_PLOT, CommonCommandRequirement.REQUIRES_OWNER); + } + + @Override + protected final Command.@NonNull Builder> prepare(final Command.@NonNull Builder> builder) { + return builder.literal("flag"); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java new file mode 100644 index 000000000..173aabf37 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java @@ -0,0 +1,153 @@ +package com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; +import com.google.inject.Inject; +import com.plotsquared.core.commands.parser.PlotFlagParser; +import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.events.PlotFlagAddEvent; +import com.plotsquared.core.events.PlotFlagRemoveEvent; +import com.plotsquared.core.events.Result; +import com.plotsquared.core.permissions.Permission; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.flag.FlagParseException; +import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.plot.flag.types.ListFlag; +import com.plotsquared.core.util.EventDispatcher; +import io.leangen.geantyref.TypeToken; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; +import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; + +public final class FlagRemoveCommand extends FlagCommandBean { + + private static final CloudKey> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken>() {}); + private static final CloudKey COMPONENT_VALUE = CloudKey.of("value", String.class); + + private final EventDispatcher eventDispatcher; + + @Inject + public FlagRemoveCommand(final @NonNull EventDispatcher eventDispatcher) { + this.eventDispatcher = eventDispatcher; + } + + @Override + protected Command.@NonNull Builder> configurePlotCommand( + final Command.@NonNull Builder> builder + ) { + return builder.literal("remove") + .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.PLOT)) + .optional(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG)); + } + + @Override + public void execute(final @NonNull CommandContext> commandContext) { + final PlotPlayer player = commandContext.sender(); + final Plot plot = commandContext.inject(Plot.class).orElseThrow(); + final PlotFlag flag = commandContext.get(COMPONENT_FLAG); + final String flagValue = commandContext.getOrDefault(COMPONENT_VALUE, null); + + final PlotFlagRemoveEvent event = this.eventDispatcher.callFlagRemove(flag, plot); + if (event.getEventResult() == Result.DENY) { + player.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver("value", Tag.inserting(Component.text("Flag set"))) + ); + return; + } + final String flagKey = flag.getName().toLowerCase(Locale.ENGLISH); + if (event.getEventResult() != Result.FORCE + && !player.hasPermission(Permission.PERMISSION_SET_FLAG_KEY.format(flagKey))) { + if (flagValue == null) { + player.sendMessage( + TranslatableCaption.of("permission.no_permission"), + TagResolver.resolver( + "node", + Tag.inserting(Component.text(Permission.PERMISSION_SET_FLAG_KEY.format(flagKey))) + ) + ); + return; + } + } + + if (flagValue != null && flag instanceof ListFlag listFlag) { + final List list = new ArrayList<>(plot.getFlag(listFlag)); + final PlotFlag parsedFlag; + try { + parsedFlag = listFlag.parse(flagValue); + } catch (final FlagParseException e) { + player.sendMessage( + TranslatableCaption.of("flag.flag_parse_error"), + TagResolver.builder() + .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) + .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) + .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) + .build() + ); + return; + } + if (((List) parsedFlag.getValue()).isEmpty()) { + player.sendMessage(TranslatableCaption.of("flag.flag_not_removed")); + return; + } + if (list.removeAll((List) parsedFlag.getValue())) { + if (list.isEmpty()) { + if (plot.removeFlag(flag)) { + player.sendMessage( + TranslatableCaption.of("flag.flag_removed"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text(flagKey))) + .tag("value", Tag.inserting(Component.text(flag.toString()))) + .build() + ); + return; + } else { + player.sendMessage(TranslatableCaption.of("flag.flag_not_removed")); + return; + } + } else { + PlotFlag plotFlag = parsedFlag.createFlagInstance(list); + PlotFlagAddEvent addEvent = eventDispatcher.callFlagAdd(plotFlag, plot); + if (addEvent.getEventResult() == Result.DENY) { + player.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver( + "value", + Tag.inserting(Component.text("Re-addition of " + plotFlag.getName())) + ) + ); + return; + } + if (plot.setFlag(addEvent.getFlag())) { + player.sendMessage(TranslatableCaption.of("flag.flag_partially_removed")); + return; + } else { + player.sendMessage(TranslatableCaption.of("flag.flag_not_removed")); + return; + } + } + } + } else if (!plot.removeFlag(flag)) { + player.sendMessage(TranslatableCaption.of("flag.flag_not_removed")); + return; + } + player.sendMessage( + TranslatableCaption.of("flag.flag_removed"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text(flagKey))) + .tag("value", Tag.inserting(Component.text(flag.toString()))) + .build() + ); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java index 2a4d243ab..6e02ad0d9 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java @@ -4,123 +4,31 @@ import cloud.commandframework.Command; import cloud.commandframework.context.CommandContext; import cloud.commandframework.keys.CloudKey; import com.google.inject.Inject; -import com.plotsquared.core.PlotSquared; -import com.plotsquared.core.command.CommandCategory; -import com.plotsquared.core.commands.CommandRequirement; -import com.plotsquared.core.commands.CommonCommandRequirement; -import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.commands.parser.PlotFlagParser; import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; -import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.caption.CaptionUtility; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.Result; -import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.flag.FlagParseException; import com.plotsquared.core.plot.flag.PlotFlag; -import com.plotsquared.core.plot.flag.types.IntegerFlag; -import com.plotsquared.core.plot.flag.types.ListFlag; import com.plotsquared.core.util.EventDispatcher; -import com.plotsquared.core.util.MathMan; import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.List; -import java.util.Set; - import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; -public final class FlagSetCommand extends PlotSquaredCommandBean { +public final class FlagSetCommand extends FlagCommandBean { private static final CloudKey> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken>() {}); private static final CloudKey COMPONENT_VALUE = CloudKey.of("value", String.class); - private static boolean checkPermValue( - final @NonNull PlotPlayer player, - final @NonNull PlotFlag flag, @NonNull String key, @NonNull String value - ) { - key = key.toLowerCase(); - value = value.toLowerCase(); - String perm = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format(key.toLowerCase(), value.toLowerCase()); - if (flag instanceof IntegerFlag && MathMan.isInteger(value)) { - try { - int numeric = Integer.parseInt(value); - // Getting full permission without "." at the end - perm = perm.substring(0, perm.length() - value.length() - 1); - boolean result = false; - if (numeric >= 0) { - int checkRange = PlotSquared.get().getPlatform().equalsIgnoreCase("bukkit") ? - numeric : - Settings.Limit.MAX_PLOTS; - result = player.hasPermissionRange(perm, checkRange) >= numeric; - } - if (!result) { - player.sendMessage( - TranslatableCaption.of("permission.no_permission"), - TagResolver.resolver( - "node", - Tag.inserting(Component.text(perm + "." + numeric)) - ) - ); - } - return result; - } catch (NumberFormatException ignore) { - } - } else if (flag instanceof final ListFlag listFlag) { - try { - PlotFlag, ?> parsedFlag = listFlag.parse(value); - for (final Object entry : parsedFlag.getValue()) { - final String permission = Permission.PERMISSION_SET_FLAG_KEY_VALUE.format( - key.toLowerCase(), - entry.toString().toLowerCase() - ); - final boolean result = player.hasPermission(permission); - if (!result) { - player.sendMessage( - TranslatableCaption.of("permission.no_permission"), - TagResolver.resolver("node", Tag.inserting(Component.text(permission))) - ); - return false; - } - } - } catch (final FlagParseException e) { - player.sendMessage( - TranslatableCaption.of("flag.flag_parse_error"), - TagResolver.builder() - .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) - .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) - .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) - .build() - ); - return false; - } catch (final Exception e) { - return false; - } - return true; - } - boolean result; - String basePerm = Permission.PERMISSION_SET_FLAG_KEY.format(key.toLowerCase()); - if (flag.isValuedPermission()) { - result = player.hasKeyedPermission(basePerm, value); - } else { - result = player.hasPermission(basePerm); - perm = basePerm; - } - if (!result) { - player.sendMessage( - TranslatableCaption.of("permission.no_permission"), - TagResolver.resolver("node", Tag.inserting(Component.text(perm))) - ); - } - return result; - } - private final EventDispatcher eventDispatcher; @Inject @@ -128,24 +36,12 @@ public final class FlagSetCommand extends PlotSquaredCommandBean { this.eventDispatcher = eventDispatcher; } - @Override - public @NonNull CommandCategory category() { - return CommandCategory.SETTINGS; - } - - @Override - public @NonNull Set<@NonNull CommandRequirement> requirements() { - // TODO: Figure out how to handle the override permission check :) - return Set.of(CommonCommandRequirement.REQUIRES_PLOT, CommonCommandRequirement.REQUIRES_OWNER); - } - @Override protected Command.@NonNull Builder> configurePlotCommand( final Command.@NonNull Builder> builder ) { - return builder.literal("flag") - .literal("set") - .required(COMPONENT_FLAG, plotFlagParser()) + return builder.literal("set") + .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL)) .required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG)); } diff --git a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java index b477f8df0..8d90aa32d 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java +++ b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java @@ -11,6 +11,8 @@ import cloud.commandframework.exceptions.parsing.ParserException; import com.plotsquared.core.configuration.caption.LocaleHolder; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.flag.FlagContainer; import com.plotsquared.core.plot.flag.GlobalFlagContainer; import com.plotsquared.core.plot.flag.InternalFlag; import com.plotsquared.core.plot.flag.PlotFlag; @@ -20,6 +22,9 @@ import net.kyori.adventure.util.ComponentMessageThrowable; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; +import java.util.function.Function; + /** * Parser that parses and suggests {@link PlotFlag plot flags}. */ @@ -29,13 +34,20 @@ public final class PlotFlagParser implements ArgumentParser, PlotF /** * Returns a new parser that parses {@link PlotFlag plot flags}. * + * @param source the source of available flag values * @return the parser */ - public static @NonNull ParserDescriptor, PlotFlag> plotFlagParser() { - return ParserDescriptor.of(new PlotFlagParser(), new TypeToken>() { + public static @NonNull ParserDescriptor, PlotFlag> plotFlagParser(final @NonNull FlagSource source) { + return ParserDescriptor.of(new PlotFlagParser(source), new TypeToken>() { }); } + private final FlagSource flagSource; + + private PlotFlagParser(final @NonNull FlagSource flagSource) { + this.flagSource = flagSource; + } + @Override public @NonNull ArgumentParseResult<@NonNull PlotFlag> parse( final @NonNull CommandContext<@NonNull PlotPlayer> commandContext, @@ -54,8 +66,7 @@ public final class PlotFlagParser implements ArgumentParser, PlotF final @NonNull CommandContext> context, final @NonNull CommandInput input ) { - return GlobalFlagContainer.getInstance() - .getRecognizedPlotFlags() + return this.flagSource.flags(context.sender()) .stream() .filter(flag -> (!(flag instanceof InternalFlag))) .map(PlotFlag::getName) @@ -63,6 +74,55 @@ public final class PlotFlagParser implements ArgumentParser, PlotF .toList(); } + public enum FlagSource { + /** + * All recognized flags. + */ + GLOBAL(player -> GlobalFlagContainer.getInstance(), false), + /** + * All flags that have been configured in the current plot. + */ + PLOT(player -> { + final Plot plot = player.getCurrentPlot(); + if (plot == null) { + return GlobalFlagContainer.getInstance(); + } + return plot.getFlagContainer(); + }, true); + + private final Function, FlagContainer> containerFunction; + private final boolean storedOnly; + + FlagSource(final @NonNull Function, FlagContainer> containerFunction, final boolean storedOnly) { + this.containerFunction = containerFunction; + this.storedOnly = storedOnly; + } + + /** + * Returns the flag container. + * + * @param player the player to get the container for + * @return the container + */ + public @NonNull FlagContainer flagContainer(final @NonNull PlotPlayer player) { + return this.containerFunction.apply(player); + } + + /** + * Returns the flags from this source. + * + * @param player the player to get the flags for + * @return the flags + */ + public @NonNull Collection<@NonNull PlotFlag> flags(final @NonNull PlotPlayer player) { + final FlagContainer container = this.flagContainer(player); + if (this.storedOnly) { + return container.getFlagMap().values(); + } + return container.getRecognizedPlotFlags(); + } + } + /** * Exception thrown when an invalid flag name is supplied. */ diff --git a/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java index 0b72a9724..80125380c 100644 --- a/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java +++ b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java @@ -4,6 +4,7 @@ import com.google.inject.AbstractModule; import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.commands.command.setting.flag.FlagRemoveCommand; import com.plotsquared.core.commands.command.setting.flag.FlagSetCommand; public final class CommandModule extends AbstractModule { @@ -16,5 +17,6 @@ public final class CommandModule extends AbstractModule { ); commands.addBinding().to(FlagSetCommand.class).in(Scopes.SINGLETON); + commands.addBinding().to(FlagRemoveCommand.class).in(Scopes.SINGLETON); } } From b62a237daba7f7978342036c5620b76ef0391ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Mon, 1 Jan 2024 10:07:17 +0100 Subject: [PATCH 03/13] port over remaining flag commands --- .../bukkit/inject/CloudModule.java | 24 +++- .../core/commands/CommandRequirement.java | 18 +++ .../commands/CommonCommandRequirement.java | 18 +++ .../commands/PlotSquaredCaptionProvider.java | 18 +++ .../core/commands/PlotSquaredCommandBean.java | 18 +++ .../commands/PlotSquaredCommandManager.java | 18 +++ .../core/commands/PlotSquaredCommandMeta.java | 18 +++ .../command/setting/flag/FlagAddCommand.java | 120 ++++++++++++++++++ .../command/setting/flag/FlagCommandBean.java | 18 +++ .../command/setting/flag/FlagInfoCommand.java | 88 +++++++++++++ .../command/setting/flag/FlagListCommand.java | 93 ++++++++++++++ .../setting/flag/FlagRemoveCommand.java | 18 +++ .../command/setting/flag/FlagSetCommand.java | 18 +++ .../core/commands/injection/PlotInjector.java | 18 +++ .../core/commands/parser/PlotFlagParser.java | 19 ++- .../CommandRequirementPostprocessor.java | 18 +++ .../FlagValueSuggestionProvider.java | 42 ++++-- .../core/inject/modules/CommandModule.java | 26 +++- 18 files changed, 591 insertions(+), 19 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index 87d437b4a..afc03eed2 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -1,10 +1,26 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.bukkit.inject; -import cloud.commandframework.CloudCapability; import cloud.commandframework.CommandManager; import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator; -import cloud.commandframework.minecraft.extras.AudienceProvider; +import cloud.commandframework.execution.ExecutionCoordinator; import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; import cloud.commandframework.paper.PaperCommandManager; import com.google.inject.AbstractModule; @@ -54,7 +70,7 @@ public class CloudModule extends AbstractModule { try { final PaperCommandManager> commandManager = new PaperCommandManager>( this.bukkitPlatform, - AsynchronousCommandExecutionCoordinator.>builder().withAsynchronousParsing().build(), + ExecutionCoordinator.asyncCoordinator(), CloudModule::convert, CloudModule::convert ); diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index 4129fb182..7bef53a1e 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java index ae0135a05..2dd69814d 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java index 2222ff4ff..9e1f4e6a7 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.captions.Caption; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index 46da2f099..f0726a147 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.Command; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java index 324ffcc9c..031413c96 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.CommandManager; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java index f182d4069..e219deeed 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; import cloud.commandframework.keys.CloudKey; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java new file mode 100644 index 000000000..01d5f0f2d --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java @@ -0,0 +1,120 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; +import com.google.inject.Inject; +import com.plotsquared.core.commands.parser.PlotFlagParser; +import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; +import com.plotsquared.core.configuration.caption.CaptionUtility; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.events.PlotFlagAddEvent; +import com.plotsquared.core.events.Result; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.flag.FlagParseException; +import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.util.EventDispatcher; +import io.leangen.geantyref.TypeToken; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; +import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; + +public final class FlagAddCommand extends FlagCommandBean { + + private static final CloudKey> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken>() {}); + private static final CloudKey COMPONENT_VALUE = CloudKey.of("value", String.class); + + private final EventDispatcher eventDispatcher; + + @Inject + public FlagAddCommand(final @NonNull EventDispatcher eventDispatcher) { + this.eventDispatcher = eventDispatcher; + } + + @Override + protected Command.@NonNull Builder> configurePlotCommand( + final Command.@NonNull Builder> builder + ) { + return builder.literal("add") + .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL)) + .required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG)); + } + + @Override + public void execute(final @NonNull CommandContext> commandContext) { + final PlotPlayer player = commandContext.sender(); + final Plot plot = commandContext.inject(Plot.class).orElseThrow(); + final PlotFlag flag = commandContext.get(COMPONENT_FLAG); + final String flagValue = commandContext.get(COMPONENT_VALUE); + + final PlotFlagAddEvent event = this.eventDispatcher.callFlagAdd(flag, plot); + if (event.getEventResult() == Result.DENY) { + player.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver("value", Tag.inserting(Component.text("Flag set"))) + ); + return; + } + if (event.getEventResult() != Result.FORCE) { + final String[] split = flagValue.split(","); + for (final String entry : split) { + if (!checkPermValue(player, flag, flag.getName(), entry)) { + return; + } + } + } + + final String sanitizedValue = CaptionUtility.stripClickEvents(flag, flagValue); + final PlotFlag parsedFlag; + try { + parsedFlag = flag.parse(flagValue); + } catch (final FlagParseException e) { + player.sendMessage( + TranslatableCaption.of("flag.flag_parse_error"), + TagResolver.builder() + .tag("flag_name", Tag.inserting(Component.text(flag.getName()))) + .tag("flag_value", Tag.inserting(Component.text(e.getValue()))) + .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player))) + .build() + ); + return; + } + + final boolean result = plot.setFlag(plot.getFlagContainer().getFlag(flag.getClass()).merge(parsedFlag.getValue())); + if (!result) { + player.sendMessage(TranslatableCaption.of("flag.flag_not_added")); + return; + } + + player.sendMessage( + TranslatableCaption.of("flag.flag_added"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text(flag.getName()))) + .tag("value", Tag.inserting(Component.text(parsedFlag.toString()))) + .build() + ); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java index 664efe794..a712d8c22 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; import cloud.commandframework.Command; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java new file mode 100644 index 000000000..b92722a14 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java @@ -0,0 +1,88 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; +import com.plotsquared.core.commands.parser.PlotFlagParser; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.flag.PlotFlag; +import io.leangen.geantyref.TypeToken; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; + +public final class FlagInfoCommand extends FlagCommandBean { + + private static final CloudKey> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken>() {}); + + @Override + protected Command.@NonNull Builder> configurePlotCommand(final Command.@NonNull Builder> builder) { + return builder.literal("info") + .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL)); + } + + @Override + public void execute(final @NonNull CommandContext> commandContext) { + final PlotFlag plotFlag = commandContext.get(COMPONENT_FLAG); + final PlotPlayer player = commandContext.sender(); + + player.sendMessage(TranslatableCaption.of("flag.flag_info_header")); + // Flag name + player.sendMessage( + TranslatableCaption.of("flag.flag_info_name"), + TagResolver.resolver("flag", Tag.inserting(Component.text(plotFlag.getName()))) + ); + // Flag category + player.sendMessage( + TranslatableCaption.of("flag.flag_info_category"), + TagResolver.resolver( + "value", + Tag.inserting(plotFlag.getFlagCategory().toComponent(player)) + ) + ); + // Flag description + // TODO maybe merge and \n instead? + player.sendMessage(TranslatableCaption.of("flag.flag_info_description")); + player.sendMessage(plotFlag.getFlagDescription()); + // Flag example + player.sendMessage( + TranslatableCaption.of("flag.flag_info_example"), + TagResolver.builder() + .tag("command", Tag.preProcessParsed("/plot flag set")) + .tag("flag", Tag.preProcessParsed(plotFlag.getName())) + .tag("value", Tag.preProcessParsed(plotFlag.getExample())) + .build() + ); + // Default value + final String defaultValue = player.getLocation().getPlotArea().getFlagContainer() + .getFlagErased(plotFlag.getClass()).toString(); + player.sendMessage( + TranslatableCaption.of("flag.flag_info_default_value"), + TagResolver.resolver("value", Tag.inserting(Component.text(defaultValue))) + ); + // Footer. Done this way to prevent the duplicate-message-thingy from catching it + player.sendMessage(TranslatableCaption.of("flag.flag_info_footer")); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java new file mode 100644 index 000000000..703dd9981 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java @@ -0,0 +1,93 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; + +import cloud.commandframework.Command; +import cloud.commandframework.context.CommandContext; +import com.plotsquared.core.configuration.caption.StaticCaption; +import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.flag.GlobalFlagContainer; +import com.plotsquared.core.plot.flag.InternalFlag; +import com.plotsquared.core.plot.flag.PlotFlag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public final class FlagListCommand extends FlagCommandBean { + + private static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build(); + + @Override + protected Command.@NonNull Builder> configurePlotCommand( + final Command.@NonNull Builder> builder + ) { + return builder.literal("list"); + } + + @Override + public void execute(final @NonNull CommandContext> commandContext) { + final PlotPlayer player = commandContext.sender(); + + final Map> flags = new HashMap<>(); + for (PlotFlag plotFlag : GlobalFlagContainer.getInstance().getRecognizedPlotFlags()) { + if (plotFlag instanceof InternalFlag) { + continue; + } + final Component category = plotFlag.getFlagCategory().toComponent(player); + final Collection flagList = flags.computeIfAbsent(category, k -> new ArrayList<>()); + flagList.add(plotFlag.getName()); + } + + for (final Map.Entry> entry : flags.entrySet()) { + Collections.sort(entry.getValue()); + Component category = + MINI_MESSAGE.deserialize( + TranslatableCaption.of("flag.flag_list_categories").getComponent(player), + TagResolver.resolver("category", Tag.inserting(entry.getKey().style(Style.empty()))) + ); + TextComponent.Builder builder = Component.text().append(category); + final Iterator flagIterator = entry.getValue().iterator(); + while (flagIterator.hasNext()) { + final String flag = flagIterator.next(); + builder.append(MINI_MESSAGE + .deserialize( + TranslatableCaption.of("flag.flag_list_flag").getComponent(player), + TagResolver.builder() + .tag("command", Tag.preProcessParsed("/plat flag info " + flag)) + .tag("flag", Tag.inserting(Component.text(flag))) + .tag("suffix", Tag.inserting(Component.text(flagIterator.hasNext() ? ", " : ""))) + .build() + )); + } + player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.build()))); + } + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java index 173aabf37..b1abd2833 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; import cloud.commandframework.Command; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java index 6e02ad0d9..b9dc711b0 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.command.setting.flag; import cloud.commandframework.Command; diff --git a/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java index b420bb040..4c9eadab0 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java +++ b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.injection; import cloud.commandframework.annotations.AnnotationAccessor; diff --git a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java index 8d90aa32d..101149ba6 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java +++ b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.parser; import cloud.commandframework.arguments.parser.ArgumentParseResult; @@ -20,7 +38,6 @@ import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.util.ComponentMessageThrowable; import org.checkerframework.checker.nullness.qual.NonNull; -import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.function.Function; diff --git a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java index c10603fd4..57154294b 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java +++ b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.processing; import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; diff --git a/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java index 372240252..0c86b1ce0 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java +++ b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java @@ -1,3 +1,21 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands.suggestions; import cloud.commandframework.arguments.suggestion.BlockingSuggestionProvider; @@ -9,10 +27,8 @@ import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.types.ListFlag; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; /** * Suggestion provider that provides context-aware {@link PlotFlag plot flag} value suggestions using @@ -43,21 +59,21 @@ public final class FlagValueSuggestionProvider implements BlockingSuggestionProv final Collection completions = plotFlag.getTabCompletions(); if (plotFlag instanceof ListFlag && input.peekString().contains(",")) { final String[] split = input.peekString().split(","); - final StringBuilder prefix = new StringBuilder(); - for (int i = 0; i < split.length - i; i++) { - prefix.append(split[i]).append(","); - } + final List existingValues = new ArrayList<>(Arrays.asList(split)); - final String cmp; + final String completingValue; if (!input.peekString().endsWith(",")) { - cmp = split[split.length - 1]; + // In this case we want to complete the value we're currently typing. + completingValue = split[split.length - 1]; + existingValues.remove(existingValues.size() - 1); } else { - prefix.append(split[split.length - 1]).append(","); - cmp = ""; + completingValue = null; } + final String prefix = existingValues.stream().collect(Collectors.joining(",", "", ",")); return completions.stream() - .filter(value -> value.startsWith(cmp.toLowerCase(Locale.ENGLISH))) + .filter(value -> !existingValues.contains(value)) + .filter(value -> completingValue == null || value.startsWith(completingValue)) .map(value -> prefix + value) .toList(); } diff --git a/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java index 80125380c..53f32008c 100644 --- a/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java +++ b/Core/src/main/java/com/plotsquared/core/inject/modules/CommandModule.java @@ -1,9 +1,30 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.inject.modules; import com.google.inject.AbstractModule; import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; import com.plotsquared.core.commands.PlotSquaredCommandBean; +import com.plotsquared.core.commands.command.setting.flag.FlagAddCommand; +import com.plotsquared.core.commands.command.setting.flag.FlagInfoCommand; +import com.plotsquared.core.commands.command.setting.flag.FlagListCommand; import com.plotsquared.core.commands.command.setting.flag.FlagRemoveCommand; import com.plotsquared.core.commands.command.setting.flag.FlagSetCommand; @@ -16,7 +37,10 @@ public final class CommandModule extends AbstractModule { PlotSquaredCommandBean.class ); - commands.addBinding().to(FlagSetCommand.class).in(Scopes.SINGLETON); + commands.addBinding().to(FlagAddCommand.class).in(Scopes.SINGLETON); + commands.addBinding().to(FlagInfoCommand.class).in(Scopes.SINGLETON); + commands.addBinding().to(FlagListCommand.class).in(Scopes.SINGLETON); commands.addBinding().to(FlagRemoveCommand.class).in(Scopes.SINGLETON); + commands.addBinding().to(FlagSetCommand.class).in(Scopes.SINGLETON); } } From 24d7fe626da3786259b09d64dbf0dde74cc5bac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Mon, 1 Jan 2024 17:31:04 +0100 Subject: [PATCH 04/13] improve the requirement system --- .../bukkit/inject/CloudModule.java | 2 - .../core/commands/CommandRequirement.java | 44 ++++++++++++- .../core/commands/CommandRequirements.java | 61 +++++++++++++++++++ .../commands/CommonCommandRequirement.java | 15 ++--- .../core/commands/PlotSquaredCommandBean.java | 8 +-- .../command/setting/flag/FlagCommandBean.java | 7 ++- .../CommandRequirementPostprocessor.java | 49 +++------------ 7 files changed, 128 insertions(+), 58 deletions(-) create mode 100644 Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index afc03eed2..9528ff3ae 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -28,7 +28,6 @@ import com.google.inject.Key; import com.google.inject.TypeLiteral; import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.util.BukkitUtil; -import com.plotsquared.core.commands.CommonCommandRequirement; import com.plotsquared.core.commands.PlotSquaredCaptionProvider; import com.plotsquared.core.commands.processing.CommandRequirementPostprocessor; import com.plotsquared.core.configuration.caption.TranslatableCaption; @@ -83,7 +82,6 @@ public class CloudModule extends AbstractModule { } final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); - requirementPostprocessor.registerRequirements(CommonCommandRequirement.values()); commandManager.registerCommandPostProcessor(requirementPostprocessor); // TODO(City): Override parsing errors using MM parsing. diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index 7bef53a1e..11bc1321b 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -19,15 +19,17 @@ package com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKeyHolder; import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; /** * Something that is required for a command to be executed. */ -public interface CommandRequirement extends CloudKeyHolder { +public interface CommandRequirement { /** * Returns the caption sent when the requirement is not met. @@ -43,4 +45,42 @@ public interface CommandRequirement extends CloudKeyHolder { * @return {@code true} if the requirement is met, else {@code false} */ boolean evaluate(final @NonNull CommandContext> context); + + /** + * Returns the placeholder values. + * + * @return placeholder values + */ + default @NonNull TagResolver @NonNull[] tagResolvers() { + return new TagResolver[0]; + } + + /** + * Returns a requirement that evaluates to {@code true} if the sender has the given {@code permission} or if + * this requirement evaluates to {@code true}. + * + * @param permission the override permission + * @return the new requirement + */ + default @NonNull CommandRequirement withPermissionOverride(final @NonNull Permission permission) { + final CommandRequirement thisRequirement = this; + return new CommandRequirement() { + @Override + public @NonNull TranslatableCaption failureCaption() { + return TranslatableCaption.of("permission.no_permission"); + } + + @Override + public @NonNull TagResolver @NonNull [] tagResolvers() { + return new TagResolver[] { + TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_SET_FLAG_OTHER)) + }; + } + + @Override + public boolean evaluate(final @NonNull CommandContext> context) { + return context.sender().hasPermission(permission) || thisRequirement.evaluate(context); + } + }; + } } diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java new file mode 100644 index 000000000..046c09b26 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java @@ -0,0 +1,61 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; + +import cloud.commandframework.keys.CloudKey; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * Holder of {@link CommandRequirement} requirements. + */ +public final class CommandRequirements implements Iterable<@NonNull CommandRequirement> { + + /** + * The key used to store the requirements in the {@link cloud.commandframework.meta.CommandMeta}. + */ + public static final CloudKey REQUIREMENTS_KEY = CloudKey.of( + "requirements", + CommandRequirements.class + ); + + /** + * Creates a new instance. + * + * @param requirements the requirements + * @return the instance + */ + public static @NonNull CommandRequirements create(final @NonNull Collection<@NonNull CommandRequirement> requirements) { + return new CommandRequirements(requirements); + } + + private final List requirements; + + private CommandRequirements(final @NonNull Collection<@NonNull CommandRequirement> requirements) { + this.requirements = List.copyOf(requirements); + } + + @Override + public @NonNull Iterator<@NonNull CommandRequirement> iterator() { + return this.requirements.iterator(); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java index 2dd69814d..93f55c5f5 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -19,7 +19,6 @@ package com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,7 +38,14 @@ public enum CommonCommandRequirement implements CommandRequirement { */ REQUIRES_OWNER(TranslatableCaption.of("working.plot_not_claimed"), ctx -> ctx.sender().getCurrentPlot() != null && ctx.sender().getCurrentPlot().hasOwner() - ); + ), + /** + * Requires that the command sender is the plot owner. + */ + IS_OWNER(TranslatableCaption.of("permission.no_plot_perms"), + ctx -> ctx.sender().getCurrentPlot() != null && ctx.sender().getCurrentPlot().isOwner(ctx.sender().getUUID()) + ) + ; private final TranslatableCaption failureCaption; private final Predicate>> predicate; @@ -60,9 +66,4 @@ public enum CommonCommandRequirement implements CommandRequirement { public boolean evaluate(final @NonNull CommandContext> context) { return this.predicate.test(context); } - - @Override - public @NonNull CloudKey key() { - return CloudKey.of(String.format("requirement_%s", this.name()), Boolean.class); - } } diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index f0726a147..60dddd855 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -63,12 +63,8 @@ public abstract class PlotSquaredCommandBean extends CommandBean> @Override protected final Command.@NonNull Builder> configure(final Command.@NonNull Builder> builder) { - Command.@NonNull Builder> intermediaryBuilder = - this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category()))); - for (final CommandRequirement requirement : this.requirements()) { - intermediaryBuilder = intermediaryBuilder.meta(requirement.key(), true); - } - return intermediaryBuilder; + return this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category()))) + .meta(CommandRequirements.REQUIREMENTS_KEY, CommandRequirements.create(this.requirements())); } protected abstract Command.@NonNull Builder> configurePlotCommand( diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java index a712d8c22..ae6445e43 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java @@ -130,8 +130,11 @@ public abstract class FlagCommandBean extends PlotSquaredCommandBean { @Override public @NonNull Set<@NonNull CommandRequirement> requirements() { - // TODO: Figure out how to handle the override permission check :) - return Set.of(CommonCommandRequirement.REQUIRES_PLOT, CommonCommandRequirement.REQUIRES_OWNER); + return Set.of( + CommonCommandRequirement.REQUIRES_PLOT, + CommonCommandRequirement.REQUIRES_OWNER, + CommonCommandRequirement.IS_OWNER.withPermissionOverride(Permission.PERMISSION_SET_FLAG_OTHER) + ); } @Override diff --git a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java index 57154294b..36fad14d1 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java +++ b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java @@ -22,58 +22,29 @@ import cloud.commandframework.execution.postprocessor.CommandPostprocessingConte import cloud.commandframework.execution.postprocessor.CommandPostprocessor; import cloud.commandframework.services.types.ConsumerService; import com.plotsquared.core.commands.CommandRequirement; +import com.plotsquared.core.commands.CommandRequirements; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Objects; - /** * Processor that evaluates registered {@link CommandRequirement command requirements} before a command is executed. */ public final class CommandRequirementPostprocessor implements CommandPostprocessor> { - private final Collection<@NonNull CommandRequirement> requirements = new ArrayList<>(); - - /** - * Requires a single requirement. - * - * @param requirement the requirement - */ - public void registerRequirement(final @NonNull CommandRequirement requirement) { - this.requirements.add(Objects.requireNonNull(requirement, "requirement")); - } - - /** - * Registers the given {@code requirements}. - * - * @param requirements the requirements - */ - public void registerRequirements(final @NonNull Collection<@NonNull CommandRequirement> requirements) { - requirements.forEach(this::registerRequirement); - } - - /** - * Registers the given {@code requirements}. - * - * @param requirements the requirements - */ - public void registerRequirements(final @NonNull CommandRequirement @NonNull... requirements) { - this.registerRequirements(Arrays.asList(requirements)); - } - @Override public void accept(final @NonNull CommandPostprocessingContext> processingContext) { - for (final CommandRequirement requirement : this.requirements) { - if (!processingContext.command().commandMeta().getOrDefault(requirement.key(), false)) { - continue; - } + final CommandRequirements requirements = processingContext.command().commandMeta().getOrDefault( + CommandRequirements.REQUIREMENTS_KEY, + null + ); + if (requirements == null) { + return; + } + for (final CommandRequirement requirement : requirements) { if (requirement.evaluate(processingContext.commandContext())) { continue; } - processingContext.commandContext().sender().sendMessage(requirement.failureCaption()); + processingContext.commandContext().sender().sendMessage(requirement.failureCaption(), requirement.tagResolvers()); // Not allowed :( ConsumerService.interrupt(); } From 1a277bbbeb3477b83adaddf5f4512da0bf4b3294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 2 Jan 2024 12:00:49 +0100 Subject: [PATCH 05/13] add requirement inheritance --- .../bukkit/commands/BukkitSenderMapper.java | 50 +++++++++++++++++ .../bukkit/inject/CloudModule.java | 54 +++++++++---------- .../core/commands/CommandRequirement.java | 16 ++++++ .../core/commands/CommandRequirements.java | 19 +++++-- .../commands/CommonCommandRequirement.java | 18 +++++-- .../core/commands/PlotSquaredCommandBean.java | 4 +- .../command/setting/flag/FlagCommandBean.java | 9 +--- 7 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java b/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java new file mode 100644 index 000000000..692a04066 --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java @@ -0,0 +1,50 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.bukkit.commands; + +import cloud.commandframework.SenderMapper; +import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.core.player.ConsolePlayer; +import com.plotsquared.core.player.PlotPlayer; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * Mapper between {@link CommandSender} and {@link PlotPlayer}. + */ +public final class BukkitSenderMapper implements SenderMapper> { + + @Override + public @NonNull PlotPlayer map(final @NonNull CommandSender base) { + if (base instanceof Player player) { + return BukkitUtil.adapt(player); + } + return ConsolePlayer.getConsole(); + } + + @Override + public @NonNull CommandSender reverse(final @NonNull PlotPlayer mapped) { + if (mapped instanceof ConsolePlayer) { + return Bukkit.getConsoleSender(); + } + return (Player) mapped.getPlatformPlayer(); + } +} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index 9528ff3ae..082836064 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -27,6 +27,7 @@ import com.google.inject.AbstractModule; import com.google.inject.Key; import com.google.inject.TypeLiteral; import com.plotsquared.bukkit.BukkitPlatform; +import com.plotsquared.bukkit.commands.BukkitSenderMapper; import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.core.commands.PlotSquaredCaptionProvider; import com.plotsquared.core.commands.processing.CommandRequirementPostprocessor; @@ -66,35 +67,30 @@ public class CloudModule extends AbstractModule { @Override protected void configure() { - try { - final PaperCommandManager> commandManager = new PaperCommandManager>( - this.bukkitPlatform, - ExecutionCoordinator.asyncCoordinator(), - CloudModule::convert, - CloudModule::convert - ); - commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider()); - if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { - commandManager.registerAsynchronousCompletions(); - } - if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { - commandManager.registerBrigadier(); - } - - final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); - commandManager.registerCommandPostProcessor(requirementPostprocessor); - - // TODO(City): Override parsing errors using MM parsing. - MinecraftExceptionHandler.>create(PlotPlayer::getAudience) - .defaultHandlers() - .decorator((ctx, component) -> TranslatableCaption.of("core.prefix"). - toComponent(ctx.context().sender()) - .append(component)) - .registerTo(commandManager); - - bind(Key.get(new TypeLiteral>>() {})).toInstance(commandManager); - } catch (final Exception e) { - LOGGER.error("Failed to configure command manager", e); + final PaperCommandManager> commandManager = new PaperCommandManager>( + this.bukkitPlatform, + ExecutionCoordinator.asyncCoordinator(), + new BukkitSenderMapper() + ); + commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider()); + if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { + commandManager.registerAsynchronousCompletions(); } + if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { + commandManager.registerBrigadier(); + } + + final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); + commandManager.registerCommandPostProcessor(requirementPostprocessor); + + // TODO(City): Override parsing errors using MM parsing. + MinecraftExceptionHandler.>create(PlotPlayer::getAudience) + .defaultHandlers() + .decorator((ctx, component) -> TranslatableCaption.of("core.prefix"). + toComponent(ctx.context().sender()) + .append(component)) + .registerTo(commandManager); + + bind(Key.get(new TypeLiteral>>() {})).toInstance(commandManager); } } diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index 11bc1321b..89dd70b36 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -26,6 +26,8 @@ import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.List; + /** * Something that is required for a command to be executed. */ @@ -55,6 +57,15 @@ public interface CommandRequirement { return new TagResolver[0]; } + /** + * Returns the list of parent requirements that should be evaluated before this requirement. + * + * @return the requirements + */ + default @NonNull List<@NonNull CommandRequirement> parents() { + return List.of(); + } + /** * Returns a requirement that evaluates to {@code true} if the sender has the given {@code permission} or if * this requirement evaluates to {@code true}. @@ -77,6 +88,11 @@ public interface CommandRequirement { }; } + @Override + public @NonNull List<@NonNull CommandRequirement> parents() { + return thisRequirement.parents(); + } + @Override public boolean evaluate(final @NonNull CommandContext> context) { return context.sender().hasPermission(permission) || thisRequirement.evaluate(context); diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java index 046c09b26..7f5aa69d0 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java @@ -21,7 +21,7 @@ package com.plotsquared.core.commands; import cloud.commandframework.keys.CloudKey; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Collection; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -44,14 +44,25 @@ public final class CommandRequirements implements Iterable<@NonNull CommandRequi * @param requirements the requirements * @return the instance */ - public static @NonNull CommandRequirements create(final @NonNull Collection<@NonNull CommandRequirement> requirements) { + public static @NonNull CommandRequirements create(final @NonNull List<@NonNull CommandRequirement> requirements) { return new CommandRequirements(requirements); } + private static @NonNull List<@NonNull CommandRequirement> extractRequirements( + final @NonNull List<@NonNull CommandRequirement> requirements + ) { + final List extractedRequirements = new ArrayList<>(); + for (final CommandRequirement requirement : requirements) { + extractedRequirements.addAll(extractRequirements(requirement.parents())); + extractedRequirements.add(requirement); + } + return extractedRequirements; + } + private final List requirements; - private CommandRequirements(final @NonNull Collection<@NonNull CommandRequirement> requirements) { - this.requirements = List.copyOf(requirements); + private CommandRequirements(final @NonNull List<@NonNull CommandRequirement> requirements) { + this.requirements = List.copyOf(extractRequirements(requirements)); } @Override diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java index 93f55c5f5..e58da8b6e 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -23,6 +23,8 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Arrays; +import java.util.List; import java.util.function.Predicate; /** @@ -37,31 +39,41 @@ public enum CommonCommandRequirement implements CommandRequirement { * Requires that the command sender is in a claimed plot. */ REQUIRES_OWNER(TranslatableCaption.of("working.plot_not_claimed"), - ctx -> ctx.sender().getCurrentPlot() != null && ctx.sender().getCurrentPlot().hasOwner() + ctx -> ctx.sender().getCurrentPlot().hasOwner(), + REQUIRES_PLOT ), /** * Requires that the command sender is the plot owner. */ IS_OWNER(TranslatableCaption.of("permission.no_plot_perms"), - ctx -> ctx.sender().getCurrentPlot() != null && ctx.sender().getCurrentPlot().isOwner(ctx.sender().getUUID()) + ctx -> ctx.sender().getCurrentPlot().isOwner(ctx.sender().getUUID()), + REQUIRES_OWNER ) ; private final TranslatableCaption failureCaption; private final Predicate>> predicate; + private final List<@NonNull CommandRequirement> parents; CommonCommandRequirement( final @NonNull TranslatableCaption failureCaption, - final @NonNull Predicate>> predicate + final @NonNull Predicate>> predicate, + final @NonNull CommandRequirement @NonNull... parents ) { this.failureCaption = failureCaption; this.predicate = predicate; + this.parents = Arrays.asList(parents); } public @NonNull TranslatableCaption failureCaption() { return this.failureCaption; } + @Override + public @NonNull List<@NonNull CommandRequirement> parents() { + return this.parents; + } + @Override public boolean evaluate(final @NonNull CommandContext> context) { return this.predicate.test(context); diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index 60dddd855..484b160d9 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -25,7 +25,7 @@ import com.plotsquared.core.command.CommandCategory; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Set; +import java.util.List; public abstract class PlotSquaredCommandBean extends CommandBean> { @@ -41,7 +41,7 @@ public abstract class PlotSquaredCommandBean extends CommandBean> * * @return the requirements */ - public abstract @NonNull Set<@NonNull CommandRequirement> requirements(); + public abstract @NonNull List<@NonNull CommandRequirement> requirements(); /** * Prepares the given {@code builder}. diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java index ae6445e43..d29bdcb83 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java @@ -39,7 +39,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; import java.util.List; -import java.util.Set; public abstract class FlagCommandBean extends PlotSquaredCommandBean { @@ -129,12 +128,8 @@ public abstract class FlagCommandBean extends PlotSquaredCommandBean { } @Override - public @NonNull Set<@NonNull CommandRequirement> requirements() { - return Set.of( - CommonCommandRequirement.REQUIRES_PLOT, - CommonCommandRequirement.REQUIRES_OWNER, - CommonCommandRequirement.IS_OWNER.withPermissionOverride(Permission.PERMISSION_SET_FLAG_OTHER) - ); + public @NonNull List<@NonNull CommandRequirement> requirements() { + return List.of(CommonCommandRequirement.IS_OWNER.withPermissionOverride(Permission.PERMISSION_SET_FLAG_OTHER)); } @Override From 3a1b373c8ed68fcf8a77d1dedc5d6ead3c0993da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 2 Jan 2024 12:08:36 +0100 Subject: [PATCH 06/13] don't use async suggestions with brigadier --- .../java/com/plotsquared/bukkit/inject/CloudModule.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index 082836064..af098aef9 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -73,11 +73,11 @@ public class CloudModule extends AbstractModule { new BukkitSenderMapper() ); commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider()); - if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { - commandManager.registerAsynchronousCompletions(); - } + if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { commandManager.registerBrigadier(); + } else if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { + commandManager.registerAsynchronousCompletions(); } final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); From 92a00ef60a5e3b6d00585e4101002ca9ce94ea97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 2 Jan 2024 18:59:39 +0100 Subject: [PATCH 07/13] use cloud-requirements --- .../bukkit/inject/CloudModule.java | 7 +- Core/build.gradle.kts | 1 + .../core/commands/CommandRequirement.java | 36 +++++----- .../core/commands/CommandRequirements.java | 72 ------------------- .../commands/CommonCommandRequirement.java | 2 +- .../core/commands/PlotSquaredCommandBean.java | 7 +- .../PlotSquaredRequirementFailureHandler.java | 35 +++++++++ .../CommandRequirementPostprocessor.java | 52 -------------- gradle/libs.versions.toml | 2 + 9 files changed, 66 insertions(+), 148 deletions(-) delete mode 100644 Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java create mode 100644 Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java delete mode 100644 Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index af098aef9..dade29c3d 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -29,8 +29,9 @@ import com.google.inject.TypeLiteral; import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.commands.BukkitSenderMapper; import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.core.commands.CommandRequirement; import com.plotsquared.core.commands.PlotSquaredCaptionProvider; -import com.plotsquared.core.commands.processing.CommandRequirementPostprocessor; +import com.plotsquared.core.commands.PlotSquaredRequirementFailureHandler; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.PlotPlayer; @@ -40,6 +41,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.requirement.RequirementPostprocessor; public class CloudModule extends AbstractModule { @@ -80,7 +82,8 @@ public class CloudModule extends AbstractModule { commandManager.registerAsynchronousCompletions(); } - final CommandRequirementPostprocessor requirementPostprocessor = new CommandRequirementPostprocessor(); + final RequirementPostprocessor, CommandRequirement> requirementPostprocessor = + RequirementPostprocessor.of(CommandRequirement.REQUIREMENTS_KEY, new PlotSquaredRequirementFailureHandler()); commandManager.registerCommandPostProcessor(requirementPostprocessor); // TODO(City): Override parsing errors using MM parsing. diff --git a/Core/build.gradle.kts b/Core/build.gradle.kts index 3ea85bff0..7e1dd24eb 100644 --- a/Core/build.gradle.kts +++ b/Core/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { // Cloud api(libs.cloud) api(libs.cloudMinecraftExtras) + api(libs.cloudRequirements) // Guice api(libs.guice) { diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index 89dd70b36..d5a7bd8dc 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -19,19 +19,32 @@ package com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; +import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; +import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.requirement.Requirement; +import org.incendo.cloud.requirement.Requirements; import java.util.List; /** * Something that is required for a command to be executed. */ -public interface CommandRequirement { +public interface CommandRequirement extends Requirement, CommandRequirement> { + + /** + * The key used to store the requirements in the {@link cloud.commandframework.meta.CommandMeta}. + */ + CloudKey, CommandRequirement>> REQUIREMENTS_KEY = CloudKey.of( + "requirements", + new TypeToken, CommandRequirement>>() { + } + ); /** * Returns the caption sent when the requirement is not met. @@ -40,14 +53,6 @@ public interface CommandRequirement { */ @NonNull TranslatableCaption failureCaption(); - /** - * Evaluates whether the requirement is met. - * - * @param context command context to evaluate - * @return {@code true} if the requirement is met, else {@code false} - */ - boolean evaluate(final @NonNull CommandContext> context); - /** * Returns the placeholder values. * @@ -57,15 +62,6 @@ public interface CommandRequirement { return new TagResolver[0]; } - /** - * Returns the list of parent requirements that should be evaluated before this requirement. - * - * @return the requirements - */ - default @NonNull List<@NonNull CommandRequirement> parents() { - return List.of(); - } - /** * Returns a requirement that evaluates to {@code true} if the sender has the given {@code permission} or if * this requirement evaluates to {@code true}. @@ -94,8 +90,8 @@ public interface CommandRequirement { } @Override - public boolean evaluate(final @NonNull CommandContext> context) { - return context.sender().hasPermission(permission) || thisRequirement.evaluate(context); + public boolean evaluateRequirement(final @NonNull CommandContext> context) { + return context.sender().hasPermission(permission) || thisRequirement.evaluateRequirement(context); } }; } diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java deleted file mode 100644 index 7f5aa69d0..000000000 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirements.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * PlotSquared, a land and world management plugin for Minecraft. - * Copyright (C) IntellectualSites - * Copyright (C) IntellectualSites team and contributors - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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 com.plotsquared.core.commands; - -import cloud.commandframework.keys.CloudKey; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Holder of {@link CommandRequirement} requirements. - */ -public final class CommandRequirements implements Iterable<@NonNull CommandRequirement> { - - /** - * The key used to store the requirements in the {@link cloud.commandframework.meta.CommandMeta}. - */ - public static final CloudKey REQUIREMENTS_KEY = CloudKey.of( - "requirements", - CommandRequirements.class - ); - - /** - * Creates a new instance. - * - * @param requirements the requirements - * @return the instance - */ - public static @NonNull CommandRequirements create(final @NonNull List<@NonNull CommandRequirement> requirements) { - return new CommandRequirements(requirements); - } - - private static @NonNull List<@NonNull CommandRequirement> extractRequirements( - final @NonNull List<@NonNull CommandRequirement> requirements - ) { - final List extractedRequirements = new ArrayList<>(); - for (final CommandRequirement requirement : requirements) { - extractedRequirements.addAll(extractRequirements(requirement.parents())); - extractedRequirements.add(requirement); - } - return extractedRequirements; - } - - private final List requirements; - - private CommandRequirements(final @NonNull List<@NonNull CommandRequirement> requirements) { - this.requirements = List.copyOf(extractRequirements(requirements)); - } - - @Override - public @NonNull Iterator<@NonNull CommandRequirement> iterator() { - return this.requirements.iterator(); - } -} diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java index e58da8b6e..30914c564 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -75,7 +75,7 @@ public enum CommonCommandRequirement implements CommandRequirement { } @Override - public boolean evaluate(final @NonNull CommandContext> context) { + public boolean evaluateRequirement(final @NonNull CommandContext> context) { return this.predicate.test(context); } } diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index 484b160d9..7859eb314 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -24,11 +24,16 @@ import cloud.commandframework.CommandProperties; import com.plotsquared.core.command.CommandCategory; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.requirement.RequirementApplicable; +import org.incendo.cloud.requirement.Requirements; import java.util.List; public abstract class PlotSquaredCommandBean extends CommandBean> { + private final RequirementApplicable.RequirementApplicableFactory, CommandRequirement> + requirementApplicableFactory = RequirementApplicable.factory(CommandRequirement.REQUIREMENTS_KEY); + /** * Returns the category of the command. * @@ -64,7 +69,7 @@ public abstract class PlotSquaredCommandBean extends CommandBean> @Override protected final Command.@NonNull Builder> configure(final Command.@NonNull Builder> builder) { return this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category()))) - .meta(CommandRequirements.REQUIREMENTS_KEY, CommandRequirements.create(this.requirements())); + .apply(this.requirementApplicableFactory.create(Requirements.of(this.requirements()))); } protected abstract Command.@NonNull Builder> configurePlotCommand( diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java new file mode 100644 index 000000000..50d26b1fd --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java @@ -0,0 +1,35 @@ +/* + * PlotSquared, a land and world management plugin for Minecraft. + * Copyright (C) IntellectualSites + * Copyright (C) IntellectualSites team and contributors + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 com.plotsquared.core.commands; + +import cloud.commandframework.context.CommandContext; +import com.plotsquared.core.player.PlotPlayer; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.requirement.RequirementFailureHandler; + +public final class PlotSquaredRequirementFailureHandler implements RequirementFailureHandler, CommandRequirement> { + + @Override + public void handleFailure( + final @NonNull CommandContext> context, + final @NonNull CommandRequirement requirement + ) { + context.sender().sendMessage(requirement.failureCaption(), requirement.tagResolvers()); + } +} diff --git a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java b/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java deleted file mode 100644 index 36fad14d1..000000000 --- a/Core/src/main/java/com/plotsquared/core/commands/processing/CommandRequirementPostprocessor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * PlotSquared, a land and world management plugin for Minecraft. - * Copyright (C) IntellectualSites - * Copyright (C) IntellectualSites team and contributors - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * 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 com.plotsquared.core.commands.processing; - -import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; -import cloud.commandframework.execution.postprocessor.CommandPostprocessor; -import cloud.commandframework.services.types.ConsumerService; -import com.plotsquared.core.commands.CommandRequirement; -import com.plotsquared.core.commands.CommandRequirements; -import com.plotsquared.core.player.PlotPlayer; -import org.checkerframework.checker.nullness.qual.NonNull; - -/** - * Processor that evaluates registered {@link CommandRequirement command requirements} before a command is executed. - */ -public final class CommandRequirementPostprocessor implements CommandPostprocessor> { - - @Override - public void accept(final @NonNull CommandPostprocessingContext> processingContext) { - final CommandRequirements requirements = processingContext.command().commandMeta().getOrDefault( - CommandRequirements.REQUIREMENTS_KEY, - null - ); - if (requirements == null) { - return; - } - for (final CommandRequirement requirement : requirements) { - if (requirement.evaluate(processingContext.commandContext())) { - continue; - } - processingContext.commandContext().sender().sendMessage(requirement.failureCaption(), requirement.tagResolvers()); - // Not allowed :( - ConsumerService.interrupt(); - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a5a7ccab0..37449159f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ informative-annotations = "1.4" vault = "1.7.1" serverlib = "2.3.4" cloud = "2.0.0-SNAPSHOT" +cloudRequirements = "1.0.0-SNAPSHOT" # Gradle plugins shadow = "8.1.1" @@ -81,6 +82,7 @@ serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.re cloud = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" } cloudPaper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" } cloudMinecraftExtras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" } +cloudRequirements = { group = "org.incendo", name = "cloud-requirements", version.ref = "cloudRequirements" } [plugins] shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } From 780c65e68c5e7d1d01f8c57e1429531d630b19b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Mon, 8 Jan 2024 05:53:35 +0100 Subject: [PATCH 08/13] migrate to cloud-processors-requirements --- .../main/java/com/plotsquared/bukkit/inject/CloudModule.java | 2 +- .../com/plotsquared/core/commands/CommandRequirement.java | 4 ++-- .../com/plotsquared/core/commands/PlotSquaredCommandBean.java | 4 ++-- .../core/commands/PlotSquaredRequirementFailureHandler.java | 2 +- gradle/libs.versions.toml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index dade29c3d..9a643f686 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -41,7 +41,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; -import org.incendo.cloud.requirement.RequirementPostprocessor; +import org.incendo.cloud.processors.requirements.RequirementPostprocessor; public class CloudModule extends AbstractModule { diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index d5a7bd8dc..e7dcf458a 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -27,8 +27,8 @@ import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; -import org.incendo.cloud.requirement.Requirement; -import org.incendo.cloud.requirement.Requirements; +import org.incendo.cloud.processors.requirements.Requirement; +import org.incendo.cloud.processors.requirements.Requirements; import java.util.List; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index 7859eb314..d59bb524c 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -24,8 +24,8 @@ import cloud.commandframework.CommandProperties; import com.plotsquared.core.command.CommandCategory; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; -import org.incendo.cloud.requirement.RequirementApplicable; -import org.incendo.cloud.requirement.Requirements; +import org.incendo.cloud.processors.requirements.RequirementApplicable; +import org.incendo.cloud.processors.requirements.Requirements; import java.util.List; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java index 50d26b1fd..5db8ceecb 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java @@ -21,7 +21,7 @@ package com.plotsquared.core.commands; import cloud.commandframework.context.CommandContext; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; -import org.incendo.cloud.requirement.RequirementFailureHandler; +import org.incendo.cloud.processors.requirements.RequirementFailureHandler; public final class PlotSquaredRequirementFailureHandler implements RequirementFailureHandler, CommandRequirement> { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 37449159f..50e794a30 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -82,7 +82,7 @@ serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.re cloud = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" } cloudPaper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" } cloudMinecraftExtras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" } -cloudRequirements = { group = "org.incendo", name = "cloud-requirements", version.ref = "cloudRequirements" } +cloudRequirements = { group = "org.incendo", name = "cloud-processors-requirements", version.ref = "cloudRequirements" } [plugins] shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } From 2a0ad92a97774ad2faa46fb10342e61745278fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Mon, 15 Jan 2024 07:54:26 +0100 Subject: [PATCH 09/13] use cloud snapshot --- Core/src/main/java/com/plotsquared/core/command/Auto.java | 2 +- build.gradle.kts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Auto.java b/Core/src/main/java/com/plotsquared/core/command/Auto.java index 230ed9e3a..600ba96d2 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Auto.java +++ b/Core/src/main/java/com/plotsquared/core/command/Auto.java @@ -332,7 +332,7 @@ public class Auto extends SubCommand { List plots = this.servicePipeline .pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea)) .through(AutoService.class) - .getResult(); + .complete(); plots = this.eventDispatcher.callAutoPlotsChosen(player, plots).getPlots(); diff --git a/build.gradle.kts b/build.gradle.kts index 55ba0b292..dd52cc123 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,6 @@ subprojects { version = rootProject.version repositories { - mavenLocal() // TODO(City): Remove once Cloud 2 is on central. mavenCentral() maven { From a65983261380fa577d18041d652d68e19b85aca2 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Mon, 29 Jan 2024 15:04:53 +0100 Subject: [PATCH 10/13] update cloud --- .../java/com/plotsquared/core/command/Auto.java | 2 +- .../core/commands/CommandRequirement.java | 6 +++--- .../core/commands/CommonCommandRequirement.java | 2 +- .../commands/PlotSquaredCaptionProvider.java | 4 ++-- .../core/commands/PlotSquaredCommandBean.java | 6 +++--- .../core/commands/PlotSquaredCommandManager.java | 4 ++-- .../core/commands/PlotSquaredCommandMeta.java | 4 ++-- .../PlotSquaredRequirementFailureHandler.java | 2 +- .../command/setting/flag/FlagAddCommand.java | 8 ++++---- .../command/setting/flag/FlagCommandBean.java | 2 +- .../command/setting/flag/FlagInfoCommand.java | 6 +++--- .../command/setting/flag/FlagListCommand.java | 4 ++-- .../command/setting/flag/FlagRemoveCommand.java | 8 ++++---- .../command/setting/flag/FlagSetCommand.java | 8 ++++---- .../core/commands/injection/PlotInjector.java | 6 +++--- .../core/commands/parser/PlotFlagParser.java | 16 ++++++++-------- .../suggestions/FlagValueSuggestionProvider.java | 14 +++++++++----- .../caption/TranslatableCaption.java | 2 +- .../core/services/plots/AutoService.java | 2 +- gradle/libs.versions.toml | 12 ++++++------ 20 files changed, 61 insertions(+), 57 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/command/Auto.java b/Core/src/main/java/com/plotsquared/core/command/Auto.java index 600ba96d2..8008c3b53 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Auto.java +++ b/Core/src/main/java/com/plotsquared/core/command/Auto.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core.command; -import cloud.commandframework.services.ServicePipeline; import com.google.inject.Inject; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; @@ -49,6 +48,7 @@ import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.services.ServicePipeline; import java.util.Collections; import java.util.Iterator; diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java index e7dcf458a..e5ea95ee5 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommandRequirement.java @@ -18,8 +18,6 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; @@ -27,6 +25,8 @@ import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; import org.incendo.cloud.processors.requirements.Requirement; import org.incendo.cloud.processors.requirements.Requirements; @@ -38,7 +38,7 @@ import java.util.List; public interface CommandRequirement extends Requirement, CommandRequirement> { /** - * The key used to store the requirements in the {@link cloud.commandframework.meta.CommandMeta}. + * The key used to store the requirements in the {@link org.incendo.cloud.meta.CommandMeta}. */ CloudKey, CommandRequirement>> REQUIREMENTS_KEY = CloudKey.of( "requirements", diff --git a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java index 30914c564..8f4708bdf 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java +++ b/Core/src/main/java/com/plotsquared/core/commands/CommonCommandRequirement.java @@ -18,10 +18,10 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.context.CommandContext; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.context.CommandContext; import java.util.Arrays; import java.util.List; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java index 9e1f4e6a7..737cbdc57 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCaptionProvider.java @@ -18,8 +18,6 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.captions.Caption; -import cloud.commandframework.captions.CaptionProvider; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.caption.CaptionMap; import com.plotsquared.core.configuration.caption.TranslatableCaption; @@ -28,6 +26,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.caption.Caption; +import org.incendo.cloud.caption.CaptionProvider; /** * {@link CaptionProvider} that retrieves caption values from the {@link CaptionMap caption map}. diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java index d59bb524c..37989cba7 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandBean.java @@ -18,12 +18,12 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.Command; -import cloud.commandframework.CommandBean; -import cloud.commandframework.CommandProperties; import com.plotsquared.core.command.CommandCategory; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.bean.CommandBean; +import org.incendo.cloud.bean.CommandProperties; import org.incendo.cloud.processors.requirements.RequirementApplicable; import org.incendo.cloud.processors.requirements.Requirements; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java index 031413c96..ad5ec2d4e 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandManager.java @@ -18,8 +18,6 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.CommandManager; -import cloud.commandframework.annotations.injection.GuiceInjectionService; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; @@ -29,6 +27,8 @@ import com.plotsquared.core.commands.injection.PlotInjector; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.injection.GuiceInjectionService; import java.util.Set; diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java index e219deeed..0234b2c7c 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredCommandMeta.java @@ -18,11 +18,11 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.command.CommandCategory; +import org.incendo.cloud.key.CloudKey; /** - * Shared {@link cloud.commandframework.meta.CommandMeta command meta} keys. + * Shared {@link org.incendo.cloud.meta.CommandMeta command meta} keys. */ public final class PlotSquaredCommandMeta { diff --git a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java index 5db8ceecb..34605924e 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java +++ b/Core/src/main/java/com/plotsquared/core/commands/PlotSquaredRequirementFailureHandler.java @@ -18,9 +18,9 @@ */ package com.plotsquared.core.commands; -import cloud.commandframework.context.CommandContext; import com.plotsquared.core.player.PlotPlayer; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.processors.requirements.RequirementFailureHandler; public final class PlotSquaredRequirementFailureHandler implements RequirementFailureHandler, CommandRequirement> { diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java index 01d5f0f2d..3e5b53a36 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagAddCommand.java @@ -18,9 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.google.inject.Inject; import com.plotsquared.core.commands.parser.PlotFlagParser; import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; @@ -38,9 +35,12 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; -import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; public final class FlagAddCommand extends FlagCommandBean { diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java index d29bdcb83..cc0435519 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagCommandBean.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.command.CommandCategory; import com.plotsquared.core.commands.CommandRequirement; @@ -37,6 +36,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; import java.util.List; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java index b92722a14..019da916b 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagInfoCommand.java @@ -18,9 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.commands.parser.PlotFlagParser; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; @@ -30,6 +27,9 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java index 703dd9981..215685b52 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagListCommand.java @@ -18,8 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; import com.plotsquared.core.configuration.caption.StaticCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; @@ -33,6 +31,8 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; import java.util.ArrayList; import java.util.Collection; diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java index b1abd2833..1245c43ea 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagRemoveCommand.java @@ -18,9 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.google.inject.Inject; import com.plotsquared.core.commands.parser.PlotFlagParser; import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; @@ -40,13 +37,16 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; public final class FlagRemoveCommand extends FlagCommandBean { diff --git a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java index b9dc711b0..b8790cde6 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java +++ b/Core/src/main/java/com/plotsquared/core/commands/command/setting/flag/FlagSetCommand.java @@ -18,9 +18,6 @@ */ package com.plotsquared.core.commands.command.setting.flag; -import cloud.commandframework.Command; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.keys.CloudKey; import com.google.inject.Inject; import com.plotsquared.core.commands.parser.PlotFlagParser; import com.plotsquared.core.commands.suggestions.FlagValueSuggestionProvider; @@ -38,9 +35,12 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.Command; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.key.CloudKey; -import static cloud.commandframework.arguments.standard.StringParser.greedyStringParser; import static com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; +import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; public final class FlagSetCommand extends FlagCommandBean { diff --git a/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java index 4c9eadab0..23a3c2e89 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java +++ b/Core/src/main/java/com/plotsquared/core/commands/injection/PlotInjector.java @@ -18,13 +18,13 @@ */ package com.plotsquared.core.commands.injection; -import cloud.commandframework.annotations.AnnotationAccessor; -import cloud.commandframework.annotations.injection.ParameterInjector; -import cloud.commandframework.context.CommandContext; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.injection.ParameterInjector; +import org.incendo.cloud.util.annotation.AnnotationAccessor; /** * {@link ParameterInjector} that returns the current plot of the player. diff --git a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java index 101149ba6..41077f140 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java +++ b/Core/src/main/java/com/plotsquared/core/commands/parser/PlotFlagParser.java @@ -18,14 +18,6 @@ */ package com.plotsquared.core.commands.parser; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.arguments.parser.ParserDescriptor; -import cloud.commandframework.arguments.suggestion.BlockingSuggestionProvider; -import cloud.commandframework.arguments.suggestion.Suggestion; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.context.CommandInput; -import cloud.commandframework.exceptions.parsing.ParserException; import com.plotsquared.core.configuration.caption.LocaleHolder; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.PlotPlayer; @@ -38,6 +30,14 @@ import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.util.ComponentMessageThrowable; import org.checkerframework.checker.nullness.qual.NonNull; +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.suggestion.BlockingSuggestionProvider; +import org.incendo.cloud.suggestion.Suggestion; import java.util.Collection; import java.util.function.Function; diff --git a/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java index 0c86b1ce0..2eba3716c 100644 --- a/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java +++ b/Core/src/main/java/com/plotsquared/core/commands/suggestions/FlagValueSuggestionProvider.java @@ -18,16 +18,20 @@ */ package com.plotsquared.core.commands.suggestions; -import cloud.commandframework.arguments.suggestion.BlockingSuggestionProvider; -import cloud.commandframework.context.CommandContext; -import cloud.commandframework.context.CommandInput; -import cloud.commandframework.keys.CloudKey; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.types.ListFlag; 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.suggestion.BlockingSuggestionProvider; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** diff --git a/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java b/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java index a8193e271..28e1aec43 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/caption/TranslatableCaption.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core.configuration.caption; -import cloud.commandframework.captions.Caption; import com.google.common.base.Objects; import com.plotsquared.core.PlotSquared; import net.kyori.adventure.text.Component; @@ -26,6 +25,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.caption.Caption; import org.jetbrains.annotations.NotNull; import java.util.Locale; diff --git a/Core/src/main/java/com/plotsquared/core/services/plots/AutoService.java b/Core/src/main/java/com/plotsquared/core/services/plots/AutoService.java index b2fdb1441..4ed178e72 100644 --- a/Core/src/main/java/com/plotsquared/core/services/plots/AutoService.java +++ b/Core/src/main/java/com/plotsquared/core/services/plots/AutoService.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core.services.plots; -import cloud.commandframework.services.types.Service; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.plotsquared.core.plot.Plot; @@ -26,6 +25,7 @@ import com.plotsquared.core.plot.PlotAreaType; import com.plotsquared.core.plot.PlotId; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.services.type.Service; import java.util.Collections; import java.util.List; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 50e794a30..4295d9e80 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,8 +31,8 @@ paperlib = "1.0.8" informative-annotations = "1.4" vault = "1.7.1" serverlib = "2.3.4" -cloud = "2.0.0-SNAPSHOT" -cloudRequirements = "1.0.0-SNAPSHOT" +cloud = "2.0.0-beta.1" +cloudRequirements = "1.0.0-beta.1" # Gradle plugins shadow = "8.1.1" @@ -68,7 +68,7 @@ faweBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukk # Third party prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } -cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } +cloudServices = { group = "org.incendo", name = "cloud-services", version.ref = "cloud-services" } mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } @@ -79,9 +79,9 @@ informativeAnnotations = { group = "com.intellectualsites.informative-annotation paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } -cloud = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" } -cloudPaper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" } -cloudMinecraftExtras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" } +cloud = { group = "org.incendo", name = "cloud-core", version.ref = "cloud" } +cloudPaper = { group = "org.incendo", name = "cloud-paper", version.ref = "cloud" } +cloudMinecraftExtras = { group = "org.incendo", name = "cloud-minecraft-extras", version.ref = "cloud" } cloudRequirements = { group = "org.incendo", name = "cloud-processors-requirements", version.ref = "cloudRequirements" } [plugins] From e0c7c58aaaa433fc65af7ec7f3e3a75a60ee0026 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Mon, 29 Jan 2024 15:26:13 +0100 Subject: [PATCH 11/13] fix remaining change --- .../com/plotsquared/core/inject/modules/PlotSquaredModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/plotsquared/core/inject/modules/PlotSquaredModule.java b/Core/src/main/java/com/plotsquared/core/inject/modules/PlotSquaredModule.java index 05f3478bc..623c36197 100644 --- a/Core/src/main/java/com/plotsquared/core/inject/modules/PlotSquaredModule.java +++ b/Core/src/main/java/com/plotsquared/core/inject/modules/PlotSquaredModule.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core.inject.modules; -import cloud.commandframework.services.ServicePipeline; import com.google.inject.AbstractModule; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.file.YamlConfiguration; @@ -31,6 +30,7 @@ import com.plotsquared.core.listener.PlotListener; import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.uuid.UUIDPipeline; import com.sk89q.worldedit.WorldEdit; +import org.incendo.cloud.services.ServicePipeline; import java.io.File; From 628c520c1bb46e2c441a71ae168b95f6bcc82ae9 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Mon, 29 Jan 2024 15:29:18 +0100 Subject: [PATCH 12/13] fix remaining change (2) --- Core/src/main/java/com/plotsquared/core/PlotPlatform.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/plotsquared/core/PlotPlatform.java b/Core/src/main/java/com/plotsquared/core/PlotPlatform.java index 958468098..65980e677 100644 --- a/Core/src/main/java/com/plotsquared/core/PlotPlatform.java +++ b/Core/src/main/java/com/plotsquared/core/PlotPlatform.java @@ -18,7 +18,6 @@ */ package com.plotsquared.core; -import cloud.commandframework.services.ServicePipeline; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.TypeLiteral; @@ -47,6 +46,7 @@ import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.services.ServicePipeline; import java.io.File; From c8e5cf163f7463637d6166f68cfd1dc723c20c05 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Mon, 29 Jan 2024 15:35:33 +0100 Subject: [PATCH 13/13] fix remaining change (3) --- .../bukkit/commands/BukkitSenderMapper.java | 2 +- .../com/plotsquared/bukkit/inject/CloudModule.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java b/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java index 692a04066..1474f9a99 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/commands/BukkitSenderMapper.java @@ -18,7 +18,6 @@ */ package com.plotsquared.bukkit.commands; -import cloud.commandframework.SenderMapper; import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.PlotPlayer; @@ -26,6 +25,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.SenderMapper; /** * Mapper between {@link CommandSender} and {@link PlotPlayer}. diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java index 9a643f686..87c16642c 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/CloudModule.java @@ -18,11 +18,6 @@ */ package com.plotsquared.bukkit.inject; -import cloud.commandframework.CommandManager; -import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.execution.ExecutionCoordinator; -import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler; -import cloud.commandframework.paper.PaperCommandManager; import com.google.inject.AbstractModule; import com.google.inject.Key; import com.google.inject.TypeLiteral; @@ -41,6 +36,11 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.CommandManager; +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 org.incendo.cloud.processors.requirements.RequirementPostprocessor; public class CloudModule extends AbstractModule {