• 欢迎加入MineBBS QQ讨论群:点击查看所有的官方讨论群
  • 我们将于近期对服务器进行迁移,服务可能中断至多2日。请各位安排好自己的访问计划,造成不便敬请谅解!
  • MineBBS入站考试已经上线!想要成为【正式会员】解锁更多功能吗?快来参与吧!【点我去看】
⚡ KaMenu⚡ - 全新菜单插件 | 对话框界面 | 探索无限可能 | 实现各种复杂逻辑 | 丰富交互体验 [1.21.6+]

原创 开源 工具 ⚡ KaMenu⚡ - 全新菜单插件 | 对话框界面 | 探索无限可能 | 实现各种复杂逻辑 | 丰富交互体验 [1.21.6+] 2.0.5

请登录后获取
[MD] ## 资源包插件字形兼容 ### ItemsAdder - 动态 Dialog 文本现在会主动调用 ItemsAdder API 解析 `:font_image:` - 支持 ItemsAdder `:offset_N:` 像素偏移符 - 解决 ItemsAdder 内部占位符在 Paper Dialog 中原文显示的问题 ### Oraxen - 支持 `<glyph:id>` 与短写 `<g:id>` - 同一 Oraxen 原始文本行支持 `<shift:N>` 像素偏移,可点击文本拆分后仍保持解析上下文 - 使用当前玩家的 Oraxen Resolver,保留字形字体、颜色、阴影和权限检查 - 只在文本出现 Oraxen glyph 标签时启用 Oraxen shift,避免与 CraftEngine 标签冲突 ### CraftEngine - 兼容 `<image:namespace:id>` 与 `<shift:N>` - 字形继续由 CraftEngine 的 Dialog 数据包拦截器处理,KaMenu 不重复转换 - 使用时需保持 CraftEngine `network.intercept-packets.dialog: true` [/MD]
[MD] ### 新增 ESC 暂停菜单入口 KaMenu 现在可以通过原版数据包,在客户端 ESC 暂停菜单中注册一个自定义入口按钮: 编辑 `plugins/KaMenu/pause_menu.yml` 执行: ```bash /km pause register ``` [/MD]
  • 喜欢
反馈: fng_fasa_
[MD] ## 新增功能 ### 1. 可点击文本支持 ItemStack 悬浮 可点击文本新增 `hover_item` 参数,鼠标悬停时可以展示完整 ItemStack,包括名称、Lore、附魔、模型和其他数据组件: ```yaml text: - '当前武器:<text="&6[主手]";hover_item=hand>' - '奖励预览:<text="&d[神奇之剑]";hover_item="stock:神奇之剑">' ``` 支持以下来源: - `hand`、`offhand` - `slot:<槽位>` - `armor:helmet`、`armor:chestplate`、`armor:leggings`、`armor:boots` - `stock:<保存物品名>` - `material:<材质ID>` 有效的 `hover_item` 优先于普通 `hover`;物品不存在时仍可使用 `hover` 文字作为回退。 ### 2. 新增 `checkitem` 物品属性变量 新增统一的物品属性查询能力。菜单内部使用大括号变量,其他插件通过 PlaceholderAPI 调用: ```text {checkitem:[hand;name]} %kamenu_checkitem_[hand;name]% ``` 支持的物品来源: - `hand`:主手物品 - `offhand`:副手物品 - `slot:<索引>`:玩家背包槽位 - `stock:<名称>`:KaMenu 保存物品 支持的属性: - 基础属性:`type`、`amt`、`name` - Lore:`lore`、`lore:<行号>`;行号从 `1` 开始 - 附魔:`enchants`、`ench:<附魔ID>` - 模型:`model` / `item_model` - 自定义模型 ID:`cmd` / `custom_model_data` / `custom_model_id`,默认按整数输出 - 耐久:`dmg`、`dura`、`dura_pct` `name` 和 Lore 默认输出纯文本,也可使用第三个参数 `fmt:legacy` 或 `fmt:mini`。`fmt` 仅影响名称和 Lore 文本。`lore` 返回 JSON 字符串数组,`enchants` 返回包含 `key` 和 `level` 的 JSON 对象数组,可直接作为 repeat 数据源。 原版附魔 ID 可省略 `minecraft:`;自定义附魔必须提供完整命名空间。 保存物品名包含分号时,使用反引号包裹内部名称,例如 ``{checkitem:[stock:`活动;长剑`;name]}``,避免与 YAML 外层引号冲突。 ### 3. `hasItem` 支持自定义模型 ID 原有 `hasItem` 条件和 `%kamenu_hasitem_[...]%` 数量变量现在可以分别判断 ItemModel 与整数 CustomModelData: ```yaml condition: 'hasItem.[mats=PAPER;amount=1;model=custom:magic_scroll]' condition: 'hasItem.[mats=PAPER;amount=1;custom_model_id=10001]' ``` - `model` / `item_model`:匹配 NamespacedKey 类型的 ItemModel - `cmd` / `custom_model_data` / `custom_model_id`:匹配整数 CustomModelData 两类模型条件可以同时填写,此时物品必须同时满足。`hasItem` 与 `checkitem` 现已共用模型属性读取逻辑,避免两套功能对同一物品给出不同结果。同时修复主手快捷栏物品可能被重复计数的问题。 [/MD]
[MD] ## ✨ 新增功能 ### 1. 新增菜单存在时间上限 `Settings` 新增 `lifetime`,用于限制 Dialog 菜单的最大存在时间,单位为秒,默认值为 `300`(5 分钟): ```yaml Settings: lifetime: 300 ``` 该值同时控制 Paper callback 的有效期和 KaMenu 服务端的菜单关闭定时器。 达到时间上限后,KaMenu 会: - 确认玩家仍处于原菜单会话,避免旧定时器关闭后来打开的新菜单 - 主动关闭已超时的 Dialog - 停止该菜单的 `Events.Tasks` - 清理 repeat 分页状态 - 执行 `Events.Close`,用于完成菜单清理逻辑 超时属于硬性上限,`Events.Close` 中的 `return` 不会阻止菜单关闭。`lifetime` 小于或等于 `0` 时会回退到默认的 300 秒。 `reset` 或打开其它菜单会替换原菜单会话并重新计时;旧菜单的超时任务不会误关新菜单。 --- ## 问题修复 ### 1. 修复菜单内 JavaScript 包被错误识别为全局包 修复菜单 UI 字段和条件化配置在解析 `{js:[name]}` 时丢失当前菜单配置的问题。 例如菜单已经定义: ```yaml JavaScript: player_name: | player.getName(); Body: info: type: message text: '&a{js:[player_name]}' ``` 旧版本可能跳过菜单内的 `JavaScript.player_name`,错误地只检查 `plugins/KaMenu/js/player_name.js`,并输出类似警告: ```text JavaScript package 'player_name' not found (checked global js/player_name.js) ``` 现在条件值解析器会保留当前 `YamlConfiguration` 上下文,恢复正确的查找顺序: 1. 当前菜单的 `JavaScript.<name>` 2. 全局 JavaScript 包 `plugins/KaMenu/js/<name>.js` 修复范围包括: - `Title` 条件值 - `Body` 文本和物品描述 - `Inputs` 文本与默认值 - `Bottom` 按钮文本和 tooltip - 条件化字符串、字符串列表和类型字段 - 条件值内部使用的菜单 JavaScript 包 现有 `{js:[name]}` 语法无需修改。 [/MD]
初步支持Folia核心
[MD] ## 问题修复 ### 1. 修复 JavaScript 延迟调度错误 修复 JavaScript 内置辅助方法在调用 Bukkit 延迟任务时可能出现的参数类型不匹配问题: ```text NoSuchMethodException: CraftScheduler.runTaskLater(...) ``` 该问题可能在 JavaScript 包或菜单内脚本使用延迟执行逻辑时触发。现在延迟 tick 参数会正确转换为 Bukkit 调度器需要的 `Long` 类型,并将 JavaScript 回调包装为 Java `Runnable`,避免 Nashorn 对方法重载解析失败。 同时更新了 JavaScript 文档中的延迟执行示例,避免继续推荐不适合当前独立执行上下文的旧写法。 ### 2. 修复自定义指令重载后 TAB 补全不立即刷新 修复新增、删除或修改 `custom-commands` 后,在线玩家需要退出重进服务器才能获得最新 TAB 补全的问题。 现在执行以下重载后,会主动刷新所有在线玩家的客户端命令树: - `/kamenu reload config` - `/kamenu reload all` 这样自定义指令重新注册完成后,在线玩家可以立刻使用新的命令补全。 ### 3. 支持播放资源包自定义音效 `sound:` 动作现在会在原版声音 Registry 查找失败时,自动使用字符串 sound key 转发给客户端播放。 这意味着可以直接播放资源包 `sounds.json` 中定义的自定义声音,例如: ```yaml - 'sound: mypack:ui.click;volume=1.0;pitch=1.0;category=ui' ``` 同时修复了原版声音 ID 使用下划线风格时的兼容问题,例如 `ENTITY_PLAYER_LEVELUP` 会尝试转换为 `entity.player.levelup`。 [/MD]
[MD] ## 📋 版本信息 - **版本号**: 1.6.0 - **发布日期**: 2026年7月8日 --- ## ✨ 新增功能 ### 1. 新增全局 actions 动作包 KaMenu 现在支持在 `plugins/KaMenu/actions/` 目录中放置全局 actions 动作包。一个 `.yml` 文件就是一个动作包,包 ID 为相对路径去掉 `.yml` 后缀。 ```text plugins/KaMenu/actions/reward/daily.yml -> reward/daily ``` 动作包文件格式: ```yaml actions: - 'toast: type=task;msg=领取成功;icon=emerald' - 'money: type=add;num={arg:0}' ``` 任意菜单动作列表、可点击文本动作、周期任务和自定义注册指令都可以调用: ```yaml - 'actions: reward/daily,100' ``` 查找优先级: 1. 当前菜单内的 `Events.Click.<动作列表名称>` 2. 全局动作包 `plugins/KaMenu/actions/<动作列表名称>.yml` 因此菜单内 `Events.Click` 与全局动作包同名时,会优先执行菜单内动作列表。 ### 2. 新增全局 JavaScript 包 KaMenu 现在支持在 `plugins/KaMenu/js/` 目录中放置全局 JavaScript 包。一个 `.js` 文件就是一个包,包 ID 为相对路径去掉 `.js` 后缀。 ```text plugins/KaMenu/js/reward/message.js -> reward/message ``` 包文件内容就是 JavaScript 代码: ```javascript var amount = args[0] || "0"; var target = args[1] || name; "恭喜 " + target + " 获得 " + amount + " 金币"; ``` 可在动作、文本、条件中调用: ```yaml - 'js: [reward/message],100,Steve' text: '提示:{js:[reward/message],100,Steve}' condition: '{js:[check/vip]} == true' ``` 查找优先级: 1. 当前菜单内的 `JavaScript.<包名>` 2. 全局 JavaScript 包 `plugins/KaMenu/js/<包名>.js` 因此菜单内 `JavaScript` 与全局 JS 包同名时,会优先执行菜单内脚本。 ### 3. 自定义注册指令支持参数 Tab 补全 `config.yml` 的 `custom-commands` 对象写法现在支持 `args` 键,用于给玩家输入指令参数时提供 Tab 补全候选项: ```yaml custom-commands: test2: args: 0: "[tp, tphere]" 1: "%kamenu_online_players%" actions: - condition: "{arg:0} == tp" allow: - "tell: 你将传送到 {arg:1}" ``` - `args` 使用从 `0` 开始的索引,与动作变量 `{arg:0}`、`{arg:1}` 保持一致 - 候选项支持 YAML 列表、逗号分隔字符串、`[a, b]` 简易列表 - 支持实时解析 PAPI,例如 `%kamenu_online_players%` - 支持实时解析 KaMenu 内置变量,例如 `{list:friends}`、`{glist:warps}` - 打开菜单的对象写法也支持 `menu: 菜单ID` + `args` --- [/MD]
修复 Paper 26.2 版本的悬浮文本导致的崩溃
[MD] ## ✨ 新增功能 ### 1. 新增输入捕获全局空格处理配置 `config.yml` 新增 `input-capture.trim-edge-spaces`: ```yaml input-capture: trim-edge-spaces: false ``` 开启后,玩家提交文本输入框时,KaMenu 会在写入 `$(输入键名)` 前自动移除内容前后的空格。 适合玩家名、指令参数、数字、ID、权限节点等对首尾空格敏感的输入场景。 ### 2. 文本输入框新增 `remove_chars` `Inputs` 的 `type: input` 文本输入框现在可以配置 `remove_chars`,用于删除玩家输入中的指定字符。 ```yaml Inputs: player_name: type: 'input' text: '&a请输入玩家名' remove_chars: '&_' ``` 也支持列表写法: ```yaml Inputs: command_arg: type: 'input' text: '&a请输入参数' remove_chars: - '&' - '_' - '"' ``` ### 3. `remove_chars` 支持特殊转义字符 为了处理不可见字符,`remove_chars` 现在支持以下转义写法: | 写法 | 含义 | |------|------| | `\s` | 普通空格 | | `\n` | 换行 | | `\r` | 回车 | | `\t` | Tab | | `\\` | 反斜杠 `\` | 例如移除颜色符号、下划线、空格和换行: ```yaml Inputs: command_arg: type: 'input' text: '&a请输入参数' remove_chars: - '&' - '_' - '\s' - '\n' ``` ### 4. 新增全局字符移除列表 `config.yml` 的 `input-capture` 下新增 `remove-char-lists`,可以集中定义常用输入过滤规则: ```yaml input-capture: remove-char-lists: global: - '&' - '_' - '\s' - '\n' ``` 菜单内可直接引用预设名: ```yaml Inputs: command_arg: type: 'input' text: '&a请输入参数' remove_chars: global ``` 如果 `remove_chars` 的字符串值匹配全局预设名,则使用该预设;如果没有匹配到预设名,则继续按旧规则作为字面字符集合处理。 --- ## 🔧 优化与加固 ### 1. 输入清洗统一进入变量上下文 输入清洗发生在 Paper Dialog 回调捕获输入后、写入 `variables` 前。 因此后续读取同一个 `$(key)` 的位置都会拿到一致的处理结果,包括: - 动作列表 - 条件判断 - JavaScript 参数 - 动作包参数 - 外部 action handler 收到的 variables ### 2. 保持旧菜单兼容 `input-capture.trim-edge-spaces` 默认关闭,旧菜单不会因为升级自动改变输入内容。 未配置 `remove_chars` 的文本输入框也会保持原样输入。 --- [/MD]
[MD] ## ✨ 新增功能 ### 1. 新增 `isNull` 条件方法 用于判断变量、PAPI 或输入值是否为空。 ```yaml condition: "isNull.%some_placeholder%" condition: "isNull.{data:nickname}" condition: "isNull.$(nickname)" condition: "!isNull.$(nickname)" ``` `isNull` 会将以下值视为空: - 空字符串 - 仅包含空格的字符串 - `null` 字符串(不区分大小写) 适合用于表单校验、数据是否存在判断、PAPI 返回值兜底等场景。 ### 2. 新增 `isPass` 条件方法 用于判断值是否为“绝对空字符串”。 ```yaml condition: "isPass.$(nickname)" condition: "!isPass.$(nickname)" ``` `isPass` 只有在字符串长度为 `0` 时才通过;如果玩家输入一个或多个空格,则不会通过。需要将空格也视为空时,请使用 `isNull`。 ### 3. 新增 `isTrue` 条件方法 用于判断变量是否为真值。 ```yaml condition: "isTrue.$(agree)" condition: "isTrue.{data:enabled}" condition: "isTrue.%some_placeholder%" condition: "!isTrue.$(agree)" ``` `isTrue` 接受: - `true`(不区分大小写) - `yes`(不区分大小写) - `1` 其他值、空值和空格字符串都视为 false。 ### 4. 新增 `getLength` 字符串长度函数 `getLength` 用于输出字符串长度,通常配合比较运算符使用。 ```yaml condition: "getLength.%player_name% >= 3" condition: "getLength.$(nickname) <= 12" condition: "getLength.{data:nickname} == 0" ``` `getLength.xxx` 会先解析变量,再计算解析后字符串的长度。适合用于限制昵称、留言、搜索关键字等输入长度。 --- ## 🔧 优化与加固 ### 1. 条件方法参数解析增强 条件引擎现在会保护 `isNull`、`isPass`、`isTrue` 和 `getLength` 的参数内容,避免空字符串或空格字符串在表达式解析阶段被丢失。 这使以下场景可以按预期工作: ```yaml condition: "isPass.$(nickname)" condition: "isNull.$(nickname)" condition: "getLength.$(nickname) > 12" ``` ### 2. 明确条件变量解析顺序 文档补充了条件判断的运行顺序:KaMenu 会先解析 `{data:*}`、`{gdata:*}`、`{meta:*}`、`%papi%`、`$(input)`、`{arg:*}` 等变量,再将解析后的结果交给条件表达式引擎和内置方法判断。 ### 3. 条件表达式注入防护 运行时变量值现在会作为完整字符串参与条件判断,不会被重新解释为 `||`、`&&`、比较符、括号等表达式语法。 这可以避免玩家通过输入内容改变条件逻辑,例如: ```yaml condition: "$(amount) <= 100" ``` 如果玩家输入 `1 || true`,该输入会作为普通字符串值处理,不会让条件表达式被改写为逻辑或判断。 [/MD]
后退
顶部 底部