Commands
Every punishment command is registered on the velocity module (ACF/co.aikar.commands) — punishments are always issued from the proxy, never from a backend server. The paper module registers one staff-facing command, /history, for browsing punishment records in-game.
All velocity commands take a MinecraftPlayer target, resolved by name via MinecraftPlayerContextResolver (AstralCore#players().loadOrCreate(name)) — this works for offline targets, not just currently-connected players.
Velocity commands
Command | Aliases | Permission | Syntax |
|---|---|---|---|
| — |
|
|
| — |
|
|
| — |
|
|
| — |
|
|
|
|
|
|
|
|
|
|
| — |
|
|
Reason parsing and the -s flag
Every [reason] argument (all commands except /warn, where reason is required and taken verbatim) is run through ParsedReason.parse(...): the raw string is split on spaces, any -s token (case-insensitive, anywhere in the string) is stripped out and sets silent = true, and the remaining tokens are rejoined as the reason. A silent punishment still records normally and still messages the operator/target — only the network-wide broadcast is skipped.
issues a 7-day ban on Notch with reason "Griefing spawn", broadcasting nothing.
/ban
Permission: punishments.ban. Stateful — reissuing while Notch already has an active BAN refreshes that row (issuer, reason, expiry) instead of creating a second one. Disconnects the target immediately if they're online (best-effort — the punishment is recorded and announced regardless of whether the kick succeeds).
Arg | Type | Description |
|---|---|---|
|
| Required. Resolved by name, online or offline. |
|
| Optional. Omit for a permanent ban. See duration syntax. |
|
| Optional free text, parsed per above. |
Feedback: target-banned (operator) → target-banned-broadcast (network, unless -s) → player-banned (shown to the target on disconnect).
/ipban
Permission: punishments.ipban. Bans an address rather than (only) an account. The address is resolved as the target's live connection address if they're online on this proxy, else their last address from ip_history; if neither is available the command replies with target-no-ip and issues nothing. Stateful — reissuing while the same target already has an active IPBAN refreshes that row (including the address). After saving, every session on this proxy whose current address matches the banned IP is disconnected (not just the named target — this can catch alt accounts sharing the address).
Arg | Type | Description |
|---|---|---|
|
| Required. Used to resolve the address to ban (see above); |
|
| Optional. Omit for a permanent IP ban. |
|
| Optional, parsed per above. |
Feedback: target-ipbanned (operator) → target-ipbanned-broadcast (network, unless -s) → player-ipbanned (shown to each disconnected session).
/mute
Permission: punishments.mute. Stateful — reissuing refreshes the existing active MUTE. Never disconnects the target.
Arg | Type | Description |
|---|---|---|
|
| Required. |
|
| Optional. Omit for a permanent mute. |
|
| Optional, parsed per above. |
Feedback: target-muted (operator) → target-muted-broadcast (network, unless -s). No target-facing screen.
/kick
Permission: punishments.kick. Point-in-time — always creates a new row, never reissues. Unlike /ban//ipban, the disconnect is required: if the target isn't currently online the command replies player-not-online and records nothing.
Arg | Type | Description |
|---|---|---|
|
| Required; must be online. |
|
| Optional, parsed per above. |
Feedback: the target is disconnected first (player-kicked screen); only once the disconnect succeeds is the record saved and player-kicked-broadcast announced (unless -s). The operator gets no dedicated "you kicked X" line (see the messages.yml note on Configuration).
/warn
Permission: punishments.warn. Point-in-time, never disconnects, no broadcast — purely a logged note. reason is required and is not passed through ParsedReason (no -s support; the whole argument is the literal reason).
Arg | Type | Description |
|---|---|---|
|
| Required. |
|
| Required, taken verbatim (no silent flag). |
Feedback: target-warned (operator only).
/unban (/pardon)
Permission: punishments.unban. Looks up the target's latest active BAN and latest active IPBAN in parallel and pardons whichever exist — a target with both an account ban and an IP ban tied to their UUID has both lifted by one command. If neither is active, replies target-not-banned.
Arg | Type | Description |
|---|---|---|
|
| Required. |
|
| Optional pardon reason, parsed per above — recorded as |
Feedback: target-unbanned (operator) → target-unbanned-broadcast (network, unless -s).
/unmute
Permission: punishments.unmute. Same shape as /unban but only for MUTE. Replies target-not-muted if none is active.
Arg | Type | Description |
|---|---|---|
|
| Required. |
|
| Optional pardon reason, parsed per above. |
Feedback: target-unmuted (operator) → target-unmuted-broadcast (network, unless -s).
Duration syntax
Duration arguments (/ban, /ipban, /mute) are parsed by DurationContextResolver → DurationParser.parse(...), which accepts one or more <number><unit> tokens (optionally space-separated, combined additively) using units y (365-day years), d, h, m (minutes), s, and ms. An unparseable string replies "Invalid duration format: <input>".
Paper commands
Command | Aliases | Permission | Syntax |
|---|---|---|---|
|
|
|
|
/history
Permission: punishments.history. Player-only (@Default takes a Player executor). Opens the punishment history menu for <player> (resolved the same offline-aware way as the velocity commands), showing every punishment ever recorded against them — active, expired, and pardoned. The optional [duration] argument (parsed by DurationParser, same syntax and w/mo caveat as above) restricts the listing to punishments issued within that window; an unparseable value replies invalid-duration and opens nothing. See Punishment History GUI for the menu itself.
Permission summary
Node | Grants |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also
Overview — stateful vs. point-in-time punishments, cross-server sync.
Configuration — the
messages.ymlkey catalogue backing every reply above.