客户端按键
ChaEngine 可以由服务端定义客户端按键。客户端把“按下”和“松开”的状态变化回传给服务端,服务端先触发事件,再以该玩家身份执行配置的动作列表。
完整配置
文件位置:plugins/ChaEngine/key/*.yml
open_skill: # 按键 ID;同一服务器中必须唯一
name: "打开技能" # 客户端按键设置中显示的名称
default-key: "SHIFT+E" # 默认组合键
category: "服务器技能" # 客户端按键设置中的分类
on-press: # 按下时按顺序执行;不需要时可删除
- "say 我按下了技能键"
on-release: # 松开时按顺序执行;不需要时可删除
- "say 我松开了技能键"on-press 与 on-release 中的动作可以带或不带开头 /,执行前会统一处理。每条动作最长 1024 个字符,支持以当前玩家为上下文解析 PlaceholderAPI 变量。
默认按键语法
组合键使用 + 分隔,不区分大小写:
E
SHIFT+E
CTRL+ALT+K
CONTROL+F5支持的修饰键:
CONTROL或CTRLSHIFTALT
主键支持:
A到Z0到9F1到F25SPACEENTER或RETURNESC或ESCAPETAB、BACKSPACE、DELETE、INSERT、HOME、ENDPAGEUP/PAGE_UP、PAGEDOWN/PAGE_DOWNUP、DOWN、LEFT、RIGHT
必须有且只有一个最终主键。解析时最后出现的非修饰键会成为主键,因此不要写多个主键。
修饰键采用精确匹配:SHIFT+E 只在 Shift 按下、Control 与 Alt 未按下时成立。玩家在按住 E 时再按下或松开修饰键,也可能产生一次释放或按下状态变化。
分类、改键与冲突
category 决定按键在客户端“控制”设置中的分组;省略时归入 ChaEngine。name 是该项显示名称,不能为空。
玩家可以在客户端按键设置中重新绑定。若两个 ChaEngine 按键最终绑定到同一组合,二者都可能报告状态并分别触发服务端事件;ChaEngine 不替业务决定谁优先。应给不同功能设置不同默认键,并在发布说明中提醒玩家检查冲突。
按键 ID 是服务器范围内的全局标识。YAML 和其他插件动态注册同一 ID 时,后写入的定义会替换现有定义;请使用带插件前缀的 ID,例如 myplugin_open_skill。
按下与松开
客户端只在状态发生变化时发送:
- 主键和修饰键从“不匹配”变为“匹配”时,服务端触发
KeyBindPressEvent,随后执行on-press。 - 从“匹配”变为“不匹配”时,服务端触发
KeyBindReleaseEvent,随后执行on-release。 - 按住不放不会每 tick 重复触发。
事件提供当前 Player 和按键 id。动作列表中的空行、过长动作或执行异常会逐条跳过并记录日志,不会阻止其他有效按键继续工作。
重载与客户端就绪
玩家加入时服务端发送当前按键快照。现代客户端登录后也会声明按键能力;只有 ChaEngineMod 已加载且连接就绪的客户端才能看到定义并回传状态。
服务端重载 YAML 后会重建内置按键注册表并向在线客户端同步。客户端会:
- 保留定义完全相同的现有映射;
- 移除已经不存在的旧映射;
- 为新增或发生定义变化的项目创建新映射;
- 离开服务器时清理该服务器同步的按键。
修改 name、default-key 或 category 会被视为新定义,玩家原先对该项的本地改键可能需要重新确认。
动态注册 API
其他 Bukkit 插件可以通过 ChaEngineKeyBindAPI 注册运行期按键:
import com.github.ginirohikocha.engine.api.key.ChaEngineKeyBindAPI;
import com.github.ginirohikocha.engine.entity.config.KeyBindConfig;
import org.bukkit.plugin.Plugin;
public boolean registerSkillKey(Plugin plugin) {
KeyBindConfig config = new KeyBindConfig();
config.setId("myplugin_open_skill");
config.setName("打开技能");
config.setDefaultKey("SHIFT+E");
config.setCategory("服务器技能");
return ChaEngineKeyBindAPI.registerKeyBind(plugin, config);
}注册成功后立即向在线玩家广播新快照。插件只能按自己的所有者身份注销按键或清理自己注册的全部按键。动态配置同样必须有非空 ID、名称和默认键;客户端还会再次验证按键语法。
监听事件:
import com.github.ginirohikocha.engine.api.key.event.KeyBindPressEvent;
import com.github.ginirohikocha.engine.api.key.event.KeyBindReleaseEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public final class SkillKeyListener implements Listener {
@EventHandler
public void onPress(KeyBindPressEvent event) {
if (event.getId().equals("myplugin_open_skill")) {
// 处理按下
}
}
@EventHandler
public void onRelease(KeyBindReleaseEvent event) {
if (event.getId().equals("myplugin_open_skill")) {
// 处理松开
}
}
}完整方法表见Java API。
无效定义如何处理
- 服务端注册时拒绝空 ID、空
name或空default-key。 - 客户端跳过没有主键、主键不在支持表或 ID 为空的定义。
- 单个无效定义不会使整个快照失效;其余定义仍会注册。
- 数量异常、同步内容无法解析或版本不匹配时,客户端保留安全状态并记录警告。
- 服务端收到未知 ID 的状态时忽略,不执行任何动作。
常见问题
客户端控制设置里没有按键:确认客户端 Mod 已加载并已进入服务器,再查看日志是否提示默认键无效。
按 E 没反应,Shift+E 正常:配置要求精确修饰键,这是预期行为。
两个功能一起触发:检查客户端最终绑定和服务端 ID 是否冲突;同时解决物理组合与逻辑 ID 两类冲突。
重载后出现旧项目:让客户端确认收到最新快照;若仍存在,退出服务器后重新进入以清理本次连接状态。
猹件开发组