Class ForgeMemberNameFixer

java.lang.Object
dev.architectury.loom.forge.ForgeMemberNameFixer

public final class ForgeMemberNameFixer extends Object
把最终 MC jar 里「对 Forge 成员的未翻译引用」改写成 Forge 侧的最终名字.

为什么需要这一步

legacy Forge 的 binpatch 会把 Forge 自己的调用写进 MC 类。这些调用在补丁里以 srg 名 出现(如 ModelLoader.a()),而 Forge universal jar 随后被重映射到 named (同方法改叫 setupModelRegistry)。MC jar 的重映射表只含 MC 自身成员, 查不到 Forge 成员,于是这些引用被原样保留,运行期抛 NoSuchMethodError: ModelLoader.a()Lnet/minecraft/util/registry/IRegistry;。

映射从哪来

Forge 会同时提供 forge-universal.jar(srg 空间)与重映射后的 forge jar(named 空间)。 两份 jar 由同一份源码编译,同类内成员的出现顺序一致,因此按顺序对齐即可得到 「srg 名 → named 名」的对应关系。这条映射不依赖 MC 映射表,所以能覆盖 MC 表里没有的 Forge 成员。

为什么按 owner+name 匹配而不是按描述符

最终 jar 里这些引用的描述符可能已经是 named 形 (()Lnet/minecraft/util/registry/IRegistry;),而映射键里的描述符是 srg 形 (()Lfm;),两者不等。若按「名字+描述符」精确匹配会静默失效 (实测:仅 2 个 class 被改写且目标引用未变)。故这里忽略描述符、只按 owner + name 匹配。

该匹配方式的前提:同一 owner 下的同名重载会映射到同一个目标名。 对 1.12.2 的 Forge 实测结果正确(重载在 srg 与 named 两版间保持同序,且改名后不与其他成员冲突)。 若将来 Forge 引入「同名重载被改成不同名字」的情况,这里会改错,需改为携带描述符的匹配。

  • Method Details

    • fix

      public static ForgeMemberNameFixer.Stats fix(Path targetJar, Path srgForgeJar, Path namedForgeJar) throws IOException
      改写 targetJar 中对 Forge 成员的 srg 名引用.

      就地改写:读原文件、写同目录临时文件、成功后替换。任一步失败时原文件保持不动。

      Parameters:
      targetJar - 待改写的 jar(最终 MC jar)
      srgForgeJar - Forge 的 universal jar(srg 空间)
      namedForgeJar - 已重映射到 named 的 Forge jar
      Returns:
      改写统计;两份 Forge jar 缺失或对不上时返回全零
      Throws:
      IOException - 读写失败