# 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 ` 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 ` shows usage & description for a subcommand ## Tab Completion - Tab completion works for first argument (subcommands) ## Example Commands ```kotlin @SubCommand( name = "autogrotto", usage = "", 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 = "", 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 ") } } } ```