-
Notifications
You must be signed in to change notification settings - Fork 5
Command API
Introduced in @1.4.0, declarative commands allow you to create commands with vast customization and extensibility, while keeping minimal code.
We can create the declarative command via a string, or a chain command.
Let's begin by making a /msg
command with two arguments
// Chain declaration
//val player by argument<Player>("player")
//val msg by argument<String>("string", true)
val player by playerArgument()
val msg by greedyStringArgument()
("msg" / player / msg) {
runs<CommandSender> {
// Make sure to invoke the arguments to get their values.
player().sendMessage(!"[${sender.name} -> Me]: ${msg()}")
reply(!"[Me -> ${player().name}]: ${msg()}")
}
} register this
// Complete string declaration (Not recommended)
"/mgs <player:player!> <msg:string...>" {
runs<CommandSender> {
val player by argument<Player>()
val msg by argument<String>()
player.sendMessage(!"[${sender.name} -> Me]: ${msg}")
}
} register this
Caution
String parse declaration will be deprecated in 2.5.0
We can declare subcommands using the div operator with a list of commands, or we can use the subcommand
block.
("foo") {
("bar" / arg).runs<Player> { /* callback */ }
("fizz" / arg).runs<Player> { /* callback */ }
("buzz" / arg) {
// code
}
} register this
Arguments can have callbacks for missing or invalid values in different scopes.
val name by argument<Player>("player")
name missing { reply(!"&cName arg is missing") }
("foo" / name) {
// Will run instead of top level missing callback
name missing { reply(!"Test") }
runs<Player> {
// ...
}
} register this
("bar" / name) {
// If missing will run the top level missing callback
runs<CommandSender> {
}
} register this
This feature is available for if the argument is missing
or invalid
.
You can also handle all missing
or invalid
args by not specifying the argument.
("bar" / name) {
// If missing will run the top level missing callback
runs<Player> {
}
invalid {
// Handles all args, lowest priority
reply(!"Missing arg ${argument.name()}")
}
} register this
Caution
This section will be rewritten since CommandSuggestionRegistry
will no longer
be primarily used for supplying suggestions/values.
When specifying an argument type, KtGui will attempt to do tab suggestions and try to get the value of a provided argument by using the CommandSuggestionRegistry
.
If we had a list of Dog
objects which hold a name
property, we can use the SimpleCommandSuggestion
class.
class Dog(val name: String)
val dogs = arrayListOf(Dog("Foo"), Dog("Bar"))
fun getDogs() = dogs
CommandSuggestionRegistry.register(
"dog_name",
SimpleCommandSuggestion(Dog::name, ::getDogs)
)
// ...
val dog by argument<Dog>("dog_name")
("pet" / dog) {
runs<CommandSender> {
reply(!"Petted ${dog().name}")
}
} register this
You can call the function buildAutomaticPermissions(rootNode: String)
to automatically register and assign permission nodes to all sub-commands in the command tree. The permission nodes will be the rootNode
arg followed by the command name
.
You can also individually assign permissions by calling permission(node: String)
or permission(block: StorageCommandInvocation<*>.() -> Unit)
. This will be checked with the automatically assigned permission node.