Context
The table handed to every command handler and every guard. It is frozen, so a handler cannot change what it was given.
type Context = {
executor: Player?,
text: string,
path: { string },
flags: { [string]: any },
jobId: string,
reply: (self: Context, message: string) -> (),
error: (self: Context, message: string) -> (),
confirm: (self: Context, prompt: string) -> boolean,
logAction: (self: Context, action: Action) -> (),
}For a client command the handler receives a narrower ClientContext instead.
Properties
| Property | Type | Meaning |
|---|---|---|
executor | Player? | who ran the command, or nil for a server-run command |
text | string | the raw input the server received |
path | { string } | the resolved command path |
flags | { [string]: any } | the command's named flags, already transformed |
jobId | string | the server's game.JobId |
Methods
:reply
context:reply(message: string): ()Adds a message for the caller. Every reply lands in Result.replies, and the first becomes Result.message.
:error
context:error(message: string): ()Marks the dispatch failed with this message. The result comes back with status = "Failed" and ok = false.
Use this for an expected failure the caller should see. A handler that raises instead is caught: the caller gets a generic the command failed and the real error goes to the logger.
:confirm
context:confirm(prompt: string): booleanAsks the executor to confirm, and yields until they answer. Returns false when there is no confirm handler installed.
:destructive() calls this for you before the handler runs; call it directly only for a second confirmation inside a handler.
:logAction
context:logAction(action: Action): ()Records a moderation action, which appears in the Ban Logs tab of the log panel. Actions are written only if the command succeeds. A command that fails, is denied, or is cancelled records nothing.
context:logAction({
action = "7 day ban",
target = args.target,
reason = args.reason,
duration = 604800,
severity = "ban",
})Action
type ActionTarget = Player | number | string
type Action = {
action: string,
target: ActionTarget?,
targetName: string?,
reason: string?,
duration: number?,
severity: string?,
}| Field | Meaning |
|---|---|
action | what happened, shown verbatim: "7 day ban", "Inventory Wipe" |
target | a Player, a user ID, or a name |
targetName | a display name to use when target is an ID |
reason | optional, shown on the row |
duration | optional, in seconds |
severity | ban, kick, wipe, warn or custom; anything else falls back to custom |
ConfirmHandler
type ConfirmHandler = (context: Context, prompt: string) -> booleanInstalled on the dispatcher, and the seam the transport uses to run a confirmation over the wire:
dispatcher:setConfirmHandler(function(context, prompt)
return askThePlayer(context.executor, prompt)
end)Example
:run(function(context, args)
if context.executor == nil then
return context:error("this command needs a player")
end
if context.flags.silent == nil then
announce(`{context.executor.Name} ran {table.concat(context.path, " ")}`)
end
context:reply("done")
end)