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

基本语法

反射,是KubeJS的一个重要特性,它能让你访问到一些安全的Java类,以使用超过KubeJS原生的功能。

使用以下语句获得一个类

const Shield = Java.loadClass("net.minecraft.world.item.ShieldItem");

这个类得到了原版的一个物品类,对应到游戏中就是盾牌的物品类。

某些类是不能反射并获取的,例如

// 反射得到java.io.File,文件读写一般需要这个类
const File = Java.loadClass('java.io.File')
// 日志的输出结果
[12:59:55] [ERROR] ! economic.js#1: Failed to load Java class 'java.io.File': Class is not allowed by class filter!

class filter 决定了哪些类能被反射,不被允许的类往往具有让整合包成为病毒软件的能力。不过,与游戏内容相关的多数类,都是可以正常使用的。

类可以直接调用其静态方法

const $KeyMappingRegistry = Java.loadClass(
  "dev.architectury.registry.client.keymappings.KeyMappingRegistry"
);
$KeyMappingRegistry.register(global.testKey)

也可以使用new,获得一个对象

const Prop = Java.loadClass("net.minecraft.world.item.Item$Properties");
const defProperties = new Prop();

可以发现,反射得到的类几乎与Java中的类相同,使用时,只要模仿Java的方式即可。更准确的说,是模仿Forge或NeoForge模组开发和使用Architectury API的开发的方式。

使用ProbeJS时

每个类至少要加载一次,才能被ProbeJS识别并生成自动补全所需的文件。

有自动补全的类是可以反射的

反射在KubeJS中的用法-第1张图片如果没有,反射后根据脚本所在位置,运行以下某条指令刷新脚本

/kubejs reload client_scripts
/kubejs reload server_scripts
/kubejs reload startup_scripts

再运行这条命令,让ProbeJS生成这个类所需的文件

/probejs dump


举例:注册几乎一样的物品

KubeJS原生提供的注册事件无法注册例如盾牌,弓,三叉戟等物品。使用反射可以注册功能几乎一样的物品,还能自定义部分属性。

// 原版的盾牌类
const Shield = Java.loadClass("net.minecraft.world.item.ShieldItem");

// 物品属性类
const Prop = Java.loadClass("net.minecraft.world.item.Item$Properties");


const defProperties = new Prop();

StartupEvents.registry("item", (event) => {
    // 设置物品属性,耐久为1024,稀有度为epic(例如,附魔金苹果的稀有度为epic,它的名字就是紫色的)
    defProperties.defaultDurability(1024);
    defProperties.rarity("epic");
    event.createCustom(name, () => {
        let item = new Shield(defProperties);
        return item;
    });
});

重点就是这个回调函数。我们可以大致的理解为,每次游戏需要这个物品的时候,该回调函数必须返回一个物品类的实例(对象)。