Mixin 引导流程
基本信息
| 属性 | 值 |
|---|---|
| coremod 入口 | com.gtnewhorizon.gtnhlib.core.GTNHLibCore |
| 源码 | src/main/java/com/gtnewhorizon/gtnhlib/core/GTNHLibCore.java |
| 接口 | implements cpw.mods.fml.relauncher.IFMLLoadingPlugin, com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader |
| MC 版本声明 | @IFMLLoadingPlugin.MCVersion("1.7.10") |
| 清单声明入口 | gradle.properties 的 coreModClass = core.GTNHLibCore |
| 依赖版本 | UniMixins ≥ 0.1.23(不满足则启动失败) |
⚠️ 4 个 mixin JSON 的 mixin 数组全为空
src/main/resources/ 下 4 个 mixin 配置的 mixins / client / server 键一个都没有:
| 文件 | package |
target |
plugin |
mixin 数组 |
|---|---|---|---|---|
mixins.gtnhlib.early.json |
…mixins.early |
@env(DEFAULT) |
无 | 空 |
mixins.gtnhlib.late.json |
…mixins.late |
@env(DEFAULT) |
无 | 空 |
mixins.gtnhlib.json |
无(@env(DEFAULT)) |
@env(DEFAULT) |
无 | 空 |
mixins.gtnhlib.preinit.json |
…mixins.preinit |
@env(PREINIT) |
PreInitMixinPlugin |
空(由 plugin 提供 1 个) |
全部由 IMixinConfigPlugin.getMixins() 或 IEarlyMixinLoader / ILateMixinLoader.getMixins() 动态提供。按 JSON 数组统计 mixin 数会得到 0 —— 这是本 wiki 最容易踩的坑,真实清单见 Mixin 枚举。
唯一例外是 preinit:mixins.gtnhlib.preinit.json 声明了 "plugin": "com.gtnewhorizon.gtnhlib.mixins.PreInitMixinPlugin",该插件的 getMixins() 硬编码 1 个 mixin:
public List<String> getMixins() {
List<String> mixins = new ArrayList<>();
mixins.add("MixinGameData_WorldConversionWarning");
return mixins;
}
preinit 通道通过 jar manifest 注册,而非 coremod —— build.gradle.kts:31-35:
tasks.jar {
manifest {
attributes["MixinConfigs"] = "mixins.gtnhlib.preinit.json"
}
}
注意 gradle.properties 的 mixinPlugin 为空,说明 preinit 插件不走 GTNHGradle 的自动 mixin JSON 生成,而是手写 JSON。
加载阶段
| 阶段 | 加载器 | 配置 | 触发点 |
|---|---|---|---|
| PREINIT | manifest MixinConfigs |
mixins.gtnhlib.preinit.json |
FML preInit 前 |
| EARLY | GTNHLibCore.getMixinConfig()(:170) |
mixins.gtnhlib.early.json |
coremod 阶段,早于 LWJGL3ify |
| LATE | GTNHLibLateMixinLoader |
mixins.gtnhlib.late.json |
mixin 之后、LWJGL3ify 之前 |
GTNHLibCore 的两处 mixin 入口:
@Override
public String getMixinConfig() {
return "mixins.gtnhlib.early.json";
}
@Override
public List<String> getMixins(Set<String> loadedCoreMods) {
return IMixins.getEarlyMixins(Mixins.class, loadedCoreMods);
}
GTNHLibLateMixinLoader(core/GTNHLibLateMixinLoader.java)带 @LateMixin,对应 mixins.gtnhlib.late.json 与 IMixins.getLateMixins(...)。
GTNHLibCore.toString() 返回 "GTNHLib Core",源码注释说明这是 EarlyMixins 加载器识别 coremod 的必需实现(依赖 Object.toString)。
ASM transformer
coremod 同时注册 2 个 transformer(GTNHLibCore.getASMTransformerClass()):
| transformer | 作用 |
|---|---|
core.fml.transformers.EventBusSubTransformer |
事件总线子类化 |
core.fml.transformers.BlockIconTransformer |
方块图标 |
第 3 个 FMLTessellatorRedirectorWrapper 不在此处注册,而是延迟注册。GTNHLibCore.injectData() 把它加进 TweakClasses(core/GTNHLibCore.java:145-167),源码注释解释原因:
If we were to register it normally in getASMTransformerClass() it would be sorted at index 0 which we do not want. So we instead register it inside an ITweaker that gets run by mixins.
仅在客户端、且 gtnhlib.rfbPluginLoaded 不为 true 时才延迟注册 —— 即 RetroFuturaBootstrap 插件存在时改由 GTNHLibRfbPlugin 处理,避免重复注入。
启动期行为
| 行为 | 位置 | 说明 |
|---|---|---|
| 委托给 GTNHExtLib | GTNHLibCore 静态块(:38-46) |
优先 Class.forName("com.gtnewhorizons.gtnhextlib.core.GTNHExtLibCore");ClassNotFoundException 时才自己做 |
| UniMixins 版本校验 | verifyDependencies()(:63-69) |
检查 mixinextras/expression/Expression.class 资源,不存在则抛 RuntimeException |
| 注册主配置 | 构造器(:54-60) |
ConfigurationManager.registerConfig(GTNHLibConfig.class),异常包成 RuntimeException |
| 移除 Brigadier 类加载异常 | removeBrigadierClassLoaderException()(:71-88) |
从 LaunchClassLoader.classLoaderExceptions 移除 com.mojang.;若检测到 Thermos/Bukkit 则补 com.mojang.util.QueueLogAppender |
| 启动 DepLoader | loadDependencies()(:90-94) |
DeploaderStub.bootstrap(false) + runDepLoader() |
| 镜像 JVM Downgrader stub | mirrorJvmdgStubToSystemClassLoader()(:96-125) |
反射 URLClassLoader.addURL 把 jvmdg stub 加到系统类加载器;找不到时仅 log.warn |
UniMixins 校验的失败信息明确指向下载地址:
UniMixins is outdated: GTNHLib requires UniMixins 0.1.23 or newer! Download the unimixins-all jar (not -dev) from: https://github.com/LegacyModdingMC/UniMixins/releases
各 JSON 的 minVersion 也不一致:early / late / 主 json 为 0.8.3-GTNH,preinit 为 0.8.5-GTNH。
数值
| 数值名 | 值 |
|---|---|
| mixin JSON 数 | 4(其中 3 个数组全空、1 个由 plugin 提供) |
由 Mixins 枚举提供的 mixin |
54(见 Mixin 枚举) |
由 PreInitMixinPlugin 提供的 mixin |
1 |
| 磁盘上 mixin 源文件合计 | 55 |
| coremod ASM transformer | 2 直接(:129)+ 1 延迟(Tessellator,:145) |
TransformerExclusions 条目 |
5 |
useMixinDebug |
true |
minVersion 最低要求 |
0.8.5-GTNH(preinit) |
| MixinExtras 最低版本 | 0.5.0(early / late / preinit) |
交互
mixins.gtnhlib.json 既无 package 也无 plugin,在本仓中没有对应加载器(manifest 只声明 preinit,coremod 声明 early,@LateMixin 声明 late)。保留该文件是为了让 FML 的 mixin 配置发现流程不报错。
GTNHLibRfbPlugin(core/rfb/GTNHLibRfbPlugin.java)是 RetroFuturaBootstrap 侧的等价入口,由 META-INF/rfb-plugin/gtnhlib.properties 声明(className=com.gtnewhorizon.gtnhlib.core.rfb.GTNHLibRfbPlugin),其 transformerExclusions 收窄为 2 项(core.shared、asm),与 coremod 侧的 5 项不同。
相关条目
- Mixin 枚举 - 27 个注入组的完整表与计数校验
- GTNHLib 主配置 - 4 个被
setApplyIf在 early 阶段读取的配置项 - 配置系统 API - 构造器中注册配置的原因