Files
Unlucky-Launcher/crates/core/src/game/java/mod.rs
T
AskaEth df331f6a60 feat(m175): Java 设置页接真运行时(扫描 / 手动路径 / 默认 JDK / 内存 / JVM 参数)
用户实测四条抱怨逐条对应:
- 「没有自动检测本机 Java」:首屏自动扫一次盘(托管根 + JAVA_HOME + PATH + 标准安装位置 +
  注册表),之后由「立即扫描」手动触发;扫描在后台线程里跑,带 done/total 进度与取消
- 「显示 Temurin 21.0.4 不知道是不是硬编码」:演示行与绊线测试一起删掉,列表来自真读盘
- 「没一个能改」:默认内存(MB,512~65536,范围与 schema 同源)与 JVM 参数可真改、真落盘、读回
- 「不能手动指定 Java 路径 / 不能改默认版本」:手动添加走严格校验(真跑 java -version),
  设为默认写 java.selected_path 并给出「为什么选它」(当前实例的版本门槛 + 每行满足与否)

core:java::manual(严格探测 + 厂商识别 + 名单持久化)、java::staged(候选收集 + 带进度与
取消的扫描)、java::proc(带超时且可打断的子进程执行:卡住的 java -version 会被 kill)。
i18n:catalog/settings/java.rs 55 条中英 + 金表按装配顺序插入。

复审 r1(p2-5items)全修:
- P2-1 「设为默认」不再清脏:只写 java.selected_path,内存/JVM 草稿一个字节都不动
- P2-2 错误文案全部走 i18n(三档「写不进去」/「路径太长」/「名单写不进去」各自一个 key),
  不再把 Rust 枚举名当人话
- P2-3 手动名单落盘有正面断言(加一条 → 从盘上新读一份 → 在)
- P2-4 版本号显示到小版本(17.0.13 / 17.0.9 可区分),解析不出来时给原始版本串
- P2-5 每候选 8 秒超时并 kill、取消打断正在跑的探测、扫描槽挂在 State 上、线程活着期间
  不许起第二个(界面显示「正在取消…」)

复审 r2(p2-2items)全修:
- P2-1 空态不再指向不存在的「Java 页」,改成真实存在的 `ull java install 21` 命令行入口
- P2-2 `auto_scan_due` 增加 `!report.cancelled`:取消过一次之后本进程不再自动扫,
  配置文件再变(存内存 / 改主题)也不会把取消无声撤销;手动「立即扫描」不受影响
- 顺带:proc 的 kill+wait 补「子进程真死了」的回归守卫(标记文件从未出现)、
  core 的 Schema 错误改成页面自己的 key(不再把中文 Display 直出给英文界面)、
  默认态 chip 用新的 `Chip::badge`(不再挂一条永远收不到的消息)
2026-11-08 19:52:04 +08:00

95 lines
4.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Java 运行时管理(D13 v1 → D23 v2):托管 JDK 的查询 / 下载 / 解压 / 探测,以及 MC↔Java 映射。
//!
//! ```text
//! target 宿主平台 → Adoptium 的 os/arch(Win=zip、Linux/mac=tar.gz)
//! vendor 四家发行版与用户可调的优先级链(国内 Temurin→Oracle→MS / 国外 Temurin→MS→Oracle)
//! api Temurin:api.adoptium.net 查询最新 GA → (github 直链, sha256, size)
//! oracle Oracle OpenJDK:镜像目录页解析(hash 段不可推导,禁止拼 URL)+ .sha256
//! microsoft MS OpenJDK:aka.ms 模板 + 内置四段版本快照 + .sha256sum.txt
//! zulu Azul Zulu:两跳 JSON API(列表 → 详情)+ CDN 直链(第四备选)
//! source 发行版分派 + 回退链记录(命中与降级原因进事件流)
//! location 落点三模式(Portable / Standard / Custom)+ 孤儿目录清理
//! release 一次版本查询的统一产物(vendor 原生版本串 + 归档 + sha256 + 大小)
//! net 版本查询用的极小 GET 文本工具(下载不走这里)
//! install 编排:回退链 → 下载引擎(镜像/健康度/退避)→ 解压 → 探测验证
//! extract zip / tar.gz 解压 + 顶层目录剥离 + 幂等戳记 + zip-slip 防护
//! probe java -version 探测、托管目录扫描(两种布局都认)
//! discover 标准安装位置扫描(Program Files 系 / 官方启动器 runtime / 注册表 / /usr/lib/jvm)+ 去重
//! select 启动选 Java 的**纯**优先链(满足要求优先,再按来源)
//! mapping MC↔Java 静态表(HMCL `GameJavaVersion`)+ 版本 JSON 优先 + 不符检查
//! ```
//!
//! # 三条边界
//!
//! 1. **不碰网络细节**:包下载一律交 `core::download` 的引擎,本模块不写重试循环
//! (`MirrorTable::expand` 负责 Temurin 的镜像展开;Oracle 的目录解析在 `oracle`);
//! 2. **不弹窗**:不符检查只产出数据([`JavaMismatch`]),提示交给 CLI 的告警行与 GUI;
//! 3. **不改启动策略**:「用哪个 Java 启动」是启动期的派生结果,不落盘;落盘的是**装到哪**
//! ([`JavaInstallRoot`],由 `java.installRoot` + 数据目录模式决定)。
//!
//! # 托管布局(D23 后两种并存)
//!
//! ```text
//! Portable:data/java-managed/
//! ├── .cache/OpenJDK21U-jdk_x64_windows_hotspot_21.0.13_9.zip 归档缓存(可删)
//! └── jdk-21-temurin/ 一个 major+vendor 一份(永不改)
//! ├── .ull-jdk.json 戳记(幂等判据)
//! └── bin/java[.exe]
//!
//! Standard / Custom:%APPDATA%\Java\<vendor>\<version>\ (mac/Linux 见 location 模块)
//! ```
pub mod api;
pub mod discover;
pub mod error;
pub mod extract;
pub mod install;
pub mod location;
pub mod manual;
pub mod mapping;
pub mod microsoft;
pub mod net;
pub mod oracle;
pub mod probe;
pub mod proc;
pub mod release;
pub mod select;
pub mod source;
pub mod staged;
pub mod target;
pub mod termux;
pub mod vendor;
pub mod zulu;
pub use self::api::{
latest_url, parse_latest, JdkArchive, JdkRelease, ADOPTIUM_API_BASE, JDK_VENDOR,
};
pub use self::discover::{
candidates, candidates_in_roots, scan_java_binaries, standard_candidates, standard_roots,
};
pub use self::error::{JavaError, JavaErrorKind};
pub use self::extract::{
extract_archive, is_ready, java_binary, java_binary_name, read_stamp, ExtractReport, JdkStamp,
STAMP_FILE,
};
pub use self::install::{
archive_path, archive_request, chain_order, install, managed_root_dir, plan, InstallRequest,
InstalledJdk,
};
pub use self::location::{
cleanup_orphans, sanitize_version, scan_roots, CleanupReport, JavaInstallRoot, LocationMode,
};
pub use self::mapping::{
check, recommended_major, requirement_for, requirement_for_version, JavaMismatch,
JavaRequirement, RequirementSource,
};
pub use self::probe::{
discover_managed, discover_managed_roots, managed_dir_name, parse_managed_dir, probe,
resolve_on_path, system_candidates, JavaOrigin, JavaRuntime, DEFAULT_MAJOR,
};
pub use self::release::parse_sha256_text;
pub use self::select::{pick, resolve, JavaResolution};
pub use self::source::{ChainLog, VendorAttempt};
pub use self::target::AdoptiumTarget;
pub use self::vendor::{order as vendor_order, JdkVendor, VENDOR_IDS};