Core Mod 类转换器
基本信息
| 属性 | 值 |
|---|---|
| 加载插件 | coremod/DefaultOptionsLoadingPlugin.java(实现 IFMLLoadingPlugin) |
| 转换器类 | coremod/DefaultOptionsClassTransformer.java(实现 IClassTransformer) |
| Gradle 声明 | coreModClass = coremod.DefaultOptionsLoadingPlugin |
| 插件名 | @IFMLLoadingPlugin.Name("Default Keyconfig & Options") |
| MC 版本标记 | @IFMLLoadingPlugin.MCVersion("1.7.10") |
| 自我排除 | @IFMLLoadingPlugin.TransformerExclusions("net.blay09.mods.defaultkeys.coremod") |
注入目标
只转换一个类:net.minecraft.client.Minecraft(DefaultOptionsClassTransformer.java:16)。其余所有类原样返回 basicClass。
在 Minecraft 类的所有方法中,匹配方法名为 ag(混淆名)或 startGame(MCP 名)且描述符为 ()V 的那一个(:21),在方法体开头插入:
INVOKESTATIC net/blay09/mods/defaultkeys/DefaultKeys . preStartGame ()V
随后 break,只注入一次。
为什么必须用 core mod
preStartGame() 要在 Minecraft 客户端启动游戏前完成配置文件的铺设与备份。此时:
- FML 生命周期事件(
preInit)已经太晚——options.txt已被GameSettings读入; - 因此只能靠类转换器在
Minecraft.startGame入口插桩。
DefaultKeys.preStartGame() 本身只是转发给 EventHandler.preStartGame()(DefaultKeys.java:35-37)。
三个 IFMLLoadingPlugin 钩子都返回 null
| 钩子 | 返回值 |
|---|---|
getModContainerClass() |
null(:19) |
getSetupClass() |
null(:24) |
getAccessTransformerClass() |
null(:32) |
injectData(...) |
空实现(:28) |
⚠️ 注意:
getAccessTransformerClass()返回null并不代表本模组没有 AT。AT 走的是 FML 的META-INF/声明机制,由gradle.properties的accessTransformersFile = defaultkeys_at.cfg打包进 jar。详见 Access Transformer。
限制
- 目标类名
net.minecraft.client.Minecraft是全限定名硬编码字符串,不随 mappings 变化。 - 同时匹配
ag与startGame两个名字是为了兼容混淆与 MCP 命名;但若将来某个版本两者都存在,只会命中先遍历到的那个。 injectData为空,未使用 FML 传入的datamap(如 coreMod 列表),因此无法检测其它 mod 是否声明了冲突的 core mod。- 转换器依赖
net.minecraft.launchwrapper.IClassTransformer(LaunchWrapper),是 1.7.10 专属 API。
相关条目
- Access Transformer - 与类转换器并存的另一处低层改写
- 启动前文件铺设 - 被注入的
preStartGame实际做的事 - /defaultconfigs 指令 - 打包作者使用的手动入口