修复切换下载源后需要重启启动器才会生效的问题 (#4296)
This commit is contained in:
@@ -31,23 +31,21 @@ import java.io.FileNotFoundException;
|
|||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.file.AccessDeniedException;
|
import java.nio.file.AccessDeniedException;
|
||||||
import java.util.Arrays;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
import static org.jackhuang.hmcl.task.FetchTask.DEFAULT_CONCURRENCY;
|
import static org.jackhuang.hmcl.task.FetchTask.DEFAULT_CONCURRENCY;
|
||||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
|
||||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
public final class DownloadProviders {
|
public final class DownloadProviders {
|
||||||
private DownloadProviders() {}
|
private DownloadProviders() {
|
||||||
|
}
|
||||||
|
|
||||||
private static DownloadProvider currentDownloadProvider;
|
private static final DownloadProviderWrapper provider;
|
||||||
|
|
||||||
public static final Map<String, DownloadProvider> providersById;
|
public static final Map<String, DownloadProvider> providersById;
|
||||||
public static final Map<String, DownloadProvider> rawProviders;
|
public static final Map<String, DownloadProvider> rawProviders;
|
||||||
@@ -59,6 +57,7 @@ public final class DownloadProviders {
|
|||||||
public static final String DEFAULT_PROVIDER_ID = "balanced";
|
public static final String DEFAULT_PROVIDER_ID = "balanced";
|
||||||
public static final String DEFAULT_RAW_PROVIDER_ID = "bmclapi";
|
public static final String DEFAULT_RAW_PROVIDER_ID = "bmclapi";
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static final InvalidationListener observer;
|
private static final InvalidationListener observer;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -68,71 +67,68 @@ public final class DownloadProviders {
|
|||||||
|
|
||||||
MOJANG = new MojangDownloadProvider();
|
MOJANG = new MojangDownloadProvider();
|
||||||
BMCLAPI = new BMCLAPIDownloadProvider(bmclapiRoot);
|
BMCLAPI = new BMCLAPIDownloadProvider(bmclapiRoot);
|
||||||
rawProviders = mapOf(
|
rawProviders = Map.of(
|
||||||
pair("mojang", MOJANG),
|
"mojang", MOJANG,
|
||||||
pair("bmclapi", BMCLAPI)
|
"bmclapi", BMCLAPI
|
||||||
);
|
);
|
||||||
|
|
||||||
AdaptedDownloadProvider fileProvider = new AdaptedDownloadProvider();
|
AdaptedDownloadProvider fileProvider = new AdaptedDownloadProvider();
|
||||||
fileProvider.setDownloadProviderCandidates(Arrays.asList(BMCLAPI, MOJANG));
|
fileProvider.setDownloadProviderCandidates(List.of(BMCLAPI, MOJANG));
|
||||||
BalancedDownloadProvider balanced = new BalancedDownloadProvider(MOJANG, BMCLAPI);
|
BalancedDownloadProvider balanced = new BalancedDownloadProvider(MOJANG, BMCLAPI);
|
||||||
|
|
||||||
providersById = mapOf(
|
providersById = Map.of(
|
||||||
pair("official", new AutoDownloadProvider(MOJANG, fileProvider)),
|
"official", new AutoDownloadProvider(MOJANG, fileProvider),
|
||||||
pair("balanced", new AutoDownloadProvider(balanced, fileProvider)),
|
"balanced", new AutoDownloadProvider(balanced, fileProvider),
|
||||||
pair("mirror", new AutoDownloadProvider(BMCLAPI, fileProvider)));
|
"mirror", new AutoDownloadProvider(BMCLAPI, fileProvider));
|
||||||
|
|
||||||
observer = FXUtils.observeWeak(() -> {
|
observer = FXUtils.observeWeak(() -> {
|
||||||
FetchTask.setDownloadExecutorConcurrency(
|
FetchTask.setDownloadExecutorConcurrency(
|
||||||
config().getAutoDownloadThreads() ? DEFAULT_CONCURRENCY : config().getDownloadThreads());
|
config().getAutoDownloadThreads() ? DEFAULT_CONCURRENCY : config().getDownloadThreads());
|
||||||
}, config().autoDownloadThreadsProperty(), config().downloadThreadsProperty());
|
}, config().autoDownloadThreadsProperty(), config().downloadThreadsProperty());
|
||||||
|
|
||||||
|
provider = new DownloadProviderWrapper(MOJANG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
FXUtils.onChangeAndOperate(config().versionListSourceProperty(), versionListSource -> {
|
InvalidationListener onChangeDownloadSource = observable -> {
|
||||||
if (!providersById.containsKey(versionListSource)) {
|
String versionListSource = Objects.requireNonNullElse(config().getVersionListSource(), "");
|
||||||
config().setVersionListSource(DEFAULT_PROVIDER_ID);
|
if (config().isAutoChooseDownloadType()) {
|
||||||
return;
|
DownloadProvider currentDownloadProvider = providersById.get(versionListSource);
|
||||||
|
if (currentDownloadProvider == null)
|
||||||
|
currentDownloadProvider = Objects.requireNonNull(providersById.get(DEFAULT_PROVIDER_ID),
|
||||||
|
"default provider is null");
|
||||||
|
|
||||||
|
provider.setProvider(currentDownloadProvider);
|
||||||
|
} else {
|
||||||
|
provider.setProvider(fileDownloadProvider);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
config().versionListSourceProperty().addListener(onChangeDownloadSource);
|
||||||
|
config().autoChooseDownloadTypeProperty().addListener(onChangeDownloadSource);
|
||||||
|
|
||||||
currentDownloadProvider = Optional.ofNullable(providersById.get(versionListSource))
|
onChangeDownloadSource.invalidated(null);
|
||||||
.orElse(providersById.get(DEFAULT_PROVIDER_ID));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!rawProviders.containsKey(config().getDownloadType())) {
|
|
||||||
config().setDownloadType(DEFAULT_RAW_PROVIDER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(config().downloadTypeProperty(), downloadType -> {
|
FXUtils.onChangeAndOperate(config().downloadTypeProperty(), downloadType -> {
|
||||||
DownloadProvider primary = Optional.ofNullable(rawProviders.get(downloadType))
|
DownloadProvider primary = Objects.requireNonNullElseGet(
|
||||||
.orElse(rawProviders.get(DEFAULT_RAW_PROVIDER_ID));
|
rawProviders.get(Objects.requireNonNullElse(downloadType, "")),
|
||||||
fileDownloadProvider.setDownloadProviderCandidates(
|
() -> rawProviders.get(DEFAULT_RAW_PROVIDER_ID));
|
||||||
Stream.concat(
|
|
||||||
Stream.of(primary),
|
List<DownloadProvider> providers = new ArrayList<>(rawProviders.size());
|
||||||
rawProviders.values().stream().filter(x -> x != primary)
|
providers.add(primary);
|
||||||
).collect(Collectors.toList())
|
for (DownloadProvider provider : rawProviders.values()) {
|
||||||
);
|
if (provider != primary)
|
||||||
|
providers.add(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDownloadProvider.setDownloadProviderCandidates(providers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPrimaryDownloadProviderId() {
|
|
||||||
String downloadType = config().getDownloadType();
|
|
||||||
if (providersById.containsKey(downloadType))
|
|
||||||
return downloadType;
|
|
||||||
else
|
|
||||||
return DEFAULT_PROVIDER_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DownloadProvider getDownloadProviderByPrimaryId(String primaryId) {
|
|
||||||
return Optional.ofNullable(providersById.get(primaryId))
|
|
||||||
.orElse(providersById.get(DEFAULT_PROVIDER_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current primary preferred download provider
|
* Get current primary preferred download provider
|
||||||
*/
|
*/
|
||||||
public static DownloadProvider getDownloadProvider() {
|
public static DownloadProvider getDownloadProvider() {
|
||||||
return config().isAutoChooseDownloadType() ? currentDownloadProvider : fileDownloadProvider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String localizeErrorMessage(Throwable exception) {
|
public static String localizeErrorMessage(Throwable exception) {
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.download;
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -29,10 +30,10 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class AdaptedDownloadProvider implements DownloadProvider {
|
public class AdaptedDownloadProvider implements DownloadProvider {
|
||||||
|
|
||||||
private List<DownloadProvider> downloadProviderCandidates;
|
private @Unmodifiable List<DownloadProvider> downloadProviderCandidates;
|
||||||
|
|
||||||
public void setDownloadProviderCandidates(List<DownloadProvider> downloadProviderCandidates) {
|
public void setDownloadProviderCandidates(List<DownloadProvider> downloadProviderCandidates) {
|
||||||
this.downloadProviderCandidates = new ArrayList<>(downloadProviderCandidates);
|
this.downloadProviderCandidates = List.copyOf(downloadProviderCandidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DownloadProvider getPreferredDownloadProvider() {
|
public DownloadProvider getPreferredDownloadProvider() {
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2025 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 java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Glavo
|
||||||
|
*/
|
||||||
|
public final class DownloadProviderWrapper implements DownloadProvider {
|
||||||
|
|
||||||
|
private DownloadProvider provider;
|
||||||
|
|
||||||
|
public DownloadProviderWrapper(DownloadProvider provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadProvider getProvider() {
|
||||||
|
return this.provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProvider(DownloadProvider provider) {
|
||||||
|
this.provider = Objects.requireNonNull(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URI> getAssetObjectCandidates(String assetObjectLocation) {
|
||||||
|
return getProvider().getAssetObjectCandidates(assetObjectLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersionListURL() {
|
||||||
|
return getProvider().getVersionListURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAssetBaseURL() {
|
||||||
|
return getProvider().getAssetBaseURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String injectURL(String baseURL) {
|
||||||
|
return getProvider().injectURL(baseURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URI> injectURLWithCandidates(String baseURL) {
|
||||||
|
return getProvider().injectURLWithCandidates(baseURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URI> injectURLsWithCandidates(List<String> urls) {
|
||||||
|
return getProvider().injectURLsWithCandidates(urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VersionList<?> getVersionListById(String id) {
|
||||||
|
return getProvider().getVersionListById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConcurrency() {
|
||||||
|
return getProvider().getConcurrency();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user