跳转至

🚥 事件 (Events)

KaMenu 支持在菜单的特定时刻执行预定义的动作列表,通过 Events 键配置。事件系统允许你在菜单打开、关闭等关键时刻执行特定逻辑。


支持的事件

事件名 触发时机 支持变量
Open 菜单打开前 {data:*}, {gdata:*}, {meta:*}, %papi_var%
Close 菜单关闭后 {data:*}, {gdata:*}, {meta:*}, %papi_var%, $(input_key)
Click 待触发的动作列表 {data:*}, {gdata:*}, {meta:*}, %papi_var%

重要说明:

  • Open 事件在菜单打开前触发,因此不支持 $(input_key) 输入变量(因为输入框还未显示)
  • Close 事件在菜单关闭后触发,支持所有变量格式,包括 $(input_key)

基本语法

简单事件(无条件执行)

Events:
  Open:
    - 'tell: &a欢迎来到本服务器!'
    - 'sound: entity.player.levelup'

条件事件(有条件执行)

Events:
  Open:
    - condition: "条件表达式"  # 可选
      allow:
        - '条件满足时执行的动作1'
        - '条件满足时执行的动作2'
      deny:
        - '条件不满足时执行的动作1'
        - '条件不满足时执行的动作2'

如何调用待触发的动作列表

先配置动作列表

Events:
  Click:
    hello:
      - 'tell: &a你好!欢迎来到服务器。'
      - 'tell: &a祝你在这里玩的愉快!'

使用 actions 动作激活:

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 确定 ]'
    actions:
      - 'actions: hello'  # 执行上面配置的`hello`待触发的动作列表

使用 可点击文本 激活:

Body:
  text:
    type: 'message'
    text: '请 <text="点击问候";actions=hello;hover=点击执行 hello 动作> 可以看到欢迎语'

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 确定 ]'
    actions:
      - 'hovertext:  <text="[点击问候]";actions=hello;hover=点击执行 hello 动作> 可以看到欢迎语'  

特殊动作

Return 动作

在事件动作列表中,支持使用 return 动作来中断后续动作的执行:

Events:
  Open:
    - condition: 'hasPerm.kamenu.admin'
      allow:
        - 'tell: &a欢迎管理员!'
      deny:
        - 'tell: &c你没有权限!'
        - 'return'  # 中断后续动作
        - 'tell: 你永远看不到这条消息'

注意事项:

  • Open 事件中的 return阻止菜单打开
  • Close 事件中的 return 只是中断剩余动作(因为菜单已经关闭)
  • return 在条件判断的 allowdeny 分支中都有效

使用场景

1. 权限检查

无条件检查:

Events:
  Open:
    - 'tell: &a欢迎来到本服务器!'
    - 'sound: entity.player.levelup'

有条件检查:

Events:
  Open:
    - condition: '%player_is_op% == true'
      allow:
        - 'tell: &a你打开了管理员菜单'
      deny:
        - 'tell: &c你没有权限打开此菜单'
        - 'return'  # 非OP玩家看不到菜单

2. 复合条件检查

Events:
  Open:
    - condition: '%player_level% >= 10 && %player_health% >= 15'
      allow:
        - 'tell: &a满足条件:等级>=10  血量>=15'
        - 'title: title=&6欢迎;subtitle=&fVIP 玩家;in=5;keep=40;out=10'
      deny:
        - 'tell: &7未达到要求:需要等级>=10  血量>=15'

3. 数据初始化

首次访问检测:

Events:
  Open:
    - condition: '{data:first_visit} == null'
      allow:
        - 'tell: &e欢迎首次访问!已初始化数据'
        - 'set-data: first_visit %timestamp%'
        - 'set-data: visit_count 1'
        - 'title: title=&6欢迎新人;subtitle=&f这是你第一次访问;in=10;keep=60;out=20'
      deny:
        - 'tell: &7欢迎回来!这是你第 {data:visit_count} 次访问'
        - 'set-data: visit_count {data:visit_count} + 1'

4. 状态检查

Events:
  Open:
    - condition: '{meta:temp_banned} == true'
      allow:
        - 'tell: &c你已被临时封禁,无法访问此菜单'
        - 'return'
    - condition: '%player_health% <= 5'
      allow:
        - 'tell: &e你的血量很低,请注意安全'

5. 问候语系统

Events:
  Open:
    - condition: '%player_health% >= 20'
      allow:
        - 'tell: &a你的血量很健康!'
      deny:
        - 'tell: &7你需要注意血量了'
    - condition: '%player_level% >= 30'
      allow:
        - 'tell: &6你已经达到30级了!'

6. 关闭事件处理

Events:
  Close:
    - 'tell: &a感谢使用本菜单'
    - 'set-meta: last_visit %timestamp%'
    - 'set-data: total_visits {data:total_visits} + 1'
    - 'sound: entity.experience_orb.pickup'

完整示例

示例 1:管理员菜单的权限控制

Title: '&8» &4&l管理员面板 &8«'

Settings:
  can_escape: false

Events:
  Open:
    - condition: 'hasPerm.kamenu.admin'
      allow:
        - 'tell: &a欢迎访问管理员面板'
      deny:
        - 'tell: &c你没有权限访问此菜单!'
        - 'sound: block.note_block.bass'
        - 'return'

Body:
  welcome:
    type: 'message'
    text: '&7管理员控制面板 - 请谨慎操作'

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

示例 2:商店菜单的欢迎系统

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

Settings:
  after_action: CLOSE

Events:
  Open:
    # 首次访问检测
    - condition: '{data:shop_first_visit} == null'
      allow:
        - 'tell: &a欢迎来到服务器商店!这是你的第一次访问'
        - 'set-data: shop_first_visit true'
        - 'title: title=&6欢迎;subtitle=&f初次访问奖励已发放;in=5;keep=60;out=20'
      deny:
        - 'tell: &7欢迎回来!继续选购吧'

    # VIP 玩家欢迎
    - condition: 'hasPerm.vip.gold'
      allow:
        - 'tell: &6尊贵的金卡会员,欢迎光临!'

    # 显示余额
    - 'tell: &f当前余额: &e%player_balance%'

Body:
  welcome:
    type: 'message'
    text: '&7请选择你需要的商品'

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 浏览商品 ]'
    actions:
      - 'tell: &a正在浏览商品...'

示例 3:带数据追踪的问卷菜单

Title: '&8» &b&l玩家问卷 &8«'

Settings:
  can_escape: false
  after_action: WAIT_FOR_RESPONSE

Events:
  Open:
    # 检查是否已经填写
    - condition: '{data:questionnaire_completed} == true'
      allow:
        - 'tell: &a你已经完成了问卷,感谢参与!'
        - 'return'

    - 'tell: &e请填写以下问卷'

  Close:
    # 标记完成时间
    - 'set-data: questionnaire_completed true'
    - 'set-data: questionnaire_date %timestamp%'
    - 'tell: &a感谢你完成问卷!'
    - 'title: title=&a完成;subtitle=&f感谢你的参与;in=5;keep=40;out=10'

Inputs:
  rating:
    type: 'slider'
    text: '服务器评分 (1-10)'
    min: 1
    max: 10
    default: 5

  feedback:
    type: 'input'
    text: '意见或建议'
    multiline:
      max_lines: 5
      height: 100
    max_length: 500

Bottom:
  type: 'confirmation'
  confirm:
    text: '&a[ 提交 ]'
    actions:
      - 'tell: &a提交成功!'
      - 'close'
  deny:
    text: '&c[ 取消 ]'
    actions:
      - 'tell: &c已取消提交'
      - 'close'

示例 4:多条件检查菜单

Title: '&8» &5&lVIP 专属功能 &8«'

Settings:
  can_escape: false

Events:
  Open:
    # 多重检查
    - condition: '%player_level% < 30'
      allow:
        - 'tell: &c你的等级不足 30 级'
        - 'return'

    - condition: '!hasPerm.vip.basic'
      allow:
        - 'tell: &c你需要 VIP 权限才能访问此菜单'
        - 'return'

    - condition: '%player_health% < 10'
      allow:
        - 'tell: &e你的血量较低,请注意安全'

    # 通过所有检查
    - 'tell: &a欢迎访问 VIP 专属功能'
    - 'sound: entity.player.levelup'

Body:
  welcome:
    type: 'message'
    text: '&6VIP 专属功能区域'

Bottom:
  type: 'notice'
  confirm:
    text: '&a[ 确定 ]'
    actions:
      - 'tell: &a开始使用 VIP 功能'

注意事项

  1. 执行顺序
  2. Open 事件在菜单解析前执行
  3. Close 事件在菜单关闭后执行
  4. 事件动作列表按顺序执行

  5. Return 的作用域

  6. Open 事件的 return 会阻止整个菜单打开
  7. Close 事件的 return 只是中断剩余动作
  8. return 对嵌套条件判断有效

  9. 变量限制

  10. Open 事件不支持 $(input_key)(输入框未显示)
  11. Close 事件支持所有变量格式
  12. 条件判断支持所有内置方法和运算符

  13. 性能考虑

  14. 避免在事件中执行大量耗时操作
  15. 使用 return 及时中断不需要的逻辑
  16. 复杂条件判断建议使用括号明确优先级

  17. 错误处理

  18. 条件判断失败时不会阻止菜单打开(除非使用 return
  19. 动作执行失败不会影响后续动作执行
  20. 建议使用 tell 动作提供反馈信息

相关文档