mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-22 14:13:44 +02:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			fix/big-bo
			...
			feature/v7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 99133ee485 | ||
|   | e415dcc8a4 | ||
|   | f2da7cbdc9 | ||
|   | f175c24523 | ||
|   | f3f44b55c4 | ||
|   | b946f31fe3 | ||
|   | 6bb1ebe1a1 | ||
|   | ab64836fc0 | ||
|   | d932d2eae6 | 
| @@ -53,6 +53,10 @@ dependencies { | |||||||
|  |  | ||||||
|     // Adventure |     // Adventure | ||||||
|     implementation("net.kyori:adventure-platform-bukkit") |     implementation("net.kyori:adventure-platform-bukkit") | ||||||
|  |  | ||||||
|  |     // Cloud | ||||||
|  |     implementation(libs.cloudPaper) | ||||||
|  |     implementation(libs.cloudMinecraftExtras) | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.processResources { | tasks.processResources { | ||||||
|   | |||||||
| @@ -63,6 +63,7 @@ import com.plotsquared.bukkit.uuid.SquirrelIdUUIDService; | |||||||
| import com.plotsquared.core.PlotPlatform; | import com.plotsquared.core.PlotPlatform; | ||||||
| import com.plotsquared.core.PlotSquared; | import com.plotsquared.core.PlotSquared; | ||||||
| import com.plotsquared.core.backup.BackupManager; | import com.plotsquared.core.backup.BackupManager; | ||||||
|  | import com.plotsquared.core.commands.PlotSquaredCommandManager; | ||||||
| import com.plotsquared.core.components.ComponentPresetManager; | import com.plotsquared.core.components.ComponentPresetManager; | ||||||
| import com.plotsquared.core.configuration.ConfigurationNode; | import com.plotsquared.core.configuration.ConfigurationNode; | ||||||
| import com.plotsquared.core.configuration.ConfigurationSection; | import com.plotsquared.core.configuration.ConfigurationSection; | ||||||
| @@ -215,6 +216,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|     @Inject |     @Inject | ||||||
|     private PlatformWorldManager<World> worldManager; |     private PlatformWorldManager<World> worldManager; | ||||||
|     private Locale serverLocale; |     private Locale serverLocale; | ||||||
|  |     @Inject | ||||||
|  |     private PlotSquaredCommandManager commandManager; | ||||||
|  |  | ||||||
|     @SuppressWarnings("StringSplitter") |     @SuppressWarnings("StringSplitter") | ||||||
|     @Override |     @Override | ||||||
| @@ -382,6 +385,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|         // Commands |         // Commands | ||||||
|         if (Settings.Enabled_Components.COMMANDS) { |         if (Settings.Enabled_Components.COMMANDS) { | ||||||
|             this.registerCommands(); |             this.registerCommands(); | ||||||
|  |             this.commandManager.initializeCommands(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Permissions |         // Permissions | ||||||
|   | |||||||
| @@ -18,12 +18,16 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.bukkit.inject; | package com.plotsquared.bukkit.inject; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.CommandManager; | ||||||
|  | import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator; | ||||||
|  | import cloud.commandframework.paper.PaperCommandManager; | ||||||
| import com.google.inject.AbstractModule; | import com.google.inject.AbstractModule; | ||||||
| import com.google.inject.Provides; | import com.google.inject.Provides; | ||||||
| import com.google.inject.Singleton; | import com.google.inject.Singleton; | ||||||
| import com.google.inject.assistedinject.FactoryModuleBuilder; | import com.google.inject.assistedinject.FactoryModuleBuilder; | ||||||
| import com.plotsquared.bukkit.BukkitPlatform; | import com.plotsquared.bukkit.BukkitPlatform; | ||||||
| import com.plotsquared.bukkit.listener.SingleWorldListener; | import com.plotsquared.bukkit.listener.SingleWorldListener; | ||||||
|  | import com.plotsquared.bukkit.player.BukkitPlayer; | ||||||
| import com.plotsquared.bukkit.player.BukkitPlayerManager; | import com.plotsquared.bukkit.player.BukkitPlayerManager; | ||||||
| import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; | import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; | ||||||
| import com.plotsquared.bukkit.queue.BukkitQueueCoordinator; | import com.plotsquared.bukkit.queue.BukkitQueueCoordinator; | ||||||
| @@ -47,6 +51,8 @@ import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory; | |||||||
| import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; | import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; | ||||||
| import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; | import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; | ||||||
| import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; | import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; | ||||||
|  | import com.plotsquared.core.player.ConsolePlayer; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.world.DefaultPlotAreaManager; | import com.plotsquared.core.plot.world.DefaultPlotAreaManager; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.plot.world.SinglePlotAreaManager; | import com.plotsquared.core.plot.world.SinglePlotAreaManager; | ||||||
| @@ -68,10 +74,14 @@ import com.sk89q.worldedit.extension.platform.Actor; | |||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.bukkit.Bukkit; | import org.bukkit.Bukkit; | ||||||
|  | import org.bukkit.command.CommandSender; | ||||||
| import org.bukkit.command.ConsoleCommandSender; | import org.bukkit.command.ConsoleCommandSender; | ||||||
|  | import org.bukkit.entity.Player; | ||||||
| import org.bukkit.plugin.java.JavaPlugin; | import org.bukkit.plugin.java.JavaPlugin; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.function.Function; | ||||||
|  |  | ||||||
| public class BukkitModule extends AbstractModule { | public class BukkitModule extends AbstractModule { | ||||||
|  |  | ||||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName()); |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName()); | ||||||
| @@ -145,4 +155,27 @@ public class BukkitModule extends AbstractModule { | |||||||
|         return EconHandler.nullEconHandler(); |         return EconHandler.nullEconHandler(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Provides | ||||||
|  |     @Singleton | ||||||
|  |     @NonNull CommandManager<PlotPlayer<?>> provideCommandManager() throws Exception { | ||||||
|  |         final Function<PlotPlayer<?>, CommandSender> plotToPlatform = plotPlayer -> { | ||||||
|  |             if (plotPlayer instanceof BukkitPlayer bukkitPlayer) { | ||||||
|  |                 return bukkitPlayer.getPlatformPlayer(); | ||||||
|  |             } | ||||||
|  |             return Bukkit.getConsoleSender(); | ||||||
|  |         }; | ||||||
|  |         final Function<CommandSender, PlotPlayer<?>> platformToPlot = commandSender -> { | ||||||
|  |             if (commandSender instanceof Player player) { | ||||||
|  |                 return BukkitUtil.adapt(player); | ||||||
|  |             } | ||||||
|  |             return ConsolePlayer.getConsole(); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         return new PaperCommandManager<>( | ||||||
|  |                 this.bukkitPlatform, | ||||||
|  |                 AsynchronousCommandExecutionCoordinator.<PlotPlayer<?>>builder().withSynchronousParsing().build(), | ||||||
|  |                 platformToPlot, | ||||||
|  |                 plotToPlatform | ||||||
|  |         ); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,6 +15,11 @@ dependencies { | |||||||
|     api("net.kyori:adventure-api") |     api("net.kyori:adventure-api") | ||||||
|     api("net.kyori:adventure-text-minimessage") |     api("net.kyori:adventure-text-minimessage") | ||||||
|  |  | ||||||
|  |     // Cloud | ||||||
|  |     api(libs.cloudServices) | ||||||
|  |     api(libs.cloudCore) | ||||||
|  |     api(libs.cloudAnnotations) | ||||||
|  |  | ||||||
|     // Guice |     // Guice | ||||||
|     api(libs.guice) { |     api(libs.guice) { | ||||||
|         exclude(group = "com.google.guava") |         exclude(group = "com.google.guava") | ||||||
| @@ -40,7 +45,6 @@ dependencies { | |||||||
|     // Other libraries |     // Other libraries | ||||||
|     api(libs.prtree) |     api(libs.prtree) | ||||||
|     api(libs.aopalliance) |     api(libs.aopalliance) | ||||||
|     api(libs.cloudServices) |  | ||||||
|     api(libs.arkitektonika) |     api(libs.arkitektonika) | ||||||
|     api("com.intellectualsites.paster:Paster") |     api("com.intellectualsites.paster:Paster") | ||||||
|     api("com.intellectualsites.informative-annotations:informative-annotations") |     api("com.intellectualsites.informative-annotations:informative-annotations") | ||||||
|   | |||||||
| @@ -1,172 +0,0 @@ | |||||||
| /* |  | ||||||
|  * 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.command; |  | ||||||
|  |  | ||||||
| import com.google.inject.Inject; |  | ||||||
| import com.plotsquared.core.configuration.Settings; |  | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; |  | ||||||
| import com.plotsquared.core.database.DBFunc; |  | ||||||
| import com.plotsquared.core.permissions.Permission; |  | ||||||
| import com.plotsquared.core.player.PlotPlayer; |  | ||||||
| import com.plotsquared.core.plot.Plot; |  | ||||||
| import com.plotsquared.core.util.EventDispatcher; |  | ||||||
| import com.plotsquared.core.util.PlayerManager; |  | ||||||
| import com.plotsquared.core.util.TabCompletions; |  | ||||||
| import com.plotsquared.core.util.task.RunnableVal2; |  | ||||||
| import com.plotsquared.core.util.task.RunnableVal3; |  | ||||||
| import net.kyori.adventure.text.Component; |  | ||||||
| import net.kyori.adventure.text.minimessage.tag.Tag; |  | ||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; |  | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; |  | ||||||
|  |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.Iterator; |  | ||||||
| import java.util.UUID; |  | ||||||
| import java.util.concurrent.CompletableFuture; |  | ||||||
| import java.util.concurrent.TimeoutException; |  | ||||||
|  |  | ||||||
| @CommandDeclaration(command = "add", |  | ||||||
|         usage = "/plot add <player | *>", |  | ||||||
|         category = CommandCategory.SETTINGS, |  | ||||||
|         permission = "plots.add", |  | ||||||
|         requiredType = RequiredType.PLAYER) |  | ||||||
| public class Add extends Command { |  | ||||||
|  |  | ||||||
|     private final EventDispatcher eventDispatcher; |  | ||||||
|  |  | ||||||
|     @Inject |  | ||||||
|     public Add(final @NonNull EventDispatcher eventDispatcher) { |  | ||||||
|         super(MainCommand.getInstance(), true); |  | ||||||
|         this.eventDispatcher = eventDispatcher; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public CompletableFuture<Boolean> execute( |  | ||||||
|             final PlotPlayer<?> player, |  | ||||||
|             String[] args, |  | ||||||
|             RunnableVal3<Command, Runnable, Runnable> confirm, |  | ||||||
|             RunnableVal2<Command, CommandResult> whenDone |  | ||||||
|     ) throws CommandException { |  | ||||||
|         final Plot plot = check(player.getCurrentPlot(), TranslatableCaption.of("errors.not_in_plot")); |  | ||||||
|         checkTrue(plot.hasOwner(), TranslatableCaption.of("info.plot_unowned")); |  | ||||||
|         checkTrue( |  | ||||||
|                 plot.isOwner(player.getUUID()) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST), |  | ||||||
|                 TranslatableCaption.of("permission.no_plot_perms") |  | ||||||
|         ); |  | ||||||
|         checkTrue(args.length == 1, |  | ||||||
|                 TranslatableCaption.of("commandconfig.command_syntax"), |  | ||||||
|                 TagResolver.resolver("value", Tag.inserting(Component.text("/plot add <player | *>"))) |  | ||||||
|         ); |  | ||||||
|         final CompletableFuture<Boolean> future = new CompletableFuture<>(); |  | ||||||
|         PlayerManager.getUUIDsFromString(args[0], (uuids, throwable) -> { |  | ||||||
|             if (throwable != null) { |  | ||||||
|                 if (throwable instanceof TimeoutException) { |  | ||||||
|                     player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); |  | ||||||
|                 } else { |  | ||||||
|                     player.sendMessage( |  | ||||||
|                             TranslatableCaption.of("errors.invalid_player"), |  | ||||||
|                             TagResolver.resolver("value", Tag.inserting(Component.text(args[0]))) |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|                 future.completeExceptionally(throwable); |  | ||||||
|                 return; |  | ||||||
|             } else { |  | ||||||
|                 try { |  | ||||||
|                     checkTrue(!uuids.isEmpty(), TranslatableCaption.of("errors.invalid_player"), |  | ||||||
|                             TagResolver.resolver("value", Tag.inserting(Component.text(args[0]))) |  | ||||||
|                     ); |  | ||||||
|                     Iterator<UUID> iterator = uuids.iterator(); |  | ||||||
|                     int size = plot.getTrusted().size() + plot.getMembers().size(); |  | ||||||
|                     while (iterator.hasNext()) { |  | ||||||
|                         UUID uuid = iterator.next(); |  | ||||||
|                         if (uuid == DBFunc.EVERYONE && !(player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission( |  | ||||||
|                                 Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { |  | ||||||
|                             player.sendMessage( |  | ||||||
|                                     TranslatableCaption.of("errors.invalid_player"), |  | ||||||
|                                     TagResolver.resolver("value", Tag.inserting( |  | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |  | ||||||
|                                     )) |  | ||||||
|                             ); |  | ||||||
|                             iterator.remove(); |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
|                         if (plot.isOwner(uuid)) { |  | ||||||
|                             player.sendMessage( |  | ||||||
|                                     TranslatableCaption.of("member.already_added"), |  | ||||||
|                                     TagResolver.resolver("player", Tag.inserting( |  | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |  | ||||||
|                                     )) |  | ||||||
|                             ); |  | ||||||
|                             iterator.remove(); |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
|                         if (plot.getMembers().contains(uuid)) { |  | ||||||
|                             player.sendMessage( |  | ||||||
|                                     TranslatableCaption.of("member.already_added"), |  | ||||||
|                                     TagResolver.resolver("player", Tag.inserting( |  | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |  | ||||||
|                                     )) |  | ||||||
|                             ); |  | ||||||
|                             iterator.remove(); |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
|                         size += plot.getTrusted().contains(uuid) ? 0 : 1; |  | ||||||
|                     } |  | ||||||
|                     checkTrue(!uuids.isEmpty(), null); |  | ||||||
|                     int localAddSize = plot.getMembers().size(); |  | ||||||
|                     int maxAddSize = player.hasPermissionRange(Permission.PERMISSION_ADD, Settings.Limit.MAX_PLOTS); |  | ||||||
|                     if (localAddSize >= maxAddSize) { |  | ||||||
|                         player.sendMessage( |  | ||||||
|                                 TranslatableCaption.of("members.plot_max_members_added"), |  | ||||||
|                                 TagResolver.resolver("amount", Tag.inserting(Component.text(localAddSize))) |  | ||||||
|                         ); |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
|                     // Success |  | ||||||
|                     confirm.run(this, () -> { |  | ||||||
|                         for (UUID uuid : uuids) { |  | ||||||
|                             if (uuid != DBFunc.EVERYONE) { |  | ||||||
|                                 if (!plot.removeTrusted(uuid)) { |  | ||||||
|                                     if (plot.getDenied().contains(uuid)) { |  | ||||||
|                                         plot.removeDenied(uuid); |  | ||||||
|                                     } |  | ||||||
|                                 } |  | ||||||
|                             } |  | ||||||
|                             plot.addMember(uuid); |  | ||||||
|                             this.eventDispatcher.callMember(player, plot, uuid, true); |  | ||||||
|                             player.sendMessage(TranslatableCaption.of("member.member_added")); |  | ||||||
|                         } |  | ||||||
|                     }, null); |  | ||||||
|                 } catch (final Throwable exception) { |  | ||||||
|                     future.completeExceptionally(exception); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             future.complete(true); |  | ||||||
|         }); |  | ||||||
|         return future; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) { |  | ||||||
|         return TabCompletions.completePlayers(player, String.join(",", args).trim(), Collections.emptyList()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,210 +0,0 @@ | |||||||
| /* |  | ||||||
|  * 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.command; |  | ||||||
|  |  | ||||||
| import com.plotsquared.core.PlotSquared; |  | ||||||
| import com.plotsquared.core.configuration.Settings; |  | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; |  | ||||||
| import com.plotsquared.core.location.Location; |  | ||||||
| import com.plotsquared.core.permissions.Permission; |  | ||||||
| import com.plotsquared.core.player.PlotPlayer; |  | ||||||
| import com.plotsquared.core.plot.Plot; |  | ||||||
| import com.plotsquared.core.util.MathMan; |  | ||||||
| import com.plotsquared.core.util.query.PlotQuery; |  | ||||||
| import net.kyori.adventure.text.Component; |  | ||||||
| import net.kyori.adventure.text.minimessage.tag.Tag; |  | ||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.concurrent.TimeoutException; |  | ||||||
|  |  | ||||||
| @CommandDeclaration(command = "alias", |  | ||||||
|         permission = "plots.alias", |  | ||||||
|         usage = "/plot alias <set | remove> <alias>", |  | ||||||
|         aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"}, |  | ||||||
|         category = CommandCategory.SETTINGS, |  | ||||||
|         requiredType = RequiredType.PLAYER) |  | ||||||
| public class Alias extends SubCommand { |  | ||||||
|  |  | ||||||
|     private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) { |  | ||||||
|     }; |  | ||||||
|     private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) { |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public boolean onCommand(PlotPlayer<?> player, String[] args) { |  | ||||||
|  |  | ||||||
|         if (args.length == 0) { |  | ||||||
|             sendUsage(player); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Location location = player.getLocation(); |  | ||||||
|         Plot plot = location.getPlotAbs(); |  | ||||||
|         if (plot == null) { |  | ||||||
|             player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (!plot.hasOwner()) { |  | ||||||
|             player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         boolean result = false; |  | ||||||
|  |  | ||||||
|         boolean owner = plot.isOwner(player.getUUID()); |  | ||||||
|         boolean permission; |  | ||||||
|         boolean admin; |  | ||||||
|         switch (args[0].toLowerCase()) { |  | ||||||
|             case "set" -> { |  | ||||||
|                 if (args.length != 2) { |  | ||||||
|                     sendUsage(player); |  | ||||||
|                     return false; |  | ||||||
|                 } |  | ||||||
|                 permission = isPermitted(player, Permission.PERMISSION_ALIAS_SET); |  | ||||||
|                 admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_SET); |  | ||||||
|                 if (!admin && !owner) { |  | ||||||
|                     player.sendMessage(TranslatableCaption.of("permission.no_plot_perms")); |  | ||||||
|                     return false; |  | ||||||
|                 } |  | ||||||
|                 if (permission) { // is either admin or owner |  | ||||||
|                     setAlias(player, plot, args[1]); |  | ||||||
|                     return true; |  | ||||||
|                 } else { |  | ||||||
|                     player.sendMessage( |  | ||||||
|                             TranslatableCaption.of("permission.no_permission"), |  | ||||||
|                             TagResolver.resolver( |  | ||||||
|                                     "node", |  | ||||||
|                                     Tag.inserting(Permission.PERMISSION_ALIAS_SET) |  | ||||||
|                             ) |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             case "remove" -> { |  | ||||||
|                 permission = isPermitted(player, Permission.PERMISSION_ALIAS_REMOVE); |  | ||||||
|                 admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_REMOVE); |  | ||||||
|                 if (!admin && !owner) { |  | ||||||
|                     player.sendMessage(TranslatableCaption.of("permission.no_plot_perms")); |  | ||||||
|                     return false; |  | ||||||
|                 } |  | ||||||
|                 if (permission) { |  | ||||||
|                     result = removeAlias(player, plot); |  | ||||||
|                 } else { |  | ||||||
|                     player.sendMessage( |  | ||||||
|                             TranslatableCaption.of("permission.no_permission"), |  | ||||||
|                             TagResolver.resolver( |  | ||||||
|                                     "node", |  | ||||||
|                                     Tag.inserting(Permission.PERMISSION_ALIAS_REMOVE) |  | ||||||
|                             ) |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             default -> { |  | ||||||
|                 sendUsage(player); |  | ||||||
|                 result = false; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) { |  | ||||||
|         final List<Command> commands = new ArrayList<>(2); |  | ||||||
|         if (args.length == 1) { |  | ||||||
|             if ("set".startsWith(args[0])) { |  | ||||||
|                 commands.add(SET_COMMAND); |  | ||||||
|             } |  | ||||||
|             if ("remove".startsWith(args[0])) { |  | ||||||
|                 commands.add(REMOVE_COMMAND); |  | ||||||
|             } |  | ||||||
|             return commands; |  | ||||||
|         } |  | ||||||
|         return Collections.emptySet(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void setAlias(PlotPlayer<?> player, Plot plot, String alias) { |  | ||||||
|         if (alias.isEmpty()) { |  | ||||||
|             sendUsage(player); |  | ||||||
|         } else if (alias.length() >= 50) { |  | ||||||
|             player.sendMessage(TranslatableCaption.of("alias.alias_too_long")); |  | ||||||
|         } else if (MathMan.isInteger(alias)) { |  | ||||||
|             player.sendMessage(TranslatableCaption.of("flag.not_valid_value")); // TODO this is obviously wrong |  | ||||||
|         } else { |  | ||||||
|             if (PlotQuery.newQuery().inArea(plot.getArea()) |  | ||||||
|                     .withAlias(alias) |  | ||||||
|                     .anyMatch()) { |  | ||||||
|                 player.sendMessage( |  | ||||||
|                         TranslatableCaption.of("alias.alias_is_taken"), |  | ||||||
|                         TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) |  | ||||||
|                 ); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             if (Settings.UUID.OFFLINE) { |  | ||||||
|                 plot.setAlias(alias); |  | ||||||
|                 player.sendMessage( |  | ||||||
|                         TranslatableCaption.of("alias.alias_set_to"), |  | ||||||
|                         TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) |  | ||||||
|                 ); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> { |  | ||||||
|                 if (throwable instanceof TimeoutException) { |  | ||||||
|                     player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); |  | ||||||
|                 } else if (uuid != null) { |  | ||||||
|                     player.sendMessage( |  | ||||||
|                             TranslatableCaption.of("alias.alias_is_taken"), |  | ||||||
|                             TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) |  | ||||||
|                     ); |  | ||||||
|                 } else { |  | ||||||
|                     plot.setAlias(alias); |  | ||||||
|                     player.sendMessage( |  | ||||||
|                             TranslatableCaption.of("alias.alias_set_to"), |  | ||||||
|                             TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             })); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private boolean removeAlias(PlotPlayer<?> player, Plot plot) { |  | ||||||
|         String alias = plot.getAlias(); |  | ||||||
|         if (!plot.getAlias().isEmpty()) { |  | ||||||
|             player.sendMessage( |  | ||||||
|                     TranslatableCaption.of("alias.alias_removed"), |  | ||||||
|                     TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) |  | ||||||
|             ); |  | ||||||
|         } else { |  | ||||||
|             player.sendMessage( |  | ||||||
|                     TranslatableCaption.of("alias.no_alias_set") |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|         plot.setAlias(null); |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private boolean isPermitted(PlotPlayer<?> player, Permission permission) { |  | ||||||
|         return player.hasPermission(permission); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -86,7 +86,6 @@ public class MainCommand extends Command { | |||||||
|             commands.add(CreateRoadSchematic.class); |             commands.add(CreateRoadSchematic.class); | ||||||
|             commands.add(DebugAllowUnsafe.class); |             commands.add(DebugAllowUnsafe.class); | ||||||
|             commands.add(RegenAllRoads.class); |             commands.add(RegenAllRoads.class); | ||||||
|             commands.add(Claim.class); |  | ||||||
|             commands.add(Auto.class); |             commands.add(Auto.class); | ||||||
|             commands.add(HomeCommand.class); |             commands.add(HomeCommand.class); | ||||||
|             commands.add(Visit.class); |             commands.add(Visit.class); | ||||||
| @@ -94,7 +93,6 @@ public class MainCommand extends Command { | |||||||
|             commands.add(Clear.class); |             commands.add(Clear.class); | ||||||
|             commands.add(Delete.class); |             commands.add(Delete.class); | ||||||
|             commands.add(Trust.class); |             commands.add(Trust.class); | ||||||
|             commands.add(Add.class); |  | ||||||
|             commands.add(Leave.class); |             commands.add(Leave.class); | ||||||
|             commands.add(Deny.class); |             commands.add(Deny.class); | ||||||
|             commands.add(Remove.class); |             commands.add(Remove.class); | ||||||
| @@ -130,7 +128,6 @@ public class MainCommand extends Command { | |||||||
|             commands.add(Owner.class); |             commands.add(Owner.class); | ||||||
|             commands.add(Desc.class); |             commands.add(Desc.class); | ||||||
|             commands.add(Biome.class); |             commands.add(Biome.class); | ||||||
|             commands.add(Alias.class); |  | ||||||
|             commands.add(SetHome.class); |             commands.add(SetHome.class); | ||||||
|             commands.add(Cluster.class); |             commands.add(Cluster.class); | ||||||
|             commands.add(DebugImportWorlds.class); |             commands.add(DebugImportWorlds.class); | ||||||
|   | |||||||
							
								
								
									
										104
									
								
								Core/src/main/java/com/plotsquared/core/commands/CommandAdd.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								Core/src/main/java/com/plotsquared/core/commands/CommandAdd.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | /* | ||||||
|  |  * 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 cloud.commandframework.annotations.Argument; | ||||||
|  | import cloud.commandframework.annotations.CommandMethod; | ||||||
|  | import cloud.commandframework.annotations.CommandPermission; | ||||||
|  | import com.google.inject.Inject; | ||||||
|  | import com.plotsquared.core.commands.arguments.PlotMember; | ||||||
|  | import com.plotsquared.core.commands.requirements.Requirement; | ||||||
|  | import com.plotsquared.core.commands.requirements.CommandRequirement; | ||||||
|  | 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.Plot; | ||||||
|  | import com.plotsquared.core.util.EventDispatcher; | ||||||
|  | import com.plotsquared.core.util.PlayerManager; | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  | class CommandAdd implements PlotSquaredCommandContainer { | ||||||
|  |  | ||||||
|  |     private final EventDispatcher eventDispatcher; | ||||||
|  |  | ||||||
|  |     @Inject | ||||||
|  |     CommandAdd(final @NonNull EventDispatcher eventDispatcher) { | ||||||
|  |         this.eventDispatcher = eventDispatcher; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Requirement(CommandRequirement.PLAYER) | ||||||
|  |     @Requirement(CommandRequirement.IS_OWNER) | ||||||
|  |     @CommandPermission("plots.add") | ||||||
|  |     @CommandMethod("${command.prefix} add [target]") | ||||||
|  |     public void commandAdd( | ||||||
|  |             final @NonNull PlotPlayer<?> sender, | ||||||
|  |             @Argument("target") final PlotMember target, | ||||||
|  |             final @NonNull Plot plot | ||||||
|  |     ) { | ||||||
|  |         if (target instanceof PlotMember.Everyone) { | ||||||
|  |             if (!sender.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) && !sender.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST)) { | ||||||
|  |                 sender.sendMessage( | ||||||
|  |                         TranslatableCaption.of("errors.invalid_player"), | ||||||
|  |                         TagResolver.resolver("value", Tag.inserting( | ||||||
|  |                                 PlayerManager.resolveName(target.uuid()).toComponent(sender) | ||||||
|  |                         )) | ||||||
|  |                 ); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } else if (plot.isOwner(target.uuid())) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("member.already_added"), | ||||||
|  |                     TagResolver.resolver("player", Tag.inserting( | ||||||
|  |                             PlayerManager.resolveName(target.uuid()).toComponent(sender) | ||||||
|  |                     )) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } else if (plot.getMembers().contains(target.uuid())) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("member.already_added"), | ||||||
|  |                     TagResolver.resolver("player", Tag.inserting( | ||||||
|  |                             PlayerManager.resolveName(target.uuid()).toComponent(sender) | ||||||
|  |                     )) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } else if (plot.getMembers().size() >= sender.hasPermissionRange(Permission.PERMISSION_ADD, Settings.Limit.MAX_PLOTS)) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("members.plot_max_members_added"), | ||||||
|  |                     TagResolver.resolver("amount", Tag.inserting(Component.text(plot.getMembers().size()))) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (target instanceof PlotMember.Player) { | ||||||
|  |             if (!plot.removeTrusted(target.uuid())) { | ||||||
|  |                 if (plot.getDenied().contains(target.uuid())) { | ||||||
|  |                     plot.removeDenied(target.uuid()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         plot.addMember(target.uuid()); | ||||||
|  |         this.eventDispatcher.callMember(sender, plot, target.uuid(), true); | ||||||
|  |         sender.sendMessage(TranslatableCaption.of("member.member_added")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,136 @@ | |||||||
|  | package com.plotsquared.core.commands; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.annotations.Argument; | ||||||
|  | import cloud.commandframework.annotations.CommandMethod; | ||||||
|  | import cloud.commandframework.annotations.CommandPermission; | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
|  | import com.plotsquared.core.commands.requirements.CommandRequirement; | ||||||
|  | import com.plotsquared.core.commands.requirements.Requirement; | ||||||
|  | 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.Plot; | ||||||
|  | import com.plotsquared.core.util.MathMan; | ||||||
|  | import com.plotsquared.core.util.query.PlotQuery; | ||||||
|  | import net.kyori.adventure.text.Component; | ||||||
|  | import net.kyori.adventure.text.minimessage.tag.Tag; | ||||||
|  | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.concurrent.TimeoutException; | ||||||
|  |  | ||||||
|  | public class CommandAlias implements PlotSquaredCommandContainer { | ||||||
|  |  | ||||||
|  |     @Requirement(CommandRequirement.PLAYER) | ||||||
|  |     @Requirement(CommandRequirement.PLOT_HAS_OWNER) | ||||||
|  |     @CommandPermission("plots.alias") | ||||||
|  |     @CommandMethod("${command.prefix} alias set <alias>") | ||||||
|  |     public void commandAliasSet( | ||||||
|  |             final @NonNull PlotPlayer<?> sender, | ||||||
|  |             final @NonNull Plot plot, | ||||||
|  |             @Argument("alias") final @NonNull String alias | ||||||
|  |     ) { | ||||||
|  |         final boolean isOwner = plot.isOwner(sender.getUUID()); | ||||||
|  |  | ||||||
|  |         if (!isOwner && !sender.hasPermission(Permission.PERMISSION_ADMIN_ALIAS_SET)) { | ||||||
|  |             sender.sendMessage(TranslatableCaption.of("permission.no_plot_perms")); | ||||||
|  |             return; | ||||||
|  |         } else if (!sender.hasPermission(Permission.PERMISSION_ALIAS_SET)) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("permission.no_permission"), | ||||||
|  |                     TagResolver.resolver( | ||||||
|  |                             "node", | ||||||
|  |                             Tag.inserting(Permission.PERMISSION_ALIAS_SET) | ||||||
|  |                     ) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (alias.length() >= 50) { | ||||||
|  |             sender.sendMessage(TranslatableCaption.of("alias.alias_too_long")); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (MathMan.isInteger(alias)) { | ||||||
|  |             sender.sendMessage(TranslatableCaption.of("flag.not_valid_value")); // TODO this is obviously wrong | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (PlotQuery.newQuery().inArea(plot.getArea()) | ||||||
|  |                 .withAlias(alias) | ||||||
|  |                 .anyMatch()) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("alias.alias_is_taken"), | ||||||
|  |                     TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (Settings.UUID.OFFLINE) { | ||||||
|  |             plot.setAlias(alias); | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("alias.alias_set_to"), | ||||||
|  |                     TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> { | ||||||
|  |             if (throwable instanceof TimeoutException) { | ||||||
|  |                 sender.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); | ||||||
|  |             } else if (uuid != null) { | ||||||
|  |                 sender.sendMessage( | ||||||
|  |                         TranslatableCaption.of("alias.alias_is_taken"), | ||||||
|  |                         TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) | ||||||
|  |                 ); | ||||||
|  |             } else { | ||||||
|  |                 plot.setAlias(alias); | ||||||
|  |                 sender.sendMessage( | ||||||
|  |                         TranslatableCaption.of("alias.alias_set_to"), | ||||||
|  |                         TagResolver.resolver("alias", Tag.inserting(Component.text(alias))) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         })); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Requirement(CommandRequirement.PLAYER) | ||||||
|  |     @Requirement(CommandRequirement.PLOT_HAS_OWNER) | ||||||
|  |     @CommandPermission("plots.alias") | ||||||
|  |     @CommandMethod("${command.prefix} alias remove") | ||||||
|  |     public void commandAliasRemove( | ||||||
|  |             final @NonNull PlotPlayer<?> sender, | ||||||
|  |             final @NonNull Plot plot | ||||||
|  |     ) { | ||||||
|  |         final boolean isOwner = plot.isOwner(sender.getUUID()); | ||||||
|  |  | ||||||
|  |         if (!isOwner && !sender.hasPermission(Permission.PERMISSION_ADMIN_ALIAS_REMOVE)) { | ||||||
|  |             sender.sendMessage(TranslatableCaption.of("permission.no_plot_perms")); | ||||||
|  |             return; | ||||||
|  |         } else if (!sender.hasPermission(Permission.PERMISSION_ALIAS_REMOVE)) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("permission.no_permission"), | ||||||
|  |                     TagResolver.resolver( | ||||||
|  |                             "node", | ||||||
|  |                             Tag.inserting(Permission.PERMISSION_ALIAS_REMOVE) | ||||||
|  |                     ) | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (plot.getAlias().isEmpty()) { | ||||||
|  |             sender.sendMessage( | ||||||
|  |                     TranslatableCaption.of("alias.no_alias_set") | ||||||
|  |             ); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         final String currentAlias = plot.getAlias(); | ||||||
|  |         plot.setAlias(null); | ||||||
|  |  | ||||||
|  |         sender.sendMessage( | ||||||
|  |                 TranslatableCaption.of("alias.alias_removed"), | ||||||
|  |                 TagResolver.resolver("alias", Tag.inserting(Component.text(currentAlias))) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,24 +1,11 @@ | |||||||
| /* | package com.plotsquared.core.commands; | ||||||
|  * 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.command; |  | ||||||
| 
 | 
 | ||||||
|  | import cloud.commandframework.annotations.Argument; | ||||||
|  | import cloud.commandframework.annotations.CommandMethod; | ||||||
|  | import cloud.commandframework.annotations.CommandPermission; | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
|  | import com.plotsquared.core.commands.requirements.CommandRequirement; | ||||||
|  | import com.plotsquared.core.commands.requirements.Requirement; | ||||||
| import com.plotsquared.core.configuration.Settings; | import com.plotsquared.core.configuration.Settings; | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
| import com.plotsquared.core.database.DBFunc; | import com.plotsquared.core.database.DBFunc; | ||||||
| @@ -26,7 +13,6 @@ import com.plotsquared.core.events.PlayerClaimPlotEvent; | |||||||
| import com.plotsquared.core.events.PlotMergeEvent; | import com.plotsquared.core.events.PlotMergeEvent; | ||||||
| import com.plotsquared.core.events.Result; | import com.plotsquared.core.events.Result; | ||||||
| import com.plotsquared.core.location.Direction; | import com.plotsquared.core.location.Direction; | ||||||
| import com.plotsquared.core.location.Location; |  | ||||||
| import com.plotsquared.core.permissions.Permission; | import com.plotsquared.core.permissions.Permission; | ||||||
| import com.plotsquared.core.player.MetaDataAccess; | import com.plotsquared.core.player.MetaDataAccess; | ||||||
| import com.plotsquared.core.player.PlayerMetaDataKeys; | import com.plotsquared.core.player.PlayerMetaDataKeys; | ||||||
| @@ -43,22 +29,17 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | |||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
| 
 | 
 | ||||||
| @CommandDeclaration( | public class CommandClaim implements PlotSquaredCommandContainer { | ||||||
|         command = "claim", |  | ||||||
|         aliases = "c", |  | ||||||
|         category = CommandCategory.CLAIMING, |  | ||||||
|         requiredType = RequiredType.PLAYER, permission = "plots.claim", |  | ||||||
|         usage = "/plot claim") |  | ||||||
| public class Claim extends SubCommand { |  | ||||||
| 
 | 
 | ||||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Claim.class.getSimpleName()); |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + CommandClaim.class.getSimpleName()); | ||||||
| 
 | 
 | ||||||
|     private final EventDispatcher eventDispatcher; |     private final EventDispatcher eventDispatcher; | ||||||
|     private final EconHandler econHandler; |     private final EconHandler econHandler; | ||||||
| 
 | 
 | ||||||
|     @Inject |     @Inject | ||||||
|     public Claim( |     CommandClaim( | ||||||
|             final @NonNull EventDispatcher eventDispatcher, |             final @NonNull EventDispatcher eventDispatcher, | ||||||
|             final @NonNull EconHandler econHandler |             final @NonNull EconHandler econHandler | ||||||
|     ) { |     ) { | ||||||
| @@ -66,124 +47,132 @@ public class Claim extends SubCommand { | |||||||
|         this.econHandler = econHandler; |         this.econHandler = econHandler; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Requirement(CommandRequirement.PLAYER) | ||||||
|     public boolean onCommand(final PlotPlayer<?> player, String[] args) { |     @Requirement(CommandRequirement.IN_PLOT) | ||||||
|         String schematic = null; |     @CommandPermission("plots.add") | ||||||
|         if (args.length >= 1) { |     @CommandMethod("${command.prefix} claim [schematic]") | ||||||
|             schematic = args[0]; |     public void commandClaim( | ||||||
|         } |             final @NonNull PlotPlayer<?> sender, | ||||||
|         Location location = player.getLocation(); |             final @NonNull Plot plot, | ||||||
|         Plot plot = location.getPlotAbs(); |             @Argument("schematic") final @Nullable String schematic | ||||||
|         if (plot == null) { |     ) { | ||||||
|             player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); |         final PlayerClaimPlotEvent event = this.eventDispatcher.callClaim(sender, plot, schematic); | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|         final PlayerClaimPlotEvent event = this.eventDispatcher.callClaim(player, plot, schematic); |  | ||||||
|         schematic = event.getSchematic(); |  | ||||||
|         if (event.getEventResult() == Result.DENY) { |         if (event.getEventResult() == Result.DENY) { | ||||||
|             player.sendMessage( |             sender.sendMessage( | ||||||
|                     TranslatableCaption.of("events.event_denied"), |                     TranslatableCaption.of("events.event_denied"), | ||||||
|                     TagResolver.resolver("value", Tag.inserting(Component.text("Claim"))) |                     TagResolver.resolver("value", Tag.inserting(Component.text("Claim"))) | ||||||
|             ); |             ); | ||||||
|             return true; |             return; | ||||||
|         } |         } | ||||||
|         boolean force = event.getEventResult() == Result.FORCE; |  | ||||||
|         int currentPlots = Settings.Limit.GLOBAL ? |  | ||||||
|                 player.getPlotCount() : |  | ||||||
|                 player.getPlotCount(location.getWorldName()); |  | ||||||
| 
 | 
 | ||||||
|  |         final boolean forceClaim = event.getEventResult() == Result.FORCE; | ||||||
|  |         final int currentPlots = Settings.Limit.GLOBAL ? | ||||||
|  |                 sender.getPlotCount() : | ||||||
|  |                 sender.getPlotCount(sender.getLocation().getWorldName()); | ||||||
|         final PlotArea area = plot.getArea(); |         final PlotArea area = plot.getArea(); | ||||||
| 
 | 
 | ||||||
|         try (final MetaDataAccess<Integer> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) { |         try (final MetaDataAccess<Integer> metaDataAccess = sender.accessPersistentMetaData( | ||||||
|  |                 PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS | ||||||
|  |         )) { | ||||||
|             int grants = 0; |             int grants = 0; | ||||||
|             if (currentPlots >= player.getAllowedPlots() && !force) { |             if (currentPlots >= sender.getAllowedPlots() && !forceClaim) { | ||||||
|                 if (metaDataAccess.isPresent()) { |                 if (metaDataAccess.isPresent()) { | ||||||
|                     grants = metaDataAccess.get().orElse(0); |                     grants = metaDataAccess.get().orElse(0); | ||||||
|                     if (grants <= 0) { |                     if (grants <= 0) { | ||||||
|                         player.sendMessage( |                         sender.sendMessage( | ||||||
|                                 TranslatableCaption.of("permission.cant_claim_more_plots"), |                                 TranslatableCaption.of("permission.cant_claim_more_plots"), | ||||||
|                                 TagResolver.resolver("amount", Tag.inserting(Component.text(grants))) |                                 TagResolver.resolver("amount", Tag.inserting(Component.text(grants))) | ||||||
|                         ); |                         ); | ||||||
|                         metaDataAccess.remove(); |                         metaDataAccess.remove(); | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     player.sendMessage( |                     sender.sendMessage( | ||||||
|                             TranslatableCaption.of("permission.cant_claim_more_plots"), |                             TranslatableCaption.of("permission.cant_claim_more_plots"), | ||||||
|                             TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots()))) |                             TagResolver.resolver("amount", Tag.inserting(Component.text(sender.getAllowedPlots()))) | ||||||
|                     ); |                     ); | ||||||
|                     return false; |                     return; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!plot.canClaim(player)) { |             if (!plot.canClaim(sender)) { | ||||||
|                 player.sendMessage(TranslatableCaption.of("working.plot_is_claimed")); |                 sender.sendMessage(TranslatableCaption.of("working.plot_is_claimed")); | ||||||
|                 return false; |                 return; | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|             if (schematic != null && !schematic.isEmpty()) { |             if (schematic != null && !schematic.isEmpty()) { | ||||||
|                 if (area.isSchematicClaimSpecify()) { |                 if (area.isSchematicClaimSpecify()) { | ||||||
|                     if (!area.hasSchematic(schematic)) { |                     if (!area.hasSchematic(schematic)) { | ||||||
|                         player.sendMessage( |                         sender.sendMessage( | ||||||
|                                 TranslatableCaption.of("schematics.schematic_invalid_named"), |                                 TranslatableCaption.of("schematics.schematic_invalid_named"), | ||||||
|                                 TagResolver.builder() |                                 TagResolver.builder() | ||||||
|                                         .tag("schemname", Tag.inserting(Component.text(schematic))) |                                         .tag("schemname", Tag.inserting(Component.text(schematic))) | ||||||
|                                         .tag("reason", Tag.inserting(Component.text("non-existent"))) |                                         .tag("reason", Tag.inserting(Component.text("non-existent"))) | ||||||
|                                         .build() |                                         .build() | ||||||
|                         ); |                         ); | ||||||
|  |                         return; | ||||||
|                     } |                     } | ||||||
|                     if (!player.hasPermission(Permission.PERMISSION_CLAIM_SCHEMATIC | 
 | ||||||
|                             .format(schematic)) && !player.hasPermission( |                     if (!sender.hasPermission( | ||||||
|  |                             Permission.PERMISSION_CLAIM_SCHEMATIC.format(schematic) | ||||||
|  |                     ) && !sender.hasPermission( | ||||||
|                             "plots.admin.command.schematic" |                             "plots.admin.command.schematic" | ||||||
|                     ) && !force) { |                     ) && !forceClaim) { | ||||||
|                         player.sendMessage( |                         sender.sendMessage( | ||||||
|                                 TranslatableCaption.of("permission.no_schematic_permission"), |                                 TranslatableCaption.of("permission.no_schematic_permission"), | ||||||
|                                 TagResolver.resolver("value", Tag.inserting(Component.text(schematic))) |                                 TagResolver.resolver("value", Tag.inserting(Component.text(schematic))) | ||||||
|                         ); |                         ); | ||||||
|  |                         return; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (this.econHandler.isEnabled(area) && !force) { | 
 | ||||||
|                 PlotExpression costExr = area.getPrices().get("claim"); |             if (this.econHandler.isEnabled(area) && !forceClaim) { | ||||||
|                 double cost = costExr.evaluate(currentPlots); |                 final PlotExpression costExr = area.getPrices().get("claim"); | ||||||
|  |                 final double cost = costExr.evaluate(currentPlots); | ||||||
|  | 
 | ||||||
|                 if (cost > 0d) { |                 if (cost > 0d) { | ||||||
|                     if (!this.econHandler.isSupported()) { |                     if (!this.econHandler.isSupported()) { | ||||||
|                         player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); |                         sender.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); | ||||||
|                         return false; |                         return; | ||||||
|                     } |                     } | ||||||
|                     if (this.econHandler.getMoney(player) < cost) { |                     if (this.econHandler.getMoney(sender) < cost) { | ||||||
|                         player.sendMessage( |                         sender.sendMessage( | ||||||
|                                 TranslatableCaption.of("economy.cannot_afford_plot"), |                                 TranslatableCaption.of("economy.cannot_afford_plot"), | ||||||
|                                 TagResolver.builder() |                                 TagResolver.builder() | ||||||
|                                         .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) |                                         .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) | ||||||
|                                         .tag( |                                         .tag( | ||||||
|                                                 "balance", |                                                 "balance", | ||||||
|                                                 Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney( |                                                 Tag.inserting( | ||||||
|                                                         player)))) |                                                         Component.text(this.econHandler.format(this.econHandler.getMoney(sender))) | ||||||
|  |                                                 ) | ||||||
|                                         ) |                                         ) | ||||||
|                                         .build() |                                         .build() | ||||||
|                         ); |                         ); | ||||||
|                         return false; |                         return; | ||||||
|                     } |                     } | ||||||
|                     this.econHandler.withdrawMoney(player, cost); |                     this.econHandler.withdrawMoney(sender, cost); | ||||||
|                     player.sendMessage( |                     sender.sendMessage( | ||||||
|                             TranslatableCaption.of("economy.removed_balance"), |                             TranslatableCaption.of("economy.removed_balance"), | ||||||
|                             TagResolver.builder() |                             TagResolver.builder() | ||||||
|                                     .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) |                                     .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) | ||||||
|                                     .tag( |                                     .tag( | ||||||
|                                             "balance", |                                             "balance", | ||||||
|                                             Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney( |                                             Tag.inserting( | ||||||
|                                                     player)))) |                                                     Component.text(this.econHandler.format(this.econHandler.getMoney(sender))) | ||||||
|  |                                             ) | ||||||
|                                     ) |                                     ) | ||||||
|                                     .build() |                                     .build() | ||||||
|                     ); |                     ); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|             if (grants > 0) { |             if (grants > 0) { | ||||||
|                 if (grants == 1) { |                 if (grants == 1) { | ||||||
|                     metaDataAccess.remove(); |                     metaDataAccess.remove(); | ||||||
|                 } else { |                 } else { | ||||||
|                     metaDataAccess.set(grants - 1); |                     metaDataAccess.set(grants - 1); | ||||||
|                 } |                 } | ||||||
|                 player.sendMessage( |                 sender.sendMessage( | ||||||
|                         TranslatableCaption.of("economy.removed_granted_plot"), |                         TranslatableCaption.of("economy.removed_granted_plot"), | ||||||
|                         TagResolver.builder() |                         TagResolver.builder() | ||||||
|                                 .tag("usedGrants", Tag.inserting(Component.text(grants - 1))) |                                 .tag("usedGrants", Tag.inserting(Component.text(grants - 1))) | ||||||
| @@ -192,27 +181,34 @@ public class Claim extends SubCommand { | |||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (!player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { | 
 | ||||||
|             int border = area.getBorder(); |         if (!sender.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { | ||||||
|             if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) { |             final int border = area.getBorder(); | ||||||
|                 player.sendMessage(TranslatableCaption.of("border.denied")); |             if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !forceClaim) { | ||||||
|                 return false; |                 sender.sendMessage(TranslatableCaption.of("border.denied")); | ||||||
|  |                 return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         plot.setOwnerAbs(player.getUUID()); | 
 | ||||||
|         final String finalSchematic = schematic; |         // Actually update the owner :) | ||||||
|  |         plot.setOwnerAbs(sender.getUUID()); | ||||||
|  | 
 | ||||||
|         DBFunc.createPlotSafe(plot, () -> { |         DBFunc.createPlotSafe(plot, () -> { | ||||||
|             try { |             try { | ||||||
|                 TaskManager.getPlatformImplementation().sync(() -> { |                 TaskManager.getPlatformImplementation().sync(() -> { | ||||||
|                     if (!plot.claim(player, true, finalSchematic, false, false)) { |                     if (!plot.claim(sender, true, event.getSchematic(), false, false)) { | ||||||
|                         LOGGER.info("Failed to claim plot {}", plot.getId().toCommaSeparatedString()); |                         LOGGER.info("Failed to claim plot {}", plot.getId().toCommaSeparatedString()); | ||||||
|                         player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); |                         sender.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); | ||||||
|                         plot.setOwnerAbs(null); |                         plot.setOwnerAbs(null); | ||||||
|                     } else if (area.isAutoMerge()) { |                     } else if (area.isAutoMerge()) { | ||||||
|                         PlotMergeEvent mergeEvent = Claim.this.eventDispatcher |                         final PlotMergeEvent mergeEvent = this.eventDispatcher.callMerge( | ||||||
|                                 .callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player); |                                 plot, | ||||||
|  |                                 Direction.ALL, | ||||||
|  |                                 Integer.MAX_VALUE, | ||||||
|  |                                 sender | ||||||
|  |                         ); | ||||||
|                         if (mergeEvent.getEventResult() == Result.DENY) { |                         if (mergeEvent.getEventResult() == Result.DENY) { | ||||||
|                             player.sendMessage( |                             sender.sendMessage( | ||||||
|                                     TranslatableCaption.of("events.event_denied"), |                                     TranslatableCaption.of("events.event_denied"), | ||||||
|                                     TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge on claim"))) |                                     TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge on claim"))) | ||||||
|                             ); |                             ); | ||||||
| @@ -220,11 +216,11 @@ public class Claim extends SubCommand { | |||||||
|                             if (plot.getPlotModificationManager().autoMerge( |                             if (plot.getPlotModificationManager().autoMerge( | ||||||
|                                     mergeEvent.getDir(), |                                     mergeEvent.getDir(), | ||||||
|                                     mergeEvent.getMax(), |                                     mergeEvent.getMax(), | ||||||
|                                     player.getUUID(), |                                     sender.getUUID(), | ||||||
|                                     player, |                                     sender, | ||||||
|                                     true |                                     true | ||||||
|                             )) { |                             )) { | ||||||
|                                 eventDispatcher.callPostMerge(player, plot); |                                 eventDispatcher.callPostMerge(sender, plot); | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| @@ -235,10 +231,8 @@ public class Claim extends SubCommand { | |||||||
|             } |             } | ||||||
|         }, () -> { |         }, () -> { | ||||||
|             LOGGER.info("Failed to add plot to database: {}", plot.getId().toCommaSeparatedString()); |             LOGGER.info("Failed to add plot to database: {}", plot.getId().toCommaSeparatedString()); | ||||||
|             player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); |             sender.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); | ||||||
|             plot.setOwnerAbs(null); |             plot.setOwnerAbs(null); | ||||||
|         }); |         }); | ||||||
|         return true; |  | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | /* | ||||||
|  |  * 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 cloud.commandframework.captions.Caption; | ||||||
|  |  | ||||||
|  | public final class PlotSquaredCaptionKeys { | ||||||
|  |  | ||||||
|  |     public static final Caption ARGUMENT_PARSE_FAILURE_TARGET = Caption.of("argument.parse.failure.target"); | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | /* | ||||||
|  |  * 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; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Indicates that a class contains commands. | ||||||
|  |  */ | ||||||
|  | public interface PlotSquaredCommandContainer { | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,82 @@ | |||||||
|  | /* | ||||||
|  |  * 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 cloud.commandframework.CommandManager; | ||||||
|  | import cloud.commandframework.annotations.AnnotationParser; | ||||||
|  | import cloud.commandframework.meta.SimpleCommandMeta; | ||||||
|  | import com.google.inject.Inject; | ||||||
|  | import com.google.inject.Injector; | ||||||
|  | import com.plotsquared.core.commands.parsers.PlotMemberParser; | ||||||
|  | import com.plotsquared.core.commands.requirements.CommandRequirementBuilderModifier; | ||||||
|  | import com.plotsquared.core.commands.requirements.CommandRequirementPostProcessor; | ||||||
|  | import com.plotsquared.core.commands.requirements.Requirements; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import io.leangen.geantyref.TypeToken; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.stream.Stream; | ||||||
|  |  | ||||||
|  | public class PlotSquaredCommandManager { | ||||||
|  |  | ||||||
|  |     private final Injector injector; | ||||||
|  |     private final CommandManager<PlotPlayer<?>> commandManager; | ||||||
|  |     private final AnnotationParser<PlotPlayer<?>> annotationParser; | ||||||
|  |  | ||||||
|  |     @Inject | ||||||
|  |     public PlotSquaredCommandManager( | ||||||
|  |             final @NonNull Injector injector, | ||||||
|  |             final @NonNull CommandManager<PlotPlayer<?>> commandManager | ||||||
|  |     ) { | ||||||
|  |         this.injector = injector; | ||||||
|  |         this.commandManager = commandManager; | ||||||
|  |         this.annotationParser = new AnnotationParser<PlotPlayer<?>>( | ||||||
|  |                 this.commandManager, | ||||||
|  |                 new TypeToken<PlotPlayer<?>>() { | ||||||
|  |                 }, | ||||||
|  |                 parameters -> SimpleCommandMeta.empty() | ||||||
|  |         ); | ||||||
|  |         this.annotationParser.registerBuilderModifier(Requirements.class, new CommandRequirementBuilderModifier()); | ||||||
|  |         this.commandManager.registerCommandPostProcessor(new CommandRequirementPostProcessor()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Scans the given {@code instance} for commands, and registers them. | ||||||
|  |      * | ||||||
|  |      * @param instance the instance to scan | ||||||
|  |      */ | ||||||
|  |     public void scanClass(final @NonNull Object instance) { | ||||||
|  |         this.annotationParser.parse(instance); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Initializes all the known commands. | ||||||
|  |      */ | ||||||
|  |     public void initializeCommands() { | ||||||
|  |         // We start by scanning the parsers. | ||||||
|  |         Stream.of( | ||||||
|  |                 PlotMemberParser.class | ||||||
|  |         ).map(this.injector::getInstance).forEach(this::scanClass); | ||||||
|  |         // Then we scan the commands. | ||||||
|  |         Stream.of( | ||||||
|  |                 CommandAdd.class, | ||||||
|  |                 CommandClaim.class | ||||||
|  |         ).map(this.injector::getInstance).forEach(this::scanClass); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | /* | ||||||
|  |  * 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.arguments; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.context.CommandContext; | ||||||
|  | import com.plotsquared.core.commands.parsers.PlotMemberParser; | ||||||
|  | import com.plotsquared.core.database.DBFunc; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import org.checkerframework.checker.nullness.qual.MonotonicNonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
|  | import java.util.UUID; | ||||||
|  |  | ||||||
|  | public sealed interface PlotMember { | ||||||
|  |  | ||||||
|  |     PlotMember EVERYONE = new Everyone(); | ||||||
|  |  | ||||||
|  |     default @NonNull UUID uuid(@NonNull CommandContext<PlotPlayer<?>> context) { | ||||||
|  |         return this.uuid(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @NonNull UUID uuid(); | ||||||
|  |  | ||||||
|  |     sealed interface PlayerLike extends PlotMember { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     record Player(@NonNull UUID uuid) implements PlayerLike { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     final class LazyPlayer implements PlayerLike { | ||||||
|  |  | ||||||
|  |         private final String candidate; | ||||||
|  |         private final UuidSupplier uuidSupplier; | ||||||
|  |         private @MonotonicNonNull UUID cachedUuid = null; | ||||||
|  |  | ||||||
|  |         public LazyPlayer( | ||||||
|  |                 final @NonNull String candidate, | ||||||
|  |                 final @NonNull UuidSupplier uuidSupplier | ||||||
|  |         ) { | ||||||
|  |             this.candidate = candidate; | ||||||
|  |             this.uuidSupplier = uuidSupplier; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public @NonNull UUID uuid() { | ||||||
|  |             throw new UnsupportedOperationException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public synchronized @NonNull UUID uuid(final @NonNull CommandContext<PlotPlayer<?>> context) { | ||||||
|  |             if (this.cachedUuid == null) { | ||||||
|  |                 try { | ||||||
|  |                     this.cachedUuid = this.uuidSupplier.uuid(); | ||||||
|  |                 } catch (Exception ignored) { | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // The player didn't exist :-( | ||||||
|  |                 if (this.cachedUuid == null) { | ||||||
|  |                     throw new PlotMemberParser.TargetParseException(this.candidate, context); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return this.cachedUuid; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @FunctionalInterface | ||||||
|  |         public interface UuidSupplier { | ||||||
|  |             @Nullable UUID uuid() throws Exception; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     final class Everyone implements PlotMember { | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public @NonNull UUID uuid() { | ||||||
|  |             return DBFunc.EVERYONE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,124 @@ | |||||||
|  | /* | ||||||
|  |  * 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.parsers; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.annotations.parsers.Parser; | ||||||
|  | import cloud.commandframework.captions.CaptionVariable; | ||||||
|  | import cloud.commandframework.context.CommandContext; | ||||||
|  | import cloud.commandframework.exceptions.parsing.NoInputProvidedException; | ||||||
|  | import cloud.commandframework.exceptions.parsing.ParserException; | ||||||
|  | import com.google.inject.Inject; | ||||||
|  | import com.plotsquared.core.commands.PlotSquaredCaptionKeys; | ||||||
|  | import com.plotsquared.core.commands.arguments.PlotMember; | ||||||
|  | import com.plotsquared.core.configuration.Settings; | ||||||
|  | import com.plotsquared.core.inject.annotations.ImpromptuPipeline; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import com.plotsquared.core.uuid.UUIDMapping; | ||||||
|  | import com.plotsquared.core.uuid.UUIDPipeline; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.io.Serial; | ||||||
|  | import java.util.Queue; | ||||||
|  | import java.util.UUID; | ||||||
|  |  | ||||||
|  | public class PlotMemberParser { | ||||||
|  |  | ||||||
|  |     private final UUIDPipeline uuidPipeline; | ||||||
|  |  | ||||||
|  |     @Inject | ||||||
|  |     public PlotMemberParser(@ImpromptuPipeline final @NonNull UUIDPipeline uuidPipeline) { | ||||||
|  |         this.uuidPipeline = uuidPipeline; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Parser | ||||||
|  |     public @NonNull PlotMember parse( | ||||||
|  |             final @NonNull CommandContext<PlotPlayer<?>> context, | ||||||
|  |             final @NonNull Queue<@NonNull String> input | ||||||
|  |     ) { | ||||||
|  |         final var candidate = input.peek(); | ||||||
|  |         if (candidate == null) { | ||||||
|  |             throw new NoInputProvidedException(this.getClass(), context); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if ("*".equals(candidate)) { | ||||||
|  |             return PlotMember.EVERYONE; | ||||||
|  |         } else if (candidate.length() > 16) { | ||||||
|  |             try { | ||||||
|  |                 return new PlotMember.Player(UUID.fromString(candidate)); | ||||||
|  |             } catch (IllegalArgumentException ignored) { | ||||||
|  |                 throw new TargetParseException(candidate, context); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (Settings.Paper_Components.PAPER_LISTENERS) { | ||||||
|  |             try { | ||||||
|  |                 return this.uuidPipeline.getUUID(candidate, Settings.UUID.NON_BLOCKING_TIMEOUT) | ||||||
|  |                         .get() | ||||||
|  |                         .map(UUIDMapping::getUuid) | ||||||
|  |                         .map(PlotMember.Player::new) | ||||||
|  |                         .orElseThrow(); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 throw new TargetParseException(candidate, context); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return new PlotMember.LazyPlayer( | ||||||
|  |                     candidate, | ||||||
|  |                     () -> this.uuidPipeline.getUUID(candidate, Settings.UUID.NON_BLOCKING_TIMEOUT) | ||||||
|  |                             .get() | ||||||
|  |                             .map(UUIDMapping::getUuid) | ||||||
|  |                             .orElse(null) | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static final class TargetParseException extends ParserException { | ||||||
|  |  | ||||||
|  |         @Serial | ||||||
|  |         private static final long serialVersionUID = 927476591631527552L; | ||||||
|  |         private final String input; | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Construct a new Player parse exception | ||||||
|  |          * | ||||||
|  |          * @param input   String input | ||||||
|  |          * @param context Command context | ||||||
|  |          */ | ||||||
|  |         public TargetParseException( | ||||||
|  |                 final @NonNull String input, | ||||||
|  |                 final @NonNull CommandContext<?> context | ||||||
|  |         ) { | ||||||
|  |             super( | ||||||
|  |                     PlotMemberParser.class, | ||||||
|  |                     context, | ||||||
|  |                     PlotSquaredCaptionKeys.ARGUMENT_PARSE_FAILURE_TARGET, | ||||||
|  |                     CaptionVariable.of("input", input) | ||||||
|  |             ); | ||||||
|  |             this.input = input; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Get the supplied input | ||||||
|  |          * | ||||||
|  |          * @return String value | ||||||
|  |          */ | ||||||
|  |         public @NonNull String getInput() { | ||||||
|  |             return this.input; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -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.requirements; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.meta.CommandMeta; | ||||||
|  | import com.plotsquared.core.configuration.caption.Caption; | ||||||
|  | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
|  | import com.plotsquared.core.player.ConsolePlayer; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import io.leangen.geantyref.TypeToken; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.EnumSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Objects; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.function.Predicate; | ||||||
|  |  | ||||||
|  | public enum CommandRequirement { | ||||||
|  |     PLAYER( | ||||||
|  |             "", | ||||||
|  |             player -> !(player instanceof ConsolePlayer) | ||||||
|  |     ), | ||||||
|  |     IN_PLOT( | ||||||
|  |             "errors.not_in_plot", | ||||||
|  |             player -> player.getCurrentPlot() != null | ||||||
|  |     ), | ||||||
|  |     PLOT_HAS_OWNER( | ||||||
|  |             "info.plot_unowned", | ||||||
|  |             player -> Objects.requireNonNull(player.getCurrentPlot()).hasOwner(), | ||||||
|  |             IN_PLOT | ||||||
|  |     ), | ||||||
|  |     IS_OWNER( | ||||||
|  |             "permission.no_plot_perms", | ||||||
|  |             player -> Objects.requireNonNull(player.getCurrentPlot()).isOwner(player.getUUID()), | ||||||
|  |             PLOT_HAS_OWNER | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     public static final CommandMeta.Key<List<CommandRequirement>> COMMAND_REQUIREMENTS_KEY = CommandMeta.Key.of( | ||||||
|  |             new TypeToken<List<CommandRequirement>>() { | ||||||
|  |             }, | ||||||
|  |             "command_requirements" | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     private final @NonNull Caption caption; | ||||||
|  |     private final @NonNull Predicate<@NonNull PlotPlayer<?>> requirementPredicate; | ||||||
|  |     private final @NonNull Set<@NonNull CommandRequirement> inheritedRequirements; | ||||||
|  |  | ||||||
|  |     CommandRequirement( | ||||||
|  |             final @NonNull String caption, | ||||||
|  |             final @NonNull Predicate<@NonNull PlotPlayer<?>> requirementPredicate, | ||||||
|  |             final @NonNull CommandRequirement... inheritedRequirements | ||||||
|  |     ) { | ||||||
|  |         this.caption = TranslatableCaption.of(caption); | ||||||
|  |         this.requirementPredicate = requirementPredicate; | ||||||
|  |         this.inheritedRequirements = EnumSet.copyOf(Arrays.asList(inheritedRequirements)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public @NonNull Set<@NonNull CommandRequirement> inheritedRequirements() { | ||||||
|  |         return Collections.unmodifiableSet(this.inheritedRequirements); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public @NonNull Caption caption() { | ||||||
|  |         return this.caption; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean checkRequirement(final @NonNull PlotPlayer<?> player) { | ||||||
|  |         return this.requirementPredicate.test(player); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | /* | ||||||
|  |  * 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.requirements; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.Command; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.EnumSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.function.BiFunction; | ||||||
|  |  | ||||||
|  | public class CommandRequirementBuilderModifier implements BiFunction< | ||||||
|  |         @NonNull Requirements, | ||||||
|  |         Command.@NonNull Builder<PlotPlayer<?>>, | ||||||
|  |         Command.@NonNull Builder<PlotPlayer<?>> | ||||||
|  | > { | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Command.@NonNull Builder<PlotPlayer<?>> apply( | ||||||
|  |             final @NonNull Requirements requirements, | ||||||
|  |             final Command.@NonNull Builder<PlotPlayer<?>> builder | ||||||
|  |     ) { | ||||||
|  |         // We use a list, because we want them to be evaluated in order. | ||||||
|  |         final Set<CommandRequirement> commandRequirements = EnumSet.noneOf(CommandRequirement.class); | ||||||
|  |         for (final Requirement requirement : requirements.value()) { | ||||||
|  |             this.addRequirements(commandRequirements, requirement.value()); | ||||||
|  |         } | ||||||
|  |         // We then sort the requirements. | ||||||
|  |         final List<CommandRequirement> sortedRequirements = commandRequirements.stream().sorted().toList(); | ||||||
|  |         // We then register all the types in the command metadata. | ||||||
|  |         return builder.meta(CommandRequirement.COMMAND_REQUIREMENTS_KEY, sortedRequirements); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void addRequirements( | ||||||
|  |             final @NonNull Set<@NonNull CommandRequirement> requirements, | ||||||
|  |             final @NonNull CommandRequirement requirement | ||||||
|  |     ) { | ||||||
|  |         for (final CommandRequirement inheritedRequirement : requirement.inheritedRequirements()) { | ||||||
|  |             addRequirements(requirements, inheritedRequirement); | ||||||
|  |         } | ||||||
|  |         requirements.add(requirement); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | /* | ||||||
|  |  * 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.requirements; | ||||||
|  |  | ||||||
|  | import cloud.commandframework.Command; | ||||||
|  | import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext; | ||||||
|  | import cloud.commandframework.execution.postprocessor.CommandPostprocessor; | ||||||
|  | import cloud.commandframework.services.types.ConsumerService; | ||||||
|  | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public class CommandRequirementPostProcessor implements CommandPostprocessor<PlotPlayer<?>> { | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept( | ||||||
|  |             @NonNull final CommandPostprocessingContext<PlotPlayer<?>> context | ||||||
|  |     ) { | ||||||
|  |         final Command<PlotPlayer<?>> command = context.getCommand(); | ||||||
|  |         final PlotPlayer<?> player = context.getCommandContext().getSender();; | ||||||
|  |         final List<CommandRequirement> commandRequirements = command.getCommandMeta().get( | ||||||
|  |                 CommandRequirement.COMMAND_REQUIREMENTS_KEY | ||||||
|  |         ).orElse(List.of()); | ||||||
|  |  | ||||||
|  |         for (final CommandRequirement requirement : commandRequirements) { | ||||||
|  |             if (requirement.checkRequirement(player)) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // They failed the requirement =( | ||||||
|  |             player.sendMessage(requirement.caption()); | ||||||
|  |  | ||||||
|  |             // Then we interrupt to make sure the command isn't executed. | ||||||
|  |             ConsumerService.interrupt(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -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.requirements; | ||||||
|  |  | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.lang.annotation.ElementType; | ||||||
|  | import java.lang.annotation.Repeatable; | ||||||
|  | import java.lang.annotation.Retention; | ||||||
|  | import java.lang.annotation.RetentionPolicy; | ||||||
|  | import java.lang.annotation.Target; | ||||||
|  |  | ||||||
|  | @Repeatable(Requirements.class) | ||||||
|  | @Retention(RetentionPolicy.RUNTIME) | ||||||
|  | @Target(ElementType.METHOD) | ||||||
|  | public @interface Requirement { | ||||||
|  |  | ||||||
|  |     @NonNull CommandRequirement value(); | ||||||
|  | } | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | /* | ||||||
|  |  * 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.requirements; | ||||||
|  |  | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.lang.annotation.ElementType; | ||||||
|  | import java.lang.annotation.Retention; | ||||||
|  | import java.lang.annotation.RetentionPolicy; | ||||||
|  | import java.lang.annotation.Target; | ||||||
|  |  | ||||||
|  | @Retention(RetentionPolicy.RUNTIME) | ||||||
|  | @Target(ElementType.METHOD) | ||||||
|  | public @interface Requirements { | ||||||
|  |  | ||||||
|  |     @NonNull Requirement @NonNull[] value(); | ||||||
|  | } | ||||||
| @@ -18,7 +18,6 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.core.events; | package com.plotsquared.core.events; | ||||||
|  |  | ||||||
| import com.plotsquared.core.command.Claim; |  | ||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
|   | |||||||
| @@ -18,7 +18,6 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.core.events; | package com.plotsquared.core.events; | ||||||
|  |  | ||||||
| import com.plotsquared.core.command.Claim; |  | ||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|   | |||||||
| @@ -288,7 +288,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer, | |||||||
|      * |      * | ||||||
|      * @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea} |      * @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea} | ||||||
|      */ |      */ | ||||||
|     public Plot getCurrentPlot() { |     public @Nullable Plot getCurrentPlot() { | ||||||
|         try (final MetaDataAccess<Plot> lastPlotAccess = |         try (final MetaDataAccess<Plot> lastPlotAccess = | ||||||
|                      this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) { |                      this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) { | ||||||
|             if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) { |             if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) { | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ import java.util.Collection; | |||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.LinkedHashSet; | import java.util.LinkedHashSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
| import java.util.concurrent.CompletableFuture; | import java.util.concurrent.CompletableFuture; | ||||||
| @@ -273,6 +274,25 @@ public class UUIDPipeline { | |||||||
|         return this.getUUIDs(requests).orTimeout(timeout, TimeUnit.MILLISECONDS); |         return this.getUUIDs(requests).orTimeout(timeout, TimeUnit.MILLISECONDS); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Asynchronously attempt to fetch the mapping from a name. | ||||||
|  |      * <p> | ||||||
|  |      * This will timeout after the specified time and throws a {@link TimeoutException} | ||||||
|  |      * if this happens | ||||||
|  |      * | ||||||
|  |      * @param username Name | ||||||
|  |      * @param timeout  Timeout in milliseconds | ||||||
|  |      * @return Mapping | ||||||
|  |      */ | ||||||
|  |     public @NonNull CompletableFuture<Optional<UUIDMapping>> getUUID( | ||||||
|  |             final @NonNull String username, | ||||||
|  |             final long timeout | ||||||
|  |     ) { | ||||||
|  |         return this.getUUIDs(List.of(username), timeout).thenApply( | ||||||
|  |                 results -> results.stream().findFirst() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Asynchronously attempt to fetch the mapping from a list of UUIDs |      * Asynchronously attempt to fetch the mapping from a list of UUIDs | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -13,9 +13,9 @@ mvdwapi = "3.1.1" | |||||||
| # Third party | # Third party | ||||||
| prtree = "2.0.0" | prtree = "2.0.0" | ||||||
| aopalliance = "1.0" | aopalliance = "1.0" | ||||||
| cloud-services = "1.8.0" |  | ||||||
| arkitektonika = "2.1.1" | arkitektonika = "2.1.1" | ||||||
| squirrelid = "0.3.1" | squirrelid = "0.3.1" | ||||||
|  | cloud = "1.8.0" | ||||||
|  |  | ||||||
| # Gradle plugins | # Gradle plugins | ||||||
| shadow = "7.1.2" | shadow = "7.1.2" | ||||||
| @@ -39,10 +39,14 @@ essentialsx = { group = "net.essentialsx", name = "EssentialsX", version.ref = " | |||||||
| # Third party | # Third party | ||||||
| prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } | prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } | ||||||
| aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } | aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } | ||||||
| cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } |  | ||||||
| mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | ||||||
| squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | ||||||
| arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | ||||||
|  | cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud" } | ||||||
|  | cloudCore = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" } | ||||||
|  | cloudAnnotations = { group = "cloud.commandframework", name = "cloud-annotations", version.ref = "cloud" } | ||||||
|  | cloudPaper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" } | ||||||
|  | cloudMinecraftExtras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" } | ||||||
|  |  | ||||||
| [plugins] | [plugins] | ||||||
| shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user