fix: 修复 SLS 实例删除残留外部数据与重装共用文件夹
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled

删除实例残留外部数据:
- remove_instance 原先只在 game_dir_override 指向 versions/<name>
  隔离目录时才删除外部目录;SLS(hosted)实例使用版本共享布局
  (外部目录直接作为游戏根),删除时落到托管目录分支,外部 mods/
  存档/配置残留。
- 现在 game_dir_override 只要指向实例独占目录(非共享 .minecraft
  根)就一并删除;新增 is_shared_minecraft_root 判据:含
  libraries/ 或 assets/ 的目录视为共享游戏根,删除实例时保留。

重装共用同一文件夹:
- hosted::create 生成 game_dir_override 时直接拼接
  `<root>/<pack name>`,无冲突处理;同一整合包安装两次会指向同一
  目录,两个实例共用一份游戏数据。
- 新增 unique_game_dir:目标目录已存在时依次尝试 `<name> (1)`、
  `<name> (2)` …,与 create_instance::resolve_instance_path 的
  实例目录去重逻辑保持一致。
This commit is contained in:
AxTps committed 2026-09-19 19:37:08 +08:00
1 parent cda7bb284a
commit 905e905eca
2 files changed
+56 -12

No files matched your search

@@ -32,12 +32,17 @@ pub(crate) async fn remove_instance(
.game_dir_override
.as_deref()
.map(PathBuf::from)
.filter(|path| is_version_isolated_game_dir(path))
.filter(|path| {
// Delete the external game directory when the instance owns it.
// A version-isolated `versions/<name>` folder is obviously
// exclusive; a plain `<root>/<pack name>` folder is also owned by
// this instance. A shared `.minecraft` root, however, holds the
// game's libraries/assets and must never be deleted with one
// instance.
is_version_isolated_game_dir(path)
|| !is_shared_minecraft_root(path)
})
{
// New instances created against a configured `.minecraft` root use
// a private `versions/<name>` directory. Remove that external
// directory when the instance is deleted, while preserving shared
// (non-isolated) overrides for backwards compatibility.
game_dir_override
} else {
state.directories.instances_dir().join(&instance.path)
@@ -69,3 +74,12 @@ fn is_version_isolated_game_dir(path: &Path) -> bool {
.and_then(|name| name.to_str())
== Some("versions")
}
/// Heuristic: a shared `.minecraft` root holds the game's libraries and
/// assets, which must survive the removal of any single instance that points
/// at it. Instance-owned external folders (e.g. a hosted modpack's
/// `<root>/<pack name>` directory) contain only mods/saves/config and no such
/// shared game body.
fn is_shared_minecraft_root(path: &Path) -> bool {
path.join("libraries").is_dir() || path.join("assets").is_dir()
}