AngelicaClientTweaker(真正的 coremod 实现)

基本信息

属性 值
类 com.gtnewhorizons.angelica.loading.AngelicaClientTweaker
路径 src/main/java/com/gtnewhorizons/angelica/loading/AngelicaClientTweaker.java
声明 public final class ... implements IFMLLoadingPlugin, IEarlyMixinLoader(:45)
Logger LogManager.getLogger("Angelica")(:47)
静态字段 private static Boolean OBF_ENV(:48)

AngelicaTweaker 是它的唯一持有者(客户端分支)。

源码注释澄清了一个常见误解

:42-44:

// this is not the real IFMLLoadingPlugin, if you put any annotations
// here it won't do anything, that's why we register transformer
// exclusions manually in the constructor

所以本类不能用 @IFMLLoadingPlugin.* 注解,classloader 排除项必须在构造函数里手工注册。

构造函数:手工注册 3 个 transformer 排除

:51-54(构造函数在 :51,3 条排除在 :52-54):

排除前缀 原因
jss.notfine.asm NotFine 的 ASM transformer 自身
com.gtnewhorizons.angelica.loading coremod 自身
com.gtnewhorizons.angelica.glsm.GLStateManager GL 状态管理器

接着 :56-58 读黑板 angelica.rfbPluginLoaded;:57-65 分两条路:RFB 已加载则 Lwjgl3ifyExclusions.apply()(:58),否则反射预热 com.gtnewhorizon.gtnhlib.core.GTNHLibCore(:62,注释标为「Fucking java 8 and non RFB」,ClassNotFoundException 被静默吞掉)。

配置注册(本类最重要的职责)

:67-87 在 try 块里完成全部配置装载,catch (ConfigException e) 直接 throw new RuntimeException(e):

行 动作
:69 ConfigurationManager.registerConfig(AngelicaConfig.class)
:70 TracyOptions.latch(enableTracy, tracyAllowRemote, tracyFineZones, tracyMaxSrcLocs)
:71 ConfigurationManager.registerConfig(CompatConfig.class)
:72 ConfigurationManager.registerConfig(FontConfig.class)
:73 MCPatcherForgeConfig.registerConfig() —— 手工登记 6 个嵌套分类
:77-80 enableDebugLogging 时把 root logger level 设为 DEBUG(:78)并 ctx.updateLoggers()(:80)
:83 AngelicaConfig.enableTestBlocks = SystemProperties.ENABLE_TEST_BLOCKS

这发生在 coremod 阶段,早于任何 mod 的 preInit,因此 NotFineConfig.renderPass 等字段在 Mixins 枚举求值时已有值。

:88-90 随后调用 DependencyVerifier.verifyOrHalt(...),缺 gtnhlib 时弹 MissingDependencySdl 致命对话框。

getASMTransformerClass:transformer 列表的真源

:114-129 是本 mod 的 transformer 注册真源,用缓存 + 三段追加:

public String[] getASMTransformerClass() {
    if (transformerClasses == null) {
        final List<String> transformers = new ArrayList<>();
        transformers.addAll(CompatHandlers.getTransformers());            // (1)
        final List<String> notFineTransformers =
            Arrays.asList(ITransformers.getTransformers(AsmTransformers.class));  // (2)
        if (!notFineTransformers.isEmpty()) Namer.initNames();
        transformers.addAll(notFineTransformers);
        final boolean rfbLoaded = Launch.blackboard.getOrDefault(
            "angelica.rfbPluginLoaded", Boolean.FALSE) == Boolean.TRUE;
        if (!rfbLoaded) {
            transformers.add("com.gtnewhorizons.angelica.loading.fml.transformers.IsbrhTessellatorAbuseTransformer");  // (3)
        }
        transformerClasses = transformers.toArray(new String[0]);
    }
    return transformerClasses;
}
段 来源 条件
(1) CompatHandlers.getTransformers() 5 项枚举按 CompatConfig 开关过滤;非空时额外追加 GenericCompatTransformer
(2) AsmTransformers 枚举(NotFine) 非空时先调 Namer.initNames()
(3) IsbrhTessellatorAbuseTransformer 仅在 RFB 未加载时

getModContainerClass()(:132-134)与 getSetupClass()(:137-139)都返回 null —— Angelica 不注入 ModContainer,也不注入 setup 类。

injectData:向黑板发布 8 个 transformer 收窄开关

:142-173。读 data.get("runtimeDeobfuscationEnabled") 存入 OBF_ENV(:143),随后从 GlobalProperties.get(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKCLASSES) 取出 Mixin 的 tweak 列表并直接 add(:145-146)。

注释 :164-165 说明为什么必须这么做:

// If we were to register them normally in getASMTransformerClass(),
// they would be sorted at index 0 which we do not want.

即:两个 late tweaker 不能走 getASMTransformerClass(),否则会被排到 index 0。RFB 未加载时追加(:166-170):

com.gtnewhorizons.angelica.loading.fml.tweakers.AngelicaLateTweaker
com.gtnewhorizons.angelica.loading.fml.tweakers.CeleritasLateTweaker

:148-155 用 narrowTransformerConfig(mod, enabled) 把 AngelicaModulesConfig 里 transformerCompat 的 8 个 boolean 发布到黑板,供 AngelicaLateTweaker.narrowEnabled() 读取(方法注释见 :175)。

NotFine 配置的加载点

:195 调用 NotFineConfig.loadSettings(); —— 这是该方法的唯一调用点。因此 notfine.cfg 的读取发生在 coremod 阶段,而非 NotFine 的 preInit。

相关条目