Skip to content

Commit 32bdd03

Browse files
feat: Operate on Modrinth versions in parallel.
1 parent 9da8d1c commit 32bdd03

1 file changed

Lines changed: 41 additions & 33 deletions

File tree

src/main/java/net/modgarden/backend/handler/v1/discord/DiscordBotSubmissionHandler.java

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
import java.sql.ResultSet;
2727
import java.sql.SQLException;
2828
import java.time.ZonedDateTime;
29-
import java.util.List;
30-
import java.util.Locale;
31-
import java.util.Optional;
32-
import java.util.Set;
29+
import java.time.temporal.ChronoField;
30+
import java.util.*;
31+
import java.util.stream.Collectors;
32+
import java.util.stream.Stream;
3333

3434
// TODO: Rewrite to use a faster deserialization library than GSON.
3535
public class DiscordBotSubmissionHandler {
@@ -461,11 +461,6 @@ private static boolean hasModrinthAttribution(Context ctx,
461461

462462
@Nullable
463463
private static ModrinthVersion getModrinthVersion(OAuthClient modrinthClient, ModrinthProject modrinthProject, String minecraftVersion, String loader, @Nullable String versionString) throws IOException, InterruptedException {
464-
ModrinthVersion modrinthVersion = null;
465-
ZonedDateTime latestVersionTime = null;
466-
boolean isNative = false; // Used within NeoForge events to make sure that Modrinth will prioritise NeoForge projects over Connector-ran Fabric projects.
467-
468-
469464
if (versionString != null) {
470465
var versionStream = modrinthClient.get("v2/project/" + modrinthProject.id + "/version/" + versionString, HttpResponse.BodyHandlers.ofInputStream());
471466
if (versionStream.statusCode() == 200) {
@@ -475,40 +470,53 @@ private static ModrinthVersion getModrinthVersion(OAuthClient modrinthClient, Mo
475470

476471
if (versionString.equals(potentialVersion.id) || versionString.equals(potentialVersion.versionNumber)) {
477472
if (potentialVersion.loaders.contains(loader) || loader.equals("neoforge") && potentialVersion.loaders.contains("fabric")) {
478-
modrinthVersion = potentialVersion;
473+
return potentialVersion;
479474
}
480475
}
481476
}
482477
}
483-
return modrinthVersion;
478+
return null;
484479
}
485480

486-
for (String versionId : modrinthProject.versions) {
487-
var versionStream = modrinthClient.get("v2/version/" + versionId, HttpResponse.BodyHandlers.ofInputStream());
488-
if (versionStream.statusCode() != 200)
489-
continue;
490-
491-
try (InputStreamReader versionReader = new InputStreamReader(versionStream.body())) {
492-
JsonElement versionJson = JsonParser.parseReader(versionReader);
493-
ModrinthVersion potentialVersion = ModrinthVersion.CODEC.parse(JsonOps.INSTANCE, versionJson).getOrThrow();
494-
495-
if (!potentialVersion.gameVersions.contains(minecraftVersion))
496-
continue;
497-
498-
// Handle natively supported mods for the event's loader.
499-
if (potentialVersion.loaders.contains(loader) && (latestVersionTime == null || potentialVersion.datePublished.isAfter(latestVersionTime))) {
500-
modrinthVersion = potentialVersion;
501-
latestVersionTime = potentialVersion.datePublished;
502-
isNative = true;
503-
// Handle Fabric mods loaded via Connector on NeoForge.
504-
} else if (!isNative && loader.equals("neoforge") && potentialVersion.loaders.contains("fabric") && (latestVersionTime == null || potentialVersion.datePublished.isAfter(latestVersionTime))) {
505-
modrinthVersion = potentialVersion;
506-
latestVersionTime = potentialVersion.datePublished;
481+
ModrinthVersion modrinthVersion = null;
482+
ZonedDateTime latestVersionTime = null;
483+
484+
List<ModrinthVersion> modrinthVersions = modrinthProject.versions.parallelStream().map(versionId -> {
485+
try {
486+
var versionStream = modrinthClient.get("v2/version/" + versionId, HttpResponse.BodyHandlers.ofInputStream());
487+
if (versionStream.statusCode() != 200)
488+
return null;
489+
490+
try (InputStreamReader versionReader = new InputStreamReader(versionStream.body())) {
491+
JsonElement versionJson = JsonParser.parseReader(versionReader);
492+
ModrinthVersion potentialVersion = ModrinthVersion.CODEC.parse(JsonOps.INSTANCE, versionJson).getOrThrow();
493+
494+
if (!potentialVersion.gameVersions.contains(minecraftVersion))
495+
return null;
496+
497+
// Handle natively supported mods for the event's loader.
498+
if (potentialVersion.loaders.contains(loader)) {
499+
return potentialVersion;
500+
// Handle Fabric mods loaded via Connector on NeoForge.
501+
} else if (loader.equals("neoforge") && potentialVersion.loaders.contains("fabric")) {
502+
return potentialVersion;
503+
}
507504
}
505+
} catch (Exception ex) {
506+
ModGardenBackend.LOG.error("Failed to read Modrinth version.", ex);
508507
}
508+
return null;
509+
}).filter(Objects::nonNull).collect(Collectors.toCollection(ArrayList::new));
510+
511+
// Filter out non-native options if the mod has a native version.
512+
// Handles cases like Sinytra Connector.
513+
if (modrinthVersions.stream().anyMatch(v -> v.loaders.contains(loader))) {
514+
modrinthVersions.removeIf(v -> !v.loaders.contains(loader));
509515
}
510516

511-
return modrinthVersion;
517+
return modrinthVersions.stream()
518+
.max(Comparator.comparingLong(value -> value.datePublished.getLong(ChronoField.INSTANT_SECONDS)))
519+
.orElse(null);
512520
}
513521

514522
private static Event getCurrentEvent(Connection connection) throws SQLException {

0 commit comments

Comments
 (0)