Coremod 与 Mixin

GuideNH 是本 wiki 中少见的同时是 coremod + mixin mod 的 1.7.10 模组。

项目 值 来源
coremod 类 com.hfstudio.guidenh.coremod.GuideNHCoreMod gradle.properties:128 的 coreModClass
usesMixins true gradle.properties:107
mixinsPackage mixins gradle.properties:123
usesMixinDebug true gradle.properties:115
必需的 mixin 框架 UniMixins(由 LateMixinLoader 拉起) —

coremod 真正挂载在 jar 的 META-INF/MANIFEST.MF: FMLCorePlugin: com.hfstudio.guidenh.coremod.GuideNHCoreMod、 FMLCorePluginContainsFMLMod: true、FMLAT: guidenh_at.cfg (src/main/resources/META-INF/MANIFEST.MF:2-4),不是写进 @Mod 注解。 @Mod(GuideNH.java:20-27)里没有 coreModClass / usesMixins 字段—— 那两行只存在于 gradle.properties,由 GTNH 的 mixin 构建插件消费。

Coremod:GuideNHCoreMod

com/hfstudio/guidenh/coremod/GuideNHCoreMod.java,实现 2 个 接口 IFMLLoadingPlugin, IEarlyMixinLoader(GuideNHCoreMod.java:16), 其中 IFMLLoadingPlugin 覆写三个方法:

方法 返回
getASMTransformerClass() ASM transformer 类名数组
getModContainerClass() FMLModContainer 替换类
getSetupClass() 早期 setup 类

IEarlyMixinLoader 是第二个接口,负责在 EARLY 阶段拉起 mixins.guidenh.early.json 那批早期 mixin。

coremod 在 Forge 加载 mod 容器之前运行,作用是给 mod 容器打补丁, 使 mixin 能在 @Mod 类加载前注入。

Mixin 加载

mixins/ 包下共 26 个 Java 文件,其中 23 个是真正被注册的 mixin 类, 清单在 mixins/Mixins.java(一个实现 GTNH IMixins 的枚举)。

⚠️ 三个 mixins.guidenh.*.json 的 "mixins" 数组在源码里是空的 (mixins.guidenh.late.json:8-10 显式写着 "mixins": [])—— 它们只是 UniMixins 的运行时外壳,真正的清单由 Mixins.java 在启动时 按已加载 mod 动态生成。数 mixin 必须数 Mixins.java 的枚举常量,不能数 JSON。

组 注册数 条件
EARLY 11 无条件(Mixins.java:15-19)
AE2_EXTERNAL_CABLE_PARTS 3 需 Mods.AE2
BQ_COMPAT 3 需 Mods.BetterQuesting
GREGTECH_HATCH_BUILDER 3 需 Mods.GregTech
STRUCTURELIB_MINIMUM_HATCHES 1 需 Mods.StructureLib
BC_TILE_GENERIC_PIPE 1 需 Mods.BuildCraftTransport
NEI_CUSTOM_DIAGRAM 1 需 Mods.NeiCustomDiagram
合计 23

除 Mixins.java(清单)与 LateMixinLoader.java(UniMixins 的 @LateMixin 加载器,实现 ILateMixinLoader)外,26 = 23 + 2 + 1 个未注册类。

早期 mixin(11)

mixins/early/ 下,全部 Accessor*(accessor mixin,只加 getter,不改行为):

分组 类
early/forge AccessorShapelessOreRecipe AccessorShapedOreRecipe AccessorGuiIngameForge AccessorForgeHooksClient
early/fml AccessorFMLClientHandler
early/minecraft AccessorAbstractResourcePack AccessorFallbackResourceManager AccessorSimpleReloadableResourceManager AccessorTextureManager

捕获型 mixin(2)

类 用途
early/minecraft/MixinModelRendererSceneExportCapture 捕获模型渲染结果,供场景导出
early/minecraft/MixinTessellatorSceneExportCapture 捕获 Tessellator 绘制,供场景导出

这两个服务于 结构导出—— 把渲染管线截下来,用于把场景渲染成贴图。

兼容 mixin(12 个已注册)

mixins/late/compat/ 下,全部是针对第三方 mod 的补丁, 只在对应 mod 存在时生效:

目标 mod 类 数
BuildCraft late/compat/buildcraft/AccessorTileGenericPipe 1
NEI Custom Diagram late/compat/neicustomdiagram/AccessorCustomInteractable 1
StructureLib late/compat/structurelib/MixinSurvivalBuildStructureWalker 1
AE2 late/compat/ae2/MixinPartToggleBus MixinPartP2PTunnelME MixinPartQuartzFiber 3
BetterQuesting late/compat/betterquesting/MixinPanelTextBox AccessorPanelTextBox MixinPanelButtonQuest 3
GregTech late/compat/gregtech/MixinHatchElementBuilderPreview AccessorHatchElementBuilder MixinHatchElementPlacementPreview 3

⚠️ 未注册的死代码:MixinGuiTextEditor

late/compat/MixinGuiTextEditor.java 存在,但没有出现在 Mixins.java 的任何 枚举常量里——grep -rn 'MixinGuiTextEditor' src/ 除自身文件外零引用。 因此它不会被加载、不生效,不计入上面的 23 个。

@Mixin(value = GuiTextEditor.class, remap = false)
public abstract class MixinGuiTextEditor {
    @Inject(method = "initPanel", at = @At("TAIL"))

源码注释说它用 remap = false 且目标是 GuiTextEditor—— 该类不来自 Minecraft,而来自 BetterQuesting。 也就是说若它被注册,也只在 BetterQuesting 存在时才有意义。 另外 GuideNhClientIntegrationBootstrap.java:87,92 里两段 PanelTextBox.registerTextProcessor(...) / registerTextInteraction(...) 同样处于注释状态,属同一处未启用的 BQ 文本交互接线。

GregTech 的 3 个 hatch mixin 支撑 MDX 标签 里的 GtPlaceHatches / GregTechPlaceHatches / GtActiveController / GregTechActiveController 这 4 个 GT 机器预览标签。

为什么需要 mixin

GuideNH 要拿到这些原版/第三方私有成员:

目标 拿什么
ShapelessOreRecipe / ShapedOreRecipe 读取 oreDict 配方,渲染 <Recipe>
TextureManager / 资源包类 接管纹理与资源重载,支持多语言指南
GuiIngameForge / ForgeHooksClient 客户端渲染挂钩
FMLClientHandler 资源重载时机
AE2 / BuildCraft / GregTech 的内部类 机器与管道预览

相关条目