🤖 动作 (Actions)¶
actions 节点定义按钮被点击后执行的操作列表。支持多种动作类型、延迟执行和条件分支。
配置结构¶
Bottom:
type: 'notice'
confirm:
text: '&a确认'
actions:
- 'tell: &a操作成功!'
- 'sound: entity.experience_orb.pickup'
- 'close'
动作列表按顺序逐一执行(wait 动作可插入延迟)。
动作类型总览¶
| 动作 | 功能说明 |
|---|---|
tell |
向玩家发送聊天消息 |
actionbar |
向玩家发送动作栏消息(屏幕底部) |
title |
向玩家发送屏幕标题和副标题 |
toast |
在屏幕上显示 Toast 通知 |
hovertext |
发送带有悬停提示和点击功能的聊天消息 |
command |
让玩家执行一条指令 |
chat |
让玩家在聊天框中发送消息 |
console |
以控制台权限执行一条指令 |
server |
传送到指定服务器(BungeeCord/Velocity) |
sound |
在玩家位置播放声音 |
money |
操作玩家金币(需要 Vault) |
stock-item |
存储库物品给予/扣除 |
item |
物品给予/扣除 |
open |
为玩家打开另一个菜单 |
close |
关闭当前菜单 |
url |
打开指定链接(仅单动作时生效) |
copy |
复制文字到剪贴板(仅单动作时生效) |
data |
操作玩家数据(支持 set/add/take/delete) |
gdata |
操作全局数据(支持 set/add/take/delete) |
meta |
操作玩家元数据(支持 set/add/take/delete) |
set-data |
设置玩家数据(旧格式,推荐使用 data) |
set-gdata |
设置全局数据(旧格式,推荐使用 gdata) |
set-meta |
设置玩家元数据(旧格式,推荐使用 meta) |
js |
执行 JavaScript 代码(支持预定义函数) |
actions |
执行 Events.Click 下定义的动作列表 |
wait |
插入延迟执行 |
return |
中断动作执行列表 |
目标选择器¶
所有动作都支持目标选择器,可以指定动作作用的目标玩家。
语法: {player: 选择器}
使用示例:
# 1. 未指定目标,发给当前玩家(默认)
- 'tell: 你好!'
# 2. 发给所有在线玩家
- 'tell: 服务器公告:服务器将在5分钟后重启!{player: *}'
- 'tell: 大家好!{player: *}'
# 3. 使用条件选择(PAPI 变量)
- 'tell: 欢迎管理员!{player: %player_is_op%}'
- 'tell: 达到10级的玩家:奖励已发送!{player: %player_level% >= 10}'
# 4. 复杂条件
- 'tell: VIP玩家专属消息{player: hasPerm.user.vip}'
- 'tell: 钱包超过10000的玩家{player: %vault_eco_balance% >= 10000}'
选择器类型:
| 选择器 | 说明 | 示例 |
|---|---|---|
{player: *} |
所有在线玩家 | {player: *} |
{player: all} |
所有在线玩家(同 *) | {player: all} |
{player: 条件} |
满足条件的在线玩家 | {player: %player_level% >= 10} |
支持的动作类型:
| 动作类型 | 是否支持目标选择器 | 说明 |
|---|---|---|
tell |
✅ | 聊天消息 |
actionbar |
✅ | 动作栏消息 |
title |
✅ | 屏幕标题 |
toast |
✅ | Toast 通知 |
hovertext |
✅ | 可点击文本 |
command |
✅ | 执行指令 |
chat |
✅ | 聊天消息 |
console |
✅ | 控制台指令(只执行一次) |
sound |
✅ | 播放声音 |
money |
✅ | 金币操作 |
stock-item |
✅ | 物品操作 |
item |
✅ | 物品操作 |
data |
✅ | 玩家数据 |
gdata |
✅ | 全局数据 |
meta |
✅ | 玩家元数据 |
js |
✅ | JavaScript 代码 |
open |
❌ | 打开菜单(只对当前玩家) |
close |
❌ | 关闭菜单(只对当前玩家) |
server |
❌ | 服务器传送(只对当前玩家) |
actions |
❌ | 动作组(只对当前玩家) |
wait |
❌ | 延迟执行(不直接执行动作) |
return |
❌ | 中断执行(不直接执行动作) |
条件表达式:
目标选择器支持所有 ConditionUtils 支持的条件表达式,包括:
- PAPI 变量:
%player_level%,%vault_eco_balance% - 比较运算:
>,>=,<,<=,==,!=,contains,!contains - 逻辑运算:
&&(与),||(或) - 括号分组:用于复杂的逻辑表达式
条件示例:
# 单条件
{player: %player_level% >= 10}
# 多条件(与)
{player: %player_level% >= 10 && hasPerm.user.vip}
# 多条件(或)
{player: %player_is_op% || hasPerm.user.vip}
# 复杂条件
{player: (%player_level% >= 10 && %vault_eco_balance% >= 1000) || %player_is_op% == true}
性能优化:
- ✅ 目标玩家列表会根据条件动态计算
- ✅ 条件表达式会被缓存以提高性能
- ✅ 不匹配任何玩家时会记录警告日志
注意事项:
- ⚠️
*和all会匹配所有在线玩家,请谨慎使用 - ⚠️ 条件表达式中的变量会为每个目标玩家单独解析
- ⚠️ 某些动作(如
open、close、server)不支持目标选择器,会忽略目标参数
动作类型一览¶
tell - 聊天消息¶
向玩家发送一条聊天消息。完整支持 Adventure MiniMessage 所有功能,包括颜色、渐变、点击事件、悬停事件等。
格式: tell: <消息>
示例(Legacy 颜色代码):
- 'tell: &a操作成功!'
- 'tell: &c操作失败,请联系管理员'
- 'tell: &7当前余额: &f%player_balance%'
- 'tell: &e你输入的内容: $(input_key)'
示例(MiniMessage 格式):
# 基础颜色和格式
- 'tell: <red>红色文字</red>'
- 'tell: <bold>粗体</bold> <italic>斜体</italic> <underline>下划线</underline>'
- 'tell: <gradient:red:blue>蓝红渐变文字</gradient>'
# 点击事件
- 'tell: 点击这里执行指令: <click:run_command:/say 你点击了这里!><gold>点我!</gold></click>'
- 'tell: <click:copy_to_clipboard:Hello KaMenu><gold>复制这段文字</gold></click>'
- 'tell: <click:open_url:https://minecraft.wiki><gold>打开Minecraft Wiki</gold></click>'
- 'tell: <click:suggest_command:/gamemode creative><gold>切换创造模式</gold></click>'
# 悬停事件
- 'tell: <hover:show_text:"<red>这是悬停文字<reset>\n<blue>支持多行显示"><gold>把鼠标放上来!</gold></hover>'
- 'tell: <hover:show_item:diamond_sword>显示钻石剑</hover>'
- 'tell: <hover:show_item:diamond><gold>显示钻石</gold></hover>'
# 组合使用(点击+悬停)
- 'tell: <click:run_command:/say 联合事件><hover:show_text:"<green>点击执行指令\n<gray>悬停显示提示"><gold>点击并悬停</gold></hover></click>'
# 物品图标和玩家头像(1.21.9+)
- 'tell: 看看这个 <sprite:block/stone> 石头'
- 'tell: 这是 <sprite:items:item/porkchop> 猪排'
- 'tell: 这是 <head:Notch> Notch的头'
- 'tell: <head:entity/player/wide/steve> Steve的头'
# 其他 MiniMessage 标签
- 'tell: <blue>按键: </blue><key:key.keyboard.b><red>B键</red>'
- 'tell: <blue>换行测试: <newline><red>这是新的一行</red></blue>'
- 'tell: <blue>NBT数据: </blue><nbt:display.Name></blue>'
MiniMessage 常用标签:
| 标签 | 说明 | 示例 |
|---|---|---|
<color> |
颜色标签 | <red>红色</red> |
<gradient> |
渐变色 | <gradient:red:blue>渐变</gradient> |
<bold> |
粗体 | <bold>粗体</bold> |
<italic> |
斜体 | <italic>斜体</italic> |
<underline> |
下划线 | <underline>下划线</underline> |
<click:action:value> |
点击事件 | <click:run_command:/say hi>点击</click> |
<hover:action:value> |
悬停事件 | <hover:show_text:提示>悬停</hover> |
<newline> |
换行 | 第一行<newline>第二行 |
<key:keyname> |
按键显示 | <key:key.keyboard.b>B键</key> |
注意:
- 支持 Legacy 颜色代码(
&a、&c等)和 MiniMessage 标签混合使用 - 当检测到 MiniMessage 标签时,会自动将 Legacy 颜色代码转换为对应的 MiniMessage 标签
- 例如:
&a→<green>,&c→<red>,&l→<bold> - 示例:
'<gold>&a这是 &c红色 &l粗体文字</l>'会自动转换为'<gold><green>这是 <red>红色 <bold>粗体文字</bold>' - 支持 PAPI 变量(
%var%)、内置数据变量({data:key})和输入组件引用($(key)) - 建议使用纯 MiniMessage 格式以获得最佳效果和功能完整性
actionbar - 动作栏消息¶
向玩家发送一条动作栏消息(显示在屏幕底部准星上方)。完整支持 Adventure MiniMessage 所有功能。
格式: actionbar: <消息>
示例:
# Legacy 颜色代码
- 'actionbar: &a操作成功!'
- 'actionbar: &7余额: &f%player_balance%'
# MiniMessage 格式
- 'actionbar: <green>操作成功!</green>'
- 'actionbar: <gradient:gold:red>余额: 1000</gradient>'
- 'actionbar: <hover:show_text:查看详细><gold>点击查看详情</gold></hover>'
注意: 消息持续显示约 3 秒后消失。支持与 tell 相同的 MiniMessage 功能。
title - 标题消息¶
向玩家发送屏幕标题和副标题。
格式: title: title=主标题;subtitle=副标题;in=淡入;keep=停留;out=淡出
参数说明:
| 参数 | 说明 | 单位 | 默认值 |
|---|---|---|---|
title |
主标题文本 | — | 空 |
subtitle |
副标题文本 | — | 空 |
in |
淡入时间 | tick | 0 |
keep |
停留时间 | tick | 60 |
out |
淡出时间 | tick | 20 |
示例:
- 'title: title=&a操作成功;subtitle=&7已完成'
- 'title: title=&6欢迎!;subtitle=&f你好,%player_name%;in=10;keep=80;out=20'
注意: 参数用分号 ; 分隔;支持颜色代码和变量。
hovertext - 可点击聊天文本¶
发送带有悬停提示和点击功能的聊天消息。
格式: hovertext: 普通文字 <text=显示文字;hover=悬停文字;command=指令;url=链接;actions=动作列表名;newline=false> 继续文字
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
text |
可点击的显示文字 | ✅ |
hover |
鼠标悬停时显示的提示文字 | ❌ |
command |
点击时玩家执行的指令 | ❌ |
url |
点击时打开的链接 | ❌ |
actions |
点击时执行的动作列表(Events.Click 下的键名) | ❌ |
newline |
是否在文字后换行(true/false) |
❌ |
示例:
- 'hovertext: &7点击这里 <text=&a[领取奖励];hover=&e点击领取今日奖励;command=/daily> 或稍后再来。'
- 'hovertext: 访问 <text=&b[官网];hover=&7打开浏览器访问官网;url=https://example.com> 了解更多。'
- 'hovertext: <text=&a[问候];actions=greet;hover=点击发送问候> 问候玩家'
使用 actions 参数:
Events:
Click:
greet:
- 'tell: &a你好!欢迎来到服务器。'
- 'sound: ENTITY_PLAYER_LEVELUP'
Body:
text:
type: 'message'
text: '<text="点击问候";actions=greet;hover=点击执行 greet 动作>'
点击事件优先级:
当同时存在多个点击参数时,优先级如下(从高到低):
1. actions - 执行动作列表
2. url - 打开链接
3. command - 执行指令
注意:
- 参数值用反引号
`、单引号'或双引号"包裹 - 可点击区域用
< >包裹 actions参数仅在 Body.message 文本组件中有效- 当使用
actions参数时,文本的点击事件会注册一个 ClickCallback,有效期 5 分钟
command - 玩家指令¶
让点击按钮的玩家执行一条指令。
格式: command: <指令>
示例:
注意: 指令前无需加 /;玩家需要有执行该指令的权限。
chat - 聊天消息¶
让玩家在聊天框中发送一条消息。
格式: chat: <消息>
示例:
- 'chat: /spawn' # 玩家发送 /spawn 指令
- 'chat: 大家好!' # 玩家发送聊天消息
- 'chat: /msg Admin 帮助我' # 玩家给管理员发送私聊
- 'chat: $(input_message)' # 发送玩家输入的内容
与 command 的区别:
| 动作 | 执行方式 | 权限要求 | 适用场景 |
|---|---|---|---|
command |
直接执行指令 | 需要玩家权限 | 执行插件指令(如 /spawn) |
chat |
模拟玩家在聊天框输入 | 不需要特殊权限 | 发送聊天消息、执行需要玩家权限的指令 |
使用场景:
- 需要让玩家在聊天框中显示消息(如广播、喊话)
- 执行需要玩家在聊天框中输入的指令
- 与其他玩家或插件进行交互
注意: 消息会被广播给在线玩家看到;支持颜色代码、PAPI 变量和输入组件引用。
console - 控制台指令¶
以控制台(OP 权限)执行一条指令。
格式: console: <指令>
示例:
- 'console: give %player_name% diamond 64'
- 'console: eco give %player_name% 1000'
- 'console: lp user %player_name% group add vip'
注意: 不需要玩家权限;指令前无需加 /;支持 PAPI 变量。
server - 传送到指定服务器¶
将玩家传送到指定的服务器(支持 BungeeCord 或 Velocity 等代理插件)。
格式: server: <服务器名称>
示例:
工作原理:
此动作会根据 config.yml 中的 bungeecord 配置自动选择传输方式:
| 配置 | 传输方式 | 优点 |
|---|---|---|
bungeecord: true |
BungeeCord 插件消息系统 | ✅ 无需玩家权限 ✅ 更加可靠 ✅ 性能更优 |
bungeecord: false |
执行 /server 命令 |
⚠️ 需要玩家有 /server 命令权限 |
使用场景:
- BungeeCord/Velocity 网络服务器
- 多服务器之间的传送
- 大厅/主菜单选择不同游戏模式
注意:
- BungeeCord 模式需要配合代理插件使用
- 服务器名称必须在代理插件配置中定义
- 玩家会立即断开当前服务器并连接到目标服务器
- 支持变量和条件判断
- 建议在 BungeeCord 网络中启用
bungeecord: true
配合变量使用:
高级示例 - 条件传送:
Events:
Click:
# 玩家选择服务器
select_server:
- condition: '{data:last_server} == survival'
allow:
- 'server: survival'
- 'tell: &a正在连接到生存服务器...'
deny:
- 'server: lobby'
- 'tell: &a正在连接到大厅...'
sound - 播放声音¶
在玩家位置播放一个声音,支持音量、音调和声音分类。
格式: sound: <声音名称>;volume=音量;pitch=音调;category=分类
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
| 声音名称 | Minecraft 声音 ID(使用 _ 或 . 均可) |
— |
volume |
音量(浮点数) | 1.0 |
pitch |
音调(浮点数) | 1.0 |
category |
声音分类 | master |
声音分类可选值:
| 值 | 说明 |
|---|---|
master |
主音量 |
music |
音乐 |
record |
唱片机 |
weather |
天气 |
block |
方块 |
hostile |
敌对生物 |
neutral |
中性生物 |
player |
玩家 |
ambient |
环境音 |
voice |
语音 |
ui |
界面音效 |
示例:
- 'sound: entity.experience_orb.pickup'
- 'sound: entity.player.levelup;volume=1.5;pitch=1.2'
- 'sound: block.note_block.pling;volume=1.0;pitch=2.0;category=ui'
open - 打开菜单¶
为玩家打开另一个菜单,当前菜单会自动关闭。
格式: open: <菜单ID>
示例:
注意: 菜单 ID 规则与 /km open 指令相同,子文件夹用 / 分隔,不包含 .yml 扩展名。
close - 关闭菜单¶
关闭当前打开的菜单。
格式: close
示例:
url - 打开链接¶
打开指定 URL(仅在按钮只有这一个动作时有效)。
格式: url: <链接地址>
示例:
信息
url 和 copy 动作为静态动作,仅当按钮的 actions 列表中只有这一个动作时才会生效。如需在执行其他动作的同时打开链接,请使用 hovertext 动作。
copy - 复制到剪贴板¶
将指定文字复制到玩家的剪贴板(仅在按钮只有这一个动作时有效)。
格式: copy: <文字>
示例:
set-data - 设置玩家数据(旧格式)¶
将一个键值对保存到当前玩家的持久化数据中。
格式: set-data: <键名> <值>
示例:
- 'set-data: language zh_CN'
- 'set-data: nickname $(player_nickname)'
- 'set-data: score %player_level%'
读取方式: 在菜单任意文本位置使用 {data:键名} 或 PAPI 变量 %kamenu_data_键名%。
警告
此为旧格式,推荐使用新的 data 动作,支持更多操作类型(add/take/delete)。
set-gdata - 设置全局数据(旧格式)¶
将一个键值对保存到全局数据中(所有玩家共享)。
格式: set-gdata: <键名> <值>
示例:
读取方式: 在菜单任意文本位置使用 {gdata:键名} 或 PAPI 变量 %kamenu_gdata_键名%。
警告
此为旧格式,推荐使用新的 gdata 动作,支持更多操作类型(add/take/delete)。
set-meta - 设置玩家元数据(旧格式)¶
将一个键值对保存到玩家的元数据中(内存缓存,无需持久化)。
格式: set-meta: <键名> <值>
示例:
- 'set-meta: time 19:02'
- 'set-meta: nickname $(player_nickname)'
- 'set-meta: last_menu shop/weapons'
读取方式: 在菜单任意文本位置使用 {meta:键名} 或 PAPI 变量 %kamenu_meta_键名%。
警告
此为旧格式,推荐使用新的 meta 动作,支持更多操作类型(add/take/delete)。
注意:
- 元数据仅存储在内存中,不持久化到数据库
- 玩家退出时自动清理该玩家的元数据
- 插件重载或关服时清理全部元数据
- 适用于需要短时间存储临时数据的场景
data - 玩家数据操作¶
操作玩家的持久化数据,支持设置、增加、减少和删除数值。
格式: data: type=操作类型;key=键名;var=值
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
type |
操作类型 | ✅ |
key |
数据键名 | ✅ |
var |
值(仅 type=set/add/take 时需要) | ❌ |
type 可选值:
set:设置值add:增加数值(仅当值为数字时有效)take:减少数值(仅当值为数字时有效)delete:删除该键值对
示例:
# 设置文本值
- 'data: type=set;key=test;var=`你好,我的世界`'
# 设置数字值
- 'data: type=set;key=num;var=`100`'
# 为数字值增加
- 'data: type=add;key=num;var=`10`'
# 为数字值减少
- 'data: type=take;key=num;var=`10`'
# 删除数据
- 'data: type=delete;key=num'
读取方式: 在菜单任意文本位置使用 {data:键名} 或 PAPI 变量 %kamenu_data_键名%。
注意:
add和take操作时,如果当前值或指定值不是数字,操作会失败并在后台输出警告delete操作时,如果键不存在,操作会静默失败(不会报错)- 旧格式
set-data: <键名> <值>仍然可用,但推荐使用新格式
gdata - 全局数据操作¶
操作全局数据(所有玩家共享),支持设置、增加、减少和删除数值。
格式: gdata: type=操作类型;key=键名;var=值
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
type |
操作类型 | ✅ |
key |
数据键名 | ✅ |
var |
值(仅 type=set/add/take 时需要) | ❌ |
type 可选值:
set:设置值add:增加数值(仅当值为数字时有效)take:减少数值(仅当值为数字时有效)delete:删除该键值对
示例:
# 设置全局数据
- 'gdata: type=set;key=total;var=`1000`'
# 增加数值
- 'gdata: type=add;key=total;var=`50`'
# 减少数值
- 'gdata: type=take;key=total;var=`20`'
# 删除数据
- 'gdata: type=delete;key=total'
读取方式: 在菜单任意文本位置使用 {gdata:键名} 或 PAPI 变量 %kamenu_gdata_键名%。
注意:
- 全局数据在所有玩家之间共享
add和take操作时,如果当前值或指定值不是数字,操作会失败并在后台输出警告delete操作时,如果键不存在,操作会静默失败(不会报错)- 旧格式
set-gdata: <键名> <值>仍然可用,但推荐使用新格式
meta - 玩家元数据操作¶
操作玩家的元数据(内存缓存),支持设置、增加、减少和删除数值。
格式: meta: type=操作类型;key=键名;var=值
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
type |
操作类型 | ✅ |
key |
数据键名 | ✅ |
var |
值(仅 type=set/add/take 时需要) | ❌ |
type 可选值:
set:设置值add:增加数值(仅当值为数字时有效)take:减少数值(仅当值为数字时有效)delete:删除该键值对
示例:
# 设置元数据
- 'meta: type=set;key=level;var=`10`'
# 增加数值
- 'meta: type=add;key=level;var=`1`'
# 减少数值
- 'meta: type=take;key=level;var=`1`'
# 删除数据
- 'meta: type=delete;key=level'
读取方式: 在菜单任意文本位置使用 {meta:键名} 或 PAPI 变量 %kamenu_meta_键名%。
注意:
- 元数据仅存储在内存中,不持久化到数据库
- 玩家退出时自动清理该玩家的元数据
- 插件重载或关服时清理全部元数据
add和take操作时,如果当前值或指定值不是数字,操作会失败并在后台输出警告delete操作时,如果键不存在,操作会静默失败(不会报错)- 旧格式
set-meta: <键名> <值>仍然可用,但推荐使用新格式
toast - Toast 通知¶
在屏幕右上角显示一个 Toast 通知。
格式: toast: type=类型;icon=物品ID;msg=标题
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
type |
通知类型 | task |
icon |
显示的物品ID | paper |
msg |
内容文本 | 空 |
type 可选值:
task:标题文本:进度已达成!(默认)goal:标题文本:目标已达成!challenge:标题文本:挑战已完成!(会播放音效)
示例:
- 'toast: msg=&f你获得了一把钻石剑;icon=diamond_sword'
- 'toast: type=challenge;msg=&f恭喜你完成了挑战!;icon=diamond'
- 'toast: type=goal;msg=&f已达成目标;icon=gold_ingot'
注意: Toast 通知会在屏幕上显示约 3 秒后自动消失。
money - 金币操作¶
操作玩家的金币(需要安装 Vault 经济插件)。
格式: money: type=操作类型;num=金额
参数说明:
| 参数 | 说明 | 可选值 |
|---|---|---|
type |
操作类型 | 如下列可选值 |
num |
金额 | 数值(支持小数) |
type 可选值:
add:给予玩家指定金额take:扣除玩家指定金额reset:将玩家余额设置为指定金额
示例:
# 给予玩家 100 金币
- 'money: type=add;num=100'
# 扣除玩家 50 金币
- 'money: type=take;num=50'
# 将玩家余额设置为 1000 金币
- 'money: type=reset;num=1000'
# 结合条件判断使用
- condition: "%player_balance% >= 500"
allow:
- 'money: type=take;num=500'
- 'tell: &a购买成功!'
deny:
- 'tell: &c余额不足!需要 500 金币'
注意:
- 需要安装 Vault 经济插件才能使用
- 此动作不会向玩家发送任何消息,玩家需自行判断和提示(如使用
tell或条件判断) take操作会检查余额,余额不足时不会执行扣除,仅会在控制台打印警告- 金额支持小数,如 1.5、0.99 等
- 金额可以使用变量,如
%player_level%或{data:price}
stock-item - 物品给予/扣除¶
给予玩家或从玩家背包中扣除指定数量的数据库的物品。
格式: stock-item: type=操作类型;name=物品名称;amount=数量
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
type |
操作类型 | ✅ |
name |
物品名称(已保存的物品) | ✅ |
amount |
数量 | ❌(默认: 1) |
type 可选值:
give:给予玩家物品take:从玩家背包中扣除物品
示例:
# 给予玩家 16 个神秘果
- 'stock-item: type=give;name=神秘果;amount=16'
# 从玩家背包扣除 16 个神秘果
- 'stock-item: type=take;name=神秘果;amount=16'
# 结合条件判断使用
- condition: "hasStockItem.神秘果;16"
allow:
- 'stock-item: type=take;name=神秘果;amount=16'
- 'tell: &a购买成功!'
deny:
- 'tell: &c物品不足!需要 16 个神秘果'
注意:
- 物品必须通过
/km item save指令保存后才能使用 give操作如果玩家背包已满,剩余物品会自动掉落在玩家位置,不会丢失take操作会遍历玩家所有背包槽位(包括主背包、盔甲槽、副手槽和主手槽)- 物品比较使用
ItemStack.isSimilar()方法,忽略物品数量差异 - 支持变量替换,如
name=$(item_name)或amount={data:price}
item - 普通物品给予/扣除¶
给予玩家或从玩家背包中扣除指定材质的普通物品。
格式:
item: type=give;mats=材质;amount=数量item: type=take;mats=材质;amount=数量;lore=描述;model=模型
参数说明:
| 参数 | 说明 | 必需 |
|---|---|---|
type |
操作类型(give/take) | ✅ |
mats |
物品材质(Material ID) | ✅ |
amount |
数量 | ❌(默认: 1) |
lore |
描述(仅用于take操作,可选) | ❌ |
model |
物品模型(仅用于take操作,可选) | ❌ |
type 可选值:
give:给予玩家物品(忽略lore和model参数)take:从玩家背包中扣除物品(支持lore和model判断)
示例:
# 给予玩家 10 个钻石
- 'item: type=give;mats=DIAMOND;amount=10'
# 从玩家背包扣除 10 个钻石
- 'item: type=take;mats=DIAMOND;amount=10'
# 扣除指定 lore 的物品
- 'item: type=take;mats=DIAMOND;amount=10;lore=锻造材料'
# 扣除指定模型的物品(如 Oraxen 物品)
- 'item: type=take;mats=DIAMOND;amount=10;model=oraxen:mana_crystal'
# 同时指定 lore 和 model
- 'item: type=take;mats=DIAMOND;amount=10;lore=锻造材料;model=oraxen:mana_crystal'
# 结合条件判断使用
- condition: "hasItem.[mats=DIAMOND;amount=10]"
allow:
- 'item: type=take;mats=DIAMOND;amount=10'
- 'tell: &a扣除成功!'
deny:
- 'tell: &c物品不足!需要 10 个钻石'
注意:
mats参数使用 Minecraft 原生材质 ID(如DIAMOND、IRON_INGOT等)give操作时,lore和model参数会被忽略,因为这两个参数仅用于判断give操作如果玩家背包已满,剩余物品会自动掉落在玩家位置,不会丢失take操作时:- 如果指定了
lore,会只扣除 lore 中包含指定字符串的物品(忽略大小写) - 如果指定了
model,会只扣除匹配指定物品模型的物品 - 如果同时指定了
lore和model,物品需要同时满足两个条件才会被扣除 model格式为namespace:key(如oraxen:mana_crystal、minecraft:diamond)take操作会遍历玩家所有背包槽位(包括主背包、盔甲槽、副手槽和主手槽)- 支持变量替换,如
mats=$(material)、amount={data:price}、lore={data:item_desc}
wait - 延迟执行¶
在动作列表中插入延迟,后续动作将在等待指定时间后执行。
格式: wait: <tick数>
单位: Minecraft tick(1 tick = 0.05 秒,20 tick = 1 秒)
示例:
- 'tell: &a开始倒计时...'
- 'wait: 20' # 等待 1 秒
- 'tell: &e3...'
- 'wait: 20'
- 'tell: &e2...'
- 'wait: 20'
- 'tell: &e1...'
- 'wait: 20'
- 'title: title=&c出发!;in=5;keep=30;out=10'
注意: wait 只影响其之后的动作;不会阻塞其他正在执行的任务。
return - 中断执行¶
在动作列表中插入中断,后续动作将不会被执行。
格式: return
示例:
- 'tell: &a开始倒计时...'
- 'wait: 20' # 等待 1 秒
- 'tell: &e3...'
- 'wait: 20'
- 'tell: &e2...'
- 'wait: 20'
- 'tell: &e1...'
- 'wait: 20'
- condition: '%player_is_online% == false'
allow:
- 'tell: &c检测到玩家离线,操作中断!'
- 'return' # 执行中断
- 'tell: &a你完成了操作。' # 若满足条件该动作不会被执行
注意: wait 只影响其之后的动作;不会阻塞其他正在执行的任务。
js - 执行 JavaScript 代码¶
执行 JavaScript 代码,支持直接执行代码或调用预定义函数。
格式: js: <JavaScript代码>
使用方式:
- 直接执行 JavaScript 代码
actions:
- 'js: player.sendMessage("Hello from JavaScript!");'
- 'js: var random = Math.floor(Math.random() * 100);'
- 'js: player.sendMessage("随机数: " + random);'
- 调用预定义函数(无参数)
JavaScript:
show_health: |
var health = player.getHealth();
var maxHealth = player.getMaxHealth();
player.sendMessage("§e生命值: §f" + health + "/" + maxHealth);
Bottom:
type: 'notice'
confirm:
text: '&a查看生命值'
actions:
- 'js: [show_health]'
- 调用预定义函数(带参数)
JavaScript:
process_data: |
var playerName = args[0];
var playerLevel = args[1];
var money = args[2];
player.sendMessage("§a玩家: §f" + playerName);
player.sendMessage("§a等级: §f" + playerLevel);
player.sendMessage("§a金币: §f" + money);
Bottom:
type: 'notice'
confirm:
text: '&e处理数据'
actions:
- 'js: [process_data] %player_name% $(level) {data:money}'
支持的变量:
player- 当前玩家对象uuid- 玩家 UUID 字符串name- 玩家名称location- 玩家位置inventory- 玩家物品栏world- 玩家所在世界server- 服务器实例args- 预定义函数的参数数组(仅在调用预定义函数时可用)
支持的参数类型(用于预定义函数):
- 字符串:直接传递
- PAPI 变量:
%player_name% - 玩家数据:
{data:money} - 全局数据:
{gdata:config} - 输入框变量:
$(input1) - 数字:
50,3.14
信息
JavaScript 功能非常强大,支持访问 Bukkit API、数学计算、条件判断等。详细了解 JavaScript 功能,请查看 🔧 JavaScript 功能 文档。
注意:
- JavaScript 代码在服务器端执行
- 预定义函数必须在菜单的
JavaScript节点中定义 - 参数以空格分隔,参数中不能包含空格
- Nashorn 引擎基于 ECMAScript 5.1 标准,不支持 ES6+ 语法
actions - 执行动作列表¶
执行 Events.Click 下定义的动作列表。这允许你在动作中复用已定义的动作列表,避免重复代码。
格式: actions: <动作列表名称>
参数说明:
| 参数 | 说明 | 示例 |
|---|---|---|
| 动作列表名称 | Events.Click 下的动作列表键名 |
greet, vip_check, daily_reward |
示例:
Events:
Click:
greet:
- 'tell: &a你好!欢迎来到服务器。'
- 'sound: ENTITY_PLAYER_LEVELUP'
vip_check:
- condition: '{permission:essentials.vip} == true'
allow:
- 'tell: &aVIP 专属欢迎!'
- 'sound: ENTITY_EXPERIENCE_ORB_PICKUP'
deny:
- 'tell: &c你需要 VIP 权限'
Bottom:
type: 'multi'
buttons:
btn_greet:
text: '问候'
actions:
- 'actions: greet' # 执行 Events.Click.greet
btn_vip:
text: 'VIP 检查'
actions:
- 'actions: vip_check' # 执行 Events.Click.vip_check
复杂动作链示例:
Events:
Click:
daily_login:
- 'tell: &6每日签到成功!'
- 'sound: ENTITY_PLAYER_LEVELUP'
- 'set-data: coins +100'
- 'tell: &e获得 100 金币'
- 'sound: ENTITY_EXPERIENCE_ORB_PICKUP'
Bottom:
type: 'multi'
buttons:
daily:
text: '每日签到'
actions:
- 'actions: daily_login'
特性:
- 异步执行:
actions动作在异步线程中执行,不会阻塞主线程 - 支持条件判断:引用的动作列表中可以使用
condition进行条件分支 - 变量支持:动作列表中支持所有 KaMenu 变量(
{data:xxx},{permission:xxx}等) - 复用代码:避免在多个按钮中重复定义相同的动作序列
错误处理:
如果引用的动作列表不存在,玩家会收到错误消息:
与其他方式对比:
| 方式 | 使用位置 | 触发方式 | 示例 |
|---|---|---|---|
actions 动作 |
按钮动作、命令 | 点击按钮/执行命令 | actions: greet |
<text> 标签的 actions 参数 |
文本组件(Body.message) | 点击文本 | <text='点击';actions=greet> |
使用场景:
- 按钮复用动作列表:多个按钮执行相同的动作序列
- 条件分支:根据玩家状态执行不同动作
- 命令快捷方式:通过命令触发预定义的动作列表
- 动作链复用:避免重复定义复杂的动作序列
注意事项:
- 动作列表必须在
Events.Click下定义 - 避免循环引用(如动作列表 A 引用自己)
actions动作本身也可以在条件判断中使用
完整示例¶
Bottom:
type: 'multi'
columns: 2
buttons:
purchase:
text: '&6[ 购买 ]'
actions:
- condition: "%player_balance% >= 500"
allow:
- 'console: eco take %player_name% 500'
- 'console: give %player_name% diamond_sword 1'
- 'tell: &a购买成功!消费 500 金币'
- 'sound: entity.player.levelup'
- 'close'
deny:
- 'tell: &c余额不足!需要 500 金币,当前: %player_balance%'
- 'sound: block.note_block.bass'
info:
text: '&7[ 查看说明 ]'
actions:
- 'tell: &6=== 神圣之剑说明 ==='
- 'tell: &f- 攻击力 +20'
- 'tell: &f- 可用于高级副本'
- 'hovertext: &7了解更多 <text=&b[点击查看官网];hover=&7打开浏览器;url=https://example.com>'