Skip to content

GUI 系统

CoreLib GUI 系统提供菜单模板、打开请求、会话管理和交互控制基础设施。业务模块不需要从零处理 InventoryClickEvent,而是定义自己的 GUI 配置,再交由 CoreLib 统一管理。

使用 GUI 系统的模块

模块用途
EmakiForge锻造界面、配方书。
EmakiStrengthen强化界面、材料槽、保护材料槽。
EmakiGem镶嵌、提取、开孔、升级界面。
EmakiSkills技能界面、触发器选择界面。
EmakiCooking蒸锅、烤炉、榨汁机、发酵桶 GUI。
EmakiAttribute属性点加点界面。
EmakiItem物品修复界面。
EmakiLevel等级面板、排行榜界面。
EmakiStorage分页仓库界面。

菜单渲染后端

plugins/EmakiCoreLib/config.ymlgui.backend 决定 Emaki 系列所有菜单如何呈现给玩家:

说明
bukkit默认值。打开真实服务端容器,无需任何前置插件。
packet由 CoreLib 内置的发包虚拟菜单,刷新不同行数时复用同一窗口、光标不会被重置;需要额外安装 PacketEvents。未安装时自动回退为 bukkit
auto安装了 PacketEvents 就用 packet,否则用 bukkit

默认保持 bukkit,升级 CoreLib 不会改变现有菜单行为。

GUI 模板配置

GUI 模板是菜单的静态定义,描述界面的标题、大小、槽位布局和按钮。

顶层字段

字段类型必填默认值说明
idstring模板唯一标识,模块内部引用时使用。
titlestring / object界面标题。支持 MiniMessage 格式字符串或 TextConfig 对象。
rowsinteger界面行数,取值范围 16,对应 9–54 个槽位。
slotsmap槽位定义,key 为槽位名称,value 为槽位配置对象。

槽位配置字段

每个槽位定义了一组格子的外观和行为:

字段类型必填默认值说明
keystring槽位名称,用于业务代码引用。
slotslist<integer>对应的格子索引列表(0 起始,从左到右、从上到下)。
typestring""槽位类型标签,如 inputoutputbuttondecoration
itemobject共享物品定义,包含 sourceamountcomponents。缺少 source 时可作为运行时物品的纯组件 patch。
soundsmap点击音效配置,按点击类型区分。

统一物品结构

新配置和默认资源只写嵌套结构:

yaml
item:
  source: minecraft-anvil
  amount: 1
  components:
    custom_name: '<green>确认</green>'
    lore:
      - '<gray>点击执行</gray>'
    item_model: emaki:confirm
    enchantment_glint_override: true
    $unset:
      - repairable
    $reset:
      - attribute_modifiers
  • source 接受 CoreLib 当前注册的全部 ItemSource 简写;实际可用性取决于对应 resolver 是否已安装。
  • 普通组件值表示 SET$unset 删除组件,$reset 恢复该材质原型的默认组件。
  • 组件 ID 必须是合法的 namespaced key;省略命名空间时默认补为 minecraft:,显式命名空间保持不变。该规则同样适用于 $unset / $reset 列表。未知 ID 或当前版本支持但值非法属于配置错误。
  • 已知但高于当前服务器版本的组件会跳过并记录警告,不会加载高版本专用类。
  • 第三方来源先克隆原物品,保留来源身份、PDC 和未知组件,只应用当前 Paper 可安全传递的 patch。
  • 旧槽位 item: <source> 与顶层 componentsdisplay_namelore 等仍可读取,但仅作为兼容输入;新旧同时出现时以嵌套 item 为准。
  • 玩家真实放入的目标物、材料和业务产物仍由会话状态决定,不会被模板展示物品强行覆盖。

旧版 GUI 物品字段自动迁移

从 CoreLib 4.5.11 起,共享 gui/*.{yml,yaml} 会在 YamlDocument 正式加载和 GuiTemplateParser 解析之前执行一次纯结构迁移。迁移会遍历整份 YAML 中的候选 configured-item 节点,因此除常见 slots 外,也能处理 pages/buttonsvirtual_items 等模块自定义容器中的旧物品定义。

迁移规则与运行时 LegacyConfiguredItemConverter 保持一致:

  • materialitem_source / item_sources、标量 item 等旧来源字段迁移到 item.sourceamount 迁移到 item.amount
  • display_nameitem_namelorecustom_model_dataenchantmentsitem_flagshidden_componentsunbreakable 等旧展示字段迁移到 item.components
  • 已存在的现代 item.sourceitem.amount 和组件值优先,混合格式中的旧值不会覆盖现代值。
  • 如果候选节点包含 components.rawitem.components.raw,整个节点会安全跳过,避免改写无法无损理解的原始组件负载。
  • 槽位布局、声音、动作、分页规则和其它非目标业务字段保持不变;迁移完成后再次运行不会产生额外修改。

每批实际修改都会先把原文件原文备份到对应插件数据目录的 migration-backups/configured-item-format/<时间戳>/,并保留相对于 gui/ 源目录的路径。迁移结果先写入同目录临时文件并重新解析校验,校验通过后才替换原文件;写入、校验或替换失败时,原文件保持不变或从本批备份恢复,GUI 加载不会继续使用未经验证的迁移结果。BoostedYAML 的注释模型会尽可能保留未改业务节点的注释,但仍建议正式服升级前备份完整配置目录。

该兼容层不读取 config.yml、语言文件或插件描述符中的版本号,也不按版本门禁执行;它只根据旧字段是否存在决定是否迁移。实现集中在 CoreLib item.migration.configureditem 包,GUI 侧只由 GuiTemplateLoader 作为生产桥接入口,因此结束兼容期后可整体删除,不会把旧格式逻辑留在通用 YamlFiles / YamlDirectoryLoader 或 canonical parser 中。

点击类型

GUI 系统识别以下点击类型:

类型说明
CLICK通用点击(作为 fallback,当没有匹配到具体类型时使用)。
LEFTCLICK左键点击。
RIGHTCLICK右键点击。

音效查找优先级:先查 LEFTCLICK / RIGHTCLICK,未找到时回退到 CLICK

完整 GUI 配置示例

强化界面示例

yaml
id: strengthen_gui
title: '<dark_gray>装备强化'
rows: 6
slots:
  background:
    slots: [0,1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53]
    type: decoration
    item:
      source: minecraft-black_stained_glass_pane
      components:
        minecraft:custom_name: ' '
        minecraft:tooltip_display:
          hide_tooltip: true
  target:
    slots: [13]
    type: input
    item:
      source: minecraft-air
      components:
        minecraft:custom_name: '<gray>放入目标装备'
        minecraft:lore:
          - '<dark_gray>将需要强化的装备放在这里'
  confirm:
    slots: [49]
    type: button
    item:
      source: minecraft-anvil
      components:
        minecraft:custom_name: '<green>开始强化'
        minecraft:lore:
          - '<gray>放入装备和材料后点击'
          - ''
          - '<yellow>左键点击开始强化'
        minecraft:enchantments:
          minecraft:unbreaking: 1
        minecraft:tooltip_display:
          hidden_components:
            - minecraft:enchantments
    sounds:
      LEFTCLICK:
        sound: minecraft:block.anvil.use
        volume: 0.8
        pitch: 1.0

锻造界面示例

yaml
id: forge_gui
title: '<dark_gray>锻造台'
rows: 6
slots:
  background:
    slots: [0,1,2,3,4,5,6,7,8,9,17,18,26,27,35,36,44,45,46,47,48,49,50,51,52,53]
    type: decoration
    item:
      source: minecraft-gray_stained_glass_pane
      components:
        minecraft:custom_name: ' '
  blueprint_slot:
    slots: [10]
    type: input
    item:
      components:
        minecraft:custom_name: '<aqua>图纸槽'
        minecraft:lore:
          - '<gray>放入锻造图纸'
  material_slots:
    slots: [11,12,13,14,15,16,19,20,21,22,23,24,25]
    type: input
    item:
      components:
        minecraft:custom_name: '<yellow>材料槽'
        minecraft:lore:
          - '<gray>放入锻造材料'
  target_slot:
    slots: [28]
    type: input
    item:
      components:
        minecraft:custom_name: '<gold>目标装备'
        minecraft:lore:
          - '<gray>放入需要锻造的装备'
  result_preview:
    slots: [34]
    type: output
    item:
      components:
        minecraft:custom_name: '<green>预览结果'
  confirm:
    slots: [43]
    type: button
    item:
      source: minecraft-smithing_table
      components:
        minecraft:custom_name: '<green>确认锻造'
    sounds:
      LEFTCLICK:
        sound: minecraft:block.anvil.use
        volume: 1.0
        pitch: 1.2

GUI 会话

GUI 会话用于记录玩家当前打开的界面状态。会话由 CoreLib 自动管理,业务模块通过 GuiSessionHandler 接口处理交互逻辑。

会话记录的信息包括:

  • 玩家正在操作哪一个配方或流程。
  • 哪些槽位是输入槽(允许放入物品),哪些槽位禁止拿取。
  • 点击按钮后应该调用哪个业务流程。
  • 关闭界面时是否需要返还输入物品。
  • 当前界面的临时状态数据。

会话的核心作用是防止玩家通过快速点击、Shift 点击、拖拽或异常关闭复制物品或绕过流程。

槽位索引参考

6 行界面的槽位索引布局:

text
行 1:  0  1  2  3  4  5  6  7  8
行 2:  9 10 11 12 13 14 15 16 17
行 3: 18 19 20 21 22 23 24 25 26
行 4: 27 28 29 30 31 32 33 34 35
行 5: 36 37 38 39 40 41 42 43 44
行 6: 45 46 47 48 49 50 51 52 53

常用位置:

  • 中心位置(6 行):22(第 3 行中间)或 31(第 4 行中间)
  • 底部中间:49
  • 四角:084553

修改 GUI 的建议

  1. 先只改显示文本:确认语言、颜色、布局是否符合预期。
  2. 再改槽位位置:移动按钮时确认不会和输入槽、输出槽冲突。
  3. 最后改交互逻辑:例如确认按钮、返回按钮、分页按钮。
  4. 每次修改后测试异常操作:Shift 点击、拖拽、双击、关闭界面、背包满。

MiniMessage 与颜色

GUI 文本建议统一使用 MiniMessage 格式:

yaml
item:
  source: minecraft-smithing_table
  components:
    minecraft:custom_name: '<gold>传说锻造台'
    minecraft:lore:
      - '<gray>放入图纸、材料和目标装备。'
      - '<yellow>点击开始锻造。'
      - ''
      - '<dark_gray>消耗:<white>500 金币'

常用 MiniMessage 标签:

标签效果
<red>红色文本
<green>绿色文本
<gold>金色文本
<gray>灰色文本
<dark_gray>深灰色文本
<yellow>黄色文本
<aqua>青色文本
<bold>粗体
<italic>斜体
<strikethrough>删除线
<gradient:gold:yellow>渐变色

如果某个模块仍兼容传统颜色符(&a§b),也建议逐步迁移到 MiniMessage,方便统一风格。