Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ public Optional<RemoteMod.Version> getRemoteVersionByLocalFile(LocalModFile loca
}

@Override
public RemoteMod getModById(String id) throws IOException {
return getBackedRemoteModRepository().getModById(id);
public RemoteMod getModById(DownloadProvider downloadProvider, String id) throws IOException {
return getBackedRemoteModRepository().getModById(downloadProvider, id);
}

@Override
Expand All @@ -125,7 +125,7 @@ public RemoteMod.File getModFile(String modId, String fileId) throws IOException
}

@Override
public Stream<RemoteMod.Version> getRemoteVersionsById(String id) throws IOException {
return getBackedRemoteModRepository().getRemoteVersionsById(id);
public Stream<RemoteMod.Version> getRemoteVersionsById(DownloadProvider downloadProvider, String id) throws IOException {
return getBackedRemoteModRepository().getRemoteVersionsById(downloadProvider, id);
}
}
2 changes: 1 addition & 1 deletion HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,7 @@ public static Task<Image> getRemoteImageTask(String url, int requestedWidth, int
.setSignificance(Task.TaskSignificance.MINOR);
}

public static Task<Image> getRemoteImageTask(URI uri, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
public static Task<Image> getRemoteImageTask(List<URI> uri, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
return new CacheFileTask(uri)
Comment on lines +1244 to 1245
.setSignificance(Task.TaskSignificance.MINOR)
.thenApplyAsync(file -> loadImage(file, requestedWidth, requestedHeight, preserveRatio, smooth))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public DownloadPage(String uploadVersion) {
newGameTab.setNodeSupplier(loadVersionFor(() -> new VersionsPage(versionPageNavigator, i18n("install.installer.choose", i18n("install.installer.game")), "", DownloadProviders.getDownloadProvider(),
"game", versionPageNavigator::onGameSelected)));
modpackTab.setNodeSupplier(loadVersionFor(() -> {
DownloadListPage page = HMCLLocalizedDownloadListPage.ofModPack((profile, __, mod, file) -> {
Versions.downloadModpackImpl(profile, uploadVersion, mod, file);
DownloadListPage page = HMCLLocalizedDownloadListPage.ofModPack((downloadProvider, profile, __, mod, file) -> {
Versions.downloadModpackImpl(downloadProvider, profile, uploadVersion, mod, file);
}, false);

JFXButton installLocalModpackButton = FXUtils.newRaisedButton(i18n("install.modpack"));
Expand All @@ -94,9 +94,9 @@ public DownloadPage(String uploadVersion) {
page.getActions().add(installLocalModpackButton);
return page;
}));
modTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofMod((profile, version, mod, file) -> download(profile, version, file, "mods"), true)));
resourcePackTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofResourcePack((profile, version, mod, file) -> download(profile, version, file, "resourcepacks"), true)));
shaderTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofShaderPack((profile, version, mod, file) -> download(profile, version, file, "shaderpacks"), true)));
modTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofMod((downloadProvider, profile, version, mod, file) -> download(downloadProvider, profile, version, file, "mods"), true)));
resourcePackTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofResourcePack((downloadProvider, profile, version, mod, file) -> download(downloadProvider, profile, version, file, "resourcepacks"), true)));
shaderTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofShaderPack((downloadProvider, profile, version, mod, file) -> download(downloadProvider, profile, version, file, "shaderpacks"), true)));
worldTab.setNodeSupplier(loadVersionFor(() -> new DownloadListPage(CurseForgeRemoteModRepository.WORLDS)));
tab = new TabHeader(transitionPane, newGameTab, modpackTab, modTab, resourcePackTab, shaderTab, worldTab);

Expand Down Expand Up @@ -129,7 +129,7 @@ private static <T extends Node> Supplier<T> loadVersionFor(Supplier<T> nodeSuppl
};
}

public static void download(Profile profile, @Nullable String version, RemoteMod.Version file, String subdirectoryName) {
public static void download(DownloadProvider downloadProvider, Profile profile, @Nullable String version, RemoteMod.Version file, String subdirectoryName) {
if (version == null) version = profile.getSelectedVersion();

Path runDirectory = profile.getRepository().hasVersion(version) ? profile.getRepository().getRunDirectory(version) : profile.getRepository().getBaseDirectory();
Expand All @@ -138,7 +138,7 @@ public static void download(Profile profile, @Nullable String version, RemoteMod
Path dest = runDirectory.resolve(subdirectoryName).resolve(result);

Controllers.taskDialog(Task.composeAsync(() -> {
var task = new FileDownloadTask(file.getFile().getUrl(), dest);
var task = new FileDownloadTask(downloadProvider.injectURLWithCandidates(file.getFile().getUrl()), dest);
task.setName(file.getName());
return task;
}).whenComplete(Schedulers.javafx(), exception -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public DownloadListPage(RemoteModRepository repository, DownloadPage.DownloadCal
this.downloadProvider = DownloadProviders.getDownloadProvider();
}

public DownloadProvider getDownloadProvider() {
return downloadProvider;
}

public ObservableList<Node> getActions() {
return actions;
}
Expand Down Expand Up @@ -233,18 +237,20 @@ protected Skin<?> createDefaultSkin() {

private static class ModDownloadListPageSkin extends SkinBase<DownloadListPage> {
private final JFXListView<RemoteMod> listView = new JFXListView<>();
private final RemoteImageLoader iconLoader = new RemoteImageLoader() {
@Override
protected @NotNull Task<Image> createLoadTask(@NotNull URI uri) {
return FXUtils.getRemoteImageTask(uri, 80, 80, true, true);
}
};
private final RemoteImageLoader iconLoader;

protected ModDownloadListPageSkin(DownloadListPage control) {
super(control);

listView.getStyleClass().add("no-horizontal-scrollbar");

iconLoader = new RemoteImageLoader(control.downloadProvider) {
@Override
protected @NotNull Task<Image> createLoadTask(@NotNull List<URI> uris) {
return FXUtils.getRemoteImageTask(uris, 80, 80, true, true);
}
};

BorderPane pane = new BorderPane();

GridPane searchPane = new GridPane();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.game.Version;
Expand Down Expand Up @@ -112,7 +113,7 @@ private void loadModVersions() {
setFailed(false);

Task.supplyAsync(() -> {
Stream<RemoteMod.Version> versions = addon.getData().loadVersions(repository);
Stream<RemoteMod.Version> versions = addon.getData().loadVersions(repository, page.getDownloadProvider());
return sortVersions(versions);
}).whenComplete(Schedulers.javafx(), (result, exception) -> {
if (exception == null) {
Expand Down Expand Up @@ -179,7 +180,7 @@ public void download(RemoteMod mod, RemoteMod.Version file) {
if (this.callback == null) {
saveAs(mod, file);
} else {
this.callback.download(version.getProfile(), version.getVersion(), mod, file);
this.callback.download(page.getDownloadProvider(), version.getProfile(), version.getVersion(), mod, file);
}
}

Expand Down Expand Up @@ -548,7 +549,7 @@ private void loadDependencies(RemoteMod.Version version, DownloadPage selfPage,
dependencies.put(dependency.getType(), list);
}

queue.add(Task.supplyAsync(Schedulers.io(), dependency::load)
queue.add(Task.supplyAsync(Schedulers.io(), () -> dependency.load(selfPage.page.getDownloadProvider()))
.setSignificance(Task.TaskSignificance.MINOR)
.thenAcceptAsync(Schedulers.javafx(), dep -> {
if (dep == RemoteMod.BROKEN) {
Expand Down Expand Up @@ -576,7 +577,8 @@ private void loadDependencies(RemoteMod.Version version, DownloadPage selfPage,
}
}

@FunctionalInterface
public interface DownloadCallback {
void download(Profile profile, @Nullable String version, RemoteMod mod, RemoteMod.Version file);
void download(DownloadProvider downloadProvider, Profile profile, @Nullable String version, RemoteMod mod, RemoteMod.Version file);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.ui.versions;

import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.mod.LocalModFile;
import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.task.Schedulers;
Expand All @@ -30,16 +31,18 @@
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

public class ModCheckUpdatesTask extends Task<List<LocalModFile.ModUpdate>> {
private final DownloadProvider downloadProvider;
private final List<Task<LocalModFile.ModUpdate>> dependents;

public ModCheckUpdatesTask(String gameVersion, Collection<LocalModFile> mods) {
public ModCheckUpdatesTask(DownloadProvider downloadProvider, String gameVersion, Collection<LocalModFile> mods) {
this.downloadProvider = downloadProvider;
dependents = mods.stream().map(mod ->
Task.supplyAsync(Schedulers.io(), () -> {
LocalModFile.ModUpdate candidate = null;
for (RemoteMod.Type type : RemoteMod.Type.values()) {
LocalModFile.ModUpdate update = null;
try {
update = mod.checkUpdates(gameVersion, type.getRemoteModRepository());
update = mod.checkUpdates(downloadProvider, gameVersion, type.getRemoteModRepository());
} catch (IOException e) {
LOG.warning(String.format("Cannot check update for mod %s.", mod.getFileName()), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.jackhuang.hmcl.mod.LocalModFile;
import org.jackhuang.hmcl.mod.ModLoaderType;
import org.jackhuang.hmcl.mod.ModManager;
import org.jackhuang.hmcl.setting.DownloadProviders;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
Expand Down Expand Up @@ -240,7 +241,7 @@ public void checkUpdates(Collection<LocalModFile> mods) {
.composeAsync(() -> {
Optional<String> gameVersion = profile.getRepository().getGameVersion(instanceId);
if (gameVersion.isPresent()) {
return new ModCheckUpdatesTask(gameVersion.get(), mods);
return new ModCheckUpdatesTask(DownloadProviders.getDownloadProvider(), gameVersion.get(), mods);
}
return null;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.jackhuang.hmcl.mod.RemoteModRepository;
import org.jackhuang.hmcl.mod.curse.CurseForgeRemoteModRepository;
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
import org.jackhuang.hmcl.setting.DownloadProviders;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.VersionIconType;
import org.jackhuang.hmcl.task.Schedulers;
Expand Down Expand Up @@ -465,7 +466,7 @@ final class ModInfoDialog extends JFXDialogLayout {
Task.runAsync(() -> {
Optional<RemoteMod.Version> versionOptional = repository.getRemoteVersionByLocalFile(modInfo.getModInfo(), modInfo.getModInfo().getFile());
if (versionOptional.isPresent()) {
RemoteMod remoteMod = repository.getModById(versionOptional.get().getModid());
RemoteMod remoteMod = repository.getModById(DownloadProviders.getDownloadProvider(), versionOptional.get().getModid());
FXUtils.runInFX(() -> {
for (ModLoaderType modLoaderType : versionOptional.get().getLoaders()) {
String loaderName = switch (modLoaderType) {
Expand Down Expand Up @@ -493,7 +494,7 @@ final class ModInfoDialog extends JFXDialogLayout {
repository instanceof CurseForgeRemoteModRepository ? HMCLLocalizedDownloadListPage.ofCurseForgeMod(null, false) : HMCLLocalizedDownloadListPage.ofModrinthMod(null, false),
remoteMod,
new Profile.ProfileVersion(ModListPageSkin.this.getSkinnable().getProfile(), ModListPageSkin.this.getSkinnable().getInstanceId()),
(profile, version, mod, file) -> org.jackhuang.hmcl.ui.download.DownloadPage.download(profile, version, file, "mods")
(downloadProvider, profile, version, mod, file) -> org.jackhuang.hmcl.ui.download.DownloadPage.download(downloadProvider, profile, version, file, "mods")
));
});
button.setDisable(false);
Expand Down
11 changes: 6 additions & 5 deletions HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.game.GameAssetDownloadTask;
import org.jackhuang.hmcl.game.*;
import org.jackhuang.hmcl.mod.RemoteMod;
Expand All @@ -42,13 +43,13 @@
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.TaskCancellationAction;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jackhuang.hmcl.util.platform.OperatingSystem;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
Expand All @@ -72,11 +73,11 @@ public static void importModpack() {
}
}

public static void downloadModpackImpl(Profile profile, String version, RemoteMod mod, RemoteMod.Version file) {
public static void downloadModpackImpl(DownloadProvider downloadProvider, Profile profile, String version, RemoteMod mod, RemoteMod.Version file) {
Path modpack;
URI downloadURL;
List<URI> downloadURLs;
try {
downloadURL = NetworkUtils.toURI(file.getFile().getUrl());
downloadURLs = downloadProvider.injectURLWithCandidates(file.getFile().getUrl());
modpack = Files.createTempFile("modpack", ".zip");
} catch (IOException | IllegalArgumentException e) {
Controllers.dialog(
Expand All @@ -85,7 +86,7 @@ public static void downloadModpackImpl(Profile profile, String version, RemoteMo
return;
}
Controllers.taskDialog(
new FileDownloadTask(downloadURL, modpack)
new FileDownloadTask(downloadURLs, modpack)
.whenComplete(Schedulers.javafx(), e -> {
if (e == null) {
ModpackInstallWizardProvider installWizardProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import javafx.beans.value.WritableValue;
import javafx.scene.image.Image;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.io.NetworkUtils;
Expand All @@ -33,18 +34,20 @@

/// @author Glavo
public abstract class RemoteImageLoader {
private final DownloadProvider downloadProvider;
private final Map<URI, WeakReference<Image>> cache = new HashMap<>();
private final Map<URI, List<WeakReference<WritableValue<Image>>>> pendingRequests = new HashMap<>();
private final WeakHashMap<WritableValue<Image>, URI> reverseLookup = new WeakHashMap<>();

public RemoteImageLoader() {
public RemoteImageLoader(DownloadProvider downloadProvider) {
this.downloadProvider = downloadProvider;
}

protected @Nullable Image getPlaceholder() {
return null;
}

protected abstract @NotNull Task<Image> createLoadTask(@NotNull URI uri);
protected abstract @NotNull Task<Image> createLoadTask(@NotNull List<URI> uris);

@FXThread
public void load(@NotNull WritableValue<Image> writableValue, String url) {
Expand Down Expand Up @@ -82,7 +85,7 @@ public void load(@NotNull WritableValue<Image> writableValue, String url) {
}
}

createLoadTask(uri).whenComplete(Schedulers.javafx(), (result, exception) -> {
createLoadTask(downloadProvider.injectURLWithCandidates(url)).whenComplete(Schedulers.javafx(), (result, exception) -> {
Image image;
if (exception == null) {
image = result;
Expand Down
Loading
Loading