MetadataCollectionTransformer
基本信息
| 属性 | 值 |
|---|---|
| 类 | com.mitchej123.jarjar.rfb.transformer.MetadataCollectionTransformer |
| Transformer ID | jarjar-serializednametransformer |
| RFB 排序 | sortBefore = ["*"] |
| 目标类 | cpw.mods.fml.common.MetadataCollection |
| 目标字段 | modList |
为 MetadataCollection.modList 字段注入 Gson @SerializedName 注解的 modlist/ModList 别名。原版 FML 的 Gson 序列化只接受 modList,但许多 modpack 在打包工具生成 mcmod.info 时把字段写成 modlist(小写 L)或 ModList(PascalCase),导致反序列化得到空 modList 数组。
ASM 注入
private static final String TARGET_CLASS = "cpw.mods.fml.common.MetadataCollection";
private static final String TARGET_FIELD = "modList";
private static final String SERIALIZED_NAME_DESC = "Lcom/google/gson/annotations/SerializedName;";
public boolean shouldTransformClass(...) {
return TARGET_CLASSES.contains(className); // 只命中 MetadataCollection
}
public void transformClass(...) {
final ClassNode cn = classNode.getNode();
if (cn == null || cn.fields == null) return;
for (FieldNode field : cn.fields) {
if (field.name.equals(TARGET_FIELD)) {
boolean hasAnnotation = false;
if (field.visibleAnnotations != null) {
for (AnnotationNode annotation : field.visibleAnnotations) {
if (annotation.desc.equals(SERIALIZED_NAME_DESC)) { hasAnnotation = true; break; }
}
}
if (!hasAnnotation) {
AnnotationNode annotation = new AnnotationNode(SERIALIZED_NAME_DESC);
annotation.values = new ArrayList<>();
annotation.values.add("value");
annotation.values.add("modList");
annotation.values.add("alternate");
annotation.values.add(Arrays.asList("modlist", "ModList"));
if (field.visibleAnnotations == null) field.visibleAnnotations = new ArrayList<>();
field.visibleAnnotations.add(annotation);
}
break;
}
}
}
注入的注解等价于:
@SerializedName(value = "modList", alternate = {"modlist", "ModList"})
public ModMetadata[] modList;
触发场景
Modpack 打工具链(典型 CurseForge / Modrinth / 自建脚本)生成 mcmod.info 时常常把首字母小写或 PascalCase 化。原版 FML 1.7.10 的 Gson 反序列化用 @SerializedName 找不到匹配键,整字段返回空数组 → ModContainer.bindMetadata() 拿不到 modId/name/version → mod 名/版本显示异常。
与 MetadataCollectionV2 的协作
MetadataCollectionTransformer 处理"字段别名",MetadataCollectionV2.from(InputStream, ...) 处理"JSON 顶层是数组 vs 对象"两种结构(modListVersion: 2)。两者覆盖了 mcmod.info 的两个常见解析失败路径。
相关条目
- RFB 插件入口 - 注册该 transformer
- MetadataCollectionV2 - JSON 结构兼容
- FMLTransformer - 把
MetadataCollection.from重定向到 V2