DelegatedTransformer

基本信息

属性 值
类全名 codechicken.core.asm.DelegatedTransformer
实现接口 net.minecraft.launchwrapper.IClassTransformer
约定名 JAR Manifest 属性 CCTransformer(DelegatedTransformer.java:105)
源码行数 198

功能

这是 CodeChicken 生态的扩展槽机制:任何模组只要在自己的 JAR manifest 里写一行 CCTransformer: 某个类名,该类就会被本模组实例化并接入整条类转换链。CodeChicken 家族之外的模组(如 CodeChickenLib 生态里的任意附属)无需自己实现 IFMLLoadingPlugin,就能对 Minecraft 与其他模组的字节码做变换。

load() 由 coremod 的 injectData() 调用(CodeChickenCorePlugin.java:95)。若扫描到 0 个委托转换器,打 debug 日志后直接返回,不注册(DelegatedTransformer.java:59-63);否则一次性 registerTransformer 自身(:66-69),把所有委托者收拢到单一入口,避免逐个注册。

扫描范围

scanModsForDelegatedTransformers()(DelegatedTransformer.java:72-93)遍历两个目录:

目录 行
<minecraftDir>/mods :73-81
<minecraftDir>/mods/<currentMcVersion> :82-92

scanMod(File)(:95-113)只处理 .jar 与 .zip 结尾的文件(:96),读出 manifest 的 main attributes,取 CCTransformer 键(:105)。manifest 缺失时静默 return(:101、:103)。

加载与依赖解析

addTransformer(String, JarFile, File)(:115-148)的流程:

  1. 先尝试 Launch.classLoader.getClassBytes(transformer)(:119)
  2. 取不到则从该 mod 自己的 jar 里读 transformer.replace('.','/') + ".class"(:122-130)
  3. defineDependancies(...) 递归解析并定义依赖类(:132)
  4. 校验类型:IClassTransformer.class.isAssignableFrom(clazz),否则抛异常(:135-136)
  5. 优先用 getDeclaredConstructor(File.class) 构造,让转换器知道自己属于哪个 jar;捕获 NoSuchMethodException 后回退到无参构造(:139-143)

defineDependancies(:150-182)用 ASM ClassReader + DependancyLister 读出类依赖列表,递归深度由 Stack<String> depStack 的 contains 去重(:160-163)。依赖类若不在类加载器中,则必须存在于同一个 jar 内,否则抛 "Dependency ... not found in jar file ..."(:168-170)。

类通过 ClassLoader.defineClass 反射注入(:184-188),并手动写入 LaunchClassLoader.cachedClasses——否则 FML 的类缓存不会认识这个类。

失败处理

  • 扫描单个 jar 失败:CodeChickenCorePlugin.logger.error("CodeChickenCore: Failed to read jar file: " + file.getName(), e)(:110-112),有日志,不影响其他 jar
  • 加载单个转换器失败:e.printStackTrace()(:145-147)——只有标准错误输出,不写 CodeChickenCore 的 log4j logger,且吞掉异常继续处理下一个
  • addTransformer 是 public static(:115),供外部直接调用

与 Gradle 依赖的关系

本机制是运行时的,与构建期的 dependencies.gradle 无关。CodeChickenCore/dependencies.gradle 中除 JUnit 5 测试依赖外没有任何 Minecraft 侧依赖声明。

相关条目