Transformer

基本信息

属性 值
类名 sedridor.forgeamidst.Transformer
文件 src/main/java/sedridor/forgeamidst/Transformer.java
行数 99
实现 IClassTransformer
注册于 CorePlugin
启用版本 Minecraft 1.7.10

功能

给 Climate Control 打补丁,使其在生成世界后回调 MapWorldRTG 以完成 RTG 兼容。

目标类

private final String class1 = "climateControl.DimensionManager";
项 值
目标类 climateControl.DimensionManager
目标方法 onCreateSpawn
描述符 (Lnet/minecraftforge/event/world/WorldEvent$CreateSpawnPosition;)V
注入内容 调用 sedridor/forgeamidst/MapWorldRTG.updateGenLayers(GenLayerRiverMixWrapper)

transform(String name, String newName, byte[] bytes)

if (newName.equals("climateControl.DimensionManager")
    && !classesPatched.containsKey("climateControl.DimensionManager")) {
    classesPatched.put("climateControl.DimensionManager", true);
    return transform1(bytes, !name.equals(newName));
}
return bytes;
机制 说明
classesPatched LinkedHashMap<String, Boolean>,幂等保护 —— 每个目标类只 patch 一次
匹配 newName 而非 name —— 兼容混淆态
obfuscated 实参 !name.equals(newName) —— dev 态两者相同即 false

⚠️ 注入点靠硬编码字节码偏移

if (targetNode.getOpcode() == 182 && index == 49) { … }

⚠️ 注入位置由 index == 49(指令流第 49 条)硬编码确定, 再按 opcode == 182(INVOKESTATIC)复核。 这是一个极其脆弱的依赖 —— Climate Control 任何改动 (哪怕只是增删一条指令)都会让偏移错位,导致:

  • 注入到错误位置 → 运行时 VerifyError / NoSuchMethodError;或
  • 静默不匹配 → 补丁不生效,RTG 兼容失效但不报错。

类中无版本检查、无偏移校验、无回退逻辑。

注入的指令序列

在 onCreateSpawn 的目标位置前插入 5 条指令:

序 指令 作用
1 VarInsnNode(25, 0) 压入局部变量 0(this / this$0)
2 InsnNode(3) POP —— 消耗掉刚压入的值
3 MethodInsnNode(183, "climateControl/DimensionManager", "riverLayerWrapper", "(I)LclimateControl/customGenLayer/GenLayerRiverMixWrapper;") 取河道层包装器
4 MethodInsnNode(182, "sedridor/forgeamidst/MapWorldRTG", "updateGenLayers", "(LclimateControl/customGenLayer/GenLayerRiverMixWrapper;)V") 实际调用点
5 — MethodInsnNode(25,0) 等,见源码 toInject

⚠️ 指令 1 + 2(ALOAD 0 后立刻 POP)是空操作占位 —— 真正的入参是第 3 步的 riverLayerWrapper 返回值。 读字节码时容易误以为传的是 this。

实现要点

  • ClassWriter(3) —— 参数 3 是 COMPUTE_MAXS; 未用 COMPUTE_FRAMES(4),因为 1.7.10 目标字节码无 StackMapTable 需求。
  • ClassReader.accept(classN, 0) —— 解析参数 0 表示不做帧展开。
  • 目标类需实现 sedridor/forgeamidst/MapWorldRTG 中的 updateGenLayers, 该类见 MapWorldRTG。

⚠️ 无 fallback

本 transformer 没有「目标类不存在则跳过」的显式判断 —— newName.equals(...) 不匹配时自然走 return bytes, 即 Climate Control 缺席时安全无副作用(因为 modid 依赖是 after: 软依赖)。 这是本 mod 能在无 Climate Control 环境下启动的原因。

关联