GUI Customization

Overview

Every GUI in XBans is defined in a YAML file under /plugins/XCore/addons/XBans/guis/. Layout, icons, custom model data, item models, click sounds, click actions and per-item permissions are all editable without touching code — XCore loads the files on startup and on /xbans reload.

XBans ships these GUI files:

  • punish.yml + punish_ban.yml, punish_mute.yml, punish_warn.yml, punish_kick.yml, punish_jail.yml — the /punish menu and its sub-menus
  • report.yml — the /report reason picker
  • banlist.yml, baniplist.yml, mutelist.yml, muteiplist.yml, warnlist.yml, warnlist_target.yml, reportlist.yml, reportlist_target.yml, jaillist.yml — the /sanctions list screens
  • players.yml, profil.yml, daccounts.yml, notes.yml, player_history.yml — the player lookup screens

Display names and lore are resolved from lang.yml keys (so they stay translatable); the structure, icons and behaviour live in the guis/*.yml files described here.

The /punish and /report menus additionally support per-button commands: and open: keys (an XBans-specific button engine) — see the GUI Screens page for those.

File Structure

Each GUI file starts with these top-level properties:

gui-title: "gui-title-key"            # a lang.yml key (or raw MiniMessage)
rows: 6                                # 1-6 rows (slots = rows x 9)
slots: [0,1,2,3,4,5,6,7,8]             # slots used for the paginated list
slots-sound: "minecraft:ui.button.click"  # sound when a list entry is clicked
PropertyDescription
gui-titleThe inventory title. If the value matches a key in lang.yml it is resolved from there (recommended — keeps it translatable); otherwise it is treated as raw MiniMessage. Paginated GUIs support %page% and %max%.
rowsInventory height, 1 to 6. Total slots = rows x 9.
slotsThe slots filled with dynamic, paginated content (player heads, listings...). Static buttons go in any other slot via the items section.
slots-soundFallback sound played when a dynamic list slot is clicked (used when the clicked entry has no sound of its own).

Item Properties

Static items live under the items: section — one block per item. Only slot and material are required:

items:
  Filler:
    slot: [45,46,47,51,52,53]      # one slot, or a list to repeat the item
    material: GRAY_STAINED_GLASS_PANE
  Info:
    slot: 49
    material: PLAYER_HEAD:eyJ0ZXh0dXJlcyI6...   # PLAYER_HEAD:<base64 texture>
    target-title: "gui-info-title"   # lang.yml key
    target-lore: "gui-info-lore"     # lang.yml key
    custom_model_data_value: 1001
    item_model_key: "mypack:info_icon"
    permission: "myserver.gui.info"
    sound: "minecraft:ui.button.click"
PropertyDescription
slotPosition in the grid. A single number, or a list (e.g. [45,46,47]) to place the same item in several slots.
materialAny Bukkit Material (e.g. DIAMOND_SWORD). For a textured head use PLAYER_HEAD:<base64 texture value>.
custom_model_data_valueCustom model data number for resource packs (ItemsAdder, Oraxen, Nexo...). Applied via the 1.21.5+ component API with a legacy fallback.
item_model_keyAn item-model identifier for 1.20.5+ custom item models (e.g. mypack:flame_sword), applied via ItemMeta#setItemModel when the server supports it.
target-titleDisplay name — a lang.yml key (MiniMessage and placeholders supported).
target-loreLore — a lang.yml key. Use the YAML pipe | and %placeholder% tokens for multi-line lore.
target-button-on / target-button-offThe two states of an animated (blinking) button label. Both are lang.yml keys.
soundSound played when the item is clicked (namespaced key, e.g. minecraft:ui.button.click), resolved version-safely through the sound registry.
permissionPermission node required to use the item. Without it, the built-in click action and any custom actions are skipped, and the lore shows the "no permission" button state.

Unlisted keys are ignored — XCore items don't read stack size, enchantments or glow from YAML; use custom_model_data_value or item_model_key with a resource pack for custom visuals.

Click Actions

Any item can run a list of actions when clicked, split by click kind: left, right, shift_left (alias shiftleft) and shift_right (alias shiftright). Each click kind takes a list, so one click can chain several steps in order.

Action types

Three types ship with XCore (resolved in GuiActionFactory):

TypeKeysEffect
close (alias close_inventory)Closes the player's inventory.
msg (alias message)valueSends a MiniMessage-formatted message. %player% becomes the clicker's name.
cmd (alias command)value, optional executor (player | console, default player)Runs a command. %player% becomes the clicker's name, sanitised to [A-Za-z0-9_] to block command injection via hostile usernames.

Example

items:
  CustomButton:
    slot: 22
    material: EMERALD
    target-title: "custom-button-title"
    target-lore: "custom-button-lore"
    sound: "minecraft:entity.experience_orb.pickup"
    permission: "myserver.gui.custombutton"   # optional
    actions:
      left:
        - type: msg
          value: "<gray>Teleporting to spawn...</gray>"
        - type: cmd
          executor: player
          value: "spawn"
        - type: close
      right:
        - type: msg
          value: "<green>You right-clicked!</green>"

On built-in items (a sanction button, a player head in a list...), the addon's own handler runs first, then your custom actions run — so you can layer a sound or a chat message on top of existing behaviour. Click kinds outside the four above (middle, drop, number keys) run no custom action.

Legacy single-action format

A shorter single-string form is still accepted for one left-click action:

  action: "click:cmd:player:spawn"
  # or "click:msg:Hello %player%"
  # or "click:close"

Prefer the structured actions: map for anything new — it supports multiple click kinds, multiple steps, and the console executor.