diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java b/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java index 4a3af9ee..6d07db59 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java +++ b/eco-api/src/main/java/com/willfp/eco/core/command/CommandBase.java @@ -1,5 +1,6 @@ package com.willfp.eco.core.command; +import com.willfp.eco.core.EcoPlugin; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; @@ -66,6 +67,13 @@ public interface CommandBase { return new ArrayList<>(); } + /** + * Get the plugin. + * + * @return The plugin. + */ + EcoPlugin getPlugin(); + /** * Get the handler. * diff --git a/eco-api/src/main/java/com/willfp/eco/core/command/impl/HandledCommand.java b/eco-api/src/main/java/com/willfp/eco/core/command/impl/HandledCommand.java index bdc0cb0f..563baa33 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/command/impl/HandledCommand.java +++ b/eco-api/src/main/java/com/willfp/eco/core/command/impl/HandledCommand.java @@ -1,7 +1,6 @@ package com.willfp.eco.core.command.impl; import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.PluginDependent; import com.willfp.eco.core.command.CommandBase; import com.willfp.eco.core.command.CommandHandler; import com.willfp.eco.core.command.TabCompleteHandler; @@ -25,7 +24,12 @@ import java.util.stream.Collectors; * layer, hence why it's a package-private class. */ @SuppressWarnings({"DeprecatedIsStillUsed"}) -abstract class HandledCommand extends PluginDependent implements CommandBase { +abstract class HandledCommand implements CommandBase { + /** + * The plugin. + */ + private final EcoPlugin plugin; + /** * The name of the command. */ @@ -78,7 +82,7 @@ abstract class HandledCommand extends PluginDependent implements Comm @NotNull final String name, @NotNull final String permission, final boolean playersOnly) { - super(plugin); + this.plugin = plugin; this.name = name; this.permission = permission; this.playersOnly = playersOnly; @@ -98,6 +102,16 @@ abstract class HandledCommand extends PluginDependent implements Comm return this; } + /** + * Get the plugin. + * + * @return The plugin. + */ + @Override + public EcoPlugin getPlugin() { + return this.plugin; + } + /** * Handle the command. * diff --git a/eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java b/eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java index 56c5e137..d48d2c88 100644 --- a/eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java +++ b/eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java @@ -5,6 +5,7 @@ import com.willfp.eco.core.Prerequisite; import com.willfp.eco.core.data.PlayerProfile; import com.willfp.eco.core.data.keys.PersistentDataKey; import com.willfp.eco.core.data.keys.PersistentDataKeyType; +import com.willfp.eco.core.integrations.anticheat.AnticheatManager; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import org.bukkit.OfflinePlayer; @@ -12,6 +13,8 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.function.Consumer; + /** * Utilities / API methods for players. */ @@ -107,6 +110,38 @@ public final class PlayerUtils { profile.write(PLAYER_NAME_KEY, player.getDisplayName()); } + /** + * Run something with the player exempted. + * + * @param player The player. + * @param action The action. + */ + public static void runExempted(@NotNull final Player player, + @NotNull final Consumer action) { + try { + AnticheatManager.exemptPlayer(player); + action.accept(player); + } finally { + AnticheatManager.unexemptPlayer(player); + } + } + + /** + * Run something with the player exempted. + * + * @param player The player. + * @param action The action. + */ + public static void runExempted(@NotNull final Player player, + @NotNull final Runnable action) { + try { + AnticheatManager.exemptPlayer(player); + action.run(); + } finally { + AnticheatManager.unexemptPlayer(player); + } + } + private PlayerUtils() { throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); } diff --git a/eco-api/src/main/kotlin/com/willfp/eco/core/commands/CommandHelpers.kt b/eco-api/src/main/kotlin/com/willfp/eco/core/commands/CommandHelpers.kt new file mode 100644 index 00000000..42eca18c --- /dev/null +++ b/eco-api/src/main/kotlin/com/willfp/eco/core/commands/CommandHelpers.kt @@ -0,0 +1,142 @@ +@file:JvmName("CommandHelperExtensions") + +package com.willfp.eco.core.commands + +import com.willfp.eco.core.EcoPlugin +import com.willfp.eco.core.command.CommandBase +import com.willfp.eco.core.command.impl.PluginCommand +import com.willfp.eco.core.command.impl.Subcommand +import org.bukkit.command.CommandSender + +/** + * Helper class for creating commands with builders. + * + * @param plugin The plugin. + * @param name The command name. + * @param permission The permission. + * @param playersOnly If only players should run the command. + * @param executor The command executor. + * @param tabCompleter The tab completer. + */ +class BuiltPluginCommand internal constructor( + plugin: EcoPlugin, + name: String, + permission: String, + playersOnly: Boolean = false, + var executor: (CommandSender, List) -> Unit, + var tabCompleter: (CommandSender, List) -> List, +) : PluginCommand(plugin, name, permission, playersOnly) { + override fun onExecute(sender: CommandSender, args: List) = + executor(sender, args) + + override fun tabComplete(sender: CommandSender, args: List): List = + tabCompleter(sender, args) +} + + +/** + * Helper class for creating commands with builders. + * + * @param plugin The plugin. + * @param name The command name. + * @param permission The permission. + * @param playersOnly If only players should run the command. + * @param executor The command executor. + * @param tabCompleter The tab completer. + */ +class BuiltSubcommand internal constructor( + plugin: EcoPlugin, + name: String, + permission: String, + playersOnly: Boolean = false, + var executor: (CommandSender, List) -> Unit, + var tabCompleter: (CommandSender, List) -> List, +) : Subcommand(plugin, name, permission, playersOnly) { + internal constructor( + parent: CommandBase, + name: String, + executor: (CommandSender, List) -> Unit, + tabCompleter: (CommandSender, List) -> List, + ) : this(parent.plugin, name, parent.permission, parent.isPlayersOnly, executor, tabCompleter) + + override fun onExecute(sender: CommandSender, args: List) = + executor(sender, args) + + override fun tabComplete(sender: CommandSender, args: List): List = + tabCompleter(sender, args) +} + +/** + * Kotlin builder for commands. + * + * @param plugin The plugin. + * @param name The command name. + * @param permission The permission. + * @param playersOnly If only players should execute the command. + * @param init The builder. + */ +fun command( + plugin: EcoPlugin, + name: String, + permission: String, + playersOnly: Boolean = false, + init: BuiltPluginCommand.() -> Unit +): PluginCommand { + val command = BuiltPluginCommand( + plugin, + name, + permission, + playersOnly, + { _, _ -> }, + { _, _ -> emptyList() } + ) + init(command) + return command +} + +/** + * Kotlin builder for commands. + * + * @param name The command name. + * @param permission The permission. + * @param playersOnly If only players should execute the command. + * @param init The builder. + */ +fun CommandBase.addSubcommand( + name: String, + permission: String, + playersOnly: Boolean = false, + init: BuiltSubcommand.() -> Unit +): Subcommand { + val command = BuiltSubcommand( + this.plugin, + name, + permission, + playersOnly, + { _, _ -> }, + { _, _ -> emptyList() } + ) + init(command) + return command +} + +/** + * Kotlin builder for commands. + * Inherits plugin, permission, players only. + * + * @param name The command name. + * @param init The builder. + */ +fun CommandBase.addSubcommand( + name: String, + init: BuiltSubcommand.() -> Unit +): Subcommand { + val command = BuiltSubcommand( + this, + name, + { _, _ -> }, + { _, _ -> emptyList() } + ) + init(command) + return command +} diff --git a/eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt b/eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt index efbcedca..cdb63c7e 100644 --- a/eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt +++ b/eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt @@ -24,3 +24,15 @@ fun Player.asAudience(): Audience = */ fun CommandSender.asAudience(): Audience = PlayerUtils.getAudience(this) + +/** + * @see PlayerUtils.runExempted + */ +fun Player.runExempted(action: Player.() -> Unit) = + PlayerUtils.runExempted(this, action) + +/** + * @see PlayerUtils.runExempted + */ +fun Player.runExempted(action: () -> Unit) = + PlayerUtils.runExempted(this, action)