refactor(modpack): 重写整合包安装 - #3523
Conversation
Reviewer's Guide将 ModModpack 重构为模块化、与格式无关的安装流水线,由新的 Modpack* 模型和归档读取器提供支持;新增对 CurseForge、Modrinth、MultiMC、HMCL、MCBBS、启动器整合包以及懒人包(包括文件夹形式整合包)的稳健检测与安装能力;并引入整合包推荐内存(RAM)支持,包括 UI、启动时安全检查和回归测试。 统一整合包安装流水线的序列图sequenceDiagram
participant User
participant ModModpack as ModModpack.ModpackInstall
participant ZipReader as ZipModpackArchiveReader
participant Detector as ModpackArchiveDetector.Detect
participant ModModpackSrc as ModModpack._InstallSource
participant CurseForge as ModModpack._InstallCurseForge
participant Modrinth as ModModpack._InstallModrinth
participant MultiMc as ModModpack._InstallMultiMc
User->>ModModpack: ModpackInstall(file, instanceName, logo, resourceId, isOnlineInstall)
ModModpack->>ZipReader: new ZipModpackArchiveReader(archive)
ModModpack->>Detector: Detect(source)
Detector-->>ModModpack: ModpackDetection(Format, ArchiveBaseFolder)
ModModpack->>ModModpackSrc: _InstallSource(source, file, instanceName, logo, resourceId, isOnlineInstall)
ModModpackSrc->>ModModpackSrc: ModpackArchiveDetector.Detect(source)
ModModpackSrc-->>ModModpackSrc: packType, archiveBaseFolder
alt packType == ModpackFormat.CurseForge
ModModpackSrc->>CurseForge: _InstallCurseForge(sourcePath, source, archiveBaseFolder, instanceName, logo, resourceId, isOnlineInstall)
else packType == ModpackFormat.Modrinth
ModModpackSrc->>Modrinth: _InstallModrinth(sourcePath, source, archiveBaseFolder, instanceName, logo, resourceId, isOnlineInstall)
else packType == ModpackFormat.MultiMc
ModModpackSrc->>MultiMc: _InstallMultiMc(sourcePath, source, archiveBaseFolder)
else other formats
ModModpackSrc->>ModModpackSrc: _InstallMcbbs / _InstallHmcl / _InstallLauncherPack / _InstallCompress
end
启动时处理整合包推荐内存(RAM)的序列图sequenceDiagram
participant Launch as ModLaunch.McLaunchPrecheck
participant Config as Config.Instance
participant States as States.Instance
participant Kernel as KernelInterop
participant Msg as ModMain.MyMsgBox
Launch->>Config: MemorySolution[ModInstanceList.McMcInstanceSelected.PathInstance]
alt MemorySolution == 3
Launch->>States: ModpackRam[ModInstanceList.McMcInstanceSelected.PathInstance]
States-->>Launch: recommendedRamMb
alt recommendedRamMb > 0
Launch->>Kernel: GetAvailablePhysicalMemoryBytes()
Kernel-->>Launch: availableBytes
Launch->>Launch: [availableMb*0.8 < recommendedRamMb || availableMb - recommendedRamMb < 2GB]
alt condition true
Launch->>Msg: MyMsgBox(ModpackRecommendedRamUnfit..., SwitchAuto, KeepRecommended)
Msg-->>Launch: result
alt result == 1
Launch->>Config: MemorySolution[...] = 0 (via ModBase.RunInUiWait)
end
end
end
end
文件级改动
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 来:
Getting HelpOriginal review guide in EnglishReviewer's GuideRefactors ModModpack into a modular, format-agnostic installer pipeline backed by new Modpack* models and archive readers, adds robust detection/installation for CurseForge, Modrinth, MultiMC, HMCL, MCBBS, launcher packs and lazy packs (including folder-based packs), and introduces modpack-recommended RAM support with UI, launch-time safeguards, and regression tests. Sequence diagram for unified modpack installation pipelinesequenceDiagram
participant User
participant ModModpack as ModModpack.ModpackInstall
participant ZipReader as ZipModpackArchiveReader
participant Detector as ModpackArchiveDetector.Detect
participant ModModpackSrc as ModModpack._InstallSource
participant CurseForge as ModModpack._InstallCurseForge
participant Modrinth as ModModpack._InstallModrinth
participant MultiMc as ModModpack._InstallMultiMc
User->>ModModpack: ModpackInstall(file, instanceName, logo, resourceId, isOnlineInstall)
ModModpack->>ZipReader: new ZipModpackArchiveReader(archive)
ModModpack->>Detector: Detect(source)
Detector-->>ModModpack: ModpackDetection(Format, ArchiveBaseFolder)
ModModpack->>ModModpackSrc: _InstallSource(source, file, instanceName, logo, resourceId, isOnlineInstall)
ModModpackSrc->>ModModpackSrc: ModpackArchiveDetector.Detect(source)
ModModpackSrc-->>ModModpackSrc: packType, archiveBaseFolder
alt packType == ModpackFormat.CurseForge
ModModpackSrc->>CurseForge: _InstallCurseForge(sourcePath, source, archiveBaseFolder, instanceName, logo, resourceId, isOnlineInstall)
else packType == ModpackFormat.Modrinth
ModModpackSrc->>Modrinth: _InstallModrinth(sourcePath, source, archiveBaseFolder, instanceName, logo, resourceId, isOnlineInstall)
else packType == ModpackFormat.MultiMc
ModModpackSrc->>MultiMc: _InstallMultiMc(sourcePath, source, archiveBaseFolder)
else other formats
ModModpackSrc->>ModModpackSrc: _InstallMcbbs / _InstallHmcl / _InstallLauncherPack / _InstallCompress
end
Sequence diagram for modpack-recommended RAM handling on launchsequenceDiagram
participant Launch as ModLaunch.McLaunchPrecheck
participant Config as Config.Instance
participant States as States.Instance
participant Kernel as KernelInterop
participant Msg as ModMain.MyMsgBox
Launch->>Config: MemorySolution[ModInstanceList.McMcInstanceSelected.PathInstance]
alt MemorySolution == 3
Launch->>States: ModpackRam[ModInstanceList.McMcInstanceSelected.PathInstance]
States-->>Launch: recommendedRamMb
alt recommendedRamMb > 0
Launch->>Kernel: GetAvailablePhysicalMemoryBytes()
Kernel-->>Launch: availableBytes
Launch->>Launch: [availableMb*0.8 < recommendedRamMb || availableMb - recommendedRamMb < 2GB]
alt condition true
Launch->>Msg: MyMsgBox(ModpackRecommendedRamUnfit..., SwitchAuto, KeepRecommended)
Msg-->>Launch: result
alt result == 1
Launch->>Config: MemorySolution[...] = 0 (via ModBase.RunInUiWait)
end
end
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Close #3403 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f08b192436
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as off-topic.
This comment was marked as off-topic.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 921205b28d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7ef0a93511
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6209d9209d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b61f312588
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e7a53e32dc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 085b1f69ca
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // 地图存档(包裹式):modules 仅有一个无扩展名的顶层条目时,是“zip 内再包一层存档文件夹”的地图 | ||
| else if (moduleNames.Count == 1 && !Path.HasExtension(moduleNames[0])) | ||
| { | ||
| targetFolder = "saves"; | ||
| type = ModComp.CompType.World; |
There was a problem hiding this comment.
Require world evidence before routing single-folder archives
For a CurseForge resource or shader pack whose modules list contains only one wrapper directory, this condition classifies it as a world despite having no level.dat. It is consequently downloaded to saves; _ExtractArchiveToDirectory then rejects it as a save and stores the archive at that incorrect destination instead of installing it under resourcepacks or shaderpacks. Require a world-specific marker rather than treating every single extensionless module as a world.
Useful? React with 👍 / 👎.
| if (Directory.Exists(targetDirectory)) | ||
| ModBase.DeleteDirectory(targetDirectory, true); | ||
| Directory.CreateDirectory(Path.GetDirectoryName(targetDirectory) ?? targetDirectory); | ||
| ModBase.CopyFile(archivePath, targetDirectory); |
There was a problem hiding this comment.
Preserve existing targets when archive fallback is needed
When a directory-form download targets a path that already exists—such as a save supplied by overrides—and the downloaded payload is not recognized as a valid save, this fallback deletes the entire existing directory before copying the payload as a file. A malformed download or misclassified non-world archive can therefore erase user/pack data, and the catch path repeats the deletion; fallback should not remove a populated target without conflict handling.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 429b4815b1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return candidates[0]; | ||
| } | ||
|
|
||
| return _PromptLazyPackPrimaryVersion(versionNames); |
There was a problem hiding this comment.
Limit the lazy-pack chooser to primary candidates
When a lazy pack contains multiple top-level instances sharing an inherited bundled base, candidates correctly excludes that base, but this fallback displays every versionNames entry anyway. A user can therefore select the inherited dependency as the primary instance, causing the pack to be installed and named around the wrong version. Fresh evidence in the current revision is that the inheritance analysis now computes the correct candidate set but discards it when opening the chooser; pass candidates when it is nonempty, reserving the full list for cases where inference found no candidates.
Useful? React with 👍 / 👎.
修改内容
测试情况
其他说明
close #3403
Summary by Sourcery
将整合包安装重构为“按格式划分的模块”,在其之上建立共享的检测与分发层;新增对“嵌套整合包”和“文件夹整合包”的安装支持,并在安装流程、实例设置和启动流程中引入“整合包推荐内存”的统一处理。
New Features:
.minecraft实例归档)安装,实现带冲突感知的文件复制以及自动版本隔离。Bug Fixes:
Enhancements:
Documentation:
Tests:
Original summary in English
Summary by Sourcery
Refactor modpack installation into format-specific modules with a shared detection and dispatch layer, add support for installing nested and folder-based modpacks, and introduce modpack-recommended memory handling across install, instance settings, and launch flows.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
新特性:
错误修复:
增强优化:
文档:
测试:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
新特性(New Features):
错误修复(Bug Fixes):
增强改进(Enhancements):
文档(Documentation):
测试(Tests):
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
新特性:
错误修复:
增强优化:
文档:
测试:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Original summary in English
Summary by Sourcery
重构整合包安装流程以统一支持多种来源和格式,并完善实例内存推荐及安装兼容性处理。
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests: