Messages & Placeholders

Messages & Placeholders

The selected locale/*.yml supports MiniMessage, legacy &/hex colors, <br>, YAML block strings and lists. Text originating from a player or moderator is inserted literally. Prefix, date format, units, screens, history, confirmations and errors are configurable. The default palette is cyan &#25c8fa, white, gray and the dark arrow separator.

Supported placeholders include all punishment/player/staff/removal fields from the specification: {id}, {public_id}, {type}, {reason}, {duration}, {remaining}, {created}, {expires}, {permanent}, {silent}, {active}, {template}, {ladder}, {player}, {player_uuid}, {player_display_name}, {player_server}, {staff}, {staff_uuid}, {removal_staff}, {removal_reason}, {removal_date}, plus {server} and {scope}. Player display name is the observed plain account name; server is the issuing node. {player_bans}, {player_mutes}, {player_warnings}, {player_kicks} are immutable history-count snapshots taken when the punishment is issued, including that punishment. Public IDs use 64 bits of random data and can be disabled in display configuration.

Webhook events cover ban/temp-ban/IP-ban/unban, mute/temp-mute/IP-mute/unmute, warn/unwarn, kick, alts and lockdown. Configure explicit silent variants as needed. Webhooks are disabled by default and accept Discord HTTPS endpoints only. Payloads use proper JSON escaping, embeds, field length limits, disabled mentions, a bounded queue and bounded retries for rate limits/transient errors. Address fields are omitted. Field labels are configurable, and webhooks.field-values.<field> can format values using punishment placeholders. Notifications are sent once by the originating node, not by every synchronized server.

Localization

/punish <player> opens paginated policy selection, with confirmation enabled by default. /history and /warnings use five-row histories with issuer heads. Normal history includes current and expired records. The amethyst History Type control selects ALL/BANS/MUTES/WARNS/KICKS; the writable-book control shows revoked, superseded and hidden records with wrongpunish.history.deleted. Filters and pages survive returning from details.

Normal clicks open details. Shift-click an active record to request revocation; this always opens a small confirmation screen with green Confirm and red Cancel. Required removal reasons are captured privately from the next chat message for up to 60 seconds. Current permission, target, state and hierarchy are checked before committing. Records remain in history. Click/drag movement and double actions are guarded; inventory changes use the entity scheduler.

The ten GUI files are punish.yml, punish-confirm.yml, history.yml, history-details.yml, history-type.yml, deleted-history.yml, warnings.yml, revoke-confirm.yml, alts.yml and banlist.yml. Defaults use a black frame and gray interior. Previous is red, Next green, and Close/Back a barrier. Items and messages use semantic colors and lighter text: red bans, purple mutes, yellow warnings, orange kicks and green confirmation. Layouts, materials, lore, model data, sounds, colors and extra permission restrictions remain configurable. See docs/GUI.md.

/alts <player> [page] opens linked accounts with account heads, status, observations and punishment counts. Set alts.display.mode: CHAT for formatted chat output. Shared IP history indicates a possible relationship, never proof of ownership. /banlist [page] always opens a GUI of active bans, with target heads and the same details/shift-click confirmation flow. There is no banlist toggle; console receives an instruction to run it in game. Both screens use bounded SQL pages and matching counts.

The backend adapter takes ownership of the unqualified /banlist command if a native or earlier plugin handler already exists. It restores the displaced handler when disabled. Check this command with the other plugins installed during staging.

Proxy GUI commands route a short-lived request through the shared SQL outbox to the player's current backend. The backend resolves its own current permissions before opening anything. This requires the backend adapter, shared database/prefix, enabled synchronization and matching backend server names. Proxy commands retain their own initial permission checks.

All default text lives in locale/EN.yml; GUI names/lore/titles beginning with @ reference locale keys. Set locale: CUSTOM to load an administrator-created locale/CUSTOM.yml without modifying the plugin. Only EN ships or is generated. Missing individual keys fall back to bundled EN; a missing selected locale file fails validation. Internal {token} and %token% placeholders, legacy/hex colors, MiniMessage and <br> work independently of PlaceholderAPI. Optional PlaceholderAPI expansions are restricted to tokens in configured text; player reasons and other literal values cannot introduce expansions or formatting.

On upgrade, legacy messages.yml is copied into EN only if EN is missing. Byte-identical previous stock GUI, EN and template files upgrade automatically with .v1.bak backups; the previous GUI redesign upgrades with .v2.bak backups. Customized files remain intact; merge the new fields/defaults to adopt the new appearance. The black frame includes the entire bottom row beneath navigation buttons; empty interior slots are gray. SQL startup adds supersession and hiding columns in place. Stop all nodes, back up SQL, replace every JAR together and restart.

Console actions run once on the issuing node. Supported action substitutions are {player}, {player_uuid}, {id} and {public_id}. Reasons, display names and arbitrary message placeholders are rejected in action configurations to prevent command injection. Commands referring to {player} require a safe observed Minecraft name. Use {player_uuid} for a target supplied only by UUID. Proxy-issued actions must be commands available on that proxy; actions can invoke /punish, /kick or other proxy commands registered there.