feat(presenter): 实例清单改并集(档案 ∪ versions/*)+ 空态接导入向导(M273)
用户实测:HMCL 能看见 `.minecraft/versions/樱落怡然客户端`,ULL 的实例页是空的 (日志 `instances=0`)。根因不是路径找错,而是 `host::game::instances()` 只列 `profiles.json` 里的档案,第三方启动器装好的版本在界面上根本不存在。 ## 列表改并集(presenter/src/host/game.rs) - `versions/*` 里**能解析出清单**(`<id>/<id>.json` 的 id 与目录名一致、继承链走到底、 符号链接不越界)且没有被任何档案绑定的版本,就地合成一条实例视图: 显示名 = 目录名、`version_id` = 目录名。扫描复用 `core::game::adopt::scan`, 没有另写一套目录遍历。 - 只读:合成视图不建目录、不写 profiles.json、不碰 versions/ 一个字节。 - 档案优先:某版本已被档案绑定时只按档案出一条(名字/隔离档/启动参数都保留),不重复列。 - 坏目录(无清单 / JSON 坏 / id 不符 / 缺父 / 越界)不当实例;`versions/` 读不出来也只是 退回「只有档案」的旧行为,不让实例页报错。 - 外部实例的视图 id 用 `ext-<fnv64>`:`is_valid_instance_id` 只收 `[A-Za-z0-9_-]`, 而版本目录名可以是中文(现场就是),直接沿用版本 id 会让**启动**在读实例设置时就失败。 ## 懒创建档案(只有第一次改它才写盘) `set_isolation()` 与 `apply_launch_args()` 的「找不到实例」改成 `game::ensure_profile()`: 外部实例第一次改隔离档 / 启动参数时才写 profiles.json(幂等,id 与视图 id 相同)。 ## 空态可见入口 + 文案(app-iced / i18n) - 空态分两种:列表里有东西但没选中(原「未选择实例」)与**一个实例都没有** (新:「还没有实例」+ 实心主行动「导入已有版本」)。用户现场看不到任何入口正是前一种文案 在误导。 - `adopt_action()` 成为「导入已有版本」意图的唯一产地,页头按钮与空态主行动共用它。 ## 门禁 `cargo test -p unlucky-app-iced --lib` 971 passed / `cargo test -p unlucky-presenter --all-targets` 384 passed / `cargo test -p unlucky-i18n` 36 passed / `cargo fmt --all --check` 0 / `cargo clippy -p unlucky-presenter -p unlucky-app-iced --all-targets -- -D warnings` 0。
This commit is contained in:
1 parent
751ae80f28
commit
5479f25068
11 files changed
+574
-46
No files matched your search
@@ -141,6 +141,14 @@ fn own_installed_instances_snapshot_carries_their_loader() {
|
||||
unlucky_core::game::install::instance::write_profiles(&env.layout, &profiles).expect("写清单");
|
||||
|
||||
let snapshot = instances(&env);
|
||||
// M273 之后 `versions/*` 也是实例来源:这个夹具为了造 `inheritsFrom` 还写了三个父版本目录
|
||||
// (`1.20.4` / `1.20.1` / `1.21.1`)而**没有**给它们建档案,于是它们会作为「外部实例」出现。
|
||||
// 这条用例守的是「这条链把加载器/版本号翻对」——所以只看它自己那四个版本,条数也在这一层断言;
|
||||
// 「盘上有版本就出现在列表里」由 `tests_union.rs` 独占。
|
||||
let snapshot: Vec<_> = snapshot
|
||||
.into_iter()
|
||||
.filter(|tile| cases.iter().any(|case| case.0 == tile.version_id))
|
||||
.collect();
|
||||
assert_eq!(snapshot.len(), cases.len());
|
||||
for ((version_id, mc_version, kind, badge), tile) in cases.iter().zip(&snapshot) {
|
||||
assert_eq!(tile.version_id.as_str(), *version_id);
|
||||
|
||||
Reference in new issue
Block a user