diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BalancedDownloadProvider.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BalancedDownloadProvider.java index 0a289917e..feee75c81 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BalancedDownloadProvider.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/BalancedDownloadProvider.java @@ -17,6 +17,9 @@ */ package org.jackhuang.hmcl.download; +import java.util.List; +import java.util.stream.Collectors; + /** * Official Download Provider fetches version list from Mojang and * download files from mcbbs. @@ -24,29 +27,70 @@ package org.jackhuang.hmcl.download; * @author huangyuhui */ public class BalancedDownloadProvider implements DownloadProvider { + List candidates; + + VersionList game, fabric, forge, liteLoader, optifine; + + public BalancedDownloadProvider(List candidates) { + this.candidates = candidates; + + this.game = new MultipleSourceVersionList( + candidates.stream() + .map(downloadProvider -> downloadProvider.getVersionListById("game")) + .collect(Collectors.toList())); + this.fabric = new MultipleSourceVersionList( + candidates.stream() + .map(downloadProvider -> downloadProvider.getVersionListById("fabric")) + .collect(Collectors.toList())); + this.forge = new MultipleSourceVersionList( + candidates.stream() + .map(downloadProvider -> downloadProvider.getVersionListById("forge")) + .collect(Collectors.toList())); + this.liteLoader = new MultipleSourceVersionList( + candidates.stream() + .map(downloadProvider -> downloadProvider.getVersionListById("liteloader")) + .collect(Collectors.toList())); + this.optifine = new MultipleSourceVersionList( + candidates.stream() + .map(downloadProvider -> downloadProvider.getVersionListById("optifine")) + .collect(Collectors.toList())); + } @Override public String getVersionListURL() { - return null; + throw new UnsupportedOperationException(); } @Override public String getAssetBaseURL() { - return null; + throw new UnsupportedOperationException(); } @Override public String injectURL(String baseURL) { - return null; + throw new UnsupportedOperationException(); } @Override public VersionList getVersionListById(String id) { - return null; + switch (id) { + case "game": + return game; + case "fabric": + return fabric; + case "forge": + return forge; + case "liteloader": + return liteLoader; + case "optifine": + return optifine; + default: + throw new IllegalArgumentException("Unrecognized version list id: " + id); + } } @Override public int getConcurrency() { - return 0; + throw new UnsupportedOperationException(); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java index 5d294f4e2..510262a62 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/MultipleSourceVersionList.java @@ -17,5 +17,50 @@ */ package org.jackhuang.hmcl.download; -public class MultipleSourceVersionList { +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class MultipleSourceVersionList extends VersionList { + + private final List> backends; + + MultipleSourceVersionList(List> backends) { + this.backends = backends; + + assert(backends.size() >= 1); + } + + @Override + public boolean hasType() { + boolean hasType = backends.get(0).hasType(); + assert(backends.stream().allMatch(versionList -> versionList.hasType() == hasType)); + return hasType; + } + + @Override + public CompletableFuture loadAsync() { + throw new UnsupportedOperationException("ForgeBMCLVersionList does not support loading the entire Forge remote version list."); + } + + @Override + public CompletableFuture refreshAsync() { + throw new UnsupportedOperationException("ForgeBMCLVersionList does not support loading the entire Forge remote version list."); + } + + @Override + public CompletableFuture refreshAsync(String gameVersion) { + versions.clear(gameVersion); + return CompletableFuture.anyOf(backends.stream() + .map(versionList -> versionList.refreshAsync(gameVersion) + .thenRunAsync(() -> { + lock.writeLock().lock(); + + try { + versions.putAll(gameVersion, versionList.getVersions(gameVersion)); + } finally { + lock.writeLock().unlock(); + } + })) + .toArray(CompletableFuture[]::new)); + } } diff --git a/settings.gradle b/settings.gradle index 32100c8ff..28fbb873a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ rootProject.name = 'HMCL3' -include 'HMCL' -include 'HMCLCore' -include 'HMCLTransformerDiscoveryService' +include ':HMCL' +include ':HMCLCore' +include ':HMCLTransformerDiscoveryService'