Coremod 豁免清单
基本信息
| 属性 | 值 |
|---|---|
| 类 | com.mitchej123.jarjar.config.CoremodExemptions |
| 资源路径 | /META-INF/jarjar_coremod_exemptions.cfg |
| 格式 | 每行一个 coremod 全限定类名;空行/# 开头注释忽略 |
| 触发场景 | 同 id 多 jar 出现时,豁免的 coremod 不再被去重 |
某些 mod 故意把同一个 coremod 类以不同 jar 形式注入到 modpack 中(例如 Thaumcraft 的 DepLoader 与 BaublesExpanded 改写的 DepLoader),它们不应被 JarJar 当作"重复"而自动禁用。JarJar 内置一份豁免清单。
文件格式
# JarJar Coremod Duplicate Detection Exemptions
# 注释行
# 空行也会被忽略
# 格式:一个 coremod 类名一行
thaumcraft.codechicken.core.launch.DepLoader
每行通过 line.trim() 后非空、非 # 开头即作为 exemptedCoremods.add(line) 加入 HashSet<String>。
默认条目(随 JarJar 0.3.7 发布)
| Coremod 类 | 来源 |
|---|---|
thaumcraft.codechicken.core.launch.DepLoader |
Thaumcraft 自带 + BaublesExpanded 自带 |
加载流程
private static void loadExemptions() {
exemptedCoremods = new HashSet<>();
try (InputStream is = CoremodExemptions.class.getResourceAsStream(CONFIG_PATH)) {
if (is == null) {
LOGGER.warn("Could not find coremod exemptions config file: {}", CONFIG_PATH);
return;
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.isEmpty() || line.startsWith("#")) continue;
exemptedCoremods.add(line);
LOGGER.debug("Added coremod exemption: {}", line);
}
LOGGER.info("Loaded {} coremod exemptions from {}", exemptedCoremods.size(), CONFIG_PATH);
}
} catch (IOException e) {
LOGGER.error("Failed to load coremod exemptions from {}", CONFIG_PATH, e);
}
}
懒加载:第一次 isExempt(...) 触发 loadExemptions()。
调用点
ModCandidateV2Sorter.handleDuplicates() 在批量比较候选 mod 前:
if (equalIdCandidates.get(0) instanceof ModCandidateV2 firstCandidate && firstCandidate.hasCoreMod()) {
String coremodClassName = firstCandidate.getCoreMod();
if (CoremodExemptions.isExempt(coremodClassName)) {
isExemptCoremod = true;
LOGGER.info("Skipping duplicate detection for exempt coremod: {} (found in {} mods)",
coremodClassName, equalIdCandidates.size());
}
}
if (isExemptCoremod) continue;
只检查 equalIdCandidates.get(0) —— 整批 id 相同的 coremod 共享一个 class name,全部豁免或全部判定。
相关条目
- 重复 mod 去重 - 实际消费豁免的去重逻辑
- ModCandidateV2 数据模型 -
hasCoreMod/getCoreMod接口 - ModCandidateV2Sorter - handleDuplicates 实现