注册时序
生命周期
GTTweaker 只挂 2 个 FML 事件处理器(GTTweaker.java:77-144):
| 阶段 | 事件 | 方法 | 动作 |
|---|---|---|---|
FMLInitializationEvent |
@EventHandler init |
init |
MineTweakerAPI.registerClass(...) × 58 |
FMLPostInitializationEvent |
@EventHandler onPostInit |
onPostInit |
MineTweakerAPI.registerClassRegistry(GTTweakerRegistry.class) |
没有 preInit、没有 serverStarting、没有 FMLServerStartingEvent(无命令)、没有 FMLConstructionEvent。
init 阶段注册的 58 个类
MineTweakerAPI.registerClass(AlloySmelter.class); // 49 个 GT 5 机器
... // (含 Fuels)
if (GTPlusPlus.isModLoaded()) { // 6 个 GT++ 机器
MineTweakerAPI.registerClass(BlastSmelter.class);
...
}
MineTweakerAPI.registerClass(RA2Builder.class); // +1
MineTweakerAPI.registerClass(RecipeRemover.class); // +1
精确计数(grep registerClass 逐行统计):
| 类别 | 数量 | 说明 |
|---|---|---|
GT 5 机器类(gregtech/machines/) |
49 | 每个 1 个 ZenClass |
Fuels |
1 | mods.gregtech.Fuels |
RA2Builder |
1 | mods.gregtech.RA2 |
RecipeRemover |
1 | mods.gregtech.RecipeRemover |
GT++ 机器(gtpp/machines/) |
6 | 条件注册 |
| 合计 | 58 |
未注册的 2 个类:GTRecipeMap(工具类,无注解)与 AddMultipleRecipeAction(抽象基类,被静态引用)。
postInit 阶段的 ZenExpansion
@ModOnly("gregtech")
public class GTTweakerRegistry {
public static void getClasses(List<Class> classes) {
classes.add(OreDictEntryExpansion.class);
}
}
registerClassRegistry 走的是与 registerClass 不同的注册通道(MineTweaker 的 registry 机制,专供 ZenExpansion / ZenGetter 等扩展)。这是全 mod 唯一走该通道的类,也是 greggedItem 唯一的注册路径。
postInit 未清理 Recipe Map 查找 的缓存 —— 若脚本在 preInit 阶段调用 RA2.addTo("...") 并缓存了 null,GT5 在之后才补全的 map 将永久查不到。
门控机制
| 门控 | 位置 | 判定内容 |
|---|---|---|
@ModOnly("gregtech") |
53 个类 | CraftTweaker 侧:modid gregtech 存在才暴露 ZenClass / ZenExpansion |
@ModOnly("miscutils") |
6 个类 | 同上,modid miscutils(GT++ 的真实 modid) |
GTPlusPlus.isModLoaded() |
GTTweaker.init |
Java 侧:来自 gregtech.api.enums.Mods 枚举,检查同一 modid |
双重门控的必要性:Java 侧 isModLoaded() 防止在无 GT++ 时执行 registerClass(虽然注册本身不会崩),@ModOnly 防止脚本侧在无 GT++ 时看到这些类。二者独立。
数值
| 数值 | 值 |
|---|---|
| 生命周期处理器数 | 2(init + onPostInit) |
registerClass 调用数 |
58 |
registerClassRegistry 调用数 |
1 |
@ModOnly("gregtech") 类数 |
53 |
@ModOnly("miscutils") 类数 |
6 |
| 注册的 ZenClass 数 | 58(49 机器 + 6 GT++ + Fuels + RA2 + RecipeRemover) |
| 注册的 ZenExpansion 数 | 1 |
| 条件注册分支数 | 1(GTPlusPlus.isModLoaded()) |
| 未注册的类数 | 2(GTRecipeMap、AddMultipleRecipeAction) |
| 资源文件数 | 1(mcmod.info) |
源码缺陷
@Mod注解缺version属性:@Mod(modid = "GTTweaker", useMetadata = true)(:74)。版本号只能来自mcmod.info的${modVersion}(由 GTNH convention 插件替换)。FML 1.7.10 在@Mod无version时会记录警告,且依赖mcmod.info解析版本的 mod 在某些 FML 版本下会报Wrong version format。本 mod 能运行是因为 mcmod.info 存在。useMetadata = true但只有一个根mcmod.info:src/main/resources下仅 1 个文件,find src/main/resources -type f结果只有mcmod.info。useMetadata的作用是允许子目录再放一份mcmod.info来合并依赖描述 —— 本 mod 完全没用这个能力,纯冗余。mcmod.info全是构建期占位符:8 个字段中 5 个是${modId}/${modName}/${modVersion}/${minecraftVersion}—— 无法从 mcmod.info 实读 modid。权威来源只能是@Mod注解(:74)与gradle.properties(modId = GTTweaker)。mcmod.info的dependencies为空数组[]:源码层面没有声明对 CraftTweaker / GT5 的依赖。虽然dependencies.gradle是api(编译期),但运行时若缺 CraftTweaker,56 个类的@ZenClass全部无法工作且无声明。@ModOnly类数 59 =registerClass58 +registerClassRegistry1:53 个@ModOnly("gregtech")(49 机器 +Fuels+RA2Builder+RecipeRemover+OreDictEntryExpansion)+ 6 个@ModOnly("miscutils")。唯一带@ModOnly但不经registerClass的是OreDictEntryExpansion(走registerClassRegistry)。计数自洽,不是缺陷,记录在此以免后续核对时误判。onPostInit参数名ev而init参数名event(:78vs:142):同文件内命名不统一。- 无
@SuppressWarnings("unused")于GTTweaker本身:两个事件处理器由 FML 反射调用,IDE 会报未使用。其余 2 个类(RecipeRemover、RA2Builder)都加了该注解,GTTweaker反而没加。 - 注册顺序即源码 import 顺序:
init中的registerClass顺序基本是 import 顺序,不是逻辑分组顺序。GT++ 6 个类被if块隔在中间,使 GT 5 类的列表在视觉上被割裂。
相关条目
- RA2 Builder - 58 个注册类之一
- Recipe Remover - 58 个注册类之一
- Fuels - 58 个注册类之一
- GT++ 机器 - 6 个条件注册的类
- OreDict greggedItem - 唯一走
registerClassRegistry的类 - Recipe Map 查找 -
postInit未清理其缓存