feat(app): GUI 接上 Forge/NeoForge installer processors(M45)

- host/install_processors:GUI 与 CLI 同序跑 processors(计划 → 依赖库 → 选 Java → 串行 java -cp),
  进度经 HostTask::Install 回流(阶段文案 + 每步处理器名 + 文件/字节/速度/ETA),取消在阶段边界生效;
- host/install_journal:安装过程追加到 .ULL/logs/install.log,失败文案带日志路径,不再静默失败;
- host/install.rs:supported() 扩到原版 + Fabric/Quilt/Forge/NeoForge,删除 Forge/NeoForge 拒装路径
  (仅剩 OptiFine/LiteLoader 两家 core 侧无管线者),spawn_install 统一持 Job 上下文;
- 失败诊断:缺 Java / processor 非零退出(保留 processor_* 大类码与脱敏 stderr 尾部)/ 依赖库下漏
  / 元数据缺失,均为结构化文案 + Toast + 装日志;
- dto::InstallStage::Installing 文案改「生成版本」(同时覆盖写版本 JSON 与跑 installer 两段);
- screenshot:新增 --screenshot-loader,Forge/NeoForge 中间态可离屏取图;
- 测试 +14(138 全绿):supported() 语义、处理器阶段注入 fake 后端覆盖跳过/缺 Java/非零退出/
  依赖库失败/命令行构造/进度文案,另修旧用例(Forge 不再被门禁拒装)。
This commit is contained in:
AskaEth committed 2026-11-01 09:14:01 +08:00
1 parent 858c227900
commit b0f747074f
9 files changed
+1182 -79

No files matched your search

+18 -1
View File
@@ -24,6 +24,8 @@ pub struct ShotOptions {
pub wizard: bool,
/// 发起一次真实安装并停 `dwell_ms` 后取图(中间态)
pub install: Option<String>,
/// 安装走哪个加载器(`--screenshot-loader forge`;缺省 = 原版)
pub loader: Option<String>,
/// 发起一次真实启动并停 `dwell_ms` 后取图(中间态)
pub launch: Option<String>,
/// 打开一个日志会话(日志页有数据态:日志行 + 诊断卡片)
@@ -58,6 +60,7 @@ pub fn shot_options() -> Option<ShotOptions> {
},
wizard: flag("--screenshot-wizard"),
install: value_of("--screenshot-install"),
loader: value_of("--screenshot-loader"),
launch: value_of("--screenshot-launch"),
session: value_of("--screenshot-session"),
dwell_ms: value_of("--screenshot-dwell")
@@ -92,7 +95,7 @@ pub fn capture(app: &AppUi, options: &ShotOptions) -> Result<(), slint::Platform
}
if let Some(version) = &options.install {
app.dispatch_and_run(
AppCommand::InstallVersion(version.clone()),
install_command(version, options.loader.as_deref()),
options.dwell_ms,
);
}
@@ -115,6 +118,20 @@ pub fn capture(app: &AppUi, options: &ShotOptions) -> Result<(), slint::Platform
Ok(())
}
/// 截图通道的安装指令:缺省原版,给了 `--screenshot-loader` 就走向导同一条路
/// (`CreateInstance`),因此 Forge/NeoForge 的中间态也能取图。
fn install_command(version: &str, loader: Option<&str>) -> AppCommand {
match loader.map(crate::dto::LoaderKind::parse) {
Some(Some(kind)) => AppCommand::CreateInstance(crate::dto::CreateRequest {
version: version.to_string(),
loader: kind,
loader_version: String::new(),
name: version.to_string(),
}),
_ => AppCommand::InstallVersion(version.to_string()),
}
}
/// `--flag` 是否存在。
pub fn flag(name: &str) -> bool {
std::env::args().skip(1).any(|arg| arg == name)