AbstractPatcher

基本信息

pl.asie.foamfix.bugfixmod.coremod.patchers.AbstractPatcher —— 所有字节码补丁的基类。 类注释 Created by Vincent on 6/6/2014(继承自上游 BugfixMod)。

字段

字段 可见性 类型 说明
patcherName public String 补丁名(日志前缀)
targetClassName protected String 目标类
targetMethodName protected String 目标方法,可为 null
targetMethodDesc protected String 目标描述符,可为 null
successful protected boolean 本次是否改写成功

构造器里的斜杠→点转换 ⚠️

this.targetClassName = targetClassName.replace('/', '.');   // 第 48 行

调用方传入的是 JVM 内部名(斜杠),如 "net/minecraft/block/BlockGrass", 基类把它转成点号名 "net.minecraft.block.BlockGrass"。

潜在不匹配(静态分析,未运行时验证)

位置 形式
addPatcher() 建表键 patcher.getTargetClassName() → 点号
transform() 取表 patchers.get(transformedName) → 斜杠(FML 传入的内部名)

两者形式不同,按静态阅读 patchers.get(...) 应恒为 null, 即按类定向的补丁不会进入 patchClassNode。 仅 globalPatchers(目标类名为空的补丁)会执行。

本条为源码静态分析结论,未在运行时验证。该 mod 在 GTNH 中长期使用, 因此也可能存在本仓未包含的上游改动。记为待核项而非定论。 相关位置:BugfixModClassTransformer.java:219、:507、 AbstractPatcher.java:48。

patch() 流程

  1. new ClassReader(bytes) —— 捕获 NullPointerException 后静默返回原字节 (注释:Thrown when LiteLoader classes are read)。
  2. classReader.accept(classNode, 0)。
  3. successful = false → patchClassNode(classNode)。
  4. 失败则原样返回 bytes;成功则 new ClassWriter(COMPUTE_MAXS) 重写。

patchClassNode 的匹配条件

(targetMethodName == null || method.name.equals(targetMethodName))
  && (targetMethodDesc == null || method.desc.equals(targetMethodDesc))

描述符为 null 时只要方法名匹配——FileRCEPatcher 正是传 null, null, 对目标类的所有方法生效。

三种注入模式(patchMethodNode 分派)

两个标记接口(均为 interface,不是抽象类)决定注入风格:

标记接口 方法 分派到
GlobalModificationPatcher modifyInsnsGlobal(InsnList) modifyInsnsGlobal(method.instructions),整表一次
ModificationPatcher modifyInsns(AbstractInsnNode, Iterator, InsnList) 逐条指令迭代调用
都不实现 实现 buildNewInsns(...) 逐条生成 InsnList 并 insert
if (this instanceof GlobalModificationPatcher) { ... }
else if (this instanceof ModificationPatcher) { ... }
else { ... }

抽象方法

public abstract InsnList buildNewInsns(AbstractInsnNode, Iterator<AbstractInsnNode>)

日志

printMessage(msg) → ["<patcherName>"] <msg>,走 BugfixModClassTransformer.instance.logger(logger 名 foamfix)。 注意第 111 行的三元恒为 "Applied transform!"(successful 此时必为 true)。

相关条目

源码

  • src/main/java/pl/asie/foamfix/bugfixmod/coremod/patchers/AbstractPatcher.java