fix(launch): M157 r3 周快照门限按继承根版本 + 保存失败保留草稿(复审 P2-1/P2-2)
P2-1 周快照 + 加载器的 --graphicsBackend 静默丢失:presenter host::launch::build_request 与 cli snapshot::prepare 给 SnapshotInput.game_version 传 None,装配按带加载器后缀的 version_id(26w14a-fabric-0.16.5)判门限,GameVersion::is_weekly_snapshot 的 6 字符形态认不出来。两个调用点改为传继承链的 MC 根版本(25 行注释说明「门槛与拼装必须同一口径」)。回归:core launch::overrides 的周快照实际装配用例(正/负两档)、presenter host::launch::tests、cli snapshot::tests 各一条根版本断言。 P2-2 保存失败丢草稿:app/update/instances.rs 的 Save 分支派发前就把 launch_form.dirty 清掉,失败事件后 pump 用旧快照重建视图并覆盖表单。改为派发不清脏;LaunchForm::sync 只在「回程快照已等于表单」(= 落盘确认)时清脏并重播种,否则保留草稿。回归:failed_save_keeps_the_draft / confirmed_save_clears_dirty_and_reseeds / save_dispatch_keeps_the_dirty_flag。 顺带:launch::overrides 测试拆到 overrides/tests.rs(守 400 行)。
This commit is contained in:
1 parent
c76a1437e6
commit
211e07b470
9 files changed
+640
-311
No files matched your search
@@ -199,11 +199,16 @@ pub fn build_request(
|
||||
.assets
|
||||
.clone()
|
||||
.or_else(|| resolved.asset_index.as_ref().map(|index| index.id.clone()));
|
||||
// 装配的门限 / 分支按**继承链的 MC 根版本**判,不是带加载器后缀的 version_id:
|
||||
// `26w14a-fabric-0.16.5` 这种 id 在 `GameVersion::is_weekly_snapshot`(6 字符形态)上判不出来,
|
||||
// 周快照的 `--graphicsBackend` 会在拼装链里被静默跳过——而详情页的门槛
|
||||
// (`host::launch_args::backend_gate`)与 CLI 用的都是根版本,两边必须同一口径。
|
||||
let (mc_version, _) = super::game::describe_version(env, &version_id);
|
||||
let snapshot = SnapshotInput {
|
||||
version_id: &version_id,
|
||||
version_name: Some(&target.name),
|
||||
version_type: None,
|
||||
game_version: None,
|
||||
game_version: Some(mc_version.as_str()),
|
||||
main_class: resolved.main_class.as_deref(),
|
||||
jvm_arguments: &expanded.jvm,
|
||||
game_arguments: &expanded.game,
|
||||
@@ -372,3 +377,6 @@ fn describe_warning(warning: &AdapterWarning) -> String {
|
||||
pub fn isolation_label(mode: IsolationMode) -> &'static str {
|
||||
mode.as_str()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -0,0 +1,96 @@
|
||||
//! `host::launch` 的回归用例(M157 r3 复审 P2-1):装配用的游戏版本必须是**继承链的 MC 根版本**。
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use super::*;
|
||||
|
||||
/// 一次性临时目录(同 `host::launch_args` 测试:不引第三方 tempfile)。
|
||||
struct TempDir(PathBuf);
|
||||
|
||||
impl TempDir {
|
||||
fn new(tag: &str) -> Self {
|
||||
static COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"ull-host-launch-{tag}-{}-{seq}",
|
||||
std::process::id()
|
||||
));
|
||||
let _ = std::fs::remove_dir_all(&path);
|
||||
std::fs::create_dir_all(&path).expect("建临时目录");
|
||||
Self(path)
|
||||
}
|
||||
|
||||
fn path(&self) -> &Path {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TempDir {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_version(env: &HostEnv, id: &str, json: &str) {
|
||||
let path = env.game.version_json(id);
|
||||
std::fs::create_dir_all(path.parent().expect("版本目录")).expect("版本目录");
|
||||
std::fs::write(&path, json).expect("写版本 JSON");
|
||||
}
|
||||
|
||||
/// **周快照 + 加载器实例**的装配:`SnapshotInput.game_version` 要拿继承链根的 `26w14a`,
|
||||
/// 不是带加载器后缀的 `26w14a-fabric-0.16.5`。
|
||||
///
|
||||
/// 抓得住:`build_request` 回退成 `game_version: None`(装配链用 `version_id` 判门限)——
|
||||
/// 那时 `GameVersion::is_weekly_snapshot` 的 6 字符形态认不出这个 id,`--graphicsBackend`
|
||||
/// 会在拼装链里被静默跳过,而详情页的门槛(`host::launch_args::backend_gate`,用根版本)
|
||||
/// 显示「可用」——正是复审复现的「UI 说能开、命令行里没有」。
|
||||
/// 抓不住:拼装本身(`crates/core/src/launch/overrides/tests.rs` 的
|
||||
/// `modded_weekly_snapshot_needs_the_root_version_for_the_gate` 出完整 argv)。
|
||||
#[test]
|
||||
fn weekly_loader_instance_assembles_against_the_mc_root_version() {
|
||||
let dir = TempDir::new("weekly");
|
||||
let env = HostEnv::at_root(dir.path());
|
||||
std::fs::create_dir_all(env.layout.config()).expect("config 目录");
|
||||
|
||||
// 周快照本体:库表带 lwjgl-vulkan(能力位),主类齐全。
|
||||
write_version(
|
||||
&env,
|
||||
"26w14a",
|
||||
r#"{"id":"26w14a","type":"snapshot","mainClass":"net.minecraft.client.main.Main",
|
||||
"libraries":[{"name":"org.lwjgl:lwjgl-vulkan:3.4.3"}]}"#,
|
||||
);
|
||||
// Fabric 层:只写自己的主类 + inheritsFrom(真实落盘形状)。
|
||||
write_version(
|
||||
&env,
|
||||
"26w14a-fabric-0.16.5",
|
||||
r#"{"id":"26w14a-fabric-0.16.5","inheritsFrom":"26w14a",
|
||||
"mainClass":"net.fabricmc.loader.impl.launch.knot.KnotClient"}"#,
|
||||
);
|
||||
|
||||
let target = LaunchTarget {
|
||||
id: "inst-1".to_string(),
|
||||
name: "周快照 Fabric".to_string(),
|
||||
version_id: "26w14a-fabric-0.16.5".to_string(),
|
||||
account: None,
|
||||
};
|
||||
let (request, _warnings) = build_request(&env, &target).expect("装配应成功");
|
||||
|
||||
assert_eq!(
|
||||
request.instance.version.raw(),
|
||||
"26w14a",
|
||||
"装配用的游戏版本必须是继承链的 MC 根版本(带加载器后缀的 id 会让周快照门限失效)"
|
||||
);
|
||||
assert!(
|
||||
request.instance.version.is_weekly_snapshot(),
|
||||
"根版本要能被识别成周快照形态"
|
||||
);
|
||||
assert!(
|
||||
request.manifest.has_vulkan_backend,
|
||||
"能力位来自继承链解析后的库表(lwjgl-vulkan 在父层)"
|
||||
);
|
||||
assert!(
|
||||
!request.instance.version.is_known(),
|
||||
"周快照刻意不可排序(is_known=false),门限只能靠库表兜底"
|
||||
);
|
||||
}
|
||||
@@ -215,10 +215,7 @@ mod tests {
|
||||
// (并行跑就是「系统找不到指定的路径」——M157 r2 实测)。
|
||||
static COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"{tag}-{}-{seq}",
|
||||
std::process::id()
|
||||
));
|
||||
let path = std::env::temp_dir().join(format!("{tag}-{}-{seq}", std::process::id()));
|
||||
let _ = std::fs::remove_dir_all(&path);
|
||||
std::fs::create_dir_all(&path).expect("建临时目录");
|
||||
Self { path }
|
||||
|
||||
Reference in new issue
Block a user