diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommand.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommand.kt
index aeb53f91..2c547d74 100644
--- a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommand.kt
+++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommand.kt
@@ -19,6 +19,7 @@ import java.util.logging.Level
class BasicsCommand internal constructor(
var info: CommandInfo,
private var executor: BasicsCommandExecutor?,
+ private var tabCompleter: BasicsTabCompleter?,
val coreMessages: CoreMessages,
val messageFactory: MessageFactory,
) :
@@ -34,11 +35,6 @@ class BasicsCommand internal constructor(
permissionMessage = info.permissionMessage.tagParsed("permission", permString).toLegacyString()
}
-// private val customUsageMessage = messageFactory.createMessage(
-// "Invalid command usage.",
-// "Usage: "
-// ).tagParsed("usage", usage).tagParsed("command", name)
-
override fun execute(
sender: CommandSender,
commandLabel: String,
@@ -108,8 +104,8 @@ class BasicsCommand internal constructor(
args = args.toMutableList(),
location = location,
)
- if (executor == null) return mutableListOf()
- val result = executor!!.tabComplete(context)
+ if (tabCompleter == null) return mutableListOf()
+ val result = tabCompleter!!.tabComplete(context)
return result ?: super.tabComplete(sender, alias, args, location)
}
@@ -120,5 +116,6 @@ class BasicsCommand internal constructor(
*/
fun disableExecutor() {
executor = null
+ tabCompleter = null
}
}
diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandBuilder.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandBuilder.kt
index afeb3e19..c0c4c4cb 100644
--- a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandBuilder.kt
+++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandBuilder.kt
@@ -14,6 +14,7 @@ class BasicsCommandBuilder(
private var usage: String = ""
private var aliases: List = emptyList()
private var executor: BasicsCommandExecutor? = null
+ private var tabCompleter: BasicsTabCompleter? = null
fun description(description: String) = apply { this.description = description }
@@ -29,6 +30,8 @@ class BasicsCommandBuilder(
fun executor(executor: BasicsCommandExecutor) = apply { this.executor = executor }
+ fun tabCompleter(tabCompleter: BasicsTabCompleter) = apply { this.tabCompleter = tabCompleter }
+
fun executor(executor: (BasicsCommandContext) -> CommandResult?) =
apply {
this.executor =
@@ -39,6 +42,16 @@ class BasicsCommandBuilder(
}
}
+ fun tabCompleter(tabCompleter: (BasicsCommandContext) -> MutableList?) =
+ apply {
+ this.tabCompleter =
+ object : BasicsTabCompleter {
+ override fun tabComplete(context: BasicsCommandContext): MutableList? {
+ return tabCompleter(context)
+ }
+ }
+ }
+
fun register(): BasicsCommand {
val command = build()
module.commandManager.registerCommand(command)
@@ -56,10 +69,11 @@ class BasicsCommandBuilder(
aliases = aliases,
)
return BasicsCommand(
- info,
- executor ?: error("Executor must be set"),
- module.plugin.messages,
- module.plugin.messageFactory,
+ info = info,
+ executor = executor ?: error("Executor must be set"),
+ tabCompleter = tabCompleter ?: executor,
+ coreMessages = module.plugin.messages,
+ messageFactory = module.plugin.messageFactory,
)
}
}
diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandContextHandler.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandContextHandler.kt
new file mode 100644
index 00000000..3302d725
--- /dev/null
+++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandContextHandler.kt
@@ -0,0 +1,79 @@
+package com.github.spigotbasics.core.command
+
+import com.github.spigotbasics.core.messages.CoreMessages
+import com.github.spigotbasics.core.messages.MessageFactory
+import org.bukkit.Bukkit
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+import org.bukkit.inventory.ItemStack
+import org.bukkit.permissions.Permission
+
+abstract class BasicsCommandContextHandler(
+ val coreMessages: CoreMessages,
+ val messageFactory: MessageFactory,
+) {
+ @Throws(BasicsCommandException::class)
+ fun requirePlayer(name: String): Player {
+ val player = Bukkit.getPlayer(name)
+ if (player == null) {
+ throw BasicsCommandException(CommandResult.playerNotFound(name))
+ }
+ return player
+ }
+
+ @Throws(BasicsCommandException::class)
+ fun notFromConsole(sender: CommandSender): Player {
+ if (sender !is Player) {
+ throw CommandResult.NOT_FROM_CONSOLE.asException()
+ }
+ return sender
+ }
+
+ // TODO: In 99% of cases, we should just use requirePlayer(CommandSender) instead of this method
+ @Throws(BasicsCommandException::class)
+ fun requirePlayerOrMustSpecifyPlayerFromConsole(sender: CommandSender): Player {
+ val player = sender as? Player
+ if (player == null) {
+ throw CommandResult.MUST_BE_PLAYER_OR_SPECIFY_PLAYER_FROM_CONSOLE.asException()
+ }
+ return player
+ }
+
+ @Throws(BasicsCommandException::class)
+ fun failIfFlagsLeft(context: BasicsCommandContext) {
+ if (context.flags.isEmpty()) return
+ throw CommandResult.unknownFlag(context.flags[0]).asException()
+ }
+
+ @Throws(BasicsCommandException::class)
+ fun failInvalidArgument(argument: String): CommandResult {
+ throw CommandResult.invalidArgument(argument).asException()
+ }
+
+ fun requirePermission(
+ sender: CommandSender,
+ permission: Permission,
+ ) {
+ if (!sender.hasPermission(permission)) {
+ throw CommandResult.noPermission(permission).asException()
+ }
+ }
+
+ // @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+
+ fun requireItemInHand(player: Player): ItemStack {
+ val item = player.inventory.itemInMainHand
+ if (item.type.isAir) {
+ throw CommandResult.NO_ITEM_IN_HAND.asException()
+ }
+ return item
+ }
+
+ fun requireItemInHandOther(player: Player): ItemStack {
+ val item = player.inventory.itemInMainHand
+ if (item.type.isAir) {
+ throw CommandResult.noItemInHandOthers(player).asException()
+ }
+ return item
+ }
+}
diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandExecutor.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandExecutor.kt
index 0d2009a2..d77277e7 100644
--- a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandExecutor.kt
+++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsCommandExecutor.kt
@@ -3,86 +3,16 @@ package com.github.spigotbasics.core.command
import com.github.spigotbasics.core.messages.CoreMessages
import com.github.spigotbasics.core.messages.MessageFactory
import com.github.spigotbasics.core.module.BasicsModule
-import org.bukkit.Bukkit
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
-import org.bukkit.inventory.ItemStack
-import org.bukkit.permissions.Permission
-abstract class BasicsCommandExecutor(module: BasicsModule) {
- protected val coreMessages: CoreMessages = module.plugin.messages
- protected val messageFactory: MessageFactory = module.plugin.messageFactory
+abstract class BasicsCommandExecutor(
+ coreMessages: CoreMessages,
+ messageFactory: MessageFactory,
+) : BasicsCommandContextHandler(coreMessages, messageFactory), BasicsTabCompleter {
+ constructor(module: BasicsModule) : this(module.coreMessages, module.messageFactory)
abstract fun execute(context: BasicsCommandContext): CommandResult?
- open fun tabComplete(context: BasicsCommandContext): MutableList? {
+ override fun tabComplete(context: BasicsCommandContext): MutableList? {
return null
}
-
- // TODO: Move these methods into own CommandParser object
-
- @Throws(BasicsCommandException::class)
- fun requirePlayer(name: String): Player {
- val player = Bukkit.getPlayer(name)
- if (player == null) {
- throw BasicsCommandException(CommandResult.playerNotFound(name))
- }
- return player
- }
-
- @Throws(BasicsCommandException::class)
- fun notFromConsole(sender: CommandSender): Player {
- if (sender !is Player) {
- throw CommandResult.NOT_FROM_CONSOLE.asException()
- }
- return sender
- }
-
- // TODO: In 99% of cases, we should just use requirePlayer(CommandSender) instead of this method
- @Throws(BasicsCommandException::class)
- fun requirePlayerOrMustSpecifyPlayerFromConsole(sender: CommandSender): Player {
- val player = sender as? Player
- if (player == null) {
- throw CommandResult.MUST_BE_PLAYER_OR_SPECIFY_PLAYER_FROM_CONSOLE.asException()
- }
- return player
- }
-
- @Throws(BasicsCommandException::class)
- fun failIfFlagsLeft(context: BasicsCommandContext) {
- if (context.flags.isEmpty()) return
- throw CommandResult.unknownFlag(context.flags[0]).asException()
- }
-
- @Throws(BasicsCommandException::class)
- fun failInvalidArgument(argument: String): CommandResult {
- throw CommandResult.invalidArgument(argument).asException()
- }
-
- fun requirePermission(
- sender: CommandSender,
- permission: Permission,
- ) {
- if (!sender.hasPermission(permission)) {
- throw CommandResult.noPermission(permission).asException()
- }
- }
-
- // @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
-
- fun requireItemInHand(player: Player): ItemStack {
- val item = player.inventory.itemInMainHand
- if (item.type.isAir) {
- throw CommandResult.NO_ITEM_IN_HAND.asException()
- }
- return item
- }
-
- fun requireItemInHandOther(player: Player): ItemStack {
- val item = player.inventory.itemInMainHand
- if (item.type.isAir) {
- throw CommandResult.noItemInHandOthers(player).asException()
- }
- return item
- }
}
diff --git a/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsTabCompleter.kt b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsTabCompleter.kt
new file mode 100644
index 00000000..da992224
--- /dev/null
+++ b/core/src/main/kotlin/com/github/spigotbasics/core/command/BasicsTabCompleter.kt
@@ -0,0 +1,5 @@
+package com.github.spigotbasics.core.command
+
+interface BasicsTabCompleter {
+ fun tabComplete(context: BasicsCommandContext): MutableList?
+}