Inventory configuration
WrongPunish generates ten independent files under guis/. The defaults use a complete black outer frame, including both bottom corners and unused navigation slots. Empty slots strictly inside the frame are gray. Buttons are placed over the frame where configured. History, deleted history, warnings, alts and banlist are five rows (45 slots). Confirmations and history-type selection are three rows (27 slots).
| File | Purpose |
|---|---|
punish.yml | Paginated policy selection and optional punishment confirmation |
punish-confirm.yml | Refreshed policy, green Confirm and red Cancel |
history.yml | Current/expired records, type selection and deleted-history access |
history-details.yml | Full record and removal/supersession/hiding information |
history-type.yml | ALL, BANS, MUTES, WARNS and KICKS choices |
deleted-history.yml | Revoked, superseded and administratively hidden records |
warnings.yml | Warning history and permission-gated deleted warning history |
revoke-confirm.yml | Selected staff-head record and mandatory confirmation |
alts.yml | Linked accounts, account heads, observations and punishment counts |
banlist.yml | Active bans with banned-player heads |
Decoration, geometry and controls
All slots are zero-based. Use size or rows; if both exist they must agree. Inventory size must be 9–54 in complete rows. Content slots cannot overlap control slots. Invalid settings report the exact file/property; YAML syntax errors report line and column. Backend validation checks actual materials and sounds.
background:
outline:
enabled: true
material: BLACK_STAINED_GLASS_PANE
name: " "
slots: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]
inner:
enabled: true
material: GRAY_STAINED_GLASS_PANE
name: " "
# Without explicit slots, ordinary interior geometry is used.
slots: [10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34]The history navigation row has Previous at 37, Type at 39, Deleted at 40, Close/Back at 41 and Next at 43. All positions are configurable. Red and green glass show only when the corresponding page exists; unavailable controls leave the black frame. Background is drawn before the outline, so overlapping background slots cannot overwrite the frame. Root pages close; nested screens return to their origin, retaining filter and page. close.back-name controls its contextual label, or supply a separate back item.
Items support material, slot, custom-model-data, name and string/list/multiline lore. entry.variants.BAN (and each other punishment type) can override record formatting. Staff-history items always use issuer UUID heads; banlist uses target UUID heads; alts uses account UUID heads. console-item supplies a fallback, normally COMMAND_BLOCK. Asynchronous profile resolution has a bounded cache and fails gracefully to an untextured head.
sounds.open, sounds.click and sounds.error support enabled/sound/volume/pitch. Sound constants and namespaced keys are accepted. Optional screen/button permission adds a restriction; it cannot remove mandatory command, deleted-history or revocation checks. Template gui fields override punish.yml's shared template-item. A custom icon can use PLAYER_HEAD plus head-uuid.
History, revocation and hidden records
The amethyst control opens type selection, refreshes the same history and resets to page 1. Warnings keep their warning-only filter. Normal history includes active, completed and expired records; revoked, superseded and hidden records appear in the writable-book screen only with wrongpunish.history.deleted.
A normal click opens details. Shift-click an active record in history, warnings, banlist or details to request revocation. There is no ordinary-click revoke button. Unauthorized actions show a localized response/error sound; authorized actions open revoke-confirm.yml. Green Confirm checks current permission/state/target/hierarchy again; red Cancel returns to the previous screen. Double clicks are guarded. History uses wrongpunish.history.revoke or .history.revoke.ban|mute|warn; warning screens use wrongpunish.warnings.revoke. Console-issued records require console or an explicit hierarchy bypass.
If requirements.removal-reason or compatibility require-removal-reason is enabled, confirmation closes the inventory and captures the next chat message privately. The prompt expires in 60 seconds; its cancel token is localized. Permissions are captured again on submission. No packet spoofing is used.
/prunehistory now hides eligible inactive records instead of deleting them. The database retains hiding actor, timestamp and reason, previous removal/supersession fields, template counters and audit records. The bulk SQL mutation does not load lifetime history into memory. A network notification refreshes affected history views.
Alts and active bans
/alts <player> [page] defaults to the GUI. Set alts.display.mode: CHAT to retain formatted chat output. The GUI uses paginated shared-IP-history queries and matching counts; accounts linked by several IPs are deduplicated. alts.history-window determines the lookup period; alts.scan-limit still bounds the chat/notification scan. Status reflects this node's applicable ban/mute cache and online observations, not proof of account ownership. colors.online|offline|banned|muted is configurable in alts.yml. With history permission, clicking an account opens its history and Back returns to linked accounts.
/banlist [page] always opens the active-ban GUI for players; there is no GUI/chat setting. Console receives an instruction to run it in game. Only the requested SQL page and a count are fetched. Clicking opens details; shift-click follows the same confirmed revoke flow.
The backend adapter replaces an existing unqualified /banlist handler so the requested command reaches this GUI, retaining the prior handler for restoration on disable. Verify command ownership on your installed server alongside other plugins.
Locale and placeholders
All default text lives in locale/EN.yml; GUI names, lore and titles beginning with @ reference locale keys. Set locale: CUSTOM to load your own locale/CUSTOM.yml. Only EN ships. Missing keys fall back to bundled EN; a missing selected locale rejects reload.
Both %token% and {token} work. Player/template/reason/offense, punishment ID/type/status/duration/remaining, staff, dates, server and scope are available where applicable. History controls add %history_type%; details add removal, supersession and hiding fields. Alts adds %account_status%, %last_seen%, %last_server%, %punishments%, %ban_remaining% and %mute_remaining%. Remaining durations use two compact units, such as 29d 4h.
%status_display% and %account_status_display% insert trusted configured color formatting. Override status-formats.ACTIVE (and other states) in a GUI, or change gui.status-format in the locale. User-supplied reasons/names remain literal. Legacy/hex colors, MiniMessage, <br> and optional PlaceholderAPI are supported; player text cannot introduce formatting or PlaceholderAPI expansions.
Default chat prefixes are lighter and use semantic type colors. Bold is reserved for the prominent ban-screen heading.
Reload, upgrade and network
/wrongpunish reload validates config, templates, webhooks, selected locale and every GUI file before applying changes. Success closes old inventories and clears reason prompts. Rendering, permission snapshots, sounds, heads and inventory changes run on entity schedulers; SQL stays asynchronous. Data changes refresh open pages/details without altering an outstanding confirmation.
Previous byte-identical 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. To adopt the full new appearance for custom layouts, back up those files and merge the new schema/defaults or let missing files regenerate. Old outline-only configurations still load with a gray interior and a black frame.
Back up SQL, replace every node's JAR together and restart. Schema migration adds hiding columns in place. Proxy GUI commands route through the shared database outbox to the current backend, requiring the adapter, enabled sync, matching table prefix/database and matching backend server names. The backend independently checks permission. See STAGING.md for live client acceptance checks.