跳转至

⚙️ 全局设置 (Settings)

Settings 节点用于配置菜单的全局行为参数,包括关闭方式、动作执行后的行为等。


配置项总览

配置项 类型 默认值 说明
can_escape Boolean true 是否允许玩家通过 ESC 键关闭菜单
after_action String CLOSE 点击按钮执行动作后的客户端行为
lifetime Long 300 菜单最大存在时间,单位为秒
need_placeholder List<String> null 菜单所需的 PlaceholderAPI 扩展列表

can_escape 参数

功能说明

控制菜单的关闭方式,决定玩家是否可以通过 ESC 键关闭菜单。

可选值

说明
true(默认) 玩家可通过 ESC 键关闭菜单,并触发底部按钮对应的动作
false 玩家必须点击指定按钮才能关闭菜单,禁用 ESC 退出功能

配置示例

Settings:
  can_escape: false  # 强制玩家必须点击按钮关闭菜单

使用场景

推荐使用 true(默认):

  • 普通菜单,允许玩家随时退出
  • 需要灵活关闭的场景

推荐使用 false

  • 重要确认菜单(如确认删除、确认支付)
  • 管理员操作菜单
  • 需要确保用户选择一个选项的场景
  • 使用 Events.Tasks 且需要明确控制关闭动作和任务停止时机的场景

ESC 触发的按钮动作

can_escape: true 时,玩家按 ESC 会根据底部按钮类型触发对应按钮的动作:

菜单类型 ESC 触发的动作
notice 唯一按钮的动作
confirmation deny(取消)按钮的动作
multi 已配置 exit 按钮时,触发 exit 按钮的动作

如果菜单依赖关闭事件或周期任务生命周期,ESC 所触发的按钮本身就是关闭路径;通常不需要在该按钮动作里额外写 close。只有你想在其它分支里主动关闭菜单时,才使用 closeforce-close

示例配置:

Settings:
  can_escape: true

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 确认 ]'
    actions:
      - 'tell: &a你选择了确认'
  deny:
    text: '&c[ 取消 ]'
    actions:
      - 'tell: &c你选择了取消'
      - 'close'

lifetime 参数

lifetime - 菜单存在时间上限

lifetime 的单位为秒,默认值为 300(5 分钟)。该值同时决定 Paper callback 的有效期和 KaMenu 服务端的菜单关闭定时器。

达到上限后,KaMenu 会:

  1. 确认该玩家当前仍处于原菜单会话,避免旧定时器误关后来打开的新菜单;
  2. 主动关闭 Dialog;
  3. 停止该菜单的 Events.Tasks
  4. 清理 repeat 分页状态;
  5. 执行 Events.Close 作为超时清理动作。

超时属于硬性上限,Events.Close 中的 return 不会阻止菜单关闭。小于或等于 0 的无效配置会回退到默认的 300 秒。

Settings:
  lifetime: 300

所有服务端 callback 始终保持一次性。reset 或打开新菜单会重新创建 callback,并重新计算 lifetimelifetime 可用于关闭长时间停留的菜单或等待遮罩,但不能代替按钮动作中的正常关闭或刷新逻辑。


after_action 参数

功能说明

定义玩家点击按钮后,客户端在等待服务器响应期间的行为。

背景:为什么需要此参数?

服务器与客户端之间的网络通信存在一定的延迟:

  • 正常情况:延迟仅为几十毫秒
  • 网络差/服务器负载高:延迟可能达到 1 秒或更长

在此期间,如果玩家对游戏世界进行操作(如移动物品、丢弃物品等),可能导致后续菜单逻辑与实际状态不一致,引发异常行为。

after_action 参数用于声明在客户端本地执行指定操作,防止玩家在服务器响应期间进行非法操作,确保菜单逻辑的完整性。

可选值

客户端行为 适用场景
CLOSE(默认) 直接关闭菜单界面 没有二级菜单或无需处理后续行为的场景
NONE 不执行任何本地行为 需要由服务器显式关闭、刷新或打开新菜单的场景
WAIT_FOR_RESPONSE 显示遮罩界面,等待服务器响应 需要等待服务器显式关闭、刷新或打开新菜单的场景

配置示例

Settings:
  after_action: CLOSE  # 默认值
  # after_action: NONE
  # after_action: WAIT_FOR_RESPONSE

详细说明

1. CLOSE(默认)

点击按钮后,客户端立即关闭菜单界面。

优点:

  • 简单直接
  • 用户体验流畅

缺点:

  • 无法防止网络延迟期间的非法操作

适用场景:

  • 没有二级菜单的简单菜单
  • 无需处理后续行为的场景

示例:

Settings:
  after_action: CLOSE

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 关闭 ]'
    actions:
      - 'close'

2. NONE

点击按钮后,客户端不执行任何本地行为,所有逻辑由服务器控制。

优点:

  • 灵活性最高
  • 服务器完全控制菜单行为
  • 适合需要根据条件决定关闭、刷新或打开其它菜单的场景

缺点:

  • 需要在每个按钮动作路径中明确关闭、刷新或打开菜单

适用场景:

  • 需要完全由服务器控制行为的场景
  • 需要根据条件决定是否关闭的场景
  • 点击后需要刷新当前菜单或打开其它菜单的场景

警告

重要提示:

after_action: NONE 时,客户端点击按钮后不会自动关闭菜单,但普通按钮和正文可点击文本的服务端 callback 均固定只能触发一次。若动作完成后没有关闭或重建菜单,后续点击将不会再产生服务器回调,客户端会留下无法响应的缓存界面。

使用 after_action: NONE 时,必须确保每个按钮的每条条件分支最终执行以下动作之一: - close / force-close:关闭菜单 - reset:刷新当前菜单,重新建立按钮回调 - open / force-open:打开其它菜单

lifetime 到期时会主动关闭菜单,避免失效界面长期残留,但它只是一项兜底措施。

示例:

Settings:
  after_action: NONE

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 确认删除 ]'
    actions:
      - condition: '%player_balance% >= 1000'
        allow:
          - 'console: eco take %player_name% 1000'
          - 'tell: &a扣款成功!'
          - 'close'  # 手动关闭菜单
        deny:
          - 'tell: &c余额不足!'
          - 'reset'  # 重新渲染菜单,避免留下无回调的旧界面
  deny:
    text: '&c[ 取消 ]'
    actions:
      - 'close'

3. WAIT_FOR_RESPONSE

点击按钮后,客户端显示遮罩界面,等待服务器响应后继续操作。

优点:

  • 完全防止网络延迟期间的非法操作
  • 适合重要操作
  • 用户体验稳定

缺点:

  • 需要确保每个按钮动作路径最终关闭、刷新或打开菜单(否则会卡在遮罩界面)
  • 增加一步等待时间

适用场景:

  • 有二级菜单(会自动打开新菜单)
  • 涉及重要操作(交易、权限变更)
  • 网络环境不稳定或 TPS 较低的服务器
  • 点击后必须等待服务端完成校验、刷新或跳转的场景

警告

重要提示:

使用 WAIT_FOR_RESPONSE 时,客户端会进入等待响应状态。和 NONE 一样,按钮回调仍然是一次性的;如果动作链结束后没有 closeresetopen / force-open 等能关闭或重新渲染菜单的动作,客户端会持续停留在等待遮罩或旧菜单状态,玩家无法继续有效交互。

因此,使用 WAIT_FOR_RESPONSE 时,请确保每个按钮的每条条件分支最终都会执行以下动作之一: - close / force-close:关闭菜单并结束等待 - reset:刷新当前菜单并重新建立按钮回调 - open / force-open:打开其它菜单并结束当前等待

示例(带二级菜单):

Settings:
  after_action: WAIT_FOR_RESPONSE

Bottom:
  type: 'multi'
  buttons:
    open_sub_menu:
      text: '&a[ 打开子菜单 ]'
      actions:
        - 'open: shop/weapons'  # 打开二级菜单,会自动关闭遮罩
    exit:
      text: '&c[ 退出 ]'
      actions:
        - 'close'

示例(无二级菜单,必须显式结束):

Settings:
  after_action: WAIT_FOR_RESPONSE

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 确认支付 ]'
    actions:
      - 'console: eco take %player_name% 1000'
      - 'tell: &a支付成功!'
      - 'close'  # 必须:关闭菜单,移除遮罩
  deny:
    text: '&c[ 取消 ]'
    actions:
      - 'close'  # 必须:关闭菜单,移除遮罩

示例(校验失败后继续交互,必须刷新):

Settings:
  after_action: WAIT_FOR_RESPONSE

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 确认 ]'
    actions:
      - condition: 'isPosInt.$(amount)'
        allow:
          - 'tell: &a输入有效'
          - 'close'
        deny:
          - 'toast: type=task;msg=输入错误;icon=barrier'
          - 'reset'  # 必须:重新渲染菜单,移除等待状态并重建按钮回调

need_placeholder 参数

功能说明

配置菜单所需的 PlaceholderAPI 扩展列表。在打开菜单前,插件会检查所需的扩展是否已加载。如果扩展未加载:

  • 管理员玩家(有 kamenu.admin 权限):会显示详细提示,包含缺失的扩展列表和点击下载按钮
  • 普通玩家:会显示简化的提示信息

此功能确保菜单中的占位符变量能正常工作,避免因扩展缺失导致的显示错误。

配置格式

Settings:
  need_placeholder:
    - 'player'     # Player 扩展
    - 'server'     # Server 扩展
    - 'vault'      # Vault 扩展

可选值

need_placeholder 是一个字符串列表,每个元素表示一个 PlaceholderAPI 扩展的标识符。

配置示例

基础示例:

Title: '&8» &6&l玩家信息 &8«'

Settings:
  need_placeholder:
    - 'player'
    - 'vault'

Body:
  message:
    type: 'message'
    text: |
      &a玩家名称: %player_name%
      &a玩家余额: %vault_eco_balance%
      &a在线时间: %player_time_played%

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 确定 ]'
    actions:
      - 'close'

管理员提示

当管理员(有 kamenu.admin 权限)尝试打开缺少依赖的菜单时,会显示类似以下信息:

§c该菜单需要以下PlaceholderAPI扩展:§e[player],§e[server]

每个扩展名称(如 [player])都是可点击的:

  • 点击扩展:自动执行 /papi ecloud download <扩展名> 命令
  • 悬停显示:显示将要执行的具体下载命令

普通玩家提示

普通玩家会看到简化提示:

§c该菜单缺少必要的依赖文件,请联系管理员。

(可在语言文件中自定义)

信息

如何获取扩展标识: 1. 使用 /papi list 命令查看已安装的扩展 2. 访问 PlaceholderAPI Expansion 搜索扩展 3. 查看扩展的官方文档或源码


完整示例

示例 1:普通商店菜单(推荐配置)

Title: '&8» &6&l服务器商店 &8«'

Settings:
  can_escape: true        # 允许 ESC 退出
  after_action: NONE      # 由服务器控制
  pause: false

Bottom:
  type: 'multi'
  buttons:
    buy:
      text: '&a[ 购买 ]'
      actions:
        - 'console: give %player_name% diamond 1'
        - 'console: eco take %player_name% 100'
        - 'tell: &a购买成功!'
        - 'close'
    exit:
      text: '&c[ 退出 ]'
      actions:
        - 'tell: &c再见!'
        - 'close'

示例 2:重要确认菜单

Title: '&8» &c&l确认删除 &8«'

Settings:
  can_escape: false                # 禁止 ESC 退出
  after_action: WAIT_FOR_RESPONSE  # 防止网络延迟操作
  pause: false

Bottom:
  type: 'confirmation'
  confirm:
    text: '&c[ 确认删除 ]'
    actions:
      - condition: '%player_name% == target_player'
        allow:
          - 'tell: &a已删除目标物品'
          - 'close'  # 必须:关闭菜单
        deny:
          - 'tell: &c你不是物品所有者!'
          - 'close'
  deny:
    text: '&a[ 取消 ]'
    actions:
      - 'tell: &a已取消删除'
      - 'close'  # 必须:关闭菜单

示例 3:管理员操作菜单

Title: '&8» &4&l管理员工具 &8«'

Settings:
  can_escape: false                # 禁止 ESC 退出
  after_action: NONE               # 由服务器控制
  pause: false

Bottom:
  type: 'multi'
  buttons:
    ban:
      text: '&c[ 封禁玩家 ]'
      actions:
        - 'open: admin/ban_player'
    kick:
      text: '&e[ 踢出玩家 ]'
      actions:
        - 'open: admin/kick_player'
    exit:
      text: '&7[ 返回 ]'
      actions:
        - 'open: main_menu'

示例 4:简单通知菜单

Title: '&8» &a&l通知 &8«'

Settings:
  can_escape: true        # 允许 ESC 退出
  after_action: CLOSE      # 直接关闭
  pause: false

Body:
  message:
    type: 'message'
    text: |
      &a欢迎访问我们的服务器!
      &7请遵守服务器规则,共同维护良好的游戏环境。

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 确定 ]'
    actions:
      - 'tell: &a已阅读通知'

最佳实践

1. 默认配置推荐

对于大多数菜单,推荐使用以下默认配置:

Settings:
  can_escape: true
  after_action: NONE

使用该配置时,所有按钮动作路径都必须显式 closereset 或打开其它菜单。

2. 重要操作配置

对于涉及重要操作(删除、支付、权限变更等)的菜单:

Settings:
  can_escape: false
  after_action: WAIT_FOR_RESPONSE

重要提示: 使用 WAIT_FOR_RESPONSE 时,确保所有按钮动作路径最终都会 closereset 或打开其它菜单。

3. 条件关闭配置

当需要根据条件决定是否关闭菜单时:

Settings:
  can_escape: true
  after_action: NONE

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 确认 ]'
    actions:
      - condition: 'checkCondition'
        allow:
          - 'tell: &a操作成功'
          - 'close'
        deny:
          - 'tell: &c操作失败,请重试'
          - 'reset'  # 保持菜单可交互时必须重新渲染

4. 网络环境考虑

网络良好的服务器:

  • 大部分场景使用 after_action: NONE
  • 简单菜单可以使用 after_action: CLOSE
  • 使用 after_action: NONE 时,每个按钮路径最终必须 closereset 或打开其它菜单,避免客户端保留无回调的缓存界面

网络不稳定或 TPS 较低的服务器:

  • 重要操作使用 after_action: WAIT_FOR_RESPONSE
  • 确保每个按钮路径最终都会 closereset 或打开其它菜单

注意事项

  1. after_action 选择

    • 默认使用 NONE,灵活性最高
    • 重要操作使用 WAIT_FOR_RESPONSE,确保数据一致性
    • NONE 不会自动关闭菜单,按钮回调是一次性的;所有动作分支都必须显式 closeresetopen
    • WAIT_FOR_RESPONSE 也必须显式结束或重建交互;所有动作分支都必须 closeresetopen
  2. can_escape 使用

    • 普通菜单保持 true,提供更好的用户体验
    • 重要确认菜单设为 false,强制用户选择
    • 使用 Events.Tasks 或依赖 Events.Close 时,优先让 ESC 对应按钮承担关闭职责;只有需要手动关闭其它分支时才使用 close / force-close
  3. pause 参数

    • 仅单机有效,多人服务器无需关注
    • 通常保持默认值 false
  4. 向后兼容

    • 旧版本配置文件不包含 Settings 节点时,使用默认值
    • 建议所有新配置文件都包含 Settings 节点

相关文档