fix(core): 同一 loader 版本 id 撞两条父链时具名报错,不覆盖盘上清单(旧实例会静默换父链)

This commit is contained in:
AskaEth committed 2026-11-10 19:34:11 +08:00
1 parent 9c6b5eaa9b
commit 0eaefebf3b
2 files changed
+84

No files matched your search

+55
View File
@@ -155,3 +155,58 @@ fn cancel_leaves_no_manifest() {
unlucky_core::game::GameError::MissingParent { .. }
));
}
/// 同一个 loader 版本 id 被两条父链请求:**具名报错**,且盘上那份清单一个字节都不动。
///
/// 为什么必须有这道门:`<原版>-liteloader-<ver>` 对「叠原版」与「叠 Forge」是同一个目录名,
/// 直接覆盖会让已经登记、指向这个版本 id 的旧实例**静默换父链**(启动行为跟着变)。
#[test]
fn parent_collision_is_refused_instead_of_overwriting() {
let temp = TempDir::new("parent-collision");
let layout = GameLayout::new(temp.path());
put_version(&layout, "1.12.2", VANILLA_1122);
put_version(
&layout,
"1.12.2-forge-14.23.5.2860",
crate::support::FORGE_1122,
);
let vanilla_release = liteloader_release("1.12.2");
let existing = serde_json::json!({
"id": vanilla_release.version_id,
"inheritsFrom": "1.12.2",
"mainClass": "net.minecraft.launchwrapper.Launch",
"arguments": {"game": ["--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker"]},
"libraries": []
});
put_version(
&layout,
&vanilla_release.version_id,
&serde_json::to_string_pretty(&existing).expect("序列化"),
);
let before = std::fs::read_to_string(layout.version_json(&vanilla_release.version_id))
.expect("读旧清单");
let forge_release = liteloader_release("1.12.2-forge-14.23.5.2860");
assert_eq!(
forge_release.version_id, vanilla_release.version_id,
"两条父链撞同一个 id"
);
let error = LoaderInstallPlan::build(LoaderPlanInput {
layout: &layout,
release: &forge_release,
environment: &Environment::host(),
parent_installed: true,
})
.expect_err("撞父链必须报错");
assert_eq!(error.kind(), LoaderErrorKind::Unsupported);
assert!(
error.message().contains("1.12.2-forge-14.23.5.2860") && error.message().contains("1.12.2"),
"要说清两条父链各是什么:{}",
error.message()
);
let after = std::fs::read_to_string(layout.version_json(&vanilla_release.version_id))
.expect("读旧清单");
assert_eq!(before, after, "报错之后盘上那份清单不许被改动");
}