Skip to content

使用 MCIM 作为回退下载源#5798

Open
Glavo wants to merge 12 commits intoHMCL-dev:mainfrom
Glavo:mcim-mr
Open

使用 MCIM 作为回退下载源#5798
Glavo wants to merge 12 commits intoHMCL-dev:mainfrom
Glavo:mcim-mr

Conversation

@Glavo
Copy link
Member

@Glavo Glavo commented Mar 16, 2026

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 将“下载候选链接注入(DownloadProvider)”接入到 Modrinth 整合包补全下载与 UI 侧的模组/整合包下载流程,以支持通过 MCIM(或其它下载源实现)进行加速与容灾下载。

Changes:

  • Modrinth 整合包补全任务下载时使用 DownloadProvider.injectURLsWithCandidates(...) 生成候选 URL 列表。
  • UI 下载回调链路新增透传 DownloadProvider,并在下载模组/整合包时使用候选 URL 列表创建 FileDownloadTask
  • DownloadListPage 暴露 getDownloadProvider() 供子页面/回调取用。

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java 使用下载源注入后的候选 URL 列表下载 Modrinth 整合包内文件
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java 整合包下载改为通过 DownloadProvider 注入候选 URL 列表
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java 适配下载回调签名变更,透传 DownloadProvider
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadPage.java 下载回调接口新增 DownloadProvider 参数并在触发时传入
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java 新增 getDownloadProvider() 以供下载回调使用
HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java 模组/资源包/光影包/整合包下载使用注入后的候选 URL 列表

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Glavo Glavo changed the title 使用 MCIM 加速下载整合包和模组 使用 MCIM 作为回退下载源 Mar 16, 2026
@Glavo Glavo requested a review from Copilot March 16, 2026 14:46
@Glavo Glavo linked an issue Mar 16, 2026 that may be closed by this pull request
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 旨在让与 Modrinth / CurseForge 相关的下载与查询支持“候选 URL 列表”,从而在默认源不可用时可回退到 MCIM 镜像源,并将 DownloadProvider 注入到远程 Mod 仓库/依赖解析链路中以统一生效。

Changes:

  • 为多处下载/拉取逻辑引入 injectURLWithCandidates / injectURLsWithCandidates,让下载任务可按候选 URL 依次尝试。
  • 调整 RemoteModRepositoryRemoteMod 依赖加载相关 API:新增 DownloadProvider 参数贯穿查询、依赖解析与更新检查。
  • 为图片加载与缓存下载(CacheFileTask / RemoteImageLoader / FXUtils)增加基于候选 URL 的下载支持。

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
HMCLCore/src/main/java/org/jackhuang/hmcl/task/CacheFileTask.java 新增支持 List<URI> 候选下载源的缓存下载构造器
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthRemoteModRepository.java Modrinth 查询/获取项目/版本列表改为使用候选 URL 并改造 API 入参
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthInstallTask.java Modrinth 安装流程中图标下载改为使用候选 URL
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthCompletionTask.java Modrinth 整理/补全任务的文件下载改为候选 URL 列表
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java 调整仓库接口签名以携带 DownloadProvider(目前部分方法未实际使用候选)
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseCompletionTask.java 依赖查询路径改为传递 DownloadProvider 以支持回退(Javadoc 有小问题)
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseAddon.java 依赖/版本加载改为透传 DownloadProvider
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RemoteModRepository.java 核心接口改造:getModById/getRemoteVersionsById 增加 DownloadProvider 参数
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/RemoteMod.java 依赖加载/版本加载接口改造,Dependency.load 需要 DownloadProvider
HMCLCore/src/main/java/org/jackhuang/hmcl/mod/LocalModFile.java 检查更新流程改为使用候选 URL 版本列表查询
HMCLCore/src/main/java/org/jackhuang/hmcl/download/*APIVersionList.java 调用 Modrinth 版本列表 API 时透传 downloadProvider
HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java 增加 MCIM 回退替换表,并实现返回候选 URL 列表的注入逻辑
HMCL/src/main/java/org/jackhuang/hmcl/util/RemoteImageLoader.java 图片加载任务改为使用候选 URL 列表
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java Modpack 下载改为候选 URL 列表下载
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java 获取远程 Mod 信息时补充传入 DownloadProvider
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java 检查更新任务创建时传入 DownloadProvider
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModCheckUpdatesTask.java 更新检查链路透传 DownloadProviderLocalModFile.checkUpdates
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadPage.java 依赖加载与下载回调签名改造以携带 DownloadProvider
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java 暴露 getDownloadProvider() 并用于 RemoteImageLoader
HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java 下载页回调改造,下载任务使用候选 URL
HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java 远程图片任务新增 List<URI> 重载以支持候选下载
Comments suppressed due to low confidence (2)

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java:235

  • getModById now receives a DownloadProvider but still always calls PREFIX + "/v1/mods/" + id directly, so MCIM (and any other provider) fallback candidates are never tried for this endpoint. Please build the request URL via downloadProvider.injectURLWithCandidates(...) and iterate candidates (similar to search) so the fallback actually applies here (and aggregate exceptions/suppressed consistently).
    public RemoteMod getModById(DownloadProvider downloadProvider, String id) throws IOException {
        SEMAPHORE.acquireUninterruptibly();
        try {
            Response<CurseAddon> response = withApiKey(HttpRequest.GET(PREFIX + "/v1/mods/" + id))
                    .getJson(Response.typeOf(CurseAddon.class));
            return response.data.toMod();

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseForgeRemoteModRepository.java:260

  • getRemoteVersionsById also ignores the passed DownloadProvider and always requests PREFIX + "/v1/mods/" + id + "/files", so candidate fallback is not used for version listing. Please apply downloadProvider.injectURLWithCandidates(...) (and loop through candidates) here as well, otherwise update checks/download flows will still fail when api.curseforge.com is unreachable.
    public Stream<RemoteMod.Version> getRemoteVersionsById(DownloadProvider downloadProvider, String id) throws IOException {
        SEMAPHORE.acquireUninterruptibly();
        try {
            Response<List<CurseAddon.LatestFile>> response = withApiKey(HttpRequest.GET(PREFIX + "/v1/mods/" + id + "/files",
                    pair("pageSize", "10000")))
                    .getJson(Response.typeOf(listTypeOf(CurseAddon.LatestFile.class)));
            return response.getData().stream().map(CurseAddon.LatestFile::toVersion);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* Guess where to store the file.
*
* @param file The file.
* @param downloadProvider
Comment on lines +1244 to 1245
public static Task<Image> getRemoteImageTask(List<URI> uri, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
return new CacheFileTask(uri)
Comment on lines +150 to +169
@Override
public String injectURL(String baseURL) {
return injectURL(replacement, baseURL);
}

public List<URI> injectURLWithCandidates(String baseURL) {
String injected = injectURL(replacement, baseURL);
if (injected.equals(baseURL)) {
String fallbackInjected = injectURL(fallbackReplacement, baseURL);
if (fallbackInjected.equals(baseURL)) {
return List.of(NetworkUtils.toURI(baseURL));
} else {
return List.of(
NetworkUtils.toURI(baseURL),
NetworkUtils.toURI(fallbackInjected)
);
}
} else {
return List.of(NetworkUtils.toURI(injected));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Mod 镜像源 MCIM

2 participants