BugfixMod Class Transformer

基本信息

pl.asie.foamfix.bugfixmod.coremod.BugfixModClassTransformer implements IClassTransformer —— 整个 mod 的注册真源:单例,所有字节码补丁在此登记。

public static BugfixModClassTransformer instance;   // 构造时若已存在则抛异常
项 值
配置文件 <mcLocation>/config/foamfix.cfg(由 FoamFixCore.injectData 写入 settingsFile)
初始化 initialize(Boolean isObf) —— isObf 传给 MappingRegistry.init(isObf)
Logger LogManager.getLogger("foamfix")

补丁分发机制

transform(name, transformedName, bytes)(第 212 行)按顺序跑两批:

  1. globalPatchers —— 对所有类执行;
  2. patchers.get(transformedName) —— 只对目标类名命中的执行。

addPatcher(AbstractPatcher)(第 500 行)是分桶逻辑:

if (patcher.getTargetClassName() == null || isEmpty) → globalPatchers
else → patchers.computeIfAbsent(targetClassName, ...)

因此目标类名为空的补丁会被应用到每一个类上,代价极高。

JndiLookup 指纹常量

用于 Log4Shell 补丁的版本判定(字节长度 + SHA-256 实测值):

常量 长度
JNDILOOKUP_MOJANG_SIZE 738
JNDILOOKUP_MULTIMC_SIZE 983

专用服务器自动降级

if (!Arrays.asList(new File(new File(settingsFile.getParent()).getParent()).list()).contains("saves")) {
    settings.BoatDesyncFixEnabled = false;
    settings.HeartBlinkFixEnabled = false;
    settings.HeartFlashFixEnabled = false;
}

以 <mcLocation>/saves 是否存在判断是否专用服务器,命中则强制关闭 3 个客户端补丁。 注意这是覆盖用户配置的写回,随后 config.save() 会把关闭值落盘。

⚠️ 已注册补丁的实际数量

grep -c 'addPatcher(' 得 27,减去:

  • private void addPatcher(...) 定义本身 1 处
  • HeartFlashFixCompatPatcher 整个 if 块被注释掉(第 287-297 行)1 处

得到 25 个实际注册的补丁实例。 注意 GhostBusterWrapStaticLiquid 被 addPatcher 调用两次 (Block.updateTick 与 BlockStaticLiquid.isFlammable), 所以「补丁名」去重后少于实例数。

相关条目

源码

  • src/main/java/pl/asie/foamfix/bugfixmod/coremod/BugfixModClassTransformer.java