From 5bd566f92f104961b0d0b7eeb64f3411778b5ec6 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Sat, 7 Nov 2026 08:53:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(termux):=20launch=20=E4=BE=A7=E5=90=8C?= =?UTF-8?q?=E6=A0=B7=E6=94=B9=E5=86=99=20arm64=20natives=EF=BC=9B=E7=9C=9F?= =?UTF-8?q?=E6=9C=BA=E8=B7=91=E9=80=9A=20MC=201.20.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Library::linux_arm64_native_name 收敛改写规则,install 与 launch 共用 - presenter/CLI 的 classpath 组装:1.19+ 的独立 natives 条目按 arm64 坐标 找文件并进 classpath;≤1.18 的 natives 表条目仍归 natives::collect - 真机验证:ull install 1.20.4(740MB)→ glibc Temurin 21 + arm64 natives + softpipe GL,MC 主菜单在 termux-x11 中渲染(窗口 854x480) - 已知非致命:narrator flite 缺失、LWJGL JNI 版本告警、oshi cpuVendor NPE --- crates/cli/src/commands/snapshot.rs | 26 ++++++++++++++++++++--- crates/core/src/game/install/libraries.rs | 8 +++---- crates/core/src/game/library.rs | 13 ++++++++++++ crates/presenter/src/host/launch.rs | 26 ++++++++++++++++++++--- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/crates/cli/src/commands/snapshot.rs b/crates/cli/src/commands/snapshot.rs index b37fd9a..efc01a8 100644 --- a/crates/cli/src/commands/snapshot.rs +++ b/crates/cli/src/commands/snapshot.rs @@ -75,18 +75,38 @@ pub fn prepare(ctx: &Ctx, input: &PlanInput) -> Result { let mut libraries: Vec = Vec::new(); for library in resolved.libraries.as_deref().unwrap_or_default() { - if !library.applies(&environment) || library.native_classifier(&environment).is_some() { + if !library.applies(&environment) { continue; } - let Ok(coordinate) = library.coordinate() else { + // 1.19+ 的 natives 是独立库条目(name 带分类器),必须进 classpath; + // ≤1.18 的 `natives` 表条目归 natives::collect,不进 classpath。 + // Linux arm64:独立条目改写成 natives-linux-arm64(路径与展示名一起改)。 + let arm64 = library.linux_arm64_native_name(&environment); + if arm64.is_none() && library.native_classifier(&environment).is_some() { continue; + } + let (coordinate, name) = match arm64 { + Some(rewritten) => { + let Ok(coordinate) = + unlucky_core::game::library::MavenCoordinate::parse(&rewritten) + else { + continue; + }; + (coordinate, rewritten) + } + None => { + let Ok(coordinate) = library.coordinate() else { + continue; + }; + (coordinate, library.name.clone()) + } }; let path = if library.is_local() { game.version_library(&version_id, &coordinate) } else { game.library(&coordinate) }; - libraries.push(LibraryInput::new(path, library.name.clone())); + libraries.push(LibraryInput::new(path, name)); } // natives 分类器构件(≤1.18.2 才有):收集口径归 core,CLI 只搬运。 diff --git a/crates/core/src/game/install/libraries.rs b/crates/core/src/game/install/libraries.rs index b5b9f7a..1fa0ccb 100644 --- a/crates/core/src/game/install/libraries.rs +++ b/crates/core/src/game/install/libraries.rs @@ -159,10 +159,8 @@ struct Arm64Native { /// Linux arm64:把 `org.lwjgl:::natives-linux` 改写成 arm64。 fn linux_arm64_native_entry(library: &Library, env: &Environment) -> Option { - if env.os != "linux" || env.arch != "arm64" || !library.name.starts_with("org.lwjgl:") { - return None; - } - let base = library.name.strip_suffix(":natives-linux")?; + let name = library.linux_arm64_native_name(env)?; + let base = name.strip_suffix(":natives-linux-arm64")?; let mut parts = base.split(':'); let group = parts.next()?; let artifact = parts.next()?; @@ -179,7 +177,7 @@ fn linux_arm64_native_entry(library: &Library, env: &Environment) -> Option::natives-linux` 改写成 `...:natives-linux-arm64`。 + /// + /// 返回 None 表示不适用(非 Linux/arm64、非 LWJGL3、或不是 natives 条目)。 + #[must_use] + pub fn linux_arm64_native_name(&self, env: &Environment) -> Option { + if env.os != "linux" || env.arch != "arm64" || !self.is_lwjgl3() { + return None; + } + let base = self.name.strip_suffix(":natives-linux")?; + Some(format!("{base}:natives-linux-arm64")) + } + /// natives 构件下载信息(按分类器查 `downloads.classifiers`)。 pub fn native_artifact(&self, classifier: &str) -> Option<&DownloadInfo> { self.downloads.as_ref()?.classifiers.get(classifier) diff --git a/crates/presenter/src/host/launch.rs b/crates/presenter/src/host/launch.rs index dc94f4f..8d65527 100644 --- a/crates/presenter/src/host/launch.rs +++ b/crates/presenter/src/host/launch.rs @@ -134,18 +134,38 @@ pub fn build_request( let mut libraries: Vec = Vec::new(); for library in resolved.libraries.as_deref().unwrap_or_default() { - if !library.applies(&environment) || library.native_classifier(&environment).is_some() { + if !library.applies(&environment) { continue; } - let Ok(coordinate) = library.coordinate() else { + // 1.19+ 的 natives 是独立库条目(name 带分类器),必须进 classpath; + // ≤1.18 的 `natives` 表条目归 natives::collect,不进 classpath。 + // Linux arm64:独立条目改写成 natives-linux-arm64(路径与展示名一起改)。 + let arm64 = library.linux_arm64_native_name(&environment); + if arm64.is_none() && library.native_classifier(&environment).is_some() { continue; + } + let (coordinate, name) = match arm64 { + Some(rewritten) => { + let Ok(coordinate) = + unlucky_core::game::library::MavenCoordinate::parse(&rewritten) + else { + continue; + }; + (coordinate, rewritten) + } + None => { + let Ok(coordinate) = library.coordinate() else { + continue; + }; + (coordinate, library.name.clone()) + } }; let path = if library.is_local() { env.game.version_library(&version_id, &coordinate) } else { env.game.library(&coordinate) }; - libraries.push(LibraryInput::new(path, library.name.clone())); + libraries.push(LibraryInput::new(path, name)); } let natives = unlucky_core::launch::natives::collect( &env.game,