基本信息
| 属性 |
值 |
| 类型 |
FML coremod 加载插件 + 类字节码转换器 |
| 实现类 |
net.vfyjxf.nechar.core.NechCorePlugin(IFMLLoadingPlugin + IFMLCallHook)<br>net.vfyjxf.nechar.core.NechClassTransformer(IClassTransformer) |
| 来源 |
NechClassTransformer 基于 Towdium 的 JustEnoughCharacters 1.12.0 版 JechClassTransformer.java 改写(MIT 协议) |
NechCorePlugin
| 成员 |
值 |
getASMTransformerClass() |
new String[] { "net.vfyjxf.nechar.core.NechClassTransformer" } |
getModContainerClass() |
null(不提供 mod 容器) |
getSetupClass() |
"net.vfyjxf.nechar.core.NechCorePlugin"(指向自身) |
getAccessTransformerClass() |
null(不使用 AT) |
injectData(Map<String, Object> data) |
空实现 |
public static boolean INITIALIZED |
初始 false;在 call() 中置为 true |
call() |
调用 TransformerRegistry.getTransformer("some.class") 触发注册表静态块(强制初始化两个转换器),随后 INITIALIZED = true,返回 null |
关键设计:getSetupClass() 返回自身类名,使 FML 在模组容器构造之前就实例化本类并调用 call()。此时配置文件尚未由模组加载,但 TransformerString / TransformerRegExp 的构造器会各自调用 reload() 读取 NechConfig——后者通过自己的 static 块从 config/NotEnoughCharacters.cfg 读值(见 配置系统),因此配置在 coremod 阶段就已可用。
public byte[] transform(String s, String s1, byte[] bytes) {
if (NechCorePlugin.INITIALIZED) {
for (Transformer t : TransformerRegistry.getTransformer(s)) {
bytes = t.transform(bytes);
}
return bytes;
} else {
return bytes;
}
}
| 要点 |
说明 |
| 开关 |
仅当 NechCorePlugin.INITIALIZED == true 才改写;否则原样返回字节码 |
| 参数 |
s 为正在加载的类名,作为 getTransformer(s) 的查询键;s1(基本类名)与字节码内容未用于其它判断 |
| 链式应用 |
返回值 bytes 覆盖进循环变量,因此同一类若命中多个转换器,前一个转换器的输出会成为后一个的输入 |
| 顺序 |
迭代顺序即 转换器注册表 中 transformers 的顺序:TransformerString → TransformerRegExp |
生命周期总览
| 阶段 |
触发者 |
动作 |
| 1. coremod 加载 |
FML 读取 IFMLLoadingPlugin |
实例化 NechCorePlugin,调用 call() → 初始化转换器注册表 → INITIALIZED = true |
| 2. 类加载 |
LaunchWrapper 遍历 IClassTransformer |
NechClassTransformer.transform 对每个类查表,命中则用 ASM 改写字节码 |
| 3. preInit |
@Mod.EventHandler preInit |
打印 Not Enough Characters - v<VERSION>,调用 onConfigChange() 把配置提交给 PinIn |
| 4. init |
@Mod.EventHandler init |
注册 /nech 客户端指令(见 /nech 命令) |
| 5. 物品列表初始化 |
NEINecharConfig#loadConfig |
注册两个搜索提供者(见 搜索提供者) |
NechClassTransformer 类上标注 @SuppressWarnings("SameParameterValue")——因为 s1 参数未被使用。
安全性说明
TransformerRegistry.getTransformer 返回的列表可能为空,此时循环不执行、字节码原样返回——未列入目标列表的类完全不受影响。改写过程只替换特定方法调用点,不改变类结构。
相关条目