ShinnUI wiki
Trang chủ/Menu/Cấu trúc menu

Cấu trúc menu

Mỗi menu là một file YAML trong thư mục menus/. Tên file chính là ID menu. Dưới đây là toàn bộ các node gốc mà serializer đọc (kèm alias regex — bạn có thể viết tên khác mà vẫn nhận).

Sơ đồ tổng thể#2>
Title: ...            # Tiêu đề (một hoặc mảng animation)
Title-Update: 40      # Chu kỳ quay title animation (ticks)
Layout: ...           # Bố cục menu (bắt buộc)
PlayerInventory: ...  # Bố cục phần inventory người chơi (tùy chọn)
Type: CHEST           # Loại container (tùy chọn)
Size: 3               # Số hàng nếu không dùng Layout (tùy chọn)
Render-Type: WINDOW   # WINDOW / ENCHANT / MERCHANT / DISPLAY / BOOK (xem trang Render-Type)
Options: ...          # Tùy chọn menu
Bindings: ...         # Lệnh / item mở menu
Events: ...           # Open / Close / Click
Icons: ...            # Phần thân menu
Input: ...            # (Fork) các slot kéo đồ vào GUI
Tasks: ...            # Tác vụ định kỳ khi mở menu
Functions: ...        # JS function dùng như biến ${name}
Lang: ...             # Đa ngôn ngữ cho chính menu này

Serializer dò key bằng regex, không bắt buộc đúng chính tả: Title cũng khớp Name, Layout khớp Shape, Options khớp Settings, Icons khớp Buttons… Tuy vậy, hãy dùng tên chuẩn ở trên cho dễ bảo trì.

Title — tiêu đề#2>
# Static
Title: 'My Shop'

# Animation — mảng title quay vòng, Title-Update là chu kỳ (ticks)
Title:
  - 'Hello, ShinnUI!'
  - 'Hello, %player_name%!'
  - 'Support Animated Titles'
Title-Update: 80
  • Title hỗ trợ màu, hex, biếnfunction variable.
  • Dynamic title đổi bằng cách gửi lại cửa sổ container (packet OpenWindow) rồi vẽ lại toàn bộ slot — không phải "đổi tên" inventory.
  • Chu kỳ Title-Update áp dụng toàn menu, không đặt riêng theo trang. Muốn title khác nhau theo trang: dùng function variable kiểm tra %shinnui_menu_page% hoặc dùng action set-title.
  • I18n: có thể đặt các title theo locale trong node Lang (xem phần Lang).

Layout — bố cục#2>

Layout là "bản vẽ" menu bằng ký tự. Mỗi ký tự là ID của một icon trong node Icons; khoảng trắng = slot trống không clickable; ký tự được bọc trong backtick (`` ` ``) cho phép dùng nhiều ký tự làm một ID.

Layout:
  - '########`Close`'
  - '         '
  - '   PT   '
  - '         '
  - '####*###`Next`'

PlayerInventory:          # Bố cục inventory người chơi (tối đa 4 dòng x 9)
  - '         '
  - '         '
  - '         '
  - '         '
  • Số dòng của Layout quyết định số hàng của chest (1–6).
  • Nhiều trang: viết Layout dạng mảng lồng nhau, mỗi phần tử là một trang:
Layout:
  - - '########`Close`'
    - '         '
    - '   P    '
    - '         '
    - '####*###`Next`'
  - - '########`Close`'
    - '         '
    - '   T    '
    - '         '
    - '`Pre`########'
  • Nếu một trang không có dòng tương ứng trong PlayerInventory thì phần inventory người chơi của trang đó bị làm trống.
  • Ký tự icon hỗ trợ cả ký tự Unicode/hán tự.
  • Icon vẫn có thể đặt slot thủ công qua slots: trong icon — khi đó nó ghi đè vị trí layout.

Options — tùy chọn#2>
Options:
  Arguments: true              # Bật truyền tham số khi mở menu (mặc định true)
  Default-Arguments: [ ]       # Tham số mặc định, tự điền phần thiếu
  Default-Layout: 0            # Trang mở mặc định (số hoặc biến)
  Free-Slots:                  # Slot "tự do" — người chơi có thể lấy đồ ra/vào
    - 71-73
  Hide-Player-Inventory: false # Che toàn bộ inventory người chơi (trang trí bằng layout)
  Min-Click-Delay: 200         # Chống click nhanh: ms giữa 2 click
  Depend-Expansions: [ 'server', 'player' ]  # PAPI expansion bắt buộc phải có khi mở menu
OptionChi tiết
ArgumentsTắt nếu lệnh bind của bạn xung đột với lệnh có tham số. Xem Truyền tham số.
Default-ArgumentsVí dụ ["a","b"] mà người chơi chỉ cung cấp ["a"] → tham số thứ 2 tự điền b.
Free-SlotsSlot nào không nằm trong layout và không free sẽ bị chặn click của người chơi. Dạng '71-73' hoặc biến trả số.
Hide-Player-InventoryKhi bật, phần dưới GUI chỉ hiển thị theo PlayerInventory layout (đồ thật không click được). Menu Input phải đặt false.
Min-Click-DelayÁp cho từng người chơi trong từng menu (cooldown CLICK_DELAY).
Depend-ExpansionsNếu thiếu expansion, sự kiện mở menu bị cancel và plugin gửi danh sách expansion cần tải (tự động yêu cầu download expansion qua PAPI cloud nếu có quyền).

Bindings — lệnh & item#2>
Bindings:
  Commands:
    - '(?i)example(-)?(gui)?(s)?'   # regex, khớp cả /example /examplegui /examples...
  Items:
    - 'material:compass'            # Item matcher
    - 'material:clock,lore:OPEN_MENU'

Lệnh bind là lệnh ảo (khớp khi người chơi gõ), còn Items tự động mở menu khi click phải item khớp khi GUI đang đóng. Xem chi tiết matcher tại Item Matcher.

Events — sự kiện menu#2>
Events:
  Open:                       # Chạy trước khi mở (có thể cancel)
    - condition: 'perm *shinnui.use'
      actions:
        - 'sound: BLOCK_CHEST_OPEN-1-0'
      deny:
        - 'sound: ENTITY_ITEM_BREAK-1-0'
        - 'title: `&c&lPermission Required` `&7&lYou need permission &6&lshinnui.use` 15 20 15'
        - 'return'            # return => HỦY sự kiện mở menu
  Close:
    - 'sound: BLOCK_CHEST_CLOSE-1-0'
  Click: []                   # Bắt click toàn menu (hiếm dùng)
  • Giá trị của event là một reaction (nhóm action có điều kiện).
  • return trong Open sẽ hủy mở menu; trong Close sẽ hủy đóng.
  • Meta open_event_reason được set trước khi chạy Open, nhận giá trị PLAYER_COMMAND, CONSOLE, BINDING_COMMANDS, BINDING_ITEMS, BINDING_SHORTCUT… — có thể đọc bằng {meta:open_event_reason}.

Input — slot kéo đồ (tính năng fork)#2>
Input:
  - slot: 10            # Slot tĩnh trong GUI
    material: IRON_INGOT # Chỉ nhận material này (hoặc dùng matcher / nexo-id)
    required: 4          # Phải đủ 4 mới cho commit (0 = tùy chọn)
    max-amount: 8        # Buffer tối đa 8

Đây là node riêng của fork này — menu cho phép người chơi shift-click kéo đồ vào GUI, buffer-pure (không trừ đồ thật cho đến khi chạy action input). Toàn bộ chi tiết ở trang Input Menu.

Tasks — tác vụ định kỳ#2>
Tasks:
  tikTok:
    period: 80              # Chu kỳ (ticks)
    task:
      - condition: '$ sender.isOp()'   # Kether mặc định
        actions:
          - 'sound: BLOCK_NOTE_BLOCK_BIT-1-2'
  • Bắt đầu chạy khi menu mở, hủy khi đóng menu.
  • Đổi trang không hủy task.
  • Cấu trúc: ID → period → task (reaction).

Functions — script nội bộ#2>
Functions:
  flash: |-
    function flash() {
      var display = new Date().getSeconds() % 2 == 0
      return display ? args[0] : "  "
    }
    flash()

Định nghĩa JS function dùng được ở mọi giá trị text trong menu bằng cú pháp ${flash_➥} (dấu _ phân tách tham số). Chi tiết ở Functions nội bộ.

Lang — đa ngôn ngữ theo menu#2>
Lang:
  vi_VN:
    Title: 'Cửa hàng'
    Icons:
      'close': { display: { name: '&cĐóng' } }
  en_US:
    Title: 'Shop'
    Icons:
      'close': { display: { name: '&cClose' } }

Node Lang cho phép định nghĩa lại Title/Icon theo locale; khi mở menu, plugin chọn theo locale người chơi. Icon ẩn danh trong Lang được map theo ID thường.

Truyền tham số (Arguments)#2>

Khi mở menu bằng lệnh có tham số (hoặc action open: Shop apple 10), các tham số trở thành biến có thể dùng ở gần như mọi chỗ:

BiếnGiá trị với args apple, juice, orange
{0}apple
{1}juice
{2}orange
  • Đóng menu không xóa tham số — lần mở sau vẫn giữ, trừ khi dùng action clear-args.
  • Đổi tham số bằng action set-arguments: a b c.
  • Lệnh bind dạng 'is upgrade' sẽ khớp cả /is upgrade 233 — phần thừa thành tham số.

Templates — menu mẫu kèm sẵn#2>

Trong menus/ của plugin có các file ví dụ rất đáng đọc:

FileDemo về
Example.ymlMenu tổng hợp: title animation, sub-icon, page, tasks, functions, bindings.
Input-Demo.ymlInput Menu: công thức 4 sắt + 4 vàng + 2 kim cương, confirm/deny.
Input-Matcher-Demo.ymlInput slot dùng matcher (enchant/pdc/nbt/nexo-id).
Random-Demo.ymlAction random: — bảng trọng số, else, lồng condition.
Catcher-Validation-Demo.ymlCatcher nhiều stage + validation: regex + fail:/retype.
Effect-Demo.ymlEffect Packs — gói sound/particle đặt tên.
Book-Demo.yml, Merchant-Demo.yml, Enchant-Demo.yml, Display-Demo.ymlBốn Render-Type đặc biệt — xem trang Render-Type.
Demo-Buttons.yml, Profile.ymlCác pattern icon thường gặp.