diff --git a/crates/core/src/game/install/libraries.rs b/crates/core/src/game/install/libraries.rs index 8c867a3..b5b9f7a 100644 --- a/crates/core/src/game/install/libraries.rs +++ b/crates/core/src/game/install/libraries.rs @@ -39,6 +39,20 @@ pub fn plan( if !library.applies(environment) { continue; } + // 现代清单把 natives 作为独立库条目(`org.lwjgl:lwjgl:3.3.2:natives-linux`), + // 不是 `natives` 表。Linux arm64 上改写坐标并兜底到 Maven 镜像。 + if let Some(rewritten) = linux_arm64_native_entry(library, environment) { + files.push(PlanFile { + role: FileRole::Native, + name: rewritten.name, + url: rewritten.url, + sha1: None, + size: None, + dest: layout.libraries_dir().join(&rewritten.relative), + resource: ResourceKind::Library, + }); + continue; + } if library.coordinate().is_err() { warnings.push(format!("库坐标不合法,已跳过:{}", library.name)); continue; @@ -136,6 +150,41 @@ fn library_dest( } } +/// 现代清单里 LWJGL3 natives 条目的改写结果。 +struct Arm64Native { + name: String, + relative: PathBuf, + url: String, +} + +/// 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 mut parts = base.split(':'); + let group = parts.next()?; + let artifact = parts.next()?; + let version = parts.next()?; + if parts.next().is_some() { + return None; + } + let relative = PathBuf::from(format!( + "{}/{artifact}/{version}/{artifact}-{version}-natives-linux-arm64.jar", + group.replace('.', "/") + )); + let url = format!( + "{LINUX_ARM64_NATIVES_BASE}{}", + relative.to_string_lossy().replace('\\', "/") + ); + Some(Arm64Native { + name: format!("{base}:natives-linux-arm64"), + relative, + url, + }) +} + /// 按库声明(或默认)的 Maven 基址拼下载地址。 fn maven_url(library: &Library, relative: &Path) -> String { let base = library @@ -311,6 +360,35 @@ mod tests { ); } + #[test] + fn modern_lwjgl_native_entry_is_rewritten_to_arm64_maven() { + // 1.20.x 的清单把 natives 作为独立条目,分类器写在 name 里。 + let library = library_with_artifact( + r#"{"name":"org.lwjgl:lwjgl:3.3.2:natives-linux", + "rules":[{"action":"allow","os":{"name":"linux"}}], + "downloads":{"artifact":{"path":"org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux.jar","url":"https://libraries.minecraft.net/x.jar","sha1":"aa"}}}"#, + ); + let env = Environment { + os: "linux".to_string(), + os_version: String::new(), + arch: "arm64".to_string(), + ..environment() + }; + let layout = GameLayout::new("/g/.minecraft"); + let (files, warnings) = plan(&layout, "1.20.4", &[library], &env); + assert!(warnings.is_empty(), "不该有告警:{warnings:?}"); + assert_eq!(files.len(), 1); + assert_eq!(files[0].role.as_str(), "native"); + assert_eq!(files[0].name, "org.lwjgl:lwjgl:3.3.2:natives-linux-arm64"); + assert_eq!( + files[0].url, + "https://maven.aliyun.com/repository/public/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux-arm64.jar" + ); + assert!(files[0] + .dest + .ends_with("libraries/org/lwjgl/lwjgl/3.3.2/lwjgl-3.3.2-natives-linux-arm64.jar")); + } + #[test] fn linux_x86_64_keeps_the_manifest_classifier() { let library = library_with_artifact(