mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-25 07:33:44 +02:00 
			
		
		
		
	Compare commits
	
		
			13 Commits
		
	
	
		
			grant-plac
			...
			feature/cl
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | c8e5cf163f | ||
|   | 628c520c1b | ||
|   | e0c7c58aaa | ||
|   | a659832613 | ||
|   | 2a0ad92a97 | ||
|   | 780c65e68c | ||
|   | 92a00ef60a | ||
|   | 3a1b373c8e | ||
|   | 1a277bbbeb | ||
|   | 24d7fe626d | ||
|   | b62a237dab | ||
|   | 2ac2f6648e | ||
|   | 6088dd8409 | 
| @@ -53,6 +53,9 @@ dependencies { | ||||
|  | ||||
|     // Adventure | ||||
|     implementation(libs.adventureBukkit) | ||||
|  | ||||
|     // Cloud | ||||
|     implementation(libs.cloudPaper) | ||||
| } | ||||
|  | ||||
| tasks.processResources { | ||||
| @@ -77,6 +80,7 @@ tasks.named<ShadowJar>("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") | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.bukkit.commands; | ||||
|  | ||||
| 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; | ||||
| import org.incendo.cloud.SenderMapper; | ||||
|  | ||||
| /** | ||||
|  * Mapper between {@link CommandSender} and {@link PlotPlayer}. | ||||
|  */ | ||||
| public final class BukkitSenderMapper implements SenderMapper<CommandSender, PlotPlayer<?>> { | ||||
|  | ||||
|     @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(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.bukkit.inject; | ||||
|  | ||||
| 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.CommandRequirement; | ||||
| import com.plotsquared.core.commands.PlotSquaredCaptionProvider; | ||||
| 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; | ||||
| 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; | ||||
| 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 { | ||||
|  | ||||
|     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() { | ||||
|         final PaperCommandManager<PlotPlayer<?>> commandManager = new PaperCommandManager<PlotPlayer<?>>( | ||||
|                 this.bukkitPlatform, | ||||
|                 ExecutionCoordinator.asyncCoordinator(), | ||||
|                 new BukkitSenderMapper() | ||||
|         ); | ||||
|         commandManager.captionRegistry().registerProvider(new PlotSquaredCaptionProvider()); | ||||
|  | ||||
|         if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { | ||||
|             commandManager.registerBrigadier(); | ||||
|         } else if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { | ||||
|             commandManager.registerAsynchronousCompletions(); | ||||
|         } | ||||
|  | ||||
|         final RequirementPostprocessor<PlotPlayer<?>, CommandRequirement> requirementPostprocessor = | ||||
|                 RequirementPostprocessor.of(CommandRequirement.REQUIREMENTS_KEY, new PlotSquaredRequirementFailureHandler()); | ||||
|         commandManager.registerCommandPostProcessor(requirementPostprocessor); | ||||
|  | ||||
|         // TODO(City): Override parsing errors using MM parsing. | ||||
|         MinecraftExceptionHandler.<PlotPlayer<?>>create(PlotPlayer::getAudience) | ||||
|                 .defaultHandlers() | ||||
|                 .decorator((ctx, component) -> TranslatableCaption.of("core.prefix"). | ||||
|                         toComponent(ctx.context().sender()) | ||||
|                         .append(component)) | ||||
|                 .registerTo(commandManager); | ||||
|  | ||||
|         bind(Key.get(new TypeLiteral<CommandManager<PlotPlayer<?>>>() {})).toInstance(commandManager); | ||||
|     } | ||||
| } | ||||
| @@ -15,6 +15,11 @@ dependencies { | ||||
|     api(libs.adventureApi) | ||||
|     api(libs.adventureMiniMessage) | ||||
|  | ||||
|     // Cloud | ||||
|     api(libs.cloud) | ||||
|     api(libs.cloudMinecraftExtras) | ||||
|     api(libs.cloudRequirements) | ||||
|  | ||||
|     // Guice | ||||
|     api(libs.guice) { | ||||
|         exclude(group = "com.google.guava") | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| @@ -332,7 +332,7 @@ public class Auto extends SubCommand { | ||||
|         List<Plot> plots = this.servicePipeline | ||||
|                 .pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea)) | ||||
|                 .through(AutoService.class) | ||||
|                 .getResult(); | ||||
|                 .complete(); | ||||
|  | ||||
|         plots = this.eventDispatcher.callAutoPlotsChosen(player, plots).getPlots(); | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,98 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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.context.CommandContext; | ||||
| import org.incendo.cloud.key.CloudKey; | ||||
| import org.incendo.cloud.processors.requirements.Requirement; | ||||
| import org.incendo.cloud.processors.requirements.Requirements; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * Something that is required for a command to be executed. | ||||
|  */ | ||||
| public interface CommandRequirement extends Requirement<PlotPlayer<?>, CommandRequirement> { | ||||
|  | ||||
|     /** | ||||
|      * The key used to store the requirements in the {@link org.incendo.cloud.meta.CommandMeta}. | ||||
|      */ | ||||
|     CloudKey<Requirements<PlotPlayer<?>, CommandRequirement>> REQUIREMENTS_KEY = CloudKey.of( | ||||
|             "requirements", | ||||
|             new TypeToken<Requirements<PlotPlayer<?>, CommandRequirement>>() { | ||||
|             } | ||||
|     ); | ||||
|  | ||||
|     /** | ||||
|      * Returns the caption sent when the requirement is not met. | ||||
|      * | ||||
|      * @return the caption | ||||
|      */ | ||||
|     @NonNull TranslatableCaption failureCaption(); | ||||
|  | ||||
|     /** | ||||
|      * 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 @NonNull List<@NonNull CommandRequirement> parents() { | ||||
|                 return thisRequirement.parents(); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean evaluateRequirement(final @NonNull CommandContext<PlotPlayer<?>> context) { | ||||
|                 return context.sender().hasPermission(permission) || thisRequirement.evaluateRequirement(context); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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; | ||||
| 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().hasOwner(), | ||||
|             REQUIRES_PLOT | ||||
|     ), | ||||
|     /** | ||||
|      * Requires that the command sender is the plot owner. | ||||
|      */ | ||||
|     IS_OWNER(TranslatableCaption.of("permission.no_plot_perms"), | ||||
|             ctx -> ctx.sender().getCurrentPlot().isOwner(ctx.sender().getUUID()), | ||||
|             REQUIRES_OWNER | ||||
|     ) | ||||
|     ; | ||||
|  | ||||
|     private final TranslatableCaption failureCaption; | ||||
|     private final Predicate<CommandContext<PlotPlayer<?>>> predicate; | ||||
|     private final List<@NonNull CommandRequirement> parents; | ||||
|  | ||||
|     CommonCommandRequirement( | ||||
|             final @NonNull TranslatableCaption failureCaption, | ||||
|             final @NonNull Predicate<CommandContext<PlotPlayer<?>>> 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 evaluateRequirement(final @NonNull CommandContext<PlotPlayer<?>> context) { | ||||
|         return this.predicate.test(context); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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; | ||||
| import org.incendo.cloud.caption.Caption; | ||||
| import org.incendo.cloud.caption.CaptionProvider; | ||||
|  | ||||
| /** | ||||
|  * {@link CaptionProvider} that retrieves caption values from the {@link CaptionMap caption map}. | ||||
|  */ | ||||
| public final class PlotSquaredCaptionProvider implements CaptionProvider<PlotPlayer<?>> { | ||||
|  | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| public abstract class PlotSquaredCommandBean extends CommandBean<PlotPlayer<?>> { | ||||
|  | ||||
|     private final RequirementApplicable.RequirementApplicableFactory<PlotPlayer<?>, CommandRequirement> | ||||
|             requirementApplicableFactory = RequirementApplicable.factory(CommandRequirement.REQUIREMENTS_KEY); | ||||
|  | ||||
|     /** | ||||
|      * 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 List<@NonNull CommandRequirement> requirements(); | ||||
|  | ||||
|     /** | ||||
|      * Prepares the given {@code builder}. | ||||
|      * | ||||
|      * <p>This should be implemented by abstract classes that extend {@link PlotSquaredCommandBean} to offer shared behavior | ||||
|      * for a subset of plot commands.</p> | ||||
|      * | ||||
|      * @param builder the builder | ||||
|      * @return the prepared builder | ||||
|      */ | ||||
|     protected Command.@NonNull Builder<PlotPlayer<?>> prepare(final Command.@NonNull Builder<PlotPlayer<?>> builder) { | ||||
|         return builder; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected final @NonNull CommandProperties properties() { | ||||
|         return CommandProperties.of("platsquared", "plat"); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected final Command.@NonNull Builder<PlotPlayer<?>> configure(final Command.@NonNull Builder<PlotPlayer<?>> builder) { | ||||
|         return this.configurePlotCommand(this.prepare(builder.meta(PlotSquaredCommandMeta.META_CATEGORY, this.category()))) | ||||
|                 .apply(this.requirementApplicableFactory.create(Requirements.of(this.requirements()))); | ||||
|     } | ||||
|  | ||||
|     protected abstract Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand( | ||||
|             Command.@NonNull Builder<PlotPlayer<?>> builder | ||||
|     ); | ||||
| } | ||||
| @@ -0,0 +1,74 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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 org.incendo.cloud.CommandManager; | ||||
| import org.incendo.cloud.injection.GuiceInjectionService; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| @Singleton | ||||
| public final class PlotSquaredCommandManager { | ||||
|  | ||||
|     private final CommandManager<PlotPlayer<?>> commandManager; | ||||
|     private final Injector injector; | ||||
|  | ||||
|     @Inject | ||||
|     public PlotSquaredCommandManager( | ||||
|             final @NonNull CommandManager<PlotPlayer<?>> 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<PlotSquaredCommandBean> commands = | ||||
|                 this.injector.getInstance(Key.get(new TypeLiteral<Set<PlotSquaredCommandBean>>() {})); | ||||
|         commands.forEach(command -> this.commandManager().command(command)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the command manager. | ||||
|      * | ||||
|      * @return the command manager | ||||
|      */ | ||||
|     public @NonNull CommandManager<PlotPlayer<?>> 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)); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| import com.plotsquared.core.command.CommandCategory; | ||||
| import org.incendo.cloud.key.CloudKey; | ||||
|  | ||||
| /** | ||||
|  * Shared {@link org.incendo.cloud.meta.CommandMeta command meta} keys. | ||||
|  */ | ||||
| public final class PlotSquaredCommandMeta { | ||||
|  | ||||
|     /** | ||||
|      * Key that determines what {@link CommandCategory category} a command belongs to. | ||||
|      */ | ||||
|     public static final CloudKey<CommandCategory> META_CATEGORY = CloudKey.of("category", CommandCategory.class); | ||||
|  | ||||
|     private PlotSquaredCommandMeta() { | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands; | ||||
|  | ||||
| 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<PlotPlayer<?>, CommandRequirement> { | ||||
|  | ||||
|     @Override | ||||
|     public void handleFailure( | ||||
|             final @NonNull CommandContext<PlotPlayer<?>> context, | ||||
|             final @NonNull CommandRequirement requirement | ||||
|     ) { | ||||
|         context.sender().sendMessage(requirement.failureCaption(), requirement.tagResolvers()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,120 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 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; | ||||
| import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; | ||||
|  | ||||
| public final class FlagAddCommand extends FlagCommandBean { | ||||
|  | ||||
|     private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {}); | ||||
|     private static final CloudKey<String> 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<PlotPlayer<?>> configurePlotCommand( | ||||
|             final Command.@NonNull Builder<PlotPlayer<?>> 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<PlotPlayer<?>> 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() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,139 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 org.incendo.cloud.Command; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| 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 ".<amount>" 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<? extends List<?>, ?> 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 List<@NonNull CommandRequirement> requirements() { | ||||
|         return List.of(CommonCommandRequirement.IS_OWNER.withPermissionOverride(Permission.PERMISSION_SET_FLAG_OTHER)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected final Command.@NonNull Builder<PlotPlayer<?>> prepare(final Command.@NonNull Builder<PlotPlayer<?>> builder) { | ||||
|         return builder.literal("flag"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,88 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 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; | ||||
|  | ||||
| public final class FlagInfoCommand extends FlagCommandBean { | ||||
|  | ||||
|     private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {}); | ||||
|  | ||||
|     @Override | ||||
|     protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand(final Command.@NonNull Builder<PlotPlayer<?>> builder) { | ||||
|         return builder.literal("info") | ||||
|                 .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(final @NonNull CommandContext<PlotPlayer<?>> 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")); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 org.incendo.cloud.Command; | ||||
| import org.incendo.cloud.context.CommandContext; | ||||
|  | ||||
| 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<PlotPlayer<?>> configurePlotCommand( | ||||
|             final Command.@NonNull Builder<PlotPlayer<?>> builder | ||||
|     ) { | ||||
|         return builder.literal("list"); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(final @NonNull CommandContext<PlotPlayer<?>> commandContext) { | ||||
|         final PlotPlayer<?> player = commandContext.sender(); | ||||
|  | ||||
|         final Map<Component, ArrayList<String>> flags = new HashMap<>(); | ||||
|         for (PlotFlag<?, ?> plotFlag : GlobalFlagContainer.getInstance().getRecognizedPlotFlags()) { | ||||
|             if (plotFlag instanceof InternalFlag) { | ||||
|                 continue; | ||||
|             } | ||||
|             final Component category = plotFlag.getFlagCategory().toComponent(player); | ||||
|             final Collection<String> flagList = flags.computeIfAbsent(category, k -> new ArrayList<>()); | ||||
|             flagList.add(plotFlag.getName()); | ||||
|         } | ||||
|  | ||||
|         for (final Map.Entry<Component, ArrayList<String>> 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<String> 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()))); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,171 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 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 com.plotsquared.core.commands.parser.PlotFlagParser.plotFlagParser; | ||||
| import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; | ||||
|  | ||||
| public final class FlagRemoveCommand extends FlagCommandBean { | ||||
|  | ||||
|     private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {}); | ||||
|     private static final CloudKey<String> 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<PlotPlayer<?>> configurePlotCommand( | ||||
|             final Command.@NonNull Builder<PlotPlayer<?>> 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<PlotPlayer<?>> 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() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,110 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.command.setting.flag; | ||||
|  | ||||
| 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 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; | ||||
| import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; | ||||
|  | ||||
| public final class FlagSetCommand extends FlagCommandBean { | ||||
|  | ||||
|     private static final CloudKey<PlotFlag<?, ?>> COMPONENT_FLAG = CloudKey.of("flag", new TypeToken<PlotFlag<?, ?>>() {}); | ||||
|     private static final CloudKey<String> COMPONENT_VALUE = CloudKey.of("value", String.class); | ||||
|  | ||||
|     private final EventDispatcher eventDispatcher; | ||||
|  | ||||
|     @Inject | ||||
|     public FlagSetCommand(final @NonNull EventDispatcher eventDispatcher) { | ||||
|         this.eventDispatcher = eventDispatcher; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Command.@NonNull Builder<PlotPlayer<?>> configurePlotCommand( | ||||
|             final Command.@NonNull Builder<PlotPlayer<?>> builder | ||||
|     ) { | ||||
|         return builder.literal("set") | ||||
|                 .required(COMPONENT_FLAG, plotFlagParser(PlotFlagParser.FlagSource.GLOBAL)) | ||||
|                 .required(COMPONENT_VALUE, greedyStringParser(), new FlagValueSuggestionProvider(COMPONENT_FLAG)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void execute(final @NonNull CommandContext<PlotPlayer<?>> 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() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,42 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.injection; | ||||
|  | ||||
| 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. | ||||
|  */ | ||||
| public final class PlotInjector implements ParameterInjector<PlotPlayer<?>, Plot> { | ||||
|  | ||||
|     @Override | ||||
|     public @Nullable Plot create( | ||||
|             final @NonNull CommandContext<PlotPlayer<?>> context, | ||||
|             final @NonNull AnnotationAccessor annotationAccessor | ||||
|     ) { | ||||
|         // TODO: Allow for overriding for console. | ||||
|         return context.sender().getCurrentPlot(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,158 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.parser; | ||||
|  | ||||
| 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; | ||||
| 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; | ||||
|  | ||||
| /** | ||||
|  * Parser that parses and suggests {@link PlotFlag plot flags}. | ||||
|  */ | ||||
| public final class PlotFlagParser implements ArgumentParser<PlotPlayer<?>, PlotFlag<?, ?>>, | ||||
|         BlockingSuggestionProvider<PlotPlayer<?>> { | ||||
|  | ||||
|     /** | ||||
|      * 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<PlotPlayer<?>, PlotFlag<?, ?>> plotFlagParser(final @NonNull FlagSource source) { | ||||
|         return ParserDescriptor.of(new PlotFlagParser(source), new TypeToken<PlotFlag<?, ?>>() { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     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, | ||||
|             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<PlotPlayer<?>> context, | ||||
|             final @NonNull CommandInput input | ||||
|     ) { | ||||
|         return this.flagSource.flags(context.sender()) | ||||
|                 .stream() | ||||
|                 .filter(flag -> (!(flag instanceof InternalFlag))) | ||||
|                 .map(PlotFlag::getName) | ||||
|                 .map(Suggestion::simple) | ||||
|                 .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<PlotPlayer<?>, FlagContainer> containerFunction; | ||||
|         private final boolean storedOnly; | ||||
|  | ||||
|         FlagSource(final @NonNull Function<PlotPlayer<?>, 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. | ||||
|      */ | ||||
|     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()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package com.plotsquared.core.commands.suggestions; | ||||
|  | ||||
| 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.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
|  * Suggestion provider that provides context-aware {@link PlotFlag plot flag} value suggestions using | ||||
|  * {@link PlotFlag#getTabCompletions()}. | ||||
|  */ | ||||
| public final class FlagValueSuggestionProvider implements BlockingSuggestionProvider.Strings<PlotPlayer<?>> { | ||||
|  | ||||
|     private final CloudKey<PlotFlag<?, ?>> 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<PlotFlag<?, ?>> flagKey) { | ||||
|         this.flagKey = Objects.requireNonNull(flagKey, "flagKey"); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public @NonNull Iterable<@NonNull String> stringSuggestions( | ||||
|             @NonNull final CommandContext<PlotPlayer<?>> context, | ||||
|             @NonNull final CommandInput input | ||||
|     ) { | ||||
|         final PlotFlag<?, ?> plotFlag = context.getOrDefault(this.flagKey, null); | ||||
|         if (plotFlag == null) { | ||||
|             return List.of(); | ||||
|         } | ||||
|         final Collection<String> completions = plotFlag.getTabCompletions(); | ||||
|         if (plotFlag instanceof ListFlag<?,?> && input.peekString().contains(",")) { | ||||
|             final String[] split = input.peekString().split(","); | ||||
|             final List<String> existingValues = new ArrayList<>(Arrays.asList(split)); | ||||
|  | ||||
|             final String completingValue; | ||||
|             if (!input.peekString().endsWith(",")) { | ||||
|                 // In this case we want to complete the value we're currently typing. | ||||
|                 completingValue = split[split.length - 1]; | ||||
|                 existingValues.remove(existingValues.size() - 1); | ||||
|             } else { | ||||
|                 completingValue = null; | ||||
|             } | ||||
|  | ||||
|             final String prefix = existingValues.stream().collect(Collectors.joining(",", "", ",")); | ||||
|             return completions.stream() | ||||
|                     .filter(value -> !existingValues.contains(value)) | ||||
|                     .filter(value -> completingValue == null || value.startsWith(completingValue)) | ||||
|                     .map(value -> prefix + value) | ||||
|                     .toList(); | ||||
|         } | ||||
|         return completions; | ||||
|     } | ||||
| } | ||||
| @@ -25,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; | ||||
| @@ -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 | ||||
|      * | ||||
|   | ||||
| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * PlotSquared, a land and world management plugin for Minecraft. | ||||
|  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||
|  * 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 <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 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; | ||||
|  | ||||
| public final class CommandModule extends AbstractModule { | ||||
|  | ||||
|     @Override | ||||
|     protected void configure() { | ||||
|         final Multibinder<PlotSquaredCommandBean> commands = Multibinder.newSetBinder( | ||||
|                 this.binder(), | ||||
|                 PlotSquaredCommandBean.class | ||||
|         ); | ||||
|  | ||||
|         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); | ||||
|     } | ||||
| } | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -31,6 +31,8 @@ paperlib = "1.0.8" | ||||
| informative-annotations = "1.4" | ||||
| vault = "1.7.1" | ||||
| serverlib = "2.3.4" | ||||
| cloud = "2.0.0-beta.1" | ||||
| cloudRequirements = "1.0.0-beta.1" | ||||
|  | ||||
| # Gradle plugins | ||||
| shadow = "8.1.1" | ||||
| @@ -66,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" } | ||||
| @@ -77,6 +79,10 @@ 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 = "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] | ||||
| shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user