Mixin 系统

基本信息

属性 值
注册表枚举 mixins/Mixins.java —— 401 个条目
引用的 Mixin 类 566 个(去重后;字符串引用总数 567,1 个类被引用两次)
源码 @Mixin 注解数 569
Mixin 实现目录 mixins/(early/ 378 + late/ 189 + hooks/ 17 + interfaces/ 15 + preinit/ 2 + plugin/ 1)
框架 com.gtnewhorizon.gtnhmixins(GTNHMixins)
目标模组表 mixins/TargetedMod.java —— 62 个条目,见 目标模组列表
关联 Coremod 引导、ASM 变换器

功能

Hodgepodge 的绝大部分改动通过 Mixin 注入。Mixins 枚举是唯一注册表 —— 401 个条目,每个条目用 MixinBuilder 声明:改了哪些类、什么条件下装、什么相位、针对哪些模组。

三个加载相位

相位 条目数 加载器 配置文件 Mixin 包 环境
PREINIT 2 个类 Mixin 自带插件 mixins.hodgepodge.json …mixins.preinit @env(PREINIT)
EARLY 274 HodgepodgeCore(IEarlyMixinLoader) mixins.hodgepodge.early.json …mixins.early —
LATE 127 HodgepodgeLateMixins(ILateMixinLoader) mixins.hodgepodge.late.json …mixins.late @env(DEFAULT)

⚠️ 三个 mixin JSON 都没有 mixins 数组

这与常见做法不同,容易误判为「没注册任何 Mixin」:

// mixins.hodgepodge.json(完整内容)
{
  "required": true,
  "minVersion": "0.8.3-GTNH",
  "mixinextras": {"minVersion": "0.5.0"},
  "refmap": "mixins.hodgepodge.refmap.json",
  "target": "@env(PREINIT)",
  "compatibilityLevel": "JAVA_8",
  "plugin": "com.mitchej123.hodgepodge.mixins.plugin.HodgepodgePreInitMixinPlugin",
  "package": "com.mitchej123.hodgepodge.mixins.preinit"
}

真正的列表在 Mixins 枚举里,由 GTNHMixins 在运行时读出:

  • EARLY:HodgepodgeCore.getMixins(Set<String>) → IMixins.getEarlyMixins(Mixins.class, loadedCoreMods)
  • LATE:HodgepodgeLateMixins.getMixins(Set<String>) → IMixins.getLateMixins(Mixins.class, loadedMods)

所有 3 个 JSON 共享同一个 refmap:mixins.hodgepodge.refmap.json。

PREINIT 相位的两个 Mixin

由 HodgepodgePreInitMixinPlugin.getMixins() 硬编码返回(plugin/HodgepodgePreInitMixinPlugin.java:36-47):

Mixin 类 安装条件
preinit.MixinLoadController_logModTimes JVM -Dhodgepodge.logModTimes
preinit.MixinGameData_BlockArraySync SpeedupsConfig.fastBlockLookup

这个插件的 shouldApplyMixin 恒返回 true(:26-28)—— 过滤完全靠 getMixins() 返回的名单,而非逐个判断。

数值

条目统计

指标 值 统计方式
枚举条目 401 4 空格缩进 + 大写标识符 + ( 的行首匹配
EARLY 条目 274 取每条目最后一个 Phase.* 出现值
LATE 条目 127 同上
Mixin 类引用 567(唯一 566) 提取 addClientMixins / addCommonMixins / addServerMixins 的字符串参数
引用可解析 566 / 566 逐个在 early/ late/ preinit/ 下 os.path.exists 校验,缺失 0 个
早期类 378 按所在目录统计
晚期类 189 同上
setApplyIf 条数 387 计数 .setApplyIf(() -> …)
无 setApplyIf 条目 4 见下
受 addRequiredMod 门控 153 至少声明一个必需模组的条目
受 addExcludedMod 门控 35 至少声明一个排除模组的条目

566 引用 vs 569 @Mixin 注解的差值来自 hooks/(17)、interfaces/(15)等非 early/late 包下的辅助类,它们不含 @Mixin,另有 3 个 early/late 外的边界情况。引用数才是注册数。

4 个无条件条目

不写 setApplyIf 即永远安装的条目 —— 它们的「开关」在别处(运行期变量或配置读取处),而非 Mixin 注册期:

条目 引用的 Mixin 类 「开关」实际在哪
LONGER_MESSAGES minecraft.MixinGuiChat_LongerMessages、minecraft.packets.MixinC01PacketChatMessage_LongerMessages Mixin 内部读 TweaksConfig.longerChat / longerSentMessages
CONFIGURABLE_PORTAL_RATIO minecraft.MixinWorldProviderHell Mixin 内部读 TweaksConfig.netherPortalRatio
ADD_MEMORY_CLEANING_SHUTDOWN_HOOKS memory.MixinMinecraftServer_ShutdownHook、memory.MixinMinecraft_ShutdownHook 无开关(常驻)
FAST_BLOCK_PLACING minecraft.MixinMinecraft_FastBlockPlacing Mixin 常驻;行为由键位在运行期翻转 TweaksConfig.fastBlockPlacing

setApplyIf 的配置分布

配置类 门控条目数
FixesConfig 217
TweaksConfig 89
SpeedupsConfig 48
MemoryConfig.leaks 16
MemoryConfig.allocs 6
DebugConfig 4
ASMConfig 4
常量 () -> true(无条件) 2(Mixins.java:674、:678)
Boolean.getBoolean("…")(JVM -D 开关) 2(如 -Dhodgepodge.logEventTimes、-Dhodgepodge.logModTimes)
SoundConfig 1

SoundConfig 只门控 1 个 Mixin,其余音频功能靠替换 Paulscode 的库与解码器实现(见 音频管线)。

支持类

目录 数量 作用
mixins/hooks/ 17 供 Mixin 调用的静态钩子实现。如 ChunkGenScheduler / BlockLookupHooks / SupernovaHelper / IC2ResourcePack
mixins/interfaces/ 15 注入到 Minecraft 类的接口(@Mixin 目标为接口实现)。如 KeyBindingExt / GameRuleExt / BlockExt_FastLookup / MutableChunkCoordIntPair
mixins/plugin/ 1 PREINIT 相位的 IMixinConfigPlugin
mixins/preinit/ 2 PREINIT 相位的两个 Mixin

相关条目