diff options
23 files changed, 372 insertions, 709 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt index 2447ec4..3bbd4a1 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommand.kt @@ -1,28 +1,20 @@ package dev.m1sk9.lunaticChat.paper.command.core import com.mojang.brigadier.builder.LiteralArgumentBuilder -import dev.m1sk9.lunaticChat.engine.command.CommandResult import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.command.annotation.Command import dev.m1sk9.lunaticChat.paper.command.annotation.Permission -import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly -import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack -import io.papermc.paper.command.brigadier.Commands -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.format.NamedTextColor -import kotlin.reflect.full.findAnnotation -import kotlin.reflect.full.memberFunctions /** - * Abstract base class for all LunaticChat commands. - * Provides common functionality and enforces consistent command structure. + * A command registered with the server under its own name. + * + * Subcommands attached under a parent literal extend [LunaticSubCommand] instead: they have no + * `@Command` annotation, so [name], [aliases] and [description] would have nothing to read. */ abstract class LunaticCommand( - // Reference to the main plugin instance - // DO NOT REMOVE - needed for command registration - protected val plugin: LunaticChat, -) { + plugin: LunaticChat, +) : LunaticCommandBase(plugin) { private val commandAnnotation: Command by lazy { this::class.annotations.filterIsInstance<Command>().firstOrNull() ?: throw IllegalStateException("Command class must be annotated with @Command") @@ -32,10 +24,6 @@ abstract class LunaticCommand( this::class.annotations.filterIsInstance<Permission>().firstOrNull() } - private val isPlayerOnly: Boolean by lazy { - this::class.annotations.any { it is PlayerOnly } - } - /** The primary command name */ val name: String get() = commandAnnotation.name @@ -71,92 +59,4 @@ abstract class LunaticCommand( return builder } - - /** - * Helper method for checking player-only restriction. - * Called at the beginning of execute methods. - */ - protected fun checkPlayerOnly(ctx: CommandContext): CommandResult? { - if (isPlayerOnly && !ctx.isPlayer) { - return CommandResult.Failure( - MessageFormatter.formatError( - plugin.languageManager.getMessage("general.playerOnlyCommand"), - ), - ) - } - - return null - } - - /** - * Utility to wrap Brigadier context into LunaticChat CommandContext. - */ - protected fun wrapContext(ctx: com.mojang.brigadier.context.CommandContext<CommandSourceStack>): CommandContext = - CommandContext(ctx.source) - - /** - * Helper for handling command results and sending appropriate messages. - */ - protected fun handleResult( - ctx: CommandContext, - result: CommandResult, - ): Int { - when (result) { - is CommandResult.Success -> {} - is CommandResult.SuccessWithMessage -> ctx.reply(result.message) - is CommandResult.Failure -> ctx.reply(result.message) - is CommandResult.InvalidUsage -> - ctx.reply( - Component - .text("Usage: ${result.usageHint}") - .color(NamedTextColor.RED), - ) - } - return result.toBrigadierResult() - } - - /** - * Creates alias nodes for a subcommand. - * Each alias gets the same children, executor, and permission requirement as the primary node. - * Brigadier automatically provides tab completion for all registered literal nodes. - * - * @param primary The primary subcommand builder - * @param aliases The alias names for the subcommand - * @return A list containing the primary builder followed by alias builders - */ - protected fun withAliases( - primary: LiteralArgumentBuilder<CommandSourceStack>, - aliases: List<String>, - ): List<LiteralArgumentBuilder<CommandSourceStack>> { - if (aliases.isEmpty()) return listOf(primary) - return listOf(primary) + - aliases.map { alias -> - val aliasBuilder = Commands.literal(alias) - primary.arguments.forEach { aliasBuilder.then(it) } - primary.command?.let { aliasBuilder.executes(it) } - aliasBuilder.requires(primary.requirement) - aliasBuilder - } - } - - /** - * Applies permission checks to a subcommand builder based on method-level @Permission annotation. - * Used for subcommands that use build() instead of buildCommand(). - * - * @param methodName The name of the method to check for @Permission annotation - * @param builder The subcommand builder to wrap - * @return The builder with permission checks applied if annotation is present - */ - protected fun applyMethodPermission( - methodName: String, - builder: LiteralArgumentBuilder<CommandSourceStack>, - ): LiteralArgumentBuilder<CommandSourceStack> { - val method = this::class.memberFunctions.find { it.name == methodName } ?: return builder - val permissionAnnotation = method.findAnnotation<Permission>() ?: return builder - val permissionNode = permissionAnnotation.value.objectInstance?.permissionNode ?: return builder - - return builder.requires { source -> - source.sender.hasPermission(permissionNode) - } - } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommandBase.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommandBase.kt new file mode 100644 index 0000000..596d70d --- /dev/null +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticCommandBase.kt @@ -0,0 +1,92 @@ +package dev.m1sk9.lunaticChat.paper.command.core + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import dev.m1sk9.lunaticChat.engine.command.CommandResult +import dev.m1sk9.lunaticChat.paper.LunaticChat +import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly +import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter +import io.papermc.paper.command.brigadier.CommandSourceStack +import io.papermc.paper.command.brigadier.Commands +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor + +/** + * Functionality shared by every command node, whether it is registered with the server + * ([LunaticCommand]) or attached under a parent literal ([LunaticSubCommand]). + */ +abstract class LunaticCommandBase( + // Reference to the main plugin instance + // DO NOT REMOVE - needed for command registration + protected val plugin: LunaticChat, +) { + private val isPlayerOnly: Boolean by lazy { + this::class.annotations.any { it is PlayerOnly } + } + + /** + * Helper method for checking player-only restriction. + * Called at the beginning of execute methods. + */ + protected fun checkPlayerOnly(ctx: CommandContext): CommandResult? { + if (isPlayerOnly && !ctx.isPlayer) { + return CommandResult.Failure( + MessageFormatter.formatError( + plugin.languageManager.getMessage("general.playerOnlyCommand"), + ), + ) + } + + return null + } + + /** + * Utility to wrap Brigadier context into LunaticChat CommandContext. + */ + protected fun wrapContext(ctx: com.mojang.brigadier.context.CommandContext<CommandSourceStack>): CommandContext = + CommandContext(ctx.source) + + /** + * Helper for handling command results and sending appropriate messages. + */ + protected fun handleResult( + ctx: CommandContext, + result: CommandResult, + ): Int { + when (result) { + is CommandResult.Success -> {} + is CommandResult.SuccessWithMessage -> ctx.reply(result.message) + is CommandResult.Failure -> ctx.reply(result.message) + is CommandResult.InvalidUsage -> + ctx.reply( + Component + .text("Usage: ${result.usageHint}") + .color(NamedTextColor.RED), + ) + } + return result.toBrigadierResult() + } + + /** + * Creates alias nodes for a subcommand. + * Each alias gets the same children, executor, and permission requirement as the primary node. + * Brigadier automatically provides tab completion for all registered literal nodes. + * + * @param primary The primary subcommand builder + * @param aliases The alias names for the subcommand + * @return A list containing the primary builder followed by alias builders + */ + protected fun withAliases( + primary: LiteralArgumentBuilder<CommandSourceStack>, + aliases: List<String>, + ): List<LiteralArgumentBuilder<CommandSourceStack>> { + if (aliases.isEmpty()) return listOf(primary) + return listOf(primary) + + aliases.map { alias -> + val aliasBuilder = Commands.literal(alias) + primary.arguments.forEach { aliasBuilder.then(it) } + primary.command?.let { aliasBuilder.executes(it) } + aliasBuilder.requires(primary.requirement) + aliasBuilder + } + } +} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommand.kt new file mode 100644 index 0000000..e8db3fb --- /dev/null +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommand.kt @@ -0,0 +1,44 @@ +package dev.m1sk9.lunaticChat.paper.command.core + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode +import dev.m1sk9.lunaticChat.paper.LunaticChat +import io.papermc.paper.command.brigadier.CommandSourceStack + +/** + * A command node attached under a parent literal rather than registered with the server. + * + * The permission gate is a declared property instead of an annotation read by reflection, so a + * subcommand that forgets it fails to compile rather than silently accepting everyone. + */ +abstract class LunaticSubCommand( + plugin: LunaticChat, +) : LunaticCommandBase(plugin) { + /** + * The literal this subcommand is typed as. Parents use it to look up help text, so it must be + * the same string [build] passes to `Commands.literal`. + */ + abstract val literal: String + + /** Permission required to see and run this subcommand, or null to inherit the parent's gate. */ + protected abstract val permissionNode: LunaticChatPermissionNode? + + /** Extra literals registered next to the primary node, sharing its arguments and executor. */ + protected open val aliases: List<String> = emptyList() + + /** + * Builds the primary subcommand node, without the permission gate. + */ + abstract fun build(): LiteralArgumentBuilder<CommandSourceStack> + + /** + * Builds the primary node and its aliases, each gated on [permissionNode]. + */ + fun buildAll(): List<LiteralArgumentBuilder<CommandSourceStack>> { + val primary = build() + permissionNode?.let { node -> + primary.requires { source -> source.sender.hasPermission(node.permissionNode) } + } + return withAliases(primary, aliases) + } +} diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChannelCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChannelCommand.kt index 13c30dd..b3a1981 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChannelCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/ChannelCommand.kt @@ -7,10 +7,9 @@ import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.command.impl.lc.channel.ChannelBanCommand import dev.m1sk9.lunaticChat.paper.command.impl.lc.channel.ChannelCreateCommand import dev.m1sk9.lunaticChat.paper.command.impl.lc.channel.ChannelDeleteCommand @@ -38,117 +37,17 @@ class ChannelCommand( private val membershipManager: ChannelMembershipManager, private val notificationHandler: ChannelNotificationHandler, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("ch")) - - @Permission(LunaticChatPermissionNode.Channel::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> { - val channelCommand = Commands.literal("channel") - - // Add subcommands (with aliases) - ChannelCreateCommand( - plugin, - channelManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelListCommand( - plugin, - channelManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelJoinCommand( - plugin, - channelManager, - membershipManager, - notificationHandler, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelLeaveCommand( - plugin, - channelManager, - membershipManager, - notificationHandler, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelSwitchCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } +) : LunaticSubCommand(plugin) { + override val literal = "channel" + override val permissionNode = LunaticChatPermissionNode.Channel + override val aliases = listOf("ch") - ChannelStatusCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } + override fun build(): LiteralArgumentBuilder<CommandSourceStack> { + val channelCommand = Commands.literal(literal) - ChannelInfoCommand( - plugin, - channelManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelDeleteCommand( - plugin, - channelManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelInviteCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelKickCommand( - plugin, - channelManager, - membershipManager, - notificationHandler, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelBanCommand( - plugin, - channelManager, - membershipManager, - notificationHandler, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelUnbanCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelModCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } - - ChannelOwnershipCommand( - plugin, - channelManager, - membershipManager, - languageManager, - ).buildAllWithPermissionCheck().forEach { channelCommand.then(it) } + subcommands().forEach { subcommand -> + subcommand.buildAll().forEach { channelCommand.then(it) } + } // Default help message when no subcommand is provided channelCommand.executes { ctx -> @@ -162,6 +61,30 @@ class ChannelCommand( return channelCommand } + /** + * The subcommands of /lc channel, in the order they are advertised by [showHelp]. + * + * Registration and help share this one list so a new subcommand cannot appear in the tree + * while staying invisible in the help output, or the reverse. + */ + private fun subcommands(): List<LunaticSubCommand> = + listOf( + ChannelCreateCommand(plugin, channelManager, languageManager), + ChannelListCommand(plugin, channelManager, languageManager), + ChannelJoinCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager), + ChannelLeaveCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager), + ChannelSwitchCommand(plugin, channelManager, membershipManager, languageManager), + ChannelStatusCommand(plugin, channelManager, membershipManager, languageManager), + ChannelInfoCommand(plugin, channelManager, languageManager), + ChannelDeleteCommand(plugin, channelManager, languageManager), + ChannelInviteCommand(plugin, channelManager, membershipManager, languageManager), + ChannelKickCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager), + ChannelBanCommand(plugin, channelManager, membershipManager, notificationHandler, languageManager), + ChannelUnbanCommand(plugin, channelManager, membershipManager, languageManager), + ChannelModCommand(plugin, channelManager, membershipManager, languageManager), + ChannelOwnershipCommand(plugin, channelManager, membershipManager, languageManager), + ) + private fun showHelp(ctx: CommandContext): CommandResult { val sender = ctx.requirePlayer() @@ -170,138 +93,18 @@ class ChannelCommand( languageManager.getMessage("channel.help.header"), ), ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.create"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.list"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.join"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.leave"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.switch"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.status"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.info"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.delete"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.invite"), + subcommands().forEach { subcommand -> + sender.sendMessage( + Component + .text(" ") + .append( + MessageFormatter.formatSuccess( + languageManager.getMessage("channel.help.${subcommand.literal}"), + ), ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.kick"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.ban"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.unban"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.mod"), - ), - ), - ) - sender.sendMessage( - Component - .text(" ") - .append( - MessageFormatter.formatSuccess( - languageManager.getMessage("channel.help.ownership"), - ), - ), - ) + ) + } return CommandResult.Success } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "Should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt index 2be0128..bd9ca9b 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/LunaticChatCommand.kt @@ -40,13 +40,13 @@ class LunaticChatCommand( plugin, settingHandlerRegistry, languageManager, - ).buildAllWithPermissionCheck().forEach { command.then(it) } + ).buildAll().forEach { command.then(it) } StatusCommand( plugin, languageManager, configuration, - ).buildAllWithPermissionCheck().forEach { command.then(it) } + ).buildAll().forEach { command.then(it) } // Add channel command if channel manager is available plugin.channelManager?.let { manager -> @@ -58,7 +58,7 @@ class LunaticChatCommand( membershipManager, notificationHandler, languageManager, - ).buildAllWithPermissionCheck().forEach { command.then(it) } + ).buildAll().forEach { command.then(it) } } } } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/SettingsCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/SettingsCommand.kt index bf5a245..e8f66d4 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/SettingsCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/SettingsCommand.kt @@ -4,10 +4,9 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder import dev.m1sk9.lunaticChat.engine.command.CommandResult import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.command.setting.SettingHandlerRegistry import dev.m1sk9.lunaticChat.paper.command.setting.SettingKey import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager @@ -29,18 +28,10 @@ class SettingsCommand( plugin: LunaticChat, private val settingHandlerRegistry: SettingHandlerRegistry, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - /** - * Builds the setting subcommand structure with permission checks. - * This method should be called from parent commands. - */ - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("set")) +) : LunaticSubCommand(plugin) { + override val literal = "settings" + override val permissionNode = LunaticChatPermissionNode.Settings + override val aliases = listOf("set") /** * Builds the setting subcommand structure. @@ -49,9 +40,8 @@ class SettingsCommand( * - /lc setting <key> off * - /lc setting <key> (shows status) */ - @Permission(LunaticChatPermissionNode.Settings::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> { - val settingCommand = Commands.literal("settings") + override fun build(): LiteralArgumentBuilder<CommandSourceStack> { + val settingCommand = Commands.literal(literal) for (settingKey in SettingKey.values()) { val handler = settingHandlerRegistry.getHandler(settingKey) @@ -114,9 +104,4 @@ class SettingsCommand( ctx.reply(helpMessage) return CommandResult.Success } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "SettingsSubcommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt index 1f75cf2..f47285e 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/StatusCommand.kt @@ -5,9 +5,8 @@ import dev.m1sk9.lunaticChat.engine.command.CommandResult import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.BuildInfo import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.config.LunaticChatConfiguration import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter @@ -23,18 +22,13 @@ class StatusCommand( plugin: LunaticChat, private val languageManager: LanguageManager, private val configuration: LunaticChatConfiguration, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("st")) +) : LunaticSubCommand(plugin) { + override val literal = "status" + override val permissionNode = LunaticChatPermissionNode.Status + override val aliases = listOf("st") - @Permission(LunaticChatPermissionNode.Status::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = - Commands.literal("status").executes { ctx -> + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = + Commands.literal(literal).executes { ctx -> val context = wrapContext(ctx) checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } @@ -177,9 +171,4 @@ class StatusCommand( .append(Component.text("$label: ", NamedTextColor.GRAY)) .append(Component.text(toggleText, color)) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "Should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt index 67a4a5d..c459ca0 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelBanCommand.kt @@ -12,10 +12,9 @@ import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -29,19 +28,13 @@ class ChannelBanCommand( private val membershipManager: ChannelMembershipManager, private val notificationHandler: ChannelNotificationHandler, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), emptyList()) +) : LunaticSubCommand(plugin) { + override val literal = "ban" + override val permissionNode = LunaticChatPermissionNode.ChannelBan - @Permission(LunaticChatPermissionNode.ChannelBan::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("ban") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -205,9 +198,4 @@ class ChannelBanCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelBanCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt index 8f93261..83382c6 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelCreateCommand.kt @@ -9,10 +9,9 @@ import dev.m1sk9.lunaticChat.engine.exception.ChannelLimitExceededException import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -23,19 +22,14 @@ class ChannelCreateCommand( plugin: LunaticChat, private val channelManager: ChannelManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("new")) +) : LunaticSubCommand(plugin) { + override val literal = "create" + override val permissionNode = LunaticChatPermissionNode.ChannelCreate + override val aliases = listOf("new") - @Permission(LunaticChatPermissionNode.ChannelCreate::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("create") + .literal(literal) .then( Commands .argument("channelId", StringArgumentType.word()) @@ -158,9 +152,4 @@ class ChannelCreateCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelCreateCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt index 9632d30..6ac6c00 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelDeleteCommand.kt @@ -8,10 +8,9 @@ import dev.m1sk9.lunaticChat.engine.exception.ChannelNotFoundException import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -22,19 +21,14 @@ class ChannelDeleteCommand( plugin: LunaticChat, private val channelManager: ChannelManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("del")) +) : LunaticSubCommand(plugin) { + override val literal = "delete" + override val permissionNode = LunaticChatPermissionNode.ChannelDelete + override val aliases = listOf("del") - @Permission(LunaticChatPermissionNode.ChannelDelete::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("delete") + .literal(literal) .then( Commands .argument("channelId", StringArgumentType.word()) @@ -124,9 +118,4 @@ class ChannelDeleteCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelDeleteCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt index 212f3dc..a9b464b 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInfoCommand.kt @@ -6,10 +6,9 @@ import dev.m1sk9.lunaticChat.engine.command.CommandResult import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -23,23 +22,18 @@ class ChannelInfoCommand( plugin: LunaticChat, private val channelManager: ChannelManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { +) : LunaticSubCommand(plugin) { companion object { private const val MAX_MEMBERS_DISPLAY = 10 } - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("i")) + override val literal = "info" + override val permissionNode = LunaticChatPermissionNode.ChannelInfo + override val aliases = listOf("i") - @Permission(LunaticChatPermissionNode.ChannelInfo::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("info") + .literal(literal) .executes { ctx -> val context = wrapContext(ctx) checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } @@ -174,9 +168,4 @@ class ChannelInfoCommand( return CommandResult.Success } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelInfoCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt index b6c0de3..096d80c 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelInviteCommand.kt @@ -11,10 +11,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -27,19 +26,14 @@ class ChannelInviteCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("inv")) +) : LunaticSubCommand(plugin) { + override val literal = "invite" + override val permissionNode = LunaticChatPermissionNode.ChannelInvite + override val aliases = listOf("inv") - @Permission(LunaticChatPermissionNode.ChannelInvite::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("invite") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -187,9 +181,4 @@ class ChannelInviteCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelInviteCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt index e5433eb..119e89a 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelJoinCommand.kt @@ -15,10 +15,9 @@ import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.common.playChannelJoinNotification import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter @@ -32,19 +31,14 @@ class ChannelJoinCommand( private val membershipManager: ChannelMembershipManager, private val notificationHandler: ChannelNotificationHandler, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("j")) +) : LunaticSubCommand(plugin) { + override val literal = "join" + override val permissionNode = LunaticChatPermissionNode.ChannelJoin + override val aliases = listOf("j") - @Permission(LunaticChatPermissionNode.ChannelJoin::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("join") + .literal(literal) .then( Commands .argument("channelId", StringArgumentType.word()) @@ -170,9 +164,4 @@ class ChannelJoinCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelJoinCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt index d4dd103..9443e5f 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelKickCommand.kt @@ -10,10 +10,9 @@ import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -27,19 +26,14 @@ class ChannelKickCommand( private val membershipManager: ChannelMembershipManager, private val notificationHandler: ChannelNotificationHandler, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("k")) +) : LunaticSubCommand(plugin) { + override val literal = "kick" + override val permissionNode = LunaticChatPermissionNode.ChannelKick + override val aliases = listOf("k") - @Permission(LunaticChatPermissionNode.ChannelKick::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("kick") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -202,9 +196,4 @@ class ChannelKickCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelKickCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt index 47556bf..e329ca3 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelLeaveCommand.kt @@ -8,10 +8,9 @@ import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager import dev.m1sk9.lunaticChat.paper.chat.handler.ChannelNotificationHandler -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -24,18 +23,13 @@ class ChannelLeaveCommand( private val membershipManager: ChannelMembershipManager, private val notificationHandler: ChannelNotificationHandler, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("l")) +) : LunaticSubCommand(plugin) { + override val literal = "leave" + override val permissionNode = LunaticChatPermissionNode.ChannelLeave + override val aliases = listOf("l") - @Permission(LunaticChatPermissionNode.ChannelLeave::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = - Commands.literal("leave").executes { ctx -> + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = + Commands.literal(literal).executes { ctx -> val context = wrapContext(ctx) checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } @@ -87,9 +81,4 @@ class ChannelLeaveCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelLeaveCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt index daa060b..949f6cc 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelListCommand.kt @@ -6,10 +6,9 @@ import dev.m1sk9.lunaticChat.engine.command.CommandResult import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -25,23 +24,18 @@ class ChannelListCommand( plugin: LunaticChat, private val channelManager: ChannelManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { +) : LunaticSubCommand(plugin) { companion object { private const val CHANNELS_PER_PAGE = 10 } - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("ls")) + override val literal = "list" + override val permissionNode = LunaticChatPermissionNode.ChannelList + override val aliases = listOf("ls") - @Permission(LunaticChatPermissionNode.ChannelList::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("list") + .literal(literal) .executes { ctx -> val context = wrapContext(ctx) checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } @@ -197,9 +191,4 @@ class ChannelListCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelListCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt index 9a29c75..8d9be52 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelModCommand.kt @@ -9,10 +9,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -25,19 +24,13 @@ class ChannelModCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), emptyList()) +) : LunaticSubCommand(plugin) { + override val literal = "mod" + override val permissionNode = LunaticChatPermissionNode.ChannelMod - @Permission(LunaticChatPermissionNode.ChannelMod::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("mod") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -193,9 +186,4 @@ class ChannelModCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelModCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt index 59ee5c0..20928bf 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelOwnershipCommand.kt @@ -9,10 +9,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -25,19 +24,14 @@ class ChannelOwnershipCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("own")) +) : LunaticSubCommand(plugin) { + override val literal = "ownership" + override val permissionNode = LunaticChatPermissionNode.ChannelOwnership + override val aliases = listOf("own") - @Permission(LunaticChatPermissionNode.ChannelOwnership::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("ownership") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -179,9 +173,4 @@ class ChannelOwnershipCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelOwnershipCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt index 8a4400b..2da2bb8 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelStatusCommand.kt @@ -7,10 +7,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -28,22 +27,17 @@ class ChannelStatusCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { +) : LunaticSubCommand(plugin) { companion object { private const val MAX_MEMBERS_DISPLAY = 10 } - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("st")) + override val literal = "status" + override val permissionNode = LunaticChatPermissionNode.ChannelStatus + override val aliases = listOf("st") - @Permission(LunaticChatPermissionNode.ChannelStatus::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = - Commands.literal("status").executes { ctx -> + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = + Commands.literal(literal).executes { ctx -> val context = wrapContext(ctx) checkPlayerOnly(context)?.let { return@executes handleResult(context, it) } @@ -247,9 +241,4 @@ class ChannelStatusCommand( return CommandResult.Success } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelStatusCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt index b5bd18d..974fd38 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelSwitchCommand.kt @@ -10,10 +10,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -25,19 +24,14 @@ class ChannelSwitchCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), listOf("sw")) +) : LunaticSubCommand(plugin) { + override val literal = "switch" + override val permissionNode = LunaticChatPermissionNode.ChannelSwitch + override val aliases = listOf("sw") - @Permission(LunaticChatPermissionNode.ChannelSwitch::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("switch") + .literal(literal) .then( Commands .argument("channelId", StringArgumentType.word()) @@ -125,9 +119,4 @@ class ChannelSwitchCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelSwitchCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt index 2bde39f..1d89b06 100644 --- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt +++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/command/impl/lc/channel/ChannelUnbanCommand.kt @@ -10,10 +10,9 @@ import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode import dev.m1sk9.lunaticChat.paper.LunaticChat import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelManager import dev.m1sk9.lunaticChat.paper.chat.channel.ChannelMembershipManager -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission import dev.m1sk9.lunaticChat.paper.command.annotation.PlayerOnly import dev.m1sk9.lunaticChat.paper.command.core.CommandContext -import dev.m1sk9.lunaticChat.paper.command.core.LunaticCommand +import dev.m1sk9.lunaticChat.paper.command.core.LunaticSubCommand import dev.m1sk9.lunaticChat.paper.i18n.LanguageManager import dev.m1sk9.lunaticChat.paper.i18n.MessageFormatter import io.papermc.paper.command.brigadier.CommandSourceStack @@ -26,19 +25,13 @@ class ChannelUnbanCommand( private val channelManager: ChannelManager, private val membershipManager: ChannelMembershipManager, private val languageManager: LanguageManager, -) : LunaticCommand(plugin) { - fun buildWithPermissionCheck(): LiteralArgumentBuilder<CommandSourceStack> { - val builder = build() - return applyMethodPermission("build", builder) - } - - fun buildAllWithPermissionCheck(): List<LiteralArgumentBuilder<CommandSourceStack>> = - withAliases(buildWithPermissionCheck(), emptyList()) +) : LunaticSubCommand(plugin) { + override val literal = "unban" + override val permissionNode = LunaticChatPermissionNode.ChannelUnban - @Permission(LunaticChatPermissionNode.ChannelUnban::class) - fun build(): LiteralArgumentBuilder<CommandSourceStack> = + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands - .literal("unban") + .literal(literal) .then( Commands .argument("playerName", StringArgumentType.word()) @@ -154,9 +147,4 @@ class ChannelUnbanCommand( }, ) } - - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = - throw UnsupportedOperationException( - "ChannelUnbanCommand should use build() method instead of buildCommand()", - ) } diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/ApplyMethodPermissionTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/ApplyMethodPermissionTest.kt deleted file mode 100644 index 1625ebd..0000000 --- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/ApplyMethodPermissionTest.kt +++ /dev/null @@ -1,67 +0,0 @@ -package dev.m1sk9.lunaticChat.paper.command.core - -import com.mojang.brigadier.builder.LiteralArgumentBuilder -import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode -import dev.m1sk9.lunaticChat.paper.LunaticChat -import dev.m1sk9.lunaticChat.paper.command.annotation.Permission -import io.mockk.every -import io.mockk.mockk -import io.papermc.paper.command.brigadier.CommandSourceStack -import io.papermc.paper.command.brigadier.Commands -import kotlin.test.Test -import kotlin.test.assertNotNull -import kotlin.test.assertSame - -@Suppress("UnstableApiUsage") -class ApplyMethodPermissionTest { - /** - * Test helper that exposes [LunaticCommand.applyMethodPermission] and has - * an annotated method for testing. - */ - private class TestableCommand( - plugin: LunaticChat, - ) : LunaticCommand(plugin) { - override fun buildCommand(): LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("test") - - /** Expose the protected applyMethodPermission for testing. */ - fun testApplyMethodPermission( - methodName: String, - builder: LiteralArgumentBuilder<CommandSourceStack>, - ): LiteralArgumentBuilder<CommandSourceStack> = applyMethodPermission(methodName, builder) - - @Permission(LunaticChatPermissionNode.Status::class) - fun annotatedMethod(): LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("annotated") - - fun unannotatedMethod(): LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("unannotated") - } - - private val plugin = mockk<LunaticChat>(relaxed = true) - private val command = TestableCommand(plugin) - - @Test - fun `applyMethodPermission adds requirement when method has Permission annotation`() { - val builder = Commands.literal("test") - val result = command.testApplyMethodPermission("annotatedMethod", builder) - - // The builder should have a requirement set (not the default always-true) - val source = mockk<CommandSourceStack>() - every { source.sender.hasPermission("lunaticchat.command.lc.status") } returns false - assertNotNull(result.requirement) - } - - @Test - fun `applyMethodPermission returns builder unchanged when method has no Permission annotation`() { - val builder = Commands.literal("test") - val result = command.testApplyMethodPermission("unannotatedMethod", builder) - - assertSame(builder, result) - } - - @Test - fun `applyMethodPermission returns builder unchanged when method does not exist`() { - val builder = Commands.literal("test") - val result = command.testApplyMethodPermission("nonExistentMethod", builder) - - assertSame(builder, result) - } -} diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommandTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommandTest.kt new file mode 100644 index 0000000..16ff92d --- /dev/null +++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/command/core/LunaticSubCommandTest.kt @@ -0,0 +1,74 @@ +package dev.m1sk9.lunaticChat.paper.command.core + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import dev.m1sk9.lunaticChat.engine.permission.LunaticChatPermissionNode +import dev.m1sk9.lunaticChat.paper.LunaticChat +import io.mockk.every +import io.mockk.mockk +import io.papermc.paper.command.brigadier.CommandSourceStack +import io.papermc.paper.command.brigadier.Commands +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +@Suppress("UnstableApiUsage") +class LunaticSubCommandTest { + private class GatedSubCommand( + plugin: LunaticChat, + override val permissionNode: LunaticChatPermissionNode?, + override val aliases: List<String> = emptyList(), + ) : LunaticSubCommand(plugin) { + override val literal = "status" + + override fun build(): LiteralArgumentBuilder<CommandSourceStack> = Commands.literal(literal) + } + + private val plugin = mockk<LunaticChat>(relaxed = true) + + private fun sourceWith( + permission: String, + granted: Boolean, + ): CommandSourceStack = + mockk<CommandSourceStack>().also { + every { it.sender.hasPermission(permission) } returns granted + } + + @Test + fun `buildAll admits a sender holding the declared permission`() { + val command = GatedSubCommand(plugin, LunaticChatPermissionNode.Status) + + val primary = command.buildAll().first() + + assertTrue(primary.requirement.test(sourceWith("lunaticchat.command.lc.status", granted = true))) + } + + @Test + fun `buildAll rejects a sender lacking the declared permission`() { + val command = GatedSubCommand(plugin, LunaticChatPermissionNode.Status) + + val primary = command.buildAll().first() + + assertFalse(primary.requirement.test(sourceWith("lunaticchat.command.lc.status", granted = false))) + } + + @Test + fun `buildAll leaves the node ungated when no permission is declared`() { + val command = GatedSubCommand(plugin, permissionNode = null) + + val primary = command.buildAll().first() + + assertTrue(primary.requirement.test(mockk<CommandSourceStack>())) + } + + @Test + fun `buildAll gates alias nodes the same as the primary`() { + val command = GatedSubCommand(plugin, LunaticChatPermissionNode.Status, aliases = listOf("st")) + + val nodes = command.buildAll() + + assertEquals(2, nodes.size) + assertEquals("st", nodes[1].literal) + assertFalse(nodes[1].requirement.test(sourceWith("lunaticchat.command.lc.status", granted = false))) + } +} |
