diff --git a/crates/core/src/addon/loader/liteloader.rs b/crates/core/src/addon/loader/liteloader.rs index c5e7627..24523fc 100644 --- a/crates/core/src/addon/loader/liteloader.rs +++ b/crates/core/src/addon/loader/liteloader.rs @@ -29,6 +29,8 @@ //! 只在 Mojang 库仓有(Central / Forge maven 都 404)。所以 `net.minecraft` 走 Mojang 默认基址、 //! 其余走 Maven Central(实测 206)。这条分流有单测钉住,别把两侧弄反。 +use std::collections::BTreeMap; + use super::plan::{LoaderRelease, LoaderSupport}; use super::{LoaderError, LoaderKind}; use crate::game::arguments::{Argument, Arguments}; diff --git a/crates/core/src/addon/loader/maven.rs b/crates/core/src/addon/loader/maven.rs index fa0c29f..c940e9a 100644 --- a/crates/core/src/addon/loader/maven.rs +++ b/crates/core/src/addon/loader/maven.rs @@ -168,17 +168,25 @@ pub fn normalize_maven_version(kind: LoaderKind, mc_version: &str, raw: &str) -> } } -/// 用户视角的加载器版本号(Forge 去掉原版前缀,NeoForge 与非 maven 族原样)。 +/// 用户视角的加载器版本号(带原版前缀的 maven 版本要去掉前缀)。 +/// +/// 谁带前缀是**按加载器 + 布局**定的:Forge 恒带;NeoForge 只有「1.20.1 走 forge 布局」 +/// 那一段带(`1.20.1-47.1.106` → `47.1.106`),其余 NeoForge 版本本身就是完整 maven 版本; +/// fabric 系与 LiteLoader 的版本号本来就是用户视角的。 #[must_use] pub fn display_loader_version(kind: LoaderKind, mc_version: &str, maven_version: &str) -> String { - match kind { - LoaderKind::Forge => maven_version + let strip = match kind { + LoaderKind::Forge => true, + LoaderKind::NeoForge => mc_version == NEOFORGE_FORGE_LAYOUT_MC, + LoaderKind::Fabric | LoaderKind::Quilt | LoaderKind::LiteLoader => false, + }; + if strip { + maven_version .strip_prefix(&format!("{mc_version}-")) .unwrap_or(maven_version) - .to_string(), - LoaderKind::NeoForge | LoaderKind::Fabric | LoaderKind::Quilt | LoaderKind::LiteLoader => { - maven_version.to_string() - } + .to_string() + } else { + maven_version.to_string() } } diff --git a/crates/core/src/addon/loader/tests/liteloader.rs b/crates/core/src/addon/loader/tests/liteloader.rs index 3b1f8d0..f42a8f6 100644 --- a/crates/core/src/addon/loader/tests/liteloader.rs +++ b/crates/core/src/addon/loader/tests/liteloader.rs @@ -228,7 +228,7 @@ fn build_release_synthesizes_launchwrapper_manifest() { ); // 父子链靠 arguments.game 追加,不写 minecraftArguments(写了会顶掉 Forge 的 tweakClass)。 assert!(json.minecraft_arguments.is_none()); - let game: Vec<&str> = json + let game: Vec = json .arguments .as_ref() .expect("arguments 必须有") diff --git a/crates/core/tests/liteloader/guards.rs b/crates/core/tests/liteloader/guards.rs index 4d45bfe..f303a3f 100644 --- a/crates/core/tests/liteloader/guards.rs +++ b/crates/core/tests/liteloader/guards.rs @@ -12,13 +12,10 @@ use unlucky_core::addon::loader::{ }; use unlucky_core::download::blocking::block_on; use unlucky_core::game::arguments::Environment; -use unlucky_core::game::inherit::resolve; use unlucky_core::game::install::{execute_with_cancel, InstallErrorKind}; use unlucky_core::game::layout::GameLayout; -use crate::support::{ - engine, liteloader_release, prefill, put_version, read_version, TempDir, VANILLA_1122, -}; +use crate::support::{engine, liteloader_release, prefill, put_version, TempDir, VANILLA_1122}; /// 父版本不是原版、又没装在盘上 → **具名报错**,绝不默默改成叠原版。 #[test] @@ -145,15 +142,6 @@ fn cancel_leaves_no_manifest() { !layout.version_json(&release.version_id).exists(), "取消之后不许留下版本清单" ); - - // 继承链在缺清单时也应明确报「父版本缺失」,而不是静默降级成原版。 - let mut source = std::collections::BTreeMap::new(); - source.insert("1.12.2".to_string(), read_version(&layout, "1.12.2")); - let error = resolve(&source, &release.version_json).expect_err("父版本缺失"); - assert!(matches!( - error, - unlucky_core::game::GameError::MissingParent { .. } - )); } /// 同一个 loader 版本 id 被两条父链请求:**具名报错**,且盘上那份清单一个字节都不动。 diff --git a/crates/core/tests/liteloader/install.rs b/crates/core/tests/liteloader/install.rs index 6c259aa..2179a9c 100644 --- a/crates/core/tests/liteloader/install.rs +++ b/crates/core/tests/liteloader/install.rs @@ -219,8 +219,16 @@ fn new_style_parent_args_are_appended_not_replaced() { ); let resolved = resolve(&source, &source[&release.version_id]).expect("三层继承应可解析"); - // 父层用的是新式参数:子层没有把 legacy 串写进来,继承后仍然没有。 - assert!(resolved.minecraft_arguments.is_none()); + // 子层没写 legacy 串:继承结果里的 `minecraftArguments` 只能是祖父层(原版)那一份, + // 里面绝不能出现 LiteLoader 的 tweakClass(写了就说明我们用了覆盖语义)。 + let legacy = resolved + .minecraft_arguments + .as_deref() + .expect("原版那份 legacy 串应沿链继承下来"); + assert!( + !legacy.contains("LiteLoaderTweaker"), + "loader 层不许往 minecraftArguments 里写:{legacy}" + ); let game = resolved .arguments .as_ref() diff --git a/crates/core/tests/liteloader.rs b/crates/core/tests/liteloader/main.rs similarity index 100% rename from crates/core/tests/liteloader.rs rename to crates/core/tests/liteloader/main.rs diff --git a/crates/presenter/src/dto/instances.rs b/crates/presenter/src/dto/instances.rs index 954ce1f..6026bb3 100644 --- a/crates/presenter/src/dto/instances.rs +++ b/crates/presenter/src/dto/instances.rs @@ -26,5 +26,3 @@ pub use super::launch_failure::{LaunchFailureCause, LaunchFailureStage, LaunchFa /// 实例标识:core::game 生成的稳定 id,app 视为不透明字符串。 pub type InstanceId = String; - -pub use super::LaunchArgsView; diff --git a/crates/presenter/src/dto/instances/tests.rs b/crates/presenter/src/dto/instances/tests.rs index 28b67c7..4ff5481 100644 --- a/crates/presenter/src/dto/instances/tests.rs +++ b/crates/presenter/src/dto/instances/tests.rs @@ -3,6 +3,8 @@ use super::*; use unlucky_core::game::LoaderKind as CoreLoaderKind; +use crate::dto::LaunchArgsView; + #[test] fn loader_badges_and_ids() { let vanilla = LoaderInfo::default();