mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-18 08:16:58 -04:00
feat: download concurrency settings. Closes #990.
This commit is contained in:
parent
b3d083877f
commit
243c9b83b9
@ -122,6 +122,12 @@ public final class Config implements Cloneable, Observable {
|
|||||||
@SerializedName("localization")
|
@SerializedName("localization")
|
||||||
private ObjectProperty<SupportedLocale> localization = new SimpleObjectProperty<>(Locales.DEFAULT);
|
private ObjectProperty<SupportedLocale> localization = new SimpleObjectProperty<>(Locales.DEFAULT);
|
||||||
|
|
||||||
|
@SerializedName("autoDownloadThreads")
|
||||||
|
private BooleanProperty autoDownloadThreads = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
|
@SerializedName("downloadThreads")
|
||||||
|
private IntegerProperty downloadThreads = new SimpleIntegerProperty(64);
|
||||||
|
|
||||||
@SerializedName("downloadType")
|
@SerializedName("downloadType")
|
||||||
private StringProperty downloadType = new SimpleStringProperty("mcbbs");
|
private StringProperty downloadType = new SimpleStringProperty("mcbbs");
|
||||||
|
|
||||||
@ -389,6 +395,30 @@ public final class Config implements Cloneable, Observable {
|
|||||||
return localization;
|
return localization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getAutoDownloadThreads() {
|
||||||
|
return autoDownloadThreads.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty autoDownloadThreadsProperty() {
|
||||||
|
return autoDownloadThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoDownloadThreads(boolean autoDownloadThreads) {
|
||||||
|
this.autoDownloadThreads.set(autoDownloadThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDownloadThreads() {
|
||||||
|
return downloadThreads.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegerProperty downloadThreadsProperty() {
|
||||||
|
return downloadThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadThreads(int downloadThreads) {
|
||||||
|
this.downloadThreads.set(downloadThreads);
|
||||||
|
}
|
||||||
|
|
||||||
public String getDownloadType() {
|
public String getDownloadType() {
|
||||||
return downloadType.get();
|
return downloadType.get();
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.setting;
|
package org.jackhuang.hmcl.setting;
|
||||||
|
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
import org.jackhuang.hmcl.download.*;
|
import org.jackhuang.hmcl.download.*;
|
||||||
|
import org.jackhuang.hmcl.task.FetchTask;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
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.util.Lang.mapOf;
|
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||||
|
|
||||||
@ -44,6 +49,8 @@ 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 = "mcbbs";
|
public static final String DEFAULT_RAW_PROVIDER_ID = "mcbbs";
|
||||||
|
|
||||||
|
private static final InvalidationListener observer;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
String bmclapiRoot = "https://bmclapi2.bangbang93.com";
|
String bmclapiRoot = "https://bmclapi2.bangbang93.com";
|
||||||
String bmclapiRootOverride = System.getProperty("hmcl.bmclapi.override");
|
String bmclapiRootOverride = System.getProperty("hmcl.bmclapi.override");
|
||||||
@ -66,6 +73,11 @@ public final class DownloadProviders {
|
|||||||
pair("official", new AutoDownloadProvider(MOJANG, fileProvider)),
|
pair("official", new AutoDownloadProvider(MOJANG, fileProvider)),
|
||||||
pair("balanced", new AutoDownloadProvider(balanced, fileProvider)),
|
pair("balanced", new AutoDownloadProvider(balanced, fileProvider)),
|
||||||
pair("mirror", new AutoDownloadProvider(MCBBS, fileProvider)));
|
pair("mirror", new AutoDownloadProvider(MCBBS, fileProvider)));
|
||||||
|
|
||||||
|
observer = FXUtils.observeWeak(() -> {
|
||||||
|
FetchTask.setDownloadExecutorConcurrency(
|
||||||
|
config().getAutoDownloadThreads() ? DEFAULT_CONCURRENCY : config().getDownloadThreads());
|
||||||
|
}, config().autoDownloadThreadsProperty(), config().downloadThreadsProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
|
@ -415,6 +415,12 @@ public final class SVG {
|
|||||||
fill, width, height);
|
fill, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Node bell(ObjectBinding<? extends Paint> fill, double width, double height) {
|
||||||
|
return createSVGPath(
|
||||||
|
"M21,19V20H3V19L5,17V11C5,7.9 7.03,5.17 10,4.29C10,4.19 10,4.1 10,4A2,2 0 0,1 12,2A2,2 0 0,1 14,4C14,4.1 14,4.19 14,4.29C16.97,5.17 19,7.9 19,11V17L21,19M14,21A2,2 0 0,1 12,23A2,2 0 0,1 10,21",
|
||||||
|
fill, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
public static Node contentSaveMoveOutline(ObjectBinding<? extends Paint> fill, double width, double height) {
|
public static Node contentSaveMoveOutline(ObjectBinding<? extends Paint> fill, double width, double height) {
|
||||||
return createSVGPath(
|
return createSVGPath(
|
||||||
"M13 17H17V14L22 18.5L17 23V20H13V17M14 12.8C13.5 12.31 12.78 12 12 12C10.34 12 9 13.34 9 15C9 16.31 9.84 17.41 11 17.82C11.07 15.67 12.27 13.8 14 12.8M11.09 19H5V5H16.17L19 7.83V12.35C19.75 12.61 20.42 13 21 13.54V7L17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H11.81C11.46 20.39 11.21 19.72 11.09 19M6 10H15V6H6V10Z",
|
"M13 17H17V14L22 18.5L17 23V20H13V17M14 12.8C13.5 12.31 12.78 12 12 12C10.34 12 9 13.34 9 15C9 16.31 9.84 17.41 11 17.82C11.07 15.67 12.27 13.8 14 12.8M11.09 19H5V5H16.17L19 7.83V12.35C19.75 12.61 20.42 13 21 13.54V7L17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H11.81C11.46 20.39 11.21 19.72 11.09 19M6 10H15V6H6V10Z",
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2021 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.construct;
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.scene.text.TextFlow;
|
||||||
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
|
public class HintPane extends VBox {
|
||||||
|
private final Text label = new Text();
|
||||||
|
private final StringProperty text = new SimpleStringProperty(this, "text");
|
||||||
|
|
||||||
|
public HintPane(MessageDialogPane.MessageType type) {
|
||||||
|
setFillWidth(true);
|
||||||
|
getStyleClass().add("hint");
|
||||||
|
HBox hbox = new HBox();
|
||||||
|
hbox.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
hbox.getChildren().setAll(
|
||||||
|
SVG.informationOutline(Theme.blackFillBinding(), 16, 16),
|
||||||
|
new Label(i18n("message.info"))
|
||||||
|
);
|
||||||
|
TextFlow flow = new TextFlow();
|
||||||
|
flow.getChildren().setAll(label);
|
||||||
|
getChildren().setAll(hbox, flow);
|
||||||
|
label.textProperty().bind(text);
|
||||||
|
VBox.setMargin(flow, new Insets(2, 2, 0, 2));
|
||||||
|
|
||||||
|
label.fillProperty().bind(BindingMapping.of(disabledProperty()).map(disabled -> disabled ? new Color(0, 0, 0, 0.5) : Color.BLACK));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty textProperty() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text.set(text);
|
||||||
|
}
|
||||||
|
}
|
@ -22,17 +22,18 @@ import javafx.geometry.HPos;
|
|||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
import org.jackhuang.hmcl.setting.DownloadProviders;
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
|
import org.jackhuang.hmcl.task.FetchTask;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.ComponentList;
|
import org.jackhuang.hmcl.ui.construct.*;
|
||||||
import org.jackhuang.hmcl.ui.construct.NumberValidator;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
|
||||||
import org.jackhuang.hmcl.util.javafx.SafeStringConverter;
|
import org.jackhuang.hmcl.util.javafx.SafeStringConverter;
|
||||||
|
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||||
@ -103,6 +104,68 @@ public class DownloadSettingsPage extends StackPane {
|
|||||||
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.version_list_source")), downloadSource);
|
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.version_list_source")), downloadSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ComponentList downloadThreads = new ComponentList();
|
||||||
|
|
||||||
|
{
|
||||||
|
VBox pane = new VBox(16);
|
||||||
|
pane.setPadding(new Insets(8, 0, 8, 0));
|
||||||
|
|
||||||
|
{
|
||||||
|
JFXCheckBox chkAutoDownloadThreads = new JFXCheckBox(i18n("settings.launcher.download.threads.auto"));
|
||||||
|
chkAutoDownloadThreads.selectedProperty().bindBidirectional(config().autoDownloadThreadsProperty());
|
||||||
|
pane.getChildren().add(chkAutoDownloadThreads);
|
||||||
|
|
||||||
|
chkAutoDownloadThreads.selectedProperty().addListener((a, b, newValue) -> {
|
||||||
|
if (newValue) {
|
||||||
|
config().downloadThreadsProperty().set(FetchTask.DEFAULT_CONCURRENCY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
HBox hbox = new HBox(8);
|
||||||
|
hbox.setAlignment(Pos.CENTER);
|
||||||
|
hbox.setPadding(new Insets(0, 0, 0, 30));
|
||||||
|
hbox.disableProperty().bind(config().autoDownloadThreadsProperty());
|
||||||
|
Label label = new Label(i18n("settings.launcher.download.threads"));
|
||||||
|
|
||||||
|
JFXSlider slider = new JFXSlider(1, 256, 64);
|
||||||
|
HBox.setHgrow(slider, Priority.ALWAYS);
|
||||||
|
|
||||||
|
JFXTextField threadsField = new JFXTextField();
|
||||||
|
FXUtils.setLimitWidth(threadsField, 60);
|
||||||
|
threadsField.textProperty().bindBidirectional(config().downloadThreadsProperty(), SafeStringConverter.fromInteger());
|
||||||
|
|
||||||
|
AtomicBoolean changedByTextField = new AtomicBoolean(false);
|
||||||
|
FXUtils.onChangeAndOperate(config().downloadThreadsProperty(), value -> {
|
||||||
|
changedByTextField.set(true);
|
||||||
|
slider.setValue(value.intValue());
|
||||||
|
changedByTextField.set(false);
|
||||||
|
});
|
||||||
|
slider.valueProperty().addListener((value, oldVal, newVal) -> {
|
||||||
|
if (changedByTextField.get()) return;
|
||||||
|
config().downloadThreadsProperty().set(value.getValue().intValue());
|
||||||
|
});
|
||||||
|
|
||||||
|
hbox.getChildren().setAll(label, slider, threadsField);
|
||||||
|
pane.getChildren().add(hbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
HintPane hintPane = new HintPane(MessageDialogPane.MessageType.INFORMATION);
|
||||||
|
VBox.setMargin(hintPane, new Insets(0, 0, 0, 30));
|
||||||
|
hintPane.disableProperty().bind(config().autoDownloadThreadsProperty());
|
||||||
|
hintPane.setText(i18n("settings.launcher.download.threads.hint"));
|
||||||
|
pane.getChildren().add(hintPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadThreads.getContent().add(pane);
|
||||||
|
}
|
||||||
|
|
||||||
|
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("download")), downloadThreads);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ComponentList proxyList = new ComponentList();
|
ComponentList proxyList = new ComponentList();
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ public class LauncherSettingsPage extends BorderPane implements DecoratorPage {
|
|||||||
{
|
{
|
||||||
AdvancedListBox sideBar = new AdvancedListBox()
|
AdvancedListBox sideBar = new AdvancedListBox()
|
||||||
.addNavigationDrawerItem(settingsItem -> {
|
.addNavigationDrawerItem(settingsItem -> {
|
||||||
settingsItem.setTitle(i18n("settings.type.global.manage"));
|
settingsItem.setTitle(i18n("settings.game.current"));
|
||||||
settingsItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20)));
|
settingsItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20)));
|
||||||
settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(gameTab));
|
settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(gameTab));
|
||||||
settingsItem.setOnAction(e -> tab.getSelectionModel().select(gameTab));
|
settingsItem.setOnAction(e -> tab.getSelectionModel().select(gameTab));
|
||||||
})
|
})
|
||||||
.startCategory(i18n("settings.launcher"))
|
.startCategory(i18n("launcher"))
|
||||||
.addNavigationDrawerItem(settingsItem -> {
|
.addNavigationDrawerItem(settingsItem -> {
|
||||||
settingsItem.setTitle(i18n("settings.launcher"));
|
settingsItem.setTitle(i18n("settings.launcher.general"));
|
||||||
settingsItem.setLeftGraphic(wrap(SVG.applicationOutline(null, 20, 20)));
|
settingsItem.setLeftGraphic(wrap(SVG.applicationOutline(null, 20, 20)));
|
||||||
settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(settingsTab));
|
settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(settingsTab));
|
||||||
settingsItem.setOnAction(e -> tab.getSelectionModel().select(settingsTab));
|
settingsItem.setOnAction(e -> tab.getSelectionModel().select(settingsTab));
|
||||||
@ -91,6 +91,7 @@ public class LauncherSettingsPage extends BorderPane implements DecoratorPage {
|
|||||||
downloadItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(downloadTab));
|
downloadItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(downloadTab));
|
||||||
downloadItem.setOnAction(e -> tab.getSelectionModel().select(downloadTab));
|
downloadItem.setOnAction(e -> tab.getSelectionModel().select(downloadTab));
|
||||||
})
|
})
|
||||||
|
.startCategory(i18n("help"))
|
||||||
.addNavigationDrawerItem(helpItem -> {
|
.addNavigationDrawerItem(helpItem -> {
|
||||||
helpItem.setTitle(i18n("help"));
|
helpItem.setTitle(i18n("help"));
|
||||||
helpItem.setLeftGraphic(wrap(SVG.helpCircleOutline(null, 20, 20)));
|
helpItem.setLeftGraphic(wrap(SVG.helpCircleOutline(null, 20, 20)));
|
||||||
|
@ -42,6 +42,15 @@
|
|||||||
-fx-text-fill: rgba(0, 0, 0, 0.5);
|
-fx-text-fill: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
-fx-border-color: #b8daff;
|
||||||
|
-fx-background-color: #cce5ff;
|
||||||
|
-fx-background-radius: 5;
|
||||||
|
-fx-border-width: 1;
|
||||||
|
-fx-border-radius: 5;
|
||||||
|
-fx-padding: 6;
|
||||||
|
}
|
||||||
|
|
||||||
.memory-label {
|
.memory-label {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +530,7 @@ settings.advanced.wrapper_launcher=Wrapper Launcher (i.e. optirun...)
|
|||||||
settings.custom=Custom
|
settings.custom=Custom
|
||||||
|
|
||||||
settings.game=Games
|
settings.game=Games
|
||||||
|
settings.game.current=Game
|
||||||
settings.game.dimension=Game Window Dimension
|
settings.game.dimension=Game Window Dimension
|
||||||
settings.game.exploration=Explore
|
settings.game.exploration=Explore
|
||||||
settings.game.fullscreen=Fullscreen
|
settings.game.fullscreen=Fullscreen
|
||||||
@ -546,10 +547,14 @@ settings.launcher=Settings
|
|||||||
settings.launcher.appearance=Appearance
|
settings.launcher.appearance=Appearance
|
||||||
settings.launcher.common_path.tooltip=This app will cache all downloads here.
|
settings.launcher.common_path.tooltip=This app will cache all downloads here.
|
||||||
settings.launcher.debug=Debug
|
settings.launcher.debug=Debug
|
||||||
|
settings.launcher.download.threads=Threads
|
||||||
|
settings.launcher.download.threads.auto=Auto Determined
|
||||||
|
settings.launcher.download.threads.hint=Too large concurrency may cause system to freeze. Download speed may be affected by ICP and destination server.
|
||||||
settings.launcher.download_source=Download Source
|
settings.launcher.download_source=Download Source
|
||||||
settings.launcher.download_source.auto=Auto choose download source
|
settings.launcher.download_source.auto=Auto choose download source
|
||||||
settings.launcher.enable_game_list=Show version list in main page
|
settings.launcher.enable_game_list=Show version list in main page
|
||||||
settings.launcher.font=Font
|
settings.launcher.font=Font
|
||||||
|
settings.launcher.general=General
|
||||||
settings.launcher.language=Language
|
settings.launcher.language=Language
|
||||||
settings.launcher.launcher_log.export=Export launcher logs
|
settings.launcher.launcher_log.export=Export launcher logs
|
||||||
settings.launcher.launcher_log.export.failed=Failed to export logs
|
settings.launcher.launcher_log.export.failed=Failed to export logs
|
||||||
|
@ -380,6 +380,7 @@ settings.advanced.wrapper_launcher=前置指令(不必填寫,如 optirun)
|
|||||||
settings.custom=自訂
|
settings.custom=自訂
|
||||||
|
|
||||||
settings.game=遊戲設定
|
settings.game=遊戲設定
|
||||||
|
settings.game.current=遊戲
|
||||||
settings.game.dimension=遊戲介面解析度大小
|
settings.game.dimension=遊戲介面解析度大小
|
||||||
settings.game.exploration=瀏覽
|
settings.game.exploration=瀏覽
|
||||||
settings.game.fullscreen=全螢幕
|
settings.game.fullscreen=全螢幕
|
||||||
|
@ -538,6 +538,7 @@ settings.advanced.wrapper_launcher=前置指令(不必填写,如 optirun)
|
|||||||
settings.custom=自定义
|
settings.custom=自定义
|
||||||
|
|
||||||
settings.game=游戏设置
|
settings.game=游戏设置
|
||||||
|
settings.game.current=游戏
|
||||||
settings.game.dimension=游戏窗口分辨率
|
settings.game.dimension=游戏窗口分辨率
|
||||||
settings.game.exploration=浏览
|
settings.game.exploration=浏览
|
||||||
settings.game.fullscreen=全屏
|
settings.game.fullscreen=全屏
|
||||||
@ -554,10 +555,15 @@ settings.launcher=启动器设置
|
|||||||
settings.launcher.appearance=外观
|
settings.launcher.appearance=外观
|
||||||
settings.launcher.common_path.tooltip=启动器将所有游戏资源及依赖库文件放于此集中管理,如果游戏文件夹内有现成的将不会使用公共库文件
|
settings.launcher.common_path.tooltip=启动器将所有游戏资源及依赖库文件放于此集中管理,如果游戏文件夹内有现成的将不会使用公共库文件
|
||||||
settings.launcher.debug=调试
|
settings.launcher.debug=调试
|
||||||
|
settings.launcher.download=下载
|
||||||
|
settings.launcher.download.threads=并发数
|
||||||
|
settings.launcher.download.threads.auto=自动选择并发数
|
||||||
|
settings.launcher.download.threads.hint=并发数过大可能导致系统卡顿。你的下载速度会受到宽带运营商、服务器等方面的影响,调大下载并发数不一定能大幅提升总下载速度。
|
||||||
settings.launcher.download_source=下载源
|
settings.launcher.download_source=下载源
|
||||||
settings.launcher.download_source.auto=自动选择下载源
|
settings.launcher.download_source.auto=自动选择下载源
|
||||||
settings.launcher.enable_game_list=在主页内显示版本列表
|
settings.launcher.enable_game_list=在主页内显示版本列表
|
||||||
settings.launcher.font=字体
|
settings.launcher.font=字体
|
||||||
|
settings.launcher.general=通用
|
||||||
settings.launcher.language=语言
|
settings.launcher.language=语言
|
||||||
settings.launcher.launcher_log.export=导出启动器日志
|
settings.launcher.launcher_log.export=导出启动器日志
|
||||||
settings.launcher.launcher_log.export.failed=无法导出日志
|
settings.launcher.launcher_log.export.failed=无法导出日志
|
||||||
|
@ -268,8 +268,9 @@ public abstract class FetchTask<T> extends Task<T> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int downloadExecutorConcurrency = Math.min(Runtime.getRuntime().availableProcessors() * 4, 64);
|
public static int DEFAULT_CONCURRENCY = Math.min(Runtime.getRuntime().availableProcessors() * 4, 64);
|
||||||
private static volatile ExecutorService DOWNLOAD_EXECUTOR;
|
private static int downloadExecutorConcurrency = DEFAULT_CONCURRENCY;
|
||||||
|
private static volatile ThreadPoolExecutor DOWNLOAD_EXECUTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get singleton instance of the thread pool for file downloading.
|
* Get singleton instance of the thread pool for file downloading.
|
||||||
@ -292,8 +293,8 @@ public abstract class FetchTask<T> extends Task<T> {
|
|||||||
synchronized (Schedulers.class) {
|
synchronized (Schedulers.class) {
|
||||||
downloadExecutorConcurrency = concurrency;
|
downloadExecutorConcurrency = concurrency;
|
||||||
if (DOWNLOAD_EXECUTOR != null) {
|
if (DOWNLOAD_EXECUTOR != null) {
|
||||||
DOWNLOAD_EXECUTOR.shutdownNow();
|
DOWNLOAD_EXECUTOR.setCorePoolSize(concurrency);
|
||||||
DOWNLOAD_EXECUTOR = null;
|
DOWNLOAD_EXECUTOR.setMaximumPoolSize(concurrency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user