add: support change download provider in install wizard
This commit is contained in:
@@ -17,19 +17,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.setting;
|
package org.jackhuang.hmcl.setting;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import org.jackhuang.hmcl.download.AdaptedDownloadProvider;
|
||||||
import javafx.beans.binding.ObjectBinding;
|
|
||||||
import javafx.beans.value.ObservableObjectValue;
|
|
||||||
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
import org.jackhuang.hmcl.download.MojangDownloadProvider;
|
import org.jackhuang.hmcl.download.MojangDownloadProvider;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -40,6 +35,8 @@ import static org.jackhuang.hmcl.util.Pair.pair;
|
|||||||
public final class DownloadProviders {
|
public final class DownloadProviders {
|
||||||
private DownloadProviders() {}
|
private DownloadProviders() {}
|
||||||
|
|
||||||
|
private static final AdaptedDownloadProvider DOWNLOAD_PROVIDER = new AdaptedDownloadProvider();
|
||||||
|
|
||||||
public static final Map<String, DownloadProvider> providersById = mapOf(
|
public static final Map<String, DownloadProvider> providersById = mapOf(
|
||||||
pair("mojang", new MojangDownloadProvider()),
|
pair("mojang", new MojangDownloadProvider()),
|
||||||
pair("bmclapi", new BMCLAPIDownloadProvider("https://bmclapi2.bangbang93.com")),
|
pair("bmclapi", new BMCLAPIDownloadProvider("https://bmclapi2.bangbang93.com")),
|
||||||
@@ -47,32 +44,44 @@ public final class DownloadProviders {
|
|||||||
|
|
||||||
public static final String DEFAULT_PROVIDER_ID = "mcbbs";
|
public static final String DEFAULT_PROVIDER_ID = "mcbbs";
|
||||||
|
|
||||||
private static ObjectBinding<DownloadProvider> downloadProviderProperty;
|
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
downloadProviderProperty = Bindings.createObjectBinding(
|
FXUtils.onChangeAndOperate(config().downloadTypeProperty(), downloadType -> {
|
||||||
() -> Optional.ofNullable(providersById.get(config().getDownloadType()))
|
DownloadProvider primary = Optional.ofNullable(providersById.get(config().getDownloadType()))
|
||||||
.orElse(providersById.get(DEFAULT_PROVIDER_ID)),
|
.orElse(providersById.get(DEFAULT_PROVIDER_ID));
|
||||||
config().downloadTypeProperty());
|
DOWNLOAD_PROVIDER.setDownloadProviderCandidates(
|
||||||
|
Stream.concat(
|
||||||
|
Stream.of(primary),
|
||||||
|
providersById.values().stream().filter(x -> x != primary)
|
||||||
|
).collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPrimaryDownloadProviderId() {
|
||||||
|
String downloadType = config().getDownloadType();
|
||||||
|
if (providersById.containsKey(downloadType))
|
||||||
|
return downloadType;
|
||||||
|
else
|
||||||
|
return DEFAULT_PROVIDER_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AdaptedDownloadProvider getDownloadProviderByPrimaryId(String primaryId) {
|
||||||
|
AdaptedDownloadProvider adaptedDownloadProvider = new AdaptedDownloadProvider();
|
||||||
|
DownloadProvider primary = Optional.ofNullable(providersById.get(primaryId))
|
||||||
|
.orElse(providersById.get(DEFAULT_PROVIDER_ID));
|
||||||
|
adaptedDownloadProvider.setDownloadProviderCandidates(
|
||||||
|
Stream.concat(
|
||||||
|
Stream.of(primary),
|
||||||
|
providersById.values().stream().filter(x -> x != primary)
|
||||||
|
).collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
return adaptedDownloadProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current primary preferred download provider
|
* Get current primary preferred download provider
|
||||||
*/
|
*/
|
||||||
public static DownloadProvider getDownloadProvider() {
|
public static AdaptedDownloadProvider getDownloadProvider() {
|
||||||
return downloadProviderProperty.get();
|
return DOWNLOAD_PROVIDER;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preferred download providers have the primary one first, the official one next.
|
|
||||||
* @return the preferred download providers
|
|
||||||
*/
|
|
||||||
public static List<DownloadProvider> getPreferredDownloadProviders() {
|
|
||||||
DownloadProvider provider = getDownloadProvider();
|
|
||||||
return Stream.concat(Stream.of(provider), providersById.values().stream().filter(x -> x != provider)).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ObservableObjectValue<DownloadProvider> downloadProviderProperty() {
|
|
||||||
return downloadProviderProperty;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.VersionList;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InstallerWizardDownloadProvider implements DownloadProvider {
|
||||||
|
|
||||||
|
private DownloadProvider fallback;
|
||||||
|
|
||||||
|
public InstallerWizardDownloadProvider(DownloadProvider fallback) {
|
||||||
|
this.fallback = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadProvider(DownloadProvider downloadProvider) {
|
||||||
|
fallback = downloadProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersionListURL() {
|
||||||
|
return fallback.getVersionListURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAssetBaseURL() {
|
||||||
|
return fallback.getAssetBaseURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URL> getAssetObjectCandidates(String assetObjectLocation) {
|
||||||
|
return fallback.injectURLWithCandidates(assetObjectLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String injectURL(String baseURL) {
|
||||||
|
return fallback.injectURL(baseURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URL> injectURLWithCandidates(String baseURL) {
|
||||||
|
return fallback.injectURLWithCandidates(baseURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionList<?> getVersionListById(String id) {
|
||||||
|
return fallback.getVersionListById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConcurrency() {
|
||||||
|
return fallback.getConcurrency();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,6 @@ import javafx.scene.input.MouseEvent;
|
|||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
@@ -64,7 +63,7 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
protected JFXTextField txtName = new JFXTextField();
|
protected JFXTextField txtName = new JFXTextField();
|
||||||
protected BooleanProperty installable = new SimpleBooleanProperty();
|
protected BooleanProperty installable = new SimpleBooleanProperty();
|
||||||
|
|
||||||
public InstallersPage(WizardController controller, GameRepository repository, String gameVersion, DownloadProvider downloadProvider) {
|
public InstallersPage(WizardController controller, GameRepository repository, String gameVersion, InstallerWizardDownloadProvider downloadProvider) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
|
|
||||||
Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s));
|
Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s));
|
||||||
|
|||||||
@@ -18,12 +18,16 @@
|
|||||||
package org.jackhuang.hmcl.ui.download;
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.jackhuang.hmcl.download.*;
|
import org.jackhuang.hmcl.download.ArtifactMalformedException;
|
||||||
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.download.VersionMismatchException;
|
||||||
import org.jackhuang.hmcl.download.fabric.FabricInstallTask;
|
import org.jackhuang.hmcl.download.fabric.FabricInstallTask;
|
||||||
import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask;
|
import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask;
|
||||||
import org.jackhuang.hmcl.download.game.LibraryDownloadException;
|
import org.jackhuang.hmcl.download.game.LibraryDownloadException;
|
||||||
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.DownloadException;
|
import org.jackhuang.hmcl.task.DownloadException;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -53,14 +57,16 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
|||||||
private final Version version;
|
private final Version version;
|
||||||
private final String libraryId;
|
private final String libraryId;
|
||||||
private final String oldLibraryVersion;
|
private final String oldLibraryVersion;
|
||||||
|
private final InstallerWizardDownloadProvider downloadProvider;
|
||||||
|
|
||||||
public UpdateInstallerWizardProvider(@NotNull Profile profile, @NotNull String gameVersion, @NotNull Version version, @NotNull String libraryId, @Nullable String oldLibraryVersion) {
|
public UpdateInstallerWizardProvider(@NotNull Profile profile, @NotNull String gameVersion, @NotNull Version version, @NotNull String libraryId, @Nullable String oldLibraryVersion) {
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.dependencyManager = profile.getDependency();
|
|
||||||
this.gameVersion = gameVersion;
|
this.gameVersion = gameVersion;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.libraryId = libraryId;
|
this.libraryId = libraryId;
|
||||||
this.oldLibraryVersion = oldLibraryVersion;
|
this.oldLibraryVersion = oldLibraryVersion;
|
||||||
|
this.downloadProvider = new InstallerWizardDownloadProvider(DownloadProviders.getDownloadProvider());
|
||||||
|
this.dependencyManager = profile.getDependency(downloadProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -95,15 +101,14 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||||
DownloadProvider provider = profile.getDependency().getPrimaryDownloadProvider();
|
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 0:
|
case 0:
|
||||||
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, provider, libraryId, () -> {
|
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> {
|
||||||
if (oldLibraryVersion == null) {
|
if (oldLibraryVersion == null) {
|
||||||
controller.onFinish();
|
controller.onFinish();
|
||||||
} else if ("game".equals(libraryId)) {
|
} else if ("game".equals(libraryId)) {
|
||||||
String newGameVersion = ((RemoteVersion) settings.get(libraryId)).getSelfVersion();
|
String newGameVersion = ((RemoteVersion) settings.get(libraryId)).getSelfVersion();
|
||||||
controller.onNext(new AdditionalInstallersPage(newGameVersion, version, controller, profile.getRepository(), provider));
|
controller.onNext(new AdditionalInstallersPage(newGameVersion, version, controller, profile.getRepository(), downloadProvider));
|
||||||
} else {
|
} else {
|
||||||
Controllers.confirm(i18n("install.change_version.confirm", i18n("install.installer." + libraryId), oldLibraryVersion, ((RemoteVersion) settings.get(libraryId)).getSelfVersion()),
|
Controllers.confirm(i18n("install.change_version.confirm", i18n("install.installer." + libraryId), oldLibraryVersion, ((RemoteVersion) settings.get(libraryId)).getSelfVersion()),
|
||||||
i18n("install.change_version"), controller::onFinish, controller::onCancel);
|
i18n("install.change_version"), controller::onFinish, controller::onCancel);
|
||||||
|
|||||||
@@ -18,9 +18,10 @@
|
|||||||
package org.jackhuang.hmcl.ui.download;
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.GameBuilder;
|
import org.jackhuang.hmcl.download.GameBuilder;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -33,9 +34,13 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|||||||
|
|
||||||
public final class VanillaInstallWizardProvider implements WizardProvider {
|
public final class VanillaInstallWizardProvider implements WizardProvider {
|
||||||
private final Profile profile;
|
private final Profile profile;
|
||||||
|
private final DefaultDependencyManager dependencyManager;
|
||||||
|
private final InstallerWizardDownloadProvider downloadProvider;
|
||||||
|
|
||||||
public VanillaInstallWizardProvider(Profile profile) {
|
public VanillaInstallWizardProvider(Profile profile) {
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
|
this.downloadProvider = new InstallerWizardDownloadProvider(DownloadProviders.getDownloadProvider());
|
||||||
|
this.dependencyManager = profile.getDependency(downloadProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,7 +49,7 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Task<Void> finishVersionDownloadingAsync(Map<String, Object> settings) {
|
private Task<Void> finishVersionDownloadingAsync(Map<String, Object> settings) {
|
||||||
GameBuilder builder = profile.getDependency().gameBuilder();
|
GameBuilder builder = dependencyManager.gameBuilder();
|
||||||
|
|
||||||
String name = (String) settings.get("name");
|
String name = (String) settings.get("name");
|
||||||
builder.name(name);
|
builder.name(name);
|
||||||
@@ -69,11 +74,10 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||||
DownloadProvider provider = profile.getDependency().getPrimaryDownloadProvider();
|
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 0:
|
case 0:
|
||||||
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer.game")), "", provider, "game",
|
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer.game")), "", downloadProvider, "game",
|
||||||
() -> controller.onNext(new InstallersPage(controller, profile.getRepository(), ((RemoteVersion) controller.getSettings().get("game")).getGameVersion(), provider)));
|
() -> controller.onNext(new InstallersPage(controller, profile.getRepository(), ((RemoteVersion) controller.getSettings().get("game")).getGameVersion(), downloadProvider)));
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("error step " + step + ", settings: " + settings + ", pages: " + controller.getPages());
|
throw new IllegalStateException("error step " + step + ", settings: " + settings + ", pages: " + controller.getPages());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.ui.download;
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXCheckBox;
|
import com.jfoenix.controls.JFXCheckBox;
|
||||||
|
import com.jfoenix.controls.JFXComboBox;
|
||||||
import com.jfoenix.controls.JFXListView;
|
import com.jfoenix.controls.JFXListView;
|
||||||
import com.jfoenix.controls.JFXSpinner;
|
import com.jfoenix.controls.JFXSpinner;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@@ -31,7 +32,6 @@ import javafx.scene.layout.BorderPane;
|
|||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.VersionList;
|
import org.jackhuang.hmcl.download.VersionList;
|
||||||
import org.jackhuang.hmcl.download.fabric.FabricRemoteVersion;
|
import org.jackhuang.hmcl.download.fabric.FabricRemoteVersion;
|
||||||
@@ -39,6 +39,7 @@ import org.jackhuang.hmcl.download.forge.ForgeRemoteVersion;
|
|||||||
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
import org.jackhuang.hmcl.download.game.GameRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion;
|
import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion;
|
import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||||
@@ -54,6 +55,7 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
@@ -83,23 +85,34 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
|||||||
private HBox checkPane;
|
private HBox checkPane;
|
||||||
@FXML
|
@FXML
|
||||||
private VBox centrePane;
|
private VBox centrePane;
|
||||||
|
@FXML
|
||||||
|
private JFXComboBox<String> downloadSourceComboBox;
|
||||||
|
|
||||||
private final VersionList<?> versionList;
|
private VersionList<?> versionList;
|
||||||
private TaskExecutor executor;
|
private TaskExecutor executor;
|
||||||
|
|
||||||
public VersionsPage(WizardController controller, String title, String gameVersion, DownloadProvider downloadProvider, String libraryId, Runnable callback) {
|
public VersionsPage(WizardController controller, String title, String gameVersion, InstallerWizardDownloadProvider downloadProvider, String libraryId, Runnable callback) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.gameVersion = gameVersion;
|
this.gameVersion = gameVersion;
|
||||||
this.libraryId = libraryId;
|
this.libraryId = libraryId;
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.versionList = downloadProvider.getVersionListById(libraryId);
|
|
||||||
|
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/download/versions.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/download/versions.fxml");
|
||||||
|
|
||||||
if (versionList.hasType()) {
|
downloadSourceComboBox.getItems().setAll(DownloadProviders.providersById.keySet());
|
||||||
centrePane.getChildren().setAll(checkPane, list);
|
downloadSourceComboBox.setConverter(stringConverter(key -> i18n("download.provider." + key)));
|
||||||
} else
|
downloadSourceComboBox.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
|
||||||
centrePane.getChildren().setAll(list);
|
controller.getSettings().put("downloadProvider", newValue);
|
||||||
|
downloadProvider.setDownloadProvider(DownloadProviders.getDownloadProviderByPrimaryId(newValue));
|
||||||
|
versionList = downloadProvider.getVersionListById(libraryId);
|
||||||
|
if (versionList.hasType()) {
|
||||||
|
centrePane.getChildren().setAll(checkPane, list);
|
||||||
|
} else {
|
||||||
|
centrePane.getChildren().setAll(list);
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
downloadSourceComboBox.getSelectionModel().select((String)controller.getSettings().getOrDefault("downloadProvider", DownloadProviders.getPrimaryDownloadProviderId()));
|
||||||
|
|
||||||
InvalidationListener listener = o -> list.getItems().setAll(loadVersions());
|
InvalidationListener listener = o -> list.getItems().setAll(loadVersions());
|
||||||
chkRelease.selectedProperty().addListener(listener);
|
chkRelease.selectedProperty().addListener(listener);
|
||||||
@@ -184,13 +197,15 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
|
VersionList<?> currentVersionList = versionList;
|
||||||
root.setContent(spinner, ContainerAnimations.FADE.getAnimationProducer());
|
root.setContent(spinner, ContainerAnimations.FADE.getAnimationProducer());
|
||||||
executor = versionList.refreshAsync(gameVersion).whenComplete(exception -> {
|
executor = currentVersionList.refreshAsync(gameVersion).whenComplete(exception -> {
|
||||||
if (exception == null) {
|
if (exception == null) {
|
||||||
List<RemoteVersion> items = loadVersions();
|
List<RemoteVersion> items = loadVersions();
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if (versionList.getVersions(gameVersion).isEmpty()) {
|
if (versionList != currentVersionList) return;
|
||||||
|
if (currentVersionList.getVersions(gameVersion).isEmpty()) {
|
||||||
root.setContent(emptyPane, ContainerAnimations.FADE.getAnimationProducer());
|
root.setContent(emptyPane, ContainerAnimations.FADE.getAnimationProducer());
|
||||||
} else {
|
} else {
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
@@ -206,6 +221,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
|||||||
} else {
|
} else {
|
||||||
LOG.log(Level.WARNING, "Failed to fetch versions list", exception);
|
LOG.log(Level.WARNING, "Failed to fetch versions list", exception);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
if (versionList != currentVersionList) return;
|
||||||
root.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
|
root.setContent(failedPane, ContainerAnimations.FADE.getAnimationProducer());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import org.jackhuang.hmcl.setting.*;
|
|||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||||
import org.jackhuang.hmcl.ui.construct.Navigator;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||||
import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
||||||
@@ -63,7 +62,7 @@ import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
|||||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.reservedSelectedPropertyFor;
|
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.reversedSelectedPropertyFor;
|
||||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
|
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
|
||||||
|
|
||||||
public final class SettingsPage extends SettingsView implements DecoratorPage {
|
public final class SettingsPage extends SettingsView implements DecoratorPage {
|
||||||
@@ -111,7 +110,7 @@ public final class SettingsPage extends SettingsView implements DecoratorPage {
|
|||||||
proxyPane.disableProperty().bind(chkDisableProxy.selectedProperty());
|
proxyPane.disableProperty().bind(chkDisableProxy.selectedProperty());
|
||||||
authPane.disableProperty().bind(chkProxyAuthentication.selectedProperty().not());
|
authPane.disableProperty().bind(chkProxyAuthentication.selectedProperty().not());
|
||||||
|
|
||||||
reservedSelectedPropertyFor(chkDisableProxy).bindBidirectional(config().hasProxyProperty());
|
reversedSelectedPropertyFor(chkDisableProxy).bindBidirectional(config().hasProxyProperty());
|
||||||
chkProxyAuthentication.selectedProperty().bindBidirectional(config().hasProxyAuthProperty());
|
chkProxyAuthentication.selectedProperty().bindBidirectional(config().hasProxyAuthProperty());
|
||||||
|
|
||||||
ToggleGroup proxyConfigurationGroup = new ToggleGroup();
|
ToggleGroup proxyConfigurationGroup = new ToggleGroup();
|
||||||
|
|||||||
@@ -9,9 +9,20 @@
|
|||||||
type="BorderPane"
|
type="BorderPane"
|
||||||
prefHeight="400.0" prefWidth="600.0">
|
prefHeight="400.0" prefWidth="600.0">
|
||||||
<top>
|
<top>
|
||||||
<StackPane styleClass="sponsor-pane" onMouseClicked="#onSponsor">
|
<VBox>
|
||||||
<Label text="%sponsor.bmclapi" />
|
<StackPane styleClass="sponsor-pane" onMouseClicked="#onSponsor">
|
||||||
</StackPane>
|
<Label text="%sponsor.bmclapi" />
|
||||||
|
</StackPane>
|
||||||
|
<BorderPane style="-fx-padding: 0 16 16 16;">
|
||||||
|
<left>
|
||||||
|
<Label text="%settings.launcher.download_source" BorderPane.alignment="CENTER_LEFT" />
|
||||||
|
</left>
|
||||||
|
<right>
|
||||||
|
<JFXComboBox fx:id="downloadSourceComboBox">
|
||||||
|
</JFXComboBox>
|
||||||
|
</right>
|
||||||
|
</BorderPane>
|
||||||
|
</VBox>
|
||||||
</top>
|
</top>
|
||||||
<center>
|
<center>
|
||||||
<TransitionPane fx:id="root">
|
<TransitionPane fx:id="root">
|
||||||
|
|||||||
@@ -17,23 +17,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.download;
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDependencyManager implements DependencyManager {
|
public abstract class AbstractDependencyManager implements DependencyManager {
|
||||||
|
|
||||||
public abstract DownloadProvider getPrimaryDownloadProvider();
|
public abstract DownloadProvider getDownloadProvider();
|
||||||
|
|
||||||
public abstract List<DownloadProvider> getPreferredDownloadProviders();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract DefaultCacheRepository getCacheRepository();
|
public abstract DefaultCacheRepository getCacheRepository();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionList<?> getVersionList(String id) {
|
public VersionList<?> getVersionList(String id) {
|
||||||
return getPrimaryDownloadProvider().getVersionListById(id);
|
return getDownloadProvider().getVersionListById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The download provider that changes the real download source in need.
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
public class AdaptedDownloadProvider implements DownloadProvider {
|
||||||
|
|
||||||
|
private List<DownloadProvider> downloadProviderCandidates;
|
||||||
|
|
||||||
|
public void setDownloadProviderCandidates(List<DownloadProvider> downloadProviderCandidates) {
|
||||||
|
this.downloadProviderCandidates = new ArrayList<>(downloadProviderCandidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadProvider getPreferredDownloadProvider() {
|
||||||
|
List<DownloadProvider> d = downloadProviderCandidates;
|
||||||
|
if (d == null || d.isEmpty()) {
|
||||||
|
throw new IllegalStateException("No download provider candidate");
|
||||||
|
}
|
||||||
|
return d.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersionListURL() {
|
||||||
|
return getPreferredDownloadProvider().getVersionListURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAssetBaseURL() {
|
||||||
|
return getPreferredDownloadProvider().getAssetBaseURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String injectURL(String baseURL) {
|
||||||
|
return getPreferredDownloadProvider().injectURL(baseURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URL> injectURLWithCandidates(String baseURL) {
|
||||||
|
List<DownloadProvider> d = downloadProviderCandidates;
|
||||||
|
List<URL> results = new ArrayList<>(d.size());
|
||||||
|
for (int i = 0; i < d.size(); i++) {
|
||||||
|
results.add(NetworkUtils.toURL(d.get(i).injectURL(baseURL)));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionList<?> getVersionListById(String id) {
|
||||||
|
return getPreferredDownloadProvider().getVersionListById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConcurrency() {
|
||||||
|
return getPreferredDownloadProvider().getConcurrency();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: This class has no state.
|
* Note: This class has no state.
|
||||||
@@ -39,13 +38,11 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
|
|
||||||
private final DefaultGameRepository repository;
|
private final DefaultGameRepository repository;
|
||||||
private final DownloadProvider downloadProvider;
|
private final DownloadProvider downloadProvider;
|
||||||
private final List<DownloadProvider> preferredDownloadProviders;
|
|
||||||
private final DefaultCacheRepository cacheRepository;
|
private final DefaultCacheRepository cacheRepository;
|
||||||
|
|
||||||
public DefaultDependencyManager(DefaultGameRepository repository, DownloadProvider downloadProvider, List<DownloadProvider> preferredDownloadProviders, DefaultCacheRepository cacheRepository) {
|
public DefaultDependencyManager(DefaultGameRepository repository, DownloadProvider downloadProvider, DefaultCacheRepository cacheRepository) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.downloadProvider = downloadProvider;
|
this.downloadProvider = downloadProvider;
|
||||||
this.preferredDownloadProviders = preferredDownloadProviders;
|
|
||||||
this.cacheRepository = cacheRepository;
|
this.cacheRepository = cacheRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,15 +52,10 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DownloadProvider getPrimaryDownloadProvider() {
|
public DownloadProvider getDownloadProvider() {
|
||||||
return downloadProvider;
|
return downloadProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DownloadProvider> getPreferredDownloadProviders() {
|
|
||||||
return preferredDownloadProviders;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultCacheRepository getCacheRepository() {
|
public DefaultCacheRepository getCacheRepository() {
|
||||||
return cacheRepository;
|
return cacheRepository;
|
||||||
|
|||||||
@@ -32,21 +32,15 @@ import java.util.Map;
|
|||||||
public class DefaultGameBuilder extends GameBuilder {
|
public class DefaultGameBuilder extends GameBuilder {
|
||||||
|
|
||||||
private final DefaultDependencyManager dependencyManager;
|
private final DefaultDependencyManager dependencyManager;
|
||||||
private final DownloadProvider downloadProvider;
|
|
||||||
|
|
||||||
public DefaultGameBuilder(DefaultDependencyManager dependencyManager) {
|
public DefaultGameBuilder(DefaultDependencyManager dependencyManager) {
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.downloadProvider = dependencyManager.getPrimaryDownloadProvider();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultDependencyManager getDependencyManager() {
|
public DefaultDependencyManager getDependencyManager() {
|
||||||
return dependencyManager;
|
return dependencyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DownloadProvider getDownloadProvider() {
|
|
||||||
return downloadProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task<?> buildAsync() {
|
public Task<?> buildAsync() {
|
||||||
List<String> stages = new ArrayList<>();
|
List<String> stages = new ArrayList<>();
|
||||||
|
|||||||
@@ -17,6 +17,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.download;
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service provider that provides Minecraft online file downloads.
|
* The service provider that provides Minecraft online file downloads.
|
||||||
*
|
*
|
||||||
@@ -28,6 +35,10 @@ public interface DownloadProvider {
|
|||||||
|
|
||||||
String getAssetBaseURL();
|
String getAssetBaseURL();
|
||||||
|
|
||||||
|
default List<URL> getAssetObjectCandidates(String assetObjectLocation) {
|
||||||
|
return Collections.singletonList(NetworkUtils.toURL(getAssetBaseURL() + assetObjectLocation));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject into original URL provided by Mojang and Forge.
|
* Inject into original URL provided by Mojang and Forge.
|
||||||
*
|
*
|
||||||
@@ -40,9 +51,26 @@ public interface DownloadProvider {
|
|||||||
String injectURL(String baseURL);
|
String injectURL(String baseURL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the specific version list that this download provider provides. i.e. "forge", "liteloader", "game", "optifine"
|
* Inject into original URL provided by Mojang and Forge.
|
||||||
*
|
*
|
||||||
* @param id the id of specific version list that this download provider provides. i.e. "forge", "liteloader", "game", "optifine"
|
* Since there are many provided URLs that are written in JSONs and are unmodifiable,
|
||||||
|
* this method provides a way to change them.
|
||||||
|
*
|
||||||
|
* @param baseURL original URL provided by Mojang and Forge.
|
||||||
|
* @return the URL that is equivalent to [baseURL], but belongs to your own service provider.
|
||||||
|
*/
|
||||||
|
default List<URL> injectURLWithCandidates(String baseURL) {
|
||||||
|
return Collections.singletonList(NetworkUtils.toURL(baseURL));
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<URL> injectURLsWithCandidates(List<String> urls) {
|
||||||
|
return urls.stream().flatMap(url -> injectURLWithCandidates(url).stream()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the specific version list that this download provider provides. i.e. "fabric", "forge", "liteloader", "game", "optifine"
|
||||||
|
*
|
||||||
|
* @param id the id of specific version list that this download provider provides. i.e. "fabric", "forge", "liteloader", "game", "optifine"
|
||||||
* @return the version list
|
* @return the version list
|
||||||
* @throws IllegalArgumentException if the version list does not exist
|
* @throws IllegalArgumentException if the version list does not exist
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
|
|||||||
private final String libraryId;
|
private final String libraryId;
|
||||||
private final String gameVersion;
|
private final String gameVersion;
|
||||||
private final String selfVersion;
|
private final String selfVersion;
|
||||||
private final String[] url;
|
private final List<String> urls;
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,10 +43,10 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
|
|||||||
*
|
*
|
||||||
* @param gameVersion the Minecraft version that this remote version suits.
|
* @param gameVersion the Minecraft version that this remote version suits.
|
||||||
* @param selfVersion the version string of the remote version.
|
* @param selfVersion the version string of the remote version.
|
||||||
* @param url the installer or universal jar URL.
|
* @param urls the installer or universal jar original URL.
|
||||||
*/
|
*/
|
||||||
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, String... url) {
|
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, List<String> urls) {
|
||||||
this(libraryId, gameVersion, selfVersion, Type.UNCATEGORIZED, url);
|
this(libraryId, gameVersion, selfVersion, Type.UNCATEGORIZED, urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,13 +54,13 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
|
|||||||
*
|
*
|
||||||
* @param gameVersion the Minecraft version that this remote version suits.
|
* @param gameVersion the Minecraft version that this remote version suits.
|
||||||
* @param selfVersion the version string of the remote version.
|
* @param selfVersion the version string of the remote version.
|
||||||
* @param url the installer or universal jar URL.
|
* @param urls the installer or universal jar URL.
|
||||||
*/
|
*/
|
||||||
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Type type, String... url) {
|
public RemoteVersion(String libraryId, String gameVersion, String selfVersion, Type type, List<String> urls) {
|
||||||
this.libraryId = Objects.requireNonNull(libraryId);
|
this.libraryId = Objects.requireNonNull(libraryId);
|
||||||
this.gameVersion = Objects.requireNonNull(gameVersion);
|
this.gameVersion = Objects.requireNonNull(gameVersion);
|
||||||
this.selfVersion = Objects.requireNonNull(selfVersion);
|
this.selfVersion = Objects.requireNonNull(selfVersion);
|
||||||
this.url = Objects.requireNonNull(url);
|
this.urls = Objects.requireNonNull(urls);
|
||||||
this.type = Objects.requireNonNull(type);
|
this.type = Objects.requireNonNull(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ public class RemoteVersion implements Comparable<RemoteVersion> {
|
|||||||
return selfVersion;
|
return selfVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getUrl() {
|
public List<String> getUrls() {
|
||||||
return url;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getVersionType() {
|
public Type getVersionType() {
|
||||||
|
|||||||
@@ -28,10 +28,8 @@ import org.jackhuang.hmcl.game.Version;
|
|||||||
import org.jackhuang.hmcl.task.GetTask;
|
import org.jackhuang.hmcl.task.GetTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <b>Note</b>: Fabric should be installed first.
|
* <b>Note</b>: Fabric should be installed first.
|
||||||
@@ -51,9 +49,7 @@ public final class FabricInstallTask extends Task<Version> {
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
this.remote = remoteVersion;
|
this.remote = remoteVersion;
|
||||||
|
|
||||||
launchMetaTask = new GetTask(dependencyManager.getPreferredDownloadProviders().stream()
|
launchMetaTask = new GetTask(dependencyManager.getDownloadProvider().injectURLsWithCandidates(remoteVersion.getUrls()))
|
||||||
.map(downloadProvider -> downloadProvider.injectURL(getLaunchMetaUrl(remote.getGameVersion(), remote.getSelfVersion())))
|
|
||||||
.map(NetworkUtils::toURL).collect(Collectors.toList()))
|
|
||||||
.setCacheRepository(dependencyManager.getCacheRepository());
|
.setCacheRepository(dependencyManager.getCacheRepository());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,10 +86,6 @@ public final class FabricInstallTask extends Task<Version> {
|
|||||||
dependencies.add(dependencyManager.checkLibraryCompletionAsync(getResult(), true));
|
dependencies.add(dependencyManager.checkLibraryCompletionAsync(getResult(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getLaunchMetaUrl(String gameVersion, String loaderVersion) {
|
|
||||||
return String.format("https://meta.fabricmc.net/v2/versions/loader/%s/%s", gameVersion, loaderVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Version getPatch(FabricInfo fabricInfo, String gameVersion, String loaderVersion) {
|
private Version getPatch(FabricInfo fabricInfo, String gameVersion, String loaderVersion) {
|
||||||
JsonObject launcherMeta = fabricInfo.launcherMeta;
|
JsonObject launcherMeta = fabricInfo.launcherMeta;
|
||||||
Arguments arguments = new Arguments();
|
Arguments arguments = new Arguments();
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public final class FabricVersionList extends VersionList<FabricRemoteVersion> {
|
|||||||
public Task<?> refreshAsync() {
|
public Task<?> refreshAsync() {
|
||||||
return new Task<Void>() {
|
return new Task<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws IOException, XMLStreamException {
|
public void execute() throws IOException {
|
||||||
List<String> gameVersions = getGameVersions(GAME_META_URL);
|
List<String> gameVersions = getGameVersions(GAME_META_URL);
|
||||||
List<String> loaderVersions = getGameVersions(LOADER_META_URL);
|
List<String> loaderVersions = getGameVersions(LOADER_META_URL);
|
||||||
|
|
||||||
|
|||||||
@@ -27,15 +27,15 @@ import org.jackhuang.hmcl.task.Task;
|
|||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileSystem;
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
|
import static org.jackhuang.hmcl.util.StringUtils.removePrefix;
|
||||||
import static org.jackhuang.hmcl.util.StringUtils.removeSuffix;
|
import static org.jackhuang.hmcl.util.StringUtils.removeSuffix;
|
||||||
@@ -69,9 +69,7 @@ public final class ForgeInstallTask extends Task<Version> {
|
|||||||
installer = Files.createTempFile("forge-installer", ".jar");
|
installer = Files.createTempFile("forge-installer", ".jar");
|
||||||
|
|
||||||
dependent = new FileDownloadTask(
|
dependent = new FileDownloadTask(
|
||||||
dependencyManager.getPreferredDownloadProviders().stream()
|
dependencyManager.getDownloadProvider().injectURLsWithCandidates(remote.getUrls()),
|
||||||
.flatMap(downloadProvider -> Arrays.stream(remote.getUrl()).map(downloadProvider::injectURL))
|
|
||||||
.map(NetworkUtils::toURL).collect(Collectors.toList()),
|
|
||||||
installer.toFile(), null)
|
installer.toFile(), null)
|
||||||
.setCacheRepository(dependencyManager.getCacheRepository())
|
.setCacheRepository(dependencyManager.getCacheRepository())
|
||||||
.setCaching(true);
|
.setCaching(true);
|
||||||
|
|||||||
@@ -23,15 +23,17 @@ import org.jackhuang.hmcl.download.RemoteVersion;
|
|||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ForgeRemoteVersion extends RemoteVersion {
|
public class ForgeRemoteVersion extends RemoteVersion {
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param gameVersion the Minecraft version that this remote version suits.
|
* @param gameVersion the Minecraft version that this remote version suits.
|
||||||
* @param selfVersion the version string of the remote version.
|
* @param selfVersion the version string of the remote version.
|
||||||
* @param url the installer or universal jar URL.
|
* @param url the installer or universal jar original URL.
|
||||||
*/
|
*/
|
||||||
public ForgeRemoteVersion(String gameVersion, String selfVersion, String... url) {
|
public ForgeRemoteVersion(String gameVersion, String selfVersion, List<String> url) {
|
||||||
super(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), gameVersion, selfVersion, url);
|
super(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), gameVersion, selfVersion, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package org.jackhuang.hmcl.download.game;
|
package org.jackhuang.hmcl.download.game;
|
||||||
|
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
import org.jackhuang.hmcl.download.AbstractDependencyManager;
|
||||||
import org.jackhuang.hmcl.game.AssetIndex;
|
import org.jackhuang.hmcl.game.AssetIndex;
|
||||||
import org.jackhuang.hmcl.game.AssetIndexInfo;
|
import org.jackhuang.hmcl.game.AssetIndexInfo;
|
||||||
@@ -30,7 +29,6 @@ import org.jackhuang.hmcl.util.CacheRepository;
|
|||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -39,7 +37,6 @@ import java.util.Collection;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -112,10 +109,7 @@ public final class GameAssetDownloadTask extends Task<Void> {
|
|||||||
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + file.toPath(), e);
|
Logging.LOG.log(Level.WARNING, "Unable to calc hash value of file " + file.toPath(), e);
|
||||||
}
|
}
|
||||||
if (download) {
|
if (download) {
|
||||||
List<URL> urls = dependencyManager.getPreferredDownloadProviders().stream()
|
List<URL> urls = dependencyManager.getDownloadProvider().getAssetObjectCandidates(assetObject.getLocation());
|
||||||
.map(downloadProvider -> downloadProvider.getAssetBaseURL() + assetObject.getLocation())
|
|
||||||
.map(NetworkUtils::toURL)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
FileDownloadTask task = new FileDownloadTask(urls, file, new FileDownloadTask.IntegrityCheck("SHA-1", assetObject.getHash()));
|
FileDownloadTask task = new FileDownloadTask(urls, file, new FileDownloadTask.IntegrityCheck("SHA-1", assetObject.getHash()));
|
||||||
task.setName(assetObject.getHash());
|
task.setName(assetObject.getHash());
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jackhuang.hmcl.game.AssetIndexInfo;
|
|||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -65,7 +64,7 @@ public final class GameAssetIndexDownloadTask extends Task<Void> {
|
|||||||
// We should not check the hash code of asset index file since this file is not consistent
|
// We should not check the hash code of asset index file since this file is not consistent
|
||||||
// And Mojang will modify this file anytime. So assetIndex.hash might be outdated.
|
// And Mojang will modify this file anytime. So assetIndex.hash might be outdated.
|
||||||
dependencies.add(new FileDownloadTask(
|
dependencies.add(new FileDownloadTask(
|
||||||
NetworkUtils.toURL(dependencyManager.getPrimaryDownloadProvider().injectURL(assetIndexInfo.getUrl())),
|
dependencyManager.getDownloadProvider().injectURLWithCandidates(assetIndexInfo.getUrl()),
|
||||||
assetIndexFile
|
assetIndexFile
|
||||||
).setCacheRepository(dependencyManager.getCacheRepository()));
|
).setCacheRepository(dependencyManager.getCacheRepository()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
import org.jackhuang.hmcl.task.FileDownloadTask.IntegrityCheck;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.CacheRepository;
|
import org.jackhuang.hmcl.util.CacheRepository;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task to download Minecraft jar
|
* Task to download Minecraft jar
|
||||||
@@ -59,9 +57,7 @@ public final class GameDownloadTask extends Task<Void> {
|
|||||||
File jar = dependencyManager.getGameRepository().getVersionJar(version);
|
File jar = dependencyManager.getGameRepository().getVersionJar(version);
|
||||||
|
|
||||||
FileDownloadTask task = new FileDownloadTask(
|
FileDownloadTask task = new FileDownloadTask(
|
||||||
dependencyManager.getPreferredDownloadProviders().stream()
|
dependencyManager.getDownloadProvider().injectURLWithCandidates(version.getDownloadInfo().getUrl()),
|
||||||
.map(downloadProvider -> downloadProvider.injectURL(version.getDownloadInfo().getUrl()))
|
|
||||||
.map(NetworkUtils::toURL).collect(Collectors.toList()),
|
|
||||||
jar,
|
jar,
|
||||||
IntegrityCheck.of(CacheRepository.SHA1, version.getDownloadInfo().getSha1()))
|
IntegrityCheck.of(CacheRepository.SHA1, version.getDownloadInfo().getSha1()))
|
||||||
.setCaching(true)
|
.setCaching(true)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import org.tukaani.xz.XZInputStream;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -42,7 +42,6 @@ import java.util.jar.JarInputStream;
|
|||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
import java.util.jar.Pack200;
|
import java.util.jar.Pack200;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
@@ -130,21 +129,15 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
URL packXz = NetworkUtils.toURL(dependencyManager.getPrimaryDownloadProvider().injectURL(url) + ".pack.xz");
|
URL packXz = NetworkUtils.toURL(dependencyManager.getDownloadProvider().injectURL(url) + ".pack.xz");
|
||||||
if (NetworkUtils.urlExists(packXz)) {
|
if (NetworkUtils.urlExists(packXz)) {
|
||||||
List<URL> urls = dependencyManager.getPreferredDownloadProviders().stream()
|
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(url + ".pack.xz");
|
||||||
.map(downloadProvider -> downloadProvider.injectURL(url) + ".pack.xz")
|
|
||||||
.map(NetworkUtils::toURL)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
task = new FileDownloadTask(urls, xzFile, null)
|
task = new FileDownloadTask(urls, xzFile, null)
|
||||||
.setCacheRepository(cacheRepository)
|
.setCacheRepository(cacheRepository)
|
||||||
.setCaching(true);
|
.setCaching(true);
|
||||||
xz = true;
|
xz = true;
|
||||||
} else {
|
} else {
|
||||||
List<URL> urls = dependencyManager.getPreferredDownloadProviders().stream()
|
List<URL> urls = dependencyManager.getDownloadProvider().injectURLWithCandidates(url);
|
||||||
.map(downloadProvider -> downloadProvider.injectURL(url))
|
|
||||||
.map(NetworkUtils::toURL)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
task = new FileDownloadTask(urls, jar,
|
task = new FileDownloadTask(urls, jar,
|
||||||
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null)
|
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null)
|
||||||
.setCacheRepository(cacheRepository)
|
.setCacheRepository(cacheRepository)
|
||||||
@@ -192,7 +185,7 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||||||
while (entry != null) {
|
while (entry != null) {
|
||||||
byte[] eData = IOUtils.readFullyWithoutClosing(jar);
|
byte[] eData = IOUtils.readFullyWithoutClosing(jar);
|
||||||
if (entry.getName().equals("checksums.sha1")) {
|
if (entry.getName().equals("checksums.sha1")) {
|
||||||
hashes = new String(eData, Charset.forName("UTF-8")).split("\n");
|
hashes = new String(eData, StandardCharsets.UTF_8).split("\n");
|
||||||
}
|
}
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
files.put(entry.getName(), encodeHex(digest("SHA-1", eData)));
|
files.put(entry.getName(), encodeHex(digest("SHA-1", eData)));
|
||||||
|
|||||||
@@ -22,14 +22,11 @@ import org.jackhuang.hmcl.download.RemoteVersion;
|
|||||||
import org.jackhuang.hmcl.download.VersionList;
|
import org.jackhuang.hmcl.download.VersionList;
|
||||||
import org.jackhuang.hmcl.task.GetTask;
|
import org.jackhuang.hmcl.task.GetTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -46,9 +43,8 @@ public final class VersionJsonDownloadTask extends Task<String> {
|
|||||||
this.gameVersion = gameVersion;
|
this.gameVersion = gameVersion;
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.gameVersionList = dependencyManager.getVersionList("game");
|
this.gameVersionList = dependencyManager.getVersionList("game");
|
||||||
|
|
||||||
if (!gameVersionList.isLoaded())
|
dependents.add(gameVersionList.loadAsync());
|
||||||
dependents.add(gameVersionList.refreshAsync());
|
|
||||||
|
|
||||||
setSignificance(TaskSignificance.MODERATE);
|
setSignificance(TaskSignificance.MODERATE);
|
||||||
}
|
}
|
||||||
@@ -67,10 +63,6 @@ public final class VersionJsonDownloadTask extends Task<String> {
|
|||||||
public void execute() throws IOException {
|
public void execute() throws IOException {
|
||||||
RemoteVersion remoteVersion = gameVersionList.getVersion(gameVersion, gameVersion)
|
RemoteVersion remoteVersion = gameVersionList.getVersion(gameVersion, gameVersion)
|
||||||
.orElseThrow(() -> new IOException("Cannot find specific version " + gameVersion + " in remote repository"));
|
.orElseThrow(() -> new IOException("Cannot find specific version " + gameVersion + " in remote repository"));
|
||||||
dependencies.add(new GetTask(
|
dependencies.add(new GetTask(dependencyManager.getDownloadProvider().injectURLsWithCandidates(remoteVersion.getUrls())).storeTo(this::setResult));
|
||||||
dependencyManager.getPreferredDownloadProviders().stream()
|
|
||||||
.flatMap(downloadProvider -> Arrays.stream(remoteVersion.getUrl()).map(downloadProvider::injectURL))
|
|
||||||
.map(NetworkUtils::toURL).collect(Collectors.toList())
|
|
||||||
).storeTo(this::setResult));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
|
||||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||||
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
||||||
import org.jenkinsci.constant_pool_scanner.ConstantPool;
|
import org.jenkinsci.constant_pool_scanner.ConstantPool;
|
||||||
@@ -96,9 +95,7 @@ public final class OptiFineInstallTask extends Task<Version> {
|
|||||||
|
|
||||||
if (installer == null) {
|
if (installer == null) {
|
||||||
dependents.add(new FileDownloadTask(
|
dependents.add(new FileDownloadTask(
|
||||||
dependencyManager.getPreferredDownloadProviders().stream()
|
dependencyManager.getDownloadProvider().injectURLsWithCandidates(remote.getUrls()),
|
||||||
.flatMap(downloadProvider -> Arrays.stream(remote.getUrl()).map(downloadProvider::injectURL))
|
|
||||||
.map(NetworkUtils::toURL).collect(Collectors.toList()),
|
|
||||||
dest.toFile(), null)
|
dest.toFile(), null)
|
||||||
.setCacheRepository(dependencyManager.getCacheRepository())
|
.setCacheRepository(dependencyManager.getCacheRepository())
|
||||||
.setCaching(true));
|
.setCaching(true));
|
||||||
|
|||||||
@@ -119,6 +119,15 @@ public class FileDownloadTask extends Task<Void> {
|
|||||||
this(Collections.singletonList(url), file, integrityCheck, retry);
|
this(Collections.singletonList(url), file, integrityCheck, retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param urls urls of remote file, will be attempted in order.
|
||||||
|
* @param file the location that download to.
|
||||||
|
*/
|
||||||
|
public FileDownloadTask(List<URL> urls, File file) {
|
||||||
|
this(urls, file, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param urls urls of remote file, will be attempted in order.
|
* @param urls urls of remote file, will be attempted in order.
|
||||||
|
|||||||
@@ -17,7 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.javafx;
|
package org.jackhuang.hmcl.util.javafx;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.beans.WeakInvalidationListener;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.Property;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -25,16 +30,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javafx.beans.InvalidationListener;
|
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||||
import javafx.beans.WeakInvalidationListener;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.Property;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.SelectionModel;
|
|
||||||
import javafx.scene.control.Toggle;
|
|
||||||
import javafx.scene.control.ToggleGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yushijinhun
|
* @author yushijinhun
|
||||||
@@ -126,7 +122,7 @@ public final class ExtendedProperties {
|
|||||||
|
|
||||||
// ==== CheckBox ====
|
// ==== CheckBox ====
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static ObjectProperty<Boolean> reservedSelectedPropertyFor(CheckBox checkbox) {
|
public static ObjectProperty<Boolean> reversedSelectedPropertyFor(CheckBox checkbox) {
|
||||||
return (ObjectProperty<Boolean>) checkbox.getProperties().computeIfAbsent(
|
return (ObjectProperty<Boolean>) checkbox.getProperties().computeIfAbsent(
|
||||||
PROP_PREFIX + ".checkbox.reservedSelected",
|
PROP_PREFIX + ".checkbox.reservedSelected",
|
||||||
any -> new MappedProperty<Boolean, Boolean>(checkbox, "ext.reservedSelected",
|
any -> new MappedProperty<Boolean, Boolean>(checkbox, "ext.reservedSelected",
|
||||||
|
|||||||
Reference in New Issue
Block a user