Skip to content

Commit 2a6cd17

Browse files
authored
重新启用 MCIM 加速 (#5030)
1 parent 285e361 commit 2a6cd17

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

HMCLCore/src/main/java/org/jackhuang/hmcl/download/BMCLAPIDownloadProvider.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,12 @@ public BMCLAPIDownloadProvider(String apiRoot) {
9393
pair("https://repo.maven.apache.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
9494
pair("https://hmcl.glavo.site/metadata/cleanroom", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/cleanroom"),
9595
pair("https://hmcl.glavo.site/metadata/fmllibs", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/fmllibs"),
96-
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto")
97-
// // https://github.com/mcmod-info-mirror/mcim-rust-api
98-
// pair("https://api.modrinth.com", "https://mod.mcimirror.top/modrinth"),
99-
// pair("https://cdn.modrinth.com", "https://mod.mcimirror.top"),
100-
// pair("https://api.curseforge.com", "https://mod.mcimirror.top/curseforge"),
101-
// pair("https://edge.forgecdn.net", "https://mod.mcimirror.top"),
102-
// pair("https://mediafilez.forgecdn.net", "https://mod.mcimirror.top")
96+
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto"),
97+
// https://github.com/mcmod-info-mirror/mcim-rust-api
98+
pair("https://api.modrinth.com", "https://mod.mcimirror.top/modrinth"),
99+
pair("https://cdn.modrinth.com", "https://mod.mcimirror.top"),
100+
pair("https://api.curseforge.com", "https://mod.mcimirror.top/curseforge"),
101+
pair("https://edge.forgecdn.net", "https://mod.mcimirror.top")
103102
);
104103
}
105104

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

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.io.ByteArrayOutputStream;
3434
import java.io.IOException;
3535
import java.io.InputStream;
36+
import java.net.URI;
3637
import java.nio.file.Files;
3738
import java.nio.file.Path;
3839
import java.util.*;
@@ -42,6 +43,7 @@
4243
import static org.jackhuang.hmcl.util.Lang.mapOf;
4344
import static org.jackhuang.hmcl.util.Pair.pair;
4445
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
46+
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
4547

4648
public final class CurseForgeRemoteModRepository implements RemoteModRepository {
4749

@@ -131,10 +133,34 @@ public SearchResult search(DownloadProvider downloadProvider, String gameVersion
131133
query.put("index", Integer.toString(pageOffset * pageSize));
132134
query.put("pageSize", Integer.toString(pageSize));
133135

134-
Response<List<CurseAddon>> response = withApiKey(HttpRequest.GET(downloadProvider.injectURL(NetworkUtils.withQuery(PREFIX + "/v1/mods/search", query))))
135-
.getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
136-
if (searchFilter.isEmpty()) {
137-
return new SearchResult(response.getData().stream().map(CurseAddon::toMod), calculateTotalPages(response, pageSize));
136+
Response<List<CurseAddon>> response = null;
137+
138+
IOException exception = null;
139+
List<URI> candidates = downloadProvider.injectURLWithCandidates(NetworkUtils.withQuery(PREFIX + "/v1/mods/search", query));
140+
for (URI candidate : candidates) {
141+
LOG.info("Fetching " + candidate);
142+
try {
143+
response = withApiKey(HttpRequest.GET(candidate.toString()))
144+
.getJson(Response.typeOf(listTypeOf(CurseAddon.class)));
145+
if (searchFilter.isEmpty()) {
146+
return new SearchResult(response.getData().stream().map(CurseAddon::toMod), calculateTotalPages(response, pageSize));
147+
}
148+
break;
149+
} catch (IOException e) {
150+
LOG.warning("Failed to search addons: " + candidate, e);
151+
if (candidates.size() == 1) {
152+
exception = e;
153+
} else {
154+
if (exception == null) {
155+
exception = new IOException("Failed to search addons");
156+
}
157+
exception.addSuppressed(e);
158+
}
159+
}
160+
}
161+
162+
if (response == null) {
163+
throw exception != null ? exception : new IOException("No candidates found");
138164
}
139165

140166
// https://github.com/HMCL-dev/HMCL/issues/1549

HMCLCore/src/main/java/org/jackhuang/hmcl/mod/modrinth/ModrinthRemoteModRepository.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
import java.io.FileNotFoundException;
3939
import java.io.IOException;
40+
import java.net.URI;
4041
import java.nio.file.NoSuchFileException;
4142
import java.nio.file.Path;
4243
import java.time.Instant;
@@ -54,6 +55,7 @@
5455
import static org.jackhuang.hmcl.util.Lang.mapOf;
5556
import static org.jackhuang.hmcl.util.Pair.pair;
5657
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
58+
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
5759

5860
public final class ModrinthRemoteModRepository implements RemoteModRepository {
5961
public static final ModrinthRemoteModRepository MODS = new ModrinthRemoteModRepository("mod");
@@ -112,9 +114,30 @@ public SearchResult search(DownloadProvider downloadProvider, String gameVersion
112114
pair("limit", Integer.toString(pageSize)),
113115
pair("index", convertSortType(sort))
114116
);
115-
Response<ProjectSearchResult> response = HttpRequest.GET(downloadProvider.injectURL(NetworkUtils.withQuery(PREFIX + "/v2/search", query)))
116-
.getJson(Response.typeOf(ProjectSearchResult.class));
117-
return new SearchResult(response.getHits().stream().map(ProjectSearchResult::toMod), (int) Math.ceil((double) response.totalHits / pageSize));
117+
118+
119+
List<URI> candidates = downloadProvider.injectURLWithCandidates(NetworkUtils.withQuery(PREFIX + "/v2/search", query));
120+
IOException exception = null;
121+
for (URI candidate : candidates) {
122+
try {
123+
LOG.info("Fetching " + candidate);
124+
Response<ProjectSearchResult> response = HttpRequest.GET(candidate.toString())
125+
.getJson(Response.typeOf(ProjectSearchResult.class));
126+
return new SearchResult(response.getHits().stream().map(ProjectSearchResult::toMod), (int) Math.ceil((double) response.totalHits / pageSize));
127+
} catch (IOException e) {
128+
LOG.warning("Failed to search addons: " + candidate, e);
129+
if (candidates.size() == 1) {
130+
exception = e;
131+
} else {
132+
if (exception == null) {
133+
exception = new IOException("Failed to search addons");
134+
}
135+
exception.addSuppressed(e);
136+
}
137+
}
138+
}
139+
140+
throw exception != null ? exception : new IOException("No candidates found");
118141
} finally {
119142
SEMAPHORE.release();
120143
}

0 commit comments

Comments
 (0)