fix: 修复从 .minecraft 导入实例的多项缺陷

修复从 .minecraft / PCL / HMCL 等启动器导入实例时的 6 个问题:

- 复制模式不再克隆 versions/ 下的所有实例,只保留选中的版本
- 版本隔离导入时把 .minecraft 根内容(mods/saves/config)与选中
  versions/<name> 合并进实例目录,不再得到纯原版实例
- 符号链接导入不再因 game_dir_override 被丢弃而在错误目录创建
  游戏数据,实例也不会在失败后被误删
- 不再将用户选择的版本隔离模式强行改为共享(InstallRequest::
  ImportInstance 的 game_dir_override 现在正确透传到导入逻辑)
- 清洗非标准加载器坐标(如 net.neoforged:neoforge:21.1.250:client]
  中的 :client] 后缀),并补充回归测试

涉及 api/pack/import 下的 generic/mod/instance_json 及各启动器
导入器,以及 install/runner 的调用点。
This commit is contained in:
2026-09-19 18:49:46 +08:00
parent a47d309103
commit 984f3ddbd6
10 changed files with 386 additions and 64 deletions

View File

@ -1529,10 +1529,10 @@ async fn run_request(
game_version,
loader,
loader_version,
game_dir_override: _,
game_dir_override,
} => {
tracing::debug!(
"InstallRequest::ImportInstance: launcher_type={launcher_type} base_path={} instance_folder={instance_folder} symlink={symlink}",
"InstallRequest::ImportInstance: launcher_type={launcher_type} base_path={} instance_folder={instance_folder} symlink={symlink} game_dir_override={game_dir_override:?}",
base_path.display()
);
let Some(instance_id) = current_instance_id(job_state) else {
@ -1562,6 +1562,7 @@ async fn run_request(
game_version,
loader,
loader_version,
game_dir_override,
},
// TODO(B2): apply overrides to launcher-specific importers
// (MultiMC/Prism/ATLauncher/GDLauncher/Curseforge/ModrinthApp);
@ -1590,8 +1591,12 @@ async fn run_request(
let state = State::get().await?;
crate::api::pack::import::copy_dotminecraft_with_reporter(
&instance_id,
crate::api::instance::get_full_path(&source_instance_id)
.await?,
Some(
crate::api::instance::get_full_path(&source_instance_id)
.await?,
),
None,
false,
&state.io_semaphore,
InstallProgressReporter::new(job_id, job_state.clone()),
InstallPhaseDetails::Empty,
@ -2526,7 +2531,9 @@ async fn copy_physical_instance_contents(
)?;
crate::api::pack::import::copy_dotminecraft_with_reporter(
target_instance_id,
source_path,
Some(source_path),
None,
false,
&state.io_semaphore,
InstallProgressReporter::new(job_id, job_state.clone()),
InstallPhaseDetails::Empty,