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() 流程
new ClassReader(bytes)—— 捕获NullPointerException后静默返回原字节 (注释:Thrown when LiteLoader classes are read)。classReader.accept(classNode, 0)。successful = false→patchClassNode(classNode)。- 失败则原样返回
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