本篇教程由作者设定使用 CC BY-NC-SA 协议。

本文将会实现KubeJS注册按键,效果如图

KubeJS注册按键-第1张图片

参考了Discord脆骨症整合包

Minecraft ForgeKubeJSArchitecturyRhinoProbeJS
1.20.147.2.192001.6.4-build.1149.1.122001.2.2-build.185.7.0

注册按键

注册按键需要在startup_scripts中。

const $KeyMapping = Java.loadClass("net.minecraft.client.KeyMapping");
const $GLFWkey = Java.loadClass("org.lwjgl.glfw.GLFW");
const $KeyMappingRegistry = Java.loadClass(
  "dev.architectury.registry.client.keymappings.KeyMappingRegistry"
);

global.testKey = new $KeyMapping(
  "key.kubejs.test",
  $GLFWkey.GLFW_KEY_K,
  "key.keybinding.test"
);

ClientEvents.init(() => {
  $KeyMappingRegistry.register(global.testKey);
});

接下来逐条分析。

反射

const $KeyMapping = Java.loadClass("net.minecraft.client.KeyMapping");
const $GLFWkey = Java.loadClass("org.lwjgl.glfw.GLFW");
const $KeyMappingRegistry = Java.loadClass(
  "dev.architectury.registry.client.keymappings.KeyMappingRegistry"
);

第1个类是原版的按键绑定。

第2个类中的lwjgl可以看做是MC的游戏引擎,在这里主要是为了获取按键代码。例如,下文的$GLFWkey.GLFW_KEY_K的值只是75而已。不使用这个类自行上网搜索按键代码也可以,但是不建议。

第3个类提供了一个静态方法注册按键,下文会提到。

当你输入这些代码后,可能没有自动补全,这是因为每个类必须至少加载1次才能被ProbeJS识别到。可以重启游戏并运行命令,接下来就会得到自动补全。

/probejs dump

存储按键对象

global.testKey = new $KeyMapping(
  "key.kubejs.test",
  $GLFWkey.GLFW_KEY_K,
  "key.keybinding.test"
);

创建对象并储存到global中。

3个参数对应着按键设置中的内容,如图所示:

KubeJS注册按键-第2张图片

"key.kubejs.test"是按键名称,使用翻译键,可以自行创建语言文件并修改。

$GLFWkey.GLFW_KEY_K 是按键代码,如果直接填75,也可以表示K,不过不建议这么做。

"key.keybinding.test"是按键类别,也使用翻译键。注册多个按键时如果这个值相同就可以到同一个类别里。

若储存到global中,接下来将可以到server_scripts和client_scripts中去访问。

接下来可以重启游戏并运行命令让ProbeJS为global添加自动补全。

注册按键

ClientEvents.init((event) => {
  $KeyMappingRegistry.register(global.testKey);
});

在客户端初始化时注册按键。

如果有多个按键也同理:

ClientEvents.init((event) => {
  $KeyMappingRegistry.register(global.testKey);
  $KeyMappingRegistry.register(global.reloadKey);
});

在客户端中使用按键

现在已经注册好按键了,接下来就要在客户端中运用按键。服务端只能间接使用按键。

在client_scripts中:

ClientEvents.tick((event) => {
  const key = global.testKey; // 访问global
  const { player } = event;
  if (key.consumeClick()) {
    player.sendData("global.testKey.consumeClick");
    player.playSound("block.anvil.use");
    console.log("🚀 ~ key.name:", key.name);
  }
});

这里每个tick检验玩家是否按下了按键。如果按下了,则key.consumeClick()返回true。

使用ProbeJS也可以发现key的很多属性,例如name将会返回类似于key.kubejs.test的翻译键。

为了使服务端间接使用按键,需要给服务端发送一条数据:

player.sendData("global.testKey.consumeClick");

在服务端中使用按键

上文已经发送了数据:

player.sendData("global.testKey.consumeClick");

接下来在server_scripts中,使用这个事件接受:

NetworkEvents.dataReceived("global.testKey.consumeClick", (event) => {

  event.player.tell(Text.green("global.testKey.consumeClick"));
  
});

这个事件中需要输入之前设置好的数据。接下来就可以在服务端中执行仅服务端可用的代码了。