ModContainerFactoryV2

基本信息

属性 值
类 com.mitchej123.jarjar.fml.common.ModContainerFactoryV2
父类 cpw.mods.fml.common.ModContainerFactory
方法 buildV2(ASMModParserV2, File, ModCandidateV2)

ModContainerFactoryV2 在原版 ModContainerFactory 之外引入 buildV2:用 V2 的 ASMModParserV2 直接构造 ModContainer,并把 @API 注解标记写入 ModCandidateV2。原版 build 方法保留兼容路径。

实现

public class ModContainerFactoryV2 extends ModContainerFactory {

    @SuppressWarnings("unused")
    public ModContainerWrapper buildV2(ASMModParserV2 modParser, File modSource, ModCandidateV2 candidate) {
        final String className = modParser.getASMType().getClassName();
        for (ModAnnotation ann : modParser.getAnnotations()) {
            if (modTypes.containsKey(ann.getASMType())) {
                FMLLog.fine("Identified a mod of type %s (%s) - loading", ann.getASMType(), className);
                try {
                    final ModContainer mod = modTypes.get(ann.getASMType()).newInstance(className, candidate, ann.getValues());
                    final MetadataCollection metadataCollection = candidate.getMetadataCollection();
                    mod.bindMetadata(metadataCollection);
                    return new ModContainerWrapper(mod, candidate, modParser);
                } catch (Exception e) {
                    FMLLog.log(Level.ERROR, e, "Unable to construct %s container", ann.getASMType().getClassName());
                    return null;
                }
            } else if (!candidate.containsAPIAnnotations() && ModCandidateV2.API_ANNOTATION_DESC.equals(ann.getASMType().getDescriptor())) {
                candidate.setContainsAPI(true);
                FMLLog.fine("Found @API annotation in %s (%s)", candidate.getFilename(), className);
            }
        }
        return null;
    }
}

行为

条件 行为
注解类型在 modTypes 注册表内 构造 ModContainer + bindMetadata + 返回 ModContainerWrapper
注解 desc 等于 Lcpw/mods/fml/common/API; 且 candidate 尚未标记 candidate.setContainsAPI(true)
都不是 跳过此类(return null)

modTypes 来自父类 ModContainerFactory,包含 @Mod/@SidedProxy/@CPW 等已知 mod 类型。

调用点

ParallellModDiscoverer.ModScanTask.computeJarFile:

final ModContainerFactoryV2 modContainerFactory = (ModContainerFactoryV2) ModContainerFactory.instance();
// ...
final ModContainerWrapper wrapped = modContainerFactory.buildV2(asmData, modCandidate.getModContainer(), modCandidate);
if (wrapped != null) {
    wrappedModList.add(wrapped);
    modList.add(wrapped.mod());
}

ModContainerFactory.instance() 返回单例 —— 由 V2ConstructionReplacerTransformer 在 ModContainerFactory.<clinit> 改写为 new ModContainerFactoryV2()。

bindMetadata

mod.bindMetadata(metadataCollection);

metadataCollection 来自 candidate.getMetadataCollection(),即 mcmod.info 解析结果。bindMetadata 把 modid/name/version/dependencies 等写入 ModContainer。

相关条目