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 传入的 data map(如 coreMod 列表),因此无法检测其它 mod 是否声明了冲突的 core mod。
  • 转换器依赖 net.minecraft.launchwrapper.IClassTransformer(LaunchWrapper),是 1.7.10 专属 API。

相关条目