132 lines
3.4 KiB
Markdown
132 lines
3.4 KiB
Markdown
|
# Client Command Framework
|
||
|
I'm using a lightweight Kotlin DSL, annotation-based command system for making client side commands.
|
||
|
|
||
|
## Defining Commands
|
||
|
|
||
|
All commands are defined as Kotlin functions annotated with `@SubCommand` in `ClientCommands.kt`.
|
||
|
|
||
|
### Example:
|
||
|
|
||
|
```kotlin
|
||
|
@SubCommand(
|
||
|
name = "test",
|
||
|
description = "Runs a test command"
|
||
|
)
|
||
|
fun test(ctx: CommandContext) {
|
||
|
ctx.send("Test command executed!")
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Subcommand Options:
|
||
|
- `name`: command name (required)
|
||
|
- `usage`: shows usage in help menu
|
||
|
- `description`: description shown in help
|
||
|
- `aliases`: optional aliases
|
||
|
|
||
|
### CommandContext helpers:
|
||
|
- `ctx.arg(index: Int)`: get argument (nullable)
|
||
|
- `ctx.require(index: Int, errorMsg: String)`: get required argument (throws error if missing)
|
||
|
- `ctx.send(msg: String)`: send message to client player
|
||
|
|
||
|
## Help System
|
||
|
- `/sbt` shows all available subcommands
|
||
|
- `/sbt help <command>` shows usage & description for a subcommand
|
||
|
|
||
|
## Tab Completion
|
||
|
- Tab completion works for first argument (subcommands)
|
||
|
|
||
|
|
||
|
### Example:
|
||
|
|
||
|
```kotlin
|
||
|
@SubCommand(
|
||
|
name = "test",
|
||
|
description = "Runs a test command"
|
||
|
)
|
||
|
fun test(ctx: CommandContext) {
|
||
|
ctx.send("Test command executed!")
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Subcommand Options:
|
||
|
- `name`: command name (required)
|
||
|
- `usage`: shows usage in help menu
|
||
|
- `description`: description shown in help
|
||
|
- `aliases`: optional aliases
|
||
|
|
||
|
### CommandContext helpers:
|
||
|
- `ctx.arg(index: Int)`: get argument (nullable)
|
||
|
- `ctx.require(index: Int, errorMsg: String)`: get required argument (throws error if missing)
|
||
|
- `ctx.send(msg: String)`: send message to client player
|
||
|
|
||
|
## Help System
|
||
|
- `/sbt` shows all available subcommands
|
||
|
- `/sbt help <command>` shows usage & description for a subcommand
|
||
|
|
||
|
## Tab Completion
|
||
|
- Tab completion works for first argument (subcommands)
|
||
|
|
||
|
## Example Commands
|
||
|
|
||
|
```kotlin
|
||
|
@SubCommand(
|
||
|
name = "autogrotto",
|
||
|
usage = "<status|enable|disable>",
|
||
|
description = "Manages the AutoGrotto feature"
|
||
|
)
|
||
|
fun autogrotto(ctx: CommandContext) {
|
||
|
when (ctx.require(0, "Provide status, enable, or disable")) {
|
||
|
"status" -> ctx.send("Autogrotto is enabled")
|
||
|
"enable" -> ctx.send("Autogrotto enabled")
|
||
|
"disable" -> ctx.send("Autogrotto disabled")
|
||
|
else -> ctx.send("Invalid usage. Try /sbt help autogrotto")
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## How to Add a New Command
|
||
|
1. Go to `ClientCommands.kt`
|
||
|
2. Define a function
|
||
|
3. Annotate with `@SubCommand`
|
||
|
4. Use `ctx` to get args and send messages
|
||
|
|
||
|
That's it!
|
||
|
|
||
|
## Using CommandContext Helpers
|
||
|
|
||
|
```kotlin
|
||
|
val playerName = ctx.player?.name // Nullable: client-side player
|
||
|
val firstArg = ctx.arg(0) // Safe nullable accessor
|
||
|
val secondArgRequired = ctx.require(1, "Missing second argument") // Throws if missing
|
||
|
ctx.send("You said: $firstArg and $secondArgRequired") // Send chat to player
|
||
|
```
|
||
|
|
||
|
## Calling Functions From Another Class
|
||
|
|
||
|
Create a utility or manager class like:
|
||
|
|
||
|
```kotlin
|
||
|
object MyFeatureManager {
|
||
|
fun toggleFeature(enabled: Boolean) {
|
||
|
// logic here
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Then call it from a command:
|
||
|
|
||
|
```kotlin
|
||
|
@SubCommand(name = "feature", usage = "<on|off>", description = "Toggles a feature")
|
||
|
fun feature(ctx: CommandContext) {
|
||
|
val toggle = ctx.require(0, "Provide a toggle option")
|
||
|
when (toggle.lowercase()) {
|
||
|
"on", "enable" -> // same action
|
||
|
"off", "disable" -> // another action
|
||
|
else -> {
|
||
|
ctx.send("Invalid argument '$toggle'. Usage:")
|
||
|
ctx.send("/sbt autogrotto <enable|disable|status>")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|