mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-15 06:45:42 -04:00
update VersionList
This commit is contained in:
parent
bcf66c8996
commit
4eab456687
@ -49,6 +49,8 @@ import org.jackhuang.hmcl.download.quilt.QuiltAPIRemoteVersion;
|
||||
import org.jackhuang.hmcl.download.quilt.QuiltRemoteVersion;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.setting.VersionIconType;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.SVG;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
@ -67,7 +69,6 @@ import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@ -96,7 +97,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
private final StackPane center;
|
||||
|
||||
private final VersionList<?> versionList;
|
||||
private CompletableFuture<?> executor;
|
||||
private Task<?> executor;
|
||||
|
||||
private final HBox searchBar;
|
||||
private final StringProperty queryString = new SimpleStringProperty();
|
||||
@ -308,7 +309,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
public void refresh() {
|
||||
VersionList<?> currentVersionList = versionList;
|
||||
root.setContent(spinner, ContainerAnimations.FADE);
|
||||
executor = currentVersionList.refreshAsync(gameVersion).whenComplete((result, exception) -> {
|
||||
executor = currentVersionList.refreshAsync(gameVersion).whenComplete(Schedulers.io(), (result, exception) -> {
|
||||
if (exception == null) {
|
||||
List<RemoteVersion> items = loadVersions();
|
||||
|
||||
@ -348,8 +349,9 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
settings.remove(libraryId);
|
||||
if (executor != null)
|
||||
executor.cancel(true);
|
||||
// fixme
|
||||
// if (executor != null)
|
||||
// executor.cancel(true);
|
||||
}
|
||||
|
||||
private void onRefresh() {
|
||||
|
@ -148,7 +148,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
||||
if (baseVersion.isResolved()) throw new IllegalArgumentException("Version should not be resolved");
|
||||
|
||||
VersionList<?> versionList = getVersionList(libraryId);
|
||||
return Task.fromCompletableFuture(versionList.loadAsync(gameVersion))
|
||||
return versionList.loadAsync(gameVersion)
|
||||
.thenComposeAsync(() -> installLibraryAsync(baseVersion, versionList.getVersion(gameVersion, libraryVersion)
|
||||
.orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion))))
|
||||
.withStage(String.format("hmcl.install.%s:%s", libraryId, libraryVersion));
|
||||
|
@ -17,8 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
@ -40,44 +41,40 @@ public class MultipleSourceVersionList extends VersionList<RemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> loadAsync() {
|
||||
public Task<?> loadAsync() {
|
||||
throw new UnsupportedOperationException("MultipleSourceVersionList does not support loading the entire remote version list.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
public Task<?> refreshAsync() {
|
||||
throw new UnsupportedOperationException("MultipleSourceVersionList does not support loading the entire remote version list.");
|
||||
}
|
||||
|
||||
private CompletableFuture<?> refreshAsync(String gameVersion, int sourceIndex) {
|
||||
private Task<?> refreshAsync(String gameVersion, int sourceIndex) {
|
||||
VersionList<?> versionList = backends[sourceIndex];
|
||||
CompletableFuture<Void> future = versionList.refreshAsync(gameVersion)
|
||||
.thenRunAsync(() -> {
|
||||
return versionList.refreshAsync(gameVersion)
|
||||
.thenComposeAsync(() -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
versions.putAll(gameVersion, versionList.getVersions(gameVersion));
|
||||
} catch (Exception e) {
|
||||
if (sourceIndex == backends.length - 1) {
|
||||
LOG.warning("Failed to fetch versions list from all sources", e);
|
||||
return null;
|
||||
} else {
|
||||
LOG.warning("Failed to fetch versions list and try to fetch from other source", e);
|
||||
return refreshAsync(gameVersion, sourceIndex + 1);
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
if (sourceIndex == backends.length - 1) {
|
||||
return future;
|
||||
} else {
|
||||
return future.<CompletableFuture<?>>handle((ignore, e) -> {
|
||||
if (e == null) {
|
||||
return future;
|
||||
}
|
||||
|
||||
LOG.warning("Failed to fetch versions list and try to fetch from other source", e);
|
||||
return refreshAsync(gameVersion, sourceIndex + 1);
|
||||
}).thenCompose(it -> it);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
versions.clear(gameVersion);
|
||||
return refreshAsync(gameVersion, 0);
|
||||
}
|
||||
|
@ -17,17 +17,16 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* The remote version list.
|
||||
*
|
||||
* @param <T> The subclass of {@code RemoteVersion}, the type of RemoteVersion.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class VersionList<T extends RemoteVersion> {
|
||||
@ -48,6 +47,7 @@ public abstract class VersionList<T extends RemoteVersion> {
|
||||
|
||||
/**
|
||||
* True if the version list that contains the remote versions which depends on the specific game version has been loaded.
|
||||
*
|
||||
* @param gameVersion the remote version depends on
|
||||
*/
|
||||
public boolean isLoaded(String gameVersion) {
|
||||
@ -61,44 +61,42 @@ public abstract class VersionList<T extends RemoteVersion> {
|
||||
/**
|
||||
* @return the task to reload the remote version list.
|
||||
*/
|
||||
public abstract CompletableFuture<?> refreshAsync();
|
||||
public abstract Task<?> refreshAsync();
|
||||
|
||||
/**
|
||||
* @param gameVersion the remote version depends on
|
||||
* @return the task to reload the remote version list.
|
||||
*/
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
return refreshAsync();
|
||||
}
|
||||
|
||||
public CompletableFuture<?> loadAsync() {
|
||||
return CompletableFuture.completedFuture(null)
|
||||
.thenComposeAsync(unused -> {
|
||||
lock.readLock().lock();
|
||||
boolean loaded;
|
||||
public Task<?> loadAsync() {
|
||||
return Task.composeAsync(() -> {
|
||||
lock.readLock().lock();
|
||||
boolean loaded;
|
||||
|
||||
try {
|
||||
loaded = isLoaded();
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return loaded ? CompletableFuture.completedFuture(null) : refreshAsync();
|
||||
});
|
||||
try {
|
||||
loaded = isLoaded();
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return loaded ? null : refreshAsync();
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<?> loadAsync(String gameVersion) {
|
||||
return CompletableFuture.completedFuture(null)
|
||||
.thenComposeAsync(unused -> {
|
||||
lock.readLock().lock();
|
||||
boolean loaded;
|
||||
public Task<?> loadAsync(String gameVersion) {
|
||||
return Task.composeAsync(() -> {
|
||||
lock.readLock().lock();
|
||||
boolean loaded;
|
||||
|
||||
try {
|
||||
loaded = isLoaded(gameVersion);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return loaded ? CompletableFuture.completedFuture(null) : refreshAsync(gameVersion);
|
||||
});
|
||||
try {
|
||||
loaded = isLoaded(gameVersion);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return loaded ? Task.completed(null) : refreshAsync(gameVersion);
|
||||
});
|
||||
}
|
||||
|
||||
protected Collection<T> getVersionsImpl(String gameVersion) {
|
||||
@ -123,7 +121,7 @@ public abstract class VersionList<T extends RemoteVersion> {
|
||||
/**
|
||||
* Get the specific remote version.
|
||||
*
|
||||
* @param gameVersion the Minecraft version that remote versions belong to
|
||||
* @param gameVersion the Minecraft version that remote versions belong to
|
||||
* @param remoteVersion the version of the remote version.
|
||||
* @return the specific remote version, null if it is not found.
|
||||
*/
|
||||
|
@ -21,12 +21,10 @@ import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
|
||||
public class FabricAPIVersionList extends VersionList<FabricAPIRemoteVersion> {
|
||||
|
||||
@ -42,14 +40,14 @@ public class FabricAPIVersionList extends VersionList<FabricAPIRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return CompletableFuture.runAsync(wrap(() -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.runAsync(() -> {
|
||||
for (RemoteMod.Version modVersion : Lang.toIterable(ModrinthRemoteModRepository.MODS.getRemoteVersionsById("P7dR8mSH"))) {
|
||||
for (String gameVersion : modVersion.getGameVersions()) {
|
||||
versions.put(gameVersion, new FabricAPIRemoteVersion(gameVersion, modVersion.getVersion(), modVersion.getName(), modVersion.getDatePublished(), modVersion,
|
||||
Collections.singletonList(modVersion.getFile().getUrl())));
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hmcl.download.fabric;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -26,10 +27,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||
|
||||
public final class FabricVersionList extends VersionList<FabricRemoteVersion> {
|
||||
@ -45,8 +44,8 @@ public final class FabricVersionList extends VersionList<FabricRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return CompletableFuture.runAsync(wrap(() -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.runAsync(() -> {
|
||||
List<String> gameVersions = getGameVersions(GAME_META_URL);
|
||||
List<String> loaderVersions = getGameVersions(LOADER_META_URL);
|
||||
|
||||
@ -60,7 +59,7 @@ public final class FabricVersionList extends VersionList<FabricRemoteVersion> {
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private static final String LOADER_META_URL = "https://meta.fabricmc.net/v2/versions/loader";
|
||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hmcl.download.forge;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
@ -34,10 +35,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
@ -58,12 +57,12 @@ public final class ForgeBMCLVersionList extends VersionList<ForgeRemoteVersion>
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> loadAsync() {
|
||||
public Task<?> loadAsync() {
|
||||
throw new UnsupportedOperationException("ForgeBMCLVersionList does not support loading the entire Forge remote version list.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
public Task<?> refreshAsync() {
|
||||
throw new UnsupportedOperationException("ForgeBMCLVersionList does not support loading the entire Forge remote version list.");
|
||||
}
|
||||
|
||||
@ -83,11 +82,10 @@ public final class ForgeBMCLVersionList extends VersionList<ForgeRemoteVersion>
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
String lookupVersion = toLookupVersion(gameVersion);
|
||||
|
||||
return CompletableFuture.completedFuture(null)
|
||||
.thenApplyAsync(wrap(unused -> HttpRequest.GET(apiRoot + "/forge/minecraft/" + lookupVersion).getJson(listTypeOf(ForgeVersion.class))))
|
||||
return Task.supplyAsync(() -> HttpRequest.GET(apiRoot + "/forge/minecraft/" + lookupVersion).getJson(listTypeOf(ForgeVersion.class)))
|
||||
.thenAcceptAsync(forgeVersions -> {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
|
@ -19,14 +19,15 @@ package org.jackhuang.hmcl.download.forge;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -53,8 +54,8 @@ public final class ForgeVersionList extends VersionList<ForgeRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return HttpRequest.GET(FORGE_LIST).getJsonAsync(ForgeVersionRoot.class)
|
||||
public Task<?> refreshAsync() {
|
||||
return new GetTask(FORGE_LIST).thenGetJsonAsync(ForgeVersionRoot.class)
|
||||
.thenAcceptAsync(root -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
@ -95,5 +96,5 @@ public final class ForgeVersionList extends VersionList<ForgeRemoteVersion> {
|
||||
});
|
||||
}
|
||||
|
||||
public static final String FORGE_LIST = "https://hmcl-dev.github.io/metadata/forge/";
|
||||
public static final URI FORGE_LIST = URI.create("https://hmcl-dev.github.io/metadata/forge/");
|
||||
}
|
||||
|
@ -19,14 +19,15 @@ package org.jackhuang.hmcl.download.game;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
@ -52,8 +53,8 @@ public final class GameVersionList extends VersionList<GameRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return HttpRequest.GET(downloadProvider.getVersionListURL()).getJsonAsync(GameRemoteVersions.class)
|
||||
public Task<?> refreshAsync() {
|
||||
return new GetTask(URI.create(downloadProvider.getVersionListURL())).thenGetJsonAsync(GameRemoteVersions.class)
|
||||
.thenAcceptAsync(root -> {
|
||||
GameRemoteVersions unlistedVersions = null;
|
||||
|
||||
|
@ -44,7 +44,7 @@ public final class VersionJsonDownloadTask extends Task<String> {
|
||||
this.dependencyManager = dependencyManager;
|
||||
this.gameVersionList = dependencyManager.getVersionList("game");
|
||||
|
||||
dependents.add(Task.fromCompletableFuture(gameVersionList.loadAsync(gameVersion)));
|
||||
dependents.add(gameVersionList.loadAsync(gameVersion));
|
||||
|
||||
setSignificance(TaskSignificance.MODERATE);
|
||||
}
|
||||
|
@ -20,12 +20,12 @@ package org.jackhuang.hmcl.download.liteloader;
|
||||
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
@ -54,17 +54,15 @@ public final class LiteLoaderBMCLVersionList extends VersionList<LiteLoaderRemot
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
public Task<?> refreshAsync() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
return HttpRequest.GET(
|
||||
downloadProvider.injectURL("https://bmclapi2.bangbang93.com/liteloader/list"), Pair.pair("mcversion", gameVersion)
|
||||
)
|
||||
.getJsonAsync(LiteLoaderBMCLVersion.class)
|
||||
.thenAccept(v -> {
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
return new GetTask(NetworkUtils.withQuery(downloadProvider.injectURLWithCandidates("https://bmclapi2.bangbang93.com/liteloader/list"), Map.of("mcversion", gameVersion)))
|
||||
.thenGetJsonAsync(LiteLoaderBMCLVersion.class)
|
||||
.thenAcceptAsync(v -> {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
versions.clear();
|
||||
|
@ -20,16 +20,18 @@ package org.jackhuang.hmcl.download.liteloader;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
@ -50,8 +52,9 @@ public final class LiteLoaderVersionList extends VersionList<LiteLoaderRemoteVer
|
||||
public static final String LITELOADER_LIST = "https://dl.liteloader.com/versions/versions.json";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
return HttpRequest.GET(downloadProvider.injectURL(LITELOADER_LIST)).getJsonAsync(LiteLoaderVersionsRoot.class)
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
return new GetTask(URI.create(downloadProvider.injectURL(LITELOADER_LIST)))
|
||||
.thenGetJsonAsync(LiteLoaderVersionsRoot.class)
|
||||
.thenAcceptAsync(root -> {
|
||||
LiteLoaderGameVersions versions = root.getVersions().get(gameVersion);
|
||||
if (versions == null) {
|
||||
@ -85,7 +88,7 @@ public final class LiteLoaderVersionList extends VersionList<LiteLoaderRemoteVer
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
public Task<?> refreshAsync() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -20,15 +20,14 @@ package org.jackhuang.hmcl.download.neoforge;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Immutable;
|
||||
import org.jackhuang.hmcl.util.gson.Validation;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||
|
||||
public final class NeoForgeBMCLVersionList extends VersionList<NeoForgeRemoteVersion> {
|
||||
@ -47,12 +46,12 @@ public final class NeoForgeBMCLVersionList extends VersionList<NeoForgeRemoteVer
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> loadAsync() {
|
||||
public Task<?> loadAsync() {
|
||||
throw new UnsupportedOperationException("NeoForgeBMCLVersionList does not support loading the entire NeoForge remote version list.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
public Task<?> refreshAsync() {
|
||||
throw new UnsupportedOperationException("NeoForgeBMCLVersionList does not support loading the entire NeoForge remote version list.");
|
||||
}
|
||||
|
||||
@ -65,9 +64,8 @@ public final class NeoForgeBMCLVersionList extends VersionList<NeoForgeRemoteVer
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync(String gameVersion) {
|
||||
return CompletableFuture.completedFuture((Void) null)
|
||||
.thenApplyAsync(wrap(unused -> HttpRequest.GET(apiRoot + "/neoforge/list/" + gameVersion).getJson(listTypeOf(NeoForgeVersion.class))))
|
||||
public Task<?> refreshAsync(String gameVersion) {
|
||||
return Task.supplyAsync(() -> HttpRequest.GET(apiRoot + "/neoforge/list/" + gameVersion).getJson(listTypeOf(NeoForgeVersion.class)))
|
||||
.thenAcceptAsync(neoForgeVersions -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
|
@ -2,14 +2,14 @@ package org.jackhuang.hmcl.download.neoforge;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
public final class NeoForgeOfficialVersionList extends VersionList<NeoForgeRemoteVersion> {
|
||||
@ -37,17 +37,17 @@ public final class NeoForgeOfficialVersionList extends VersionList<NeoForgeRemot
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return CompletableFuture.supplyAsync(wrap(() -> new OfficialAPIResult[]{
|
||||
HttpRequest.GET(downloadProvider.injectURL(OLD_URL)).getJson(OfficialAPIResult.class),
|
||||
HttpRequest.GET(downloadProvider.injectURL(META_URL)).getJson(OfficialAPIResult.class)
|
||||
})).thenAccept(results -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.allOf(
|
||||
new GetTask(URI.create(downloadProvider.injectURL(OLD_URL))).thenGetJsonAsync(OfficialAPIResult.class),
|
||||
new GetTask(URI.create(downloadProvider.injectURL(META_URL))).thenGetJsonAsync(OfficialAPIResult.class)
|
||||
).thenAcceptAsync(results -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
versions.clear();
|
||||
|
||||
for (String version : results[0].versions) {
|
||||
for (String version : results.get(0).versions) {
|
||||
versions.put("1.20.1", new NeoForgeRemoteVersion(
|
||||
"1.20.1", NeoForgeRemoteVersion.normalize(version),
|
||||
Collections.singletonList(
|
||||
@ -56,7 +56,7 @@ public final class NeoForgeOfficialVersionList extends VersionList<NeoForgeRemot
|
||||
));
|
||||
}
|
||||
|
||||
for (String version : results[1].versions) {
|
||||
for (String version : results.get(1).versions) {
|
||||
String mcVersion;
|
||||
|
||||
try {
|
||||
|
@ -19,14 +19,15 @@ package org.jackhuang.hmcl.download.optifine;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.HttpRequest;
|
||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||
|
||||
@ -71,8 +72,8 @@ public final class OptiFineBMCLVersionList extends VersionList<OptiFineRemoteVer
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return HttpRequest.GET(apiRoot + "/optifine/versionlist").getJsonAsync(listTypeOf(OptiFineVersion.class)).thenAcceptAsync(root -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return new GetTask(URI.create(apiRoot + "/optifine/versionlist")).thenGetJsonAsync(listTypeOf(OptiFineVersion.class)).thenAcceptAsync(root -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
|
@ -21,12 +21,10 @@ import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
|
||||
public class QuiltAPIVersionList extends VersionList<QuiltAPIRemoteVersion> {
|
||||
|
||||
@ -42,14 +40,14 @@ public class QuiltAPIVersionList extends VersionList<QuiltAPIRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return CompletableFuture.runAsync(wrap(() -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.runAsync(() -> {
|
||||
for (RemoteMod.Version modVersion : Lang.toIterable(ModrinthRemoteModRepository.MODS.getRemoteVersionsById("qsl"))) {
|
||||
for (String gameVersion : modVersion.getGameVersions()) {
|
||||
versions.put(gameVersion, new QuiltAPIRemoteVersion(gameVersion, modVersion.getVersion(), modVersion.getName(), modVersion.getDatePublished(), modVersion,
|
||||
Collections.singletonList(modVersion.getFile().getUrl())));
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hmcl.download.quilt;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -26,10 +27,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.wrap;
|
||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||
|
||||
public final class QuiltVersionList extends VersionList<QuiltRemoteVersion> {
|
||||
@ -45,8 +44,8 @@ public final class QuiltVersionList extends VersionList<QuiltRemoteVersion> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> refreshAsync() {
|
||||
return CompletableFuture.runAsync(wrap(() -> {
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.runAsync(() -> {
|
||||
List<String> gameVersions = getGameVersions(GAME_META_URL);
|
||||
List<String> loaderVersions = getGameVersions(LOADER_META_URL);
|
||||
|
||||
@ -60,7 +59,7 @@ public final class QuiltVersionList extends VersionList<QuiltRemoteVersion> {
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private static final String LOADER_META_URL = "https://meta.quiltmc.org/v3/versions/loader";
|
||||
|
@ -17,6 +17,9 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.task;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
@ -29,7 +32,6 @@ import java.util.List;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class GetTask extends FetchTask<String> {
|
||||
@ -95,4 +97,11 @@ public final class GetTask extends FetchTask<String> {
|
||||
};
|
||||
}
|
||||
|
||||
public <T> Task<T> thenGetJsonAsync(Class<T> type) {
|
||||
return thenGetJsonAsync(TypeToken.get(type));
|
||||
}
|
||||
|
||||
public <T> Task<T> thenGetJsonAsync(TypeToken<T> type) {
|
||||
return thenApplyAsync(jsonString -> JsonUtils.fromNonNullJson(jsonString, type));
|
||||
}
|
||||
}
|
||||
|
@ -917,7 +917,8 @@ public abstract class Task<T> {
|
||||
* @param tasks the Tasks
|
||||
* @return a new Task that is completed when all of the given Tasks complete
|
||||
*/
|
||||
public static Task<List<Object>> allOf(Task<?>... tasks) {
|
||||
@SafeVarargs
|
||||
public static <T> Task<List<T>> allOf(Task<? extends T>... tasks) {
|
||||
return allOf(Arrays.asList(tasks));
|
||||
}
|
||||
|
||||
@ -932,8 +933,8 @@ public abstract class Task<T> {
|
||||
* @param tasks the Tasks
|
||||
* @return a new Task that is completed when all of the given Tasks complete
|
||||
*/
|
||||
public static Task<List<Object>> allOf(Collection<Task<?>> tasks) {
|
||||
return new Task<List<Object>>() {
|
||||
public static <T> Task<List<T>> allOf(Collection<? extends Task<? extends T>> tasks) {
|
||||
return new Task<>() {
|
||||
{
|
||||
setSignificance(TaskSignificance.MINOR);
|
||||
}
|
||||
@ -944,7 +945,7 @@ public abstract class Task<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task<?>> getDependents() {
|
||||
public Collection<? extends Task<?>> getDependents() {
|
||||
return tasks;
|
||||
}
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
@ -68,6 +69,10 @@ public final class NetworkUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static List<URI> withQuery(List<URI> list, Map<String, String> params) {
|
||||
return list.stream().map(uri -> URI.create(withQuery(uri.toString(), params))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<Pair<String, String>> parseQuery(URI uri) {
|
||||
return parseQuery(uri.getRawQuery());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user