feat: balanced download provider. Closes #959.

This commit is contained in:
huanghongxun 2021-08-29 17:19:09 +08:00
parent 19bcf453a5
commit 48aab94fdf
3 changed files with 98 additions and 9 deletions

View File

@ -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<DownloadProvider> candidates;
VersionList<?> game, fabric, forge, liteLoader, optifine;
public BalancedDownloadProvider(List<DownloadProvider> 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();
}
}

View File

@ -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<RemoteVersion> {
private final List<VersionList<?>> backends;
MultipleSourceVersionList(List<VersionList<?>> 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));
}
}

View File

@ -1,5 +1,5 @@
rootProject.name = 'HMCL3'
include 'HMCL'
include 'HMCLCore'
include 'HMCLTransformerDiscoveryService'
include ':HMCL'
include ':HMCLCore'
include ':HMCLTransformerDiscoveryService'