From c26579bebd3c4af906d9a124e59f1f32105a9ce6 Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Wed, 19 Feb 2020 16:51:05 +0800 Subject: [PATCH] add: show stages of game installation --- .../jackhuang/hmcl/game/LauncherHelper.java | 7 +-- .../ui/construct/TaskExecutorDialogPane.java | 10 +---- .../hmcl/ui/construct/TaskListPane.java | 43 ++++++++++++------- .../ui/download/InstallerWizardProvider.java | 24 ++++++++++- .../ModpackInstallWizardProvider.java | 1 + .../UpdateInstallerWizardProvider.java | 22 ++++++++++ .../VanillaInstallWizardProvider.java | 27 ++++++++++++ .../hmcl/ui/export/ExportWizardProvider.java | 15 ++++--- .../TaskExecutorDialogWizardDisplayer.java | 5 ++- .../hmcl/util/i18n/LocalizedTaskStages.java | 32 ++++++++++++++ .../resources/assets/lang/I18N.properties | 2 +- .../resources/assets/lang/I18N_es.properties | 2 +- .../resources/assets/lang/I18N_ru.properties | 2 +- .../resources/assets/lang/I18N_zh.properties | 5 ++- .../assets/lang/I18N_zh_CN.properties | 2 +- .../download/DefaultDependencyManager.java | 9 ++-- .../hmcl/download/DefaultGameBuilder.java | 2 +- .../hmcl/download/game/GameInstallTask.java | 2 +- .../hmcl/mod/curse/CurseInstallTask.java | 4 +- .../org/jackhuang/hmcl/task/TaskExecutor.java | 9 ++++ .../org/jackhuang/hmcl/task/TaskStages.java | 43 +++++++++++++++++++ 21 files changed, 218 insertions(+), 50 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedTaskStages.java create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskStages.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index d4931efef..876c506c3 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -49,6 +49,7 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; import org.jackhuang.hmcl.util.*; import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter; +import org.jackhuang.hmcl.util.i18n.LocalizedTaskStages; import org.jackhuang.hmcl.util.io.ResponseCodeException; import org.jackhuang.hmcl.util.platform.CommandBuilder; import org.jackhuang.hmcl.util.platform.JavaVersion; @@ -199,12 +200,12 @@ public final class LauncherHelper { launchingLatch.await(); }).withStage("launch.state.waiting_launching")) .cancellableExecutor(); - - launchingStepsPane.setExecutor(executor, Lang.immutableListOf( + executor.setStages(new LocalizedTaskStages(Lang.immutableListOf( "launch.state.dependencies", "launch.state.modpack", "launch.state.logging_in", - "launch.state.waiting_launching"), false); + "launch.state.waiting_launching"))); + launchingStepsPane.setExecutor(executor, false); executor.addTaskListener(new TaskListener() { @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java index 6790eb11b..f78cc19b1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskExecutorDialogPane.java @@ -85,18 +85,10 @@ public class TaskExecutorDialogPane extends StackPane { } public void setExecutor(TaskExecutor executor, boolean autoClose) { - setExecutor(executor, Collections.emptyList(), autoClose); - } - - public void setExecutor(TaskExecutor executor, List stages) { - setExecutor(executor, stages, true); - } - - public void setExecutor(TaskExecutor executor, List stages, boolean autoClose) { this.executor = executor; if (executor != null) { - taskListPane.setExecutor(executor, stages); + taskListPane.setExecutor(executor); if (autoClose) executor.addTaskListener(new TaskListener() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java index 372e4bc57..a0f88927f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/TaskListPane.java @@ -19,13 +19,16 @@ package org.jackhuang.hmcl.ui.construct; import com.jfoenix.controls.JFXProgressBar; import javafx.application.Platform; -import javafx.beans.property.ReadOnlyIntegerProperty; -import javafx.beans.property.ReadOnlyIntegerWrapper; +import javafx.beans.binding.Bindings; +import javafx.beans.binding.DoubleBinding; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; +import org.jackhuang.hmcl.download.fabric.FabricInstallTask; import org.jackhuang.hmcl.download.forge.ForgeInstallTask; import org.jackhuang.hmcl.download.game.GameAssetDownloadTask; import org.jackhuang.hmcl.download.game.GameInstallTask; @@ -43,6 +46,7 @@ import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.task.TaskListener; +import org.jackhuang.hmcl.task.TaskStages; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.SVG; @@ -52,9 +56,11 @@ import java.util.stream.Collectors; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class TaskListPane extends StackPane { + private TaskExecutor executor; private final AdvancedListBox listBox = new AdvancedListBox(); private final Map, ProgressListNode> nodes = new HashMap<>(); private final List stageNodes = new ArrayList<>(); + private final ObjectProperty progressNodePadding = new SimpleObjectProperty<>(Insets.EMPTY); public TaskListPane() { listBox.setSpacing(0); @@ -63,19 +69,19 @@ public final class TaskListPane extends StackPane { } public void setExecutor(TaskExecutor executor) { - setExecutor(executor, Collections.emptyList()); - } - - public void setExecutor(TaskExecutor executor, List stages) { - + TaskStages stages = executor.getStages(); + this.executor = executor; executor.addTaskListener(new TaskListener() { @Override public void onStart() { Platform.runLater(() -> { stageNodes.clear(); listBox.clear(); - stageNodes.addAll(stages.stream().map(StageNode::new).collect(Collectors.toList())); + stageNodes.addAll(stages.getStages().stream().map(StageNode::new).collect(Collectors.toList())); stageNodes.forEach(listBox::add); + + if (stages.getStages().isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0)); + else progressNodePadding.setValue(new Insets(0, 0, 8, 26)); }); } @@ -103,6 +109,8 @@ public final class TaskListPane extends StackPane { task.setName(i18n("install.installer.install", i18n("install.installer.liteloader"))); } else if (task instanceof OptiFineInstallTask) { task.setName(i18n("install.installer.install", i18n("install.installer.optifine"))); + } else if (task instanceof FabricInstallTask) { + task.setName(i18n("install.installer.install", i18n("install.installer.fabric"))); } else if (task instanceof CurseCompletionTask) { task.setName(i18n("modpack.type.curse.completion")); } else if (task instanceof ModpackInstallTask) { @@ -163,7 +171,7 @@ public final class TaskListPane extends StackPane { }); } - private static class StageNode extends BorderPane { + private class StageNode extends BorderPane { private final String stage; private final Label title = new Label(); private boolean started = false; @@ -171,12 +179,12 @@ public final class TaskListPane extends StackPane { public StageNode(String stage) { this.stage = stage; - title.setText(i18n(stage)); + title.setText(executor.getStages().localize(stage)); BorderPane.setAlignment(title, Pos.CENTER_LEFT); BorderPane.setMargin(title, new Insets(0, 0, 0, 8)); setPadding(new Insets(0, 0, 8, 4)); setCenter(title); - setLeft(SVG.dotsHorizontal(Theme.blackFillBinding(), 14, 14)); + setLeft(FXUtils.limitingSize(SVG.dotsHorizontal(Theme.blackFillBinding(), 14, 14), 14, 14)); } public void begin() { @@ -194,10 +202,13 @@ public final class TaskListPane extends StackPane { } } - private static class ProgressListNode extends BorderPane { + private class ProgressListNode extends BorderPane { private final JFXProgressBar bar = new JFXProgressBar(); private final Label title = new Label(); private final Label state = new Label(); + private final DoubleBinding binding = Bindings.createDoubleBinding(() -> + getWidth() - getPadding().getLeft() - getPadding().getRight(), + paddingProperty(), widthProperty()); public ProgressListNode(Task task) { bar.progressProperty().bind(task.progressProperty()); @@ -208,9 +219,11 @@ public final class TaskListPane extends StackPane { setRight(state); setBottom(bar); - bar.minWidthProperty().bind(widthProperty()); - bar.prefWidthProperty().bind(widthProperty()); - bar.maxWidthProperty().bind(widthProperty()); + bar.minWidthProperty().bind(binding); + bar.prefWidthProperty().bind(binding); + bar.maxWidthProperty().bind(binding); + + paddingProperty().bind(progressNodePadding); } public void unbind() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java index c80c7c788..5aab98603 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallerWizardProvider.java @@ -30,6 +30,7 @@ import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.task.DownloadException; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskStages; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; import org.jackhuang.hmcl.ui.wizard.WizardController; @@ -73,14 +74,35 @@ public final class InstallerWizardProvider implements WizardProvider { @Override public Object finish(Map settings) { + settings.put("title", i18n("install.installer.install_online")); settings.put("success_message", i18n("install.success")); settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next)); + settings.put("stages", new TaskStages() { + { + if (settings.containsKey("forge")) { + RemoteVersion forge = (RemoteVersion) settings.get("forge"); + addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion())); + } + if (settings.containsKey("liteloader")) { + RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader"); + addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion())); + } + if (settings.containsKey("optifine")) { + RemoteVersion optifine = (RemoteVersion) settings.get("optifine"); + addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion())); + } + if (settings.containsKey("fabric")) { + RemoteVersion fabric = (RemoteVersion) settings.get("fabric"); + addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion())); + } + } + }); Task ret = Task.supplyAsync(() -> version); for (Object value : settings.values()) { if (value instanceof RemoteVersion) - ret = ret.thenComposeAsync(profile.getDependency().installLibraryAsync((RemoteVersion) value)); + ret = ret.thenComposeAsync(version -> profile.getDependency().installLibraryAsync(version, (RemoteVersion) value)); } return ret.thenComposeAsync(profile.getRepository().refreshVersionsAsync()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/ModpackInstallWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/ModpackInstallWizardProvider.java index 18b0fbad1..4be8dc258 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/ModpackInstallWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/ModpackInstallWizardProvider.java @@ -107,6 +107,7 @@ public class ModpackInstallWizardProvider implements WizardProvider { @Override public Object finish(Map settings) { + settings.put("title", i18n("install.modpack")); settings.put("success_message", i18n("install.success")); settings.put("failure_callback", new FailureCallback() { @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java index 0b108652e..5cd0d4428 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java @@ -22,6 +22,7 @@ import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Profile; +import org.jackhuang.hmcl.task.TaskStages; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardProvider; @@ -53,8 +54,29 @@ public final class UpdateInstallerWizardProvider implements WizardProvider { @Override public Object finish(Map settings) { + settings.put("title", i18n("install.change_version")); settings.put("success_message", i18n("install.success")); settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next)); + settings.put("stages", new TaskStages() { + { + if (settings.containsKey("forge")) { + RemoteVersion forge = (RemoteVersion) settings.get("forge"); + addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion())); + } + if (settings.containsKey("liteloader")) { + RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader"); + addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion())); + } + if (settings.containsKey("optifine")) { + RemoteVersion optifine = (RemoteVersion) settings.get("optifine"); + addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion())); + } + if (settings.containsKey("fabric")) { + RemoteVersion fabric = (RemoteVersion) settings.get("fabric"); + addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion())); + } + } + }); // We remove library but not save it, // so if installation failed will not break down current version. diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java index 82a6b670f..98ade9d75 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java @@ -24,6 +24,7 @@ import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.task.TaskStages; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardProvider; @@ -60,8 +61,34 @@ public final class VanillaInstallWizardProvider implements WizardProvider { @Override public Object finish(Map settings) { + settings.put("title", i18n("install.new_game")); settings.put("success_message", i18n("install.success")); settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> InstallerWizardProvider.alertFailureMessage(exception, next)); + settings.put("stages", new TaskStages() { + { + if (settings.containsKey("game")) { + RemoteVersion game = (RemoteVersion) settings.get("game"); + addStage("hmcl.install.game", i18n("install.installer.install", i18n("install.installer.game") + " " + game.getSelfVersion())); + addStage("hmcl.install.assets", i18n("assets.download")); + } + if (settings.containsKey("forge")) { + RemoteVersion forge = (RemoteVersion) settings.get("forge"); + addStage("hmcl.install.forge", i18n("install.installer.install", i18n("install.installer.forge") + " " + forge.getSelfVersion())); + } + if (settings.containsKey("liteloader")) { + RemoteVersion liteloader = (RemoteVersion) settings.get("liteloader"); + addStage("hmcl.install.liteloader", i18n("install.installer.install", i18n("install.installer.liteloader") + " " + liteloader.getSelfVersion())); + } + if (settings.containsKey("optifine")) { + RemoteVersion optifine = (RemoteVersion) settings.get("optifine"); + addStage("hmcl.install.optifine", i18n("install.installer.install", i18n("install.installer.optifine") + " " + optifine.getSelfVersion())); + } + if (settings.containsKey("fabric")) { + RemoteVersion fabric = (RemoteVersion) settings.get("fabric"); + addStage("hmcl.install.fabric", i18n("install.installer.install", i18n("install.installer.fabric") + " " + fabric.getSelfVersion())); + } + } + }); return finishVersionDownloadingAsync(settings); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ExportWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ExportWizardProvider.java index b2aa75749..1bfe7f9ab 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ExportWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ExportWizardProvider.java @@ -196,13 +196,18 @@ public final class ExportWizardProvider implements WizardProvider { } }; } - @Override + + @Override public Node createPage(WizardController controller, int step, Map settings) { switch (step) { - case 0: return new ModpackTypeSelectionPage(controller); - case 1: return new ModpackInfoPage(controller, version); - case 2: return new ModpackFileSelectionPage(controller, profile, version, ModAdviser::suggestMod); - default: throw new IllegalArgumentException("step"); + case 0: + return new ModpackTypeSelectionPage(controller); + case 1: + return new ModpackInfoPage(controller, version); + case 2: + return new ModpackFileSelectionPage(controller, profile, version, ModAdviser::suggestMod); + default: + throw new IllegalArgumentException("step"); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/TaskExecutorDialogWizardDisplayer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/TaskExecutorDialogWizardDisplayer.java index 32c42dd69..554897b07 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/TaskExecutorDialogWizardDisplayer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/wizard/TaskExecutorDialogWizardDisplayer.java @@ -21,6 +21,7 @@ import javafx.beans.property.StringProperty; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.task.TaskListener; +import org.jackhuang.hmcl.task.TaskStages; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.construct.DialogCloseEvent; import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; @@ -65,7 +66,7 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay return; String appendix = StringUtils.getStackTrace(executor.getException()); if (settings.get("failure_callback") instanceof WizardProvider.FailureCallback) - ((WizardProvider.FailureCallback)settings.get("failure_callback")).onFail(settings, executor.getException(), () -> onEnd()); + ((WizardProvider.FailureCallback) settings.get("failure_callback")).onFail(settings, executor.getException(), () -> onEnd()); else if (settings.get("failure_message") instanceof String) Controllers.dialog(appendix, (String) settings.get("failure_message"), MessageType.ERROR, () -> onEnd()); else if (!settings.containsKey("forbid_failure_message")) @@ -75,6 +76,8 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay }); } }); + if (settings.containsKey("stages")) + executor.setStages((TaskStages) settings.get("stages")); pane.setExecutor(executor); Controllers.dialog(pane); executor.start(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedTaskStages.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedTaskStages.java new file mode 100644 index 000000000..cb0cc5c2b --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedTaskStages.java @@ -0,0 +1,32 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2020 huangyuhui 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 . + */ +package org.jackhuang.hmcl.util.i18n; + +import org.jackhuang.hmcl.task.TaskStages; + +import java.util.List; + +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; + +public class LocalizedTaskStages extends TaskStages { + public LocalizedTaskStages(List stages) { + for (String stage : stages) { + addStage(stage, i18n(stage)); + } + } +} diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 1b1f5e4bf..c52b1a0ac 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -142,7 +142,7 @@ install.failed.version_mismatch=The library requires the game version %s, but th install.installer.choose=Choose a %s version install.installer.fabric=Fabric install.installer.forge=Forge -install.installer.game=Game +install.installer.game=Minecraft install.installer.install=Install %s install.installer.install_offline=Install/Upgrade from file install.installer.install_offline.extension=Forge/OptiFine installer diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 64db4d276..2df8610d4 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -139,7 +139,7 @@ install.failed.version_mismatch=El library requiere versión del juego %s, pero install.installer.choose=Escoja una versión de %s install.installer.fabric=Fabric install.installer.forge=Forge -install.installer.game=Juego +install.installer.game=Minecraft install.installer.install=Instalar %s install.installer.install_offline=Instalar/actualizar con archivo local install.installer.install_offline.extension=Instalador de Forge/OptiFine diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index ca5ba70e6..6c90468bf 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -139,7 +139,7 @@ install.failed.version_mismatch=Для библиотеки требуется install.installer.choose=Выберите %s версию install.installer.fabric=Fabric install.installer.forge=Forge -install.installer.game=Версия +install.installer.game=Minecraft install.installer.install=Установка %s install.installer.install_offline=Установить/Обновить из файла install.installer.install_offline.extension=Forge/OptiFine установщик diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index ddd5d232f..a088351a2 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -139,9 +139,10 @@ install.failed.malformed=剛才下載的檔案格式損壞。您可以切換到 install.failed.optifine_conflict=暫不支援 OptiFine 與 Forge 同時安裝在 Minecraft 1.13 上 install.failed.version_mismatch=該軟體需要的遊戲版本為 %s,但實際的遊戲版本為 %s。 install.installer.choose=選擇 %s 版本 +install.installer.fabric=Fabric install.installer.forge=Forge -install.installer.game=遊戲 -install.installer.install=安裝 %s +install.installer.game=Minecraft +install.installer.install=安裝%s install.installer.install_offline=從本機檔案安裝或升級 install.installer.install_offline.extension=Forge/OptiFine 安裝器 install.installer.install_offline.tooltip=支援匯入已經下載好的 Forge/OptiFine 安裝器 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 0ff6ec304..0b9dff638 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -141,7 +141,7 @@ install.failed.version_mismatch=该软件需要的游戏版本为 %s,但实际 install.installer.choose=选择 %s 版本 install.installer.fabric=Fabric install.installer.forge=Forge -install.installer.game=游戏 +install.installer.game=Minecraft install.installer.install=安装 %s install.installer.install_offline=从本地文件安装/升级 install.installer.install_offline.extension=Forge/OptiFine 安装器 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java index e8efa256a..6a453a81f 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultDependencyManager.java @@ -102,7 +102,8 @@ public class DefaultDependencyManager extends AbstractDependencyManager { VersionList versionList = getVersionList(libraryId); return versionList.loadAsync(gameVersion) .thenComposeAsync(() -> installLibraryAsync(baseVersion, versionList.getVersion(gameVersion, libraryVersion) - .orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion)))); + .orElseThrow(() -> new IOException("Remote library " + libraryId + " has no version " + libraryVersion)))) + .withStage("hmcl.install." + libraryId); } @Override @@ -112,11 +113,7 @@ public class DefaultDependencyManager extends AbstractDependencyManager { return removeLibraryAsync(baseVersion.resolvePreservingPatches(repository), libraryVersion.getLibraryId()) .thenComposeAsync(version -> libraryVersion.getInstallTask(this, version)) .thenApplyAsync(baseVersion::addPatch) - .thenComposeAsync(repository::save); - } - - public ExceptionalFunction, ?> installLibraryAsync(RemoteVersion libraryVersion) { - return version -> installLibraryAsync(version, libraryVersion); + .thenComposeAsync(repository::save).withStage("hmcl.install." + libraryVersion.getLibraryId()); } public Task installLibraryAsync(Version oldVersion, Path installer) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java index 9a8433c2b..40cd175c9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultGameBuilder.java @@ -54,7 +54,7 @@ public class DefaultGameBuilder extends GameBuilder { libraryTask = libraryTask.thenComposeAsync(libraryTaskHelper(gameVersion, entry.getKey(), entry.getValue())); for (RemoteVersion remoteVersion : remoteVersions) - libraryTask = libraryTask.thenComposeAsync(dependencyManager.installLibraryAsync(remoteVersion)); + libraryTask = libraryTask.thenComposeAsync(version -> dependencyManager.installLibraryAsync(version, remoteVersion)); return libraryTask.whenComplete(exception -> { if (exception != null) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameInstallTask.java index 4422f6a5b..8bada4526 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/game/GameInstallTask.java @@ -73,7 +73,7 @@ public class GameInstallTask extends Task { .thenComposeAsync(Task.allOf( new GameAssetDownloadTask(dependencyManager, version, GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY), new GameLibrariesTask(dependencyManager, version) - ).withComposeAsync(gameRepository.save(version)))); + ).withStage("hmcl.install.assets").withComposeAsync(gameRepository.save(version)))); } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java index d46deb6c1..08192cfba 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/curse/CurseInstallTask.java @@ -133,8 +133,8 @@ public final class CurseInstallTask extends Task { File root = repository.getVersionRoot(name); FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(manifest)); - dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest)); - dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), manifest.getOverrides(), manifest, MODPACK_TYPE, repository.getModpackConfiguration(name))); + dependencies.add(new CurseCompletionTask(dependencyManager, name, manifest).withStage("hmcl.modpack.download")); + dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), manifest.getOverrides(), manifest, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack.unzip")); } public static final String MODPACK_TYPE = "Curse"; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java index 853b5dbcf..3fe6888b1 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskExecutor.java @@ -30,6 +30,7 @@ public abstract class TaskExecutor { protected final AtomicInteger totTask = new AtomicInteger(0); protected final AtomicBoolean cancelled = new AtomicBoolean(false); protected Exception exception; + private TaskStages stages = TaskStages.EMPTY; public TaskExecutor(Task task) { this.firstTask = task; @@ -64,4 +65,12 @@ public abstract class TaskExecutor { public int getRunningTasks() { return totTask.get(); } + + public TaskStages getStages() { + return stages; + } + + public void setStages(TaskStages stages) { + this.stages = stages; + } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskStages.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskStages.java new file mode 100644 index 000000000..0f4463636 --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/TaskStages.java @@ -0,0 +1,43 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2020 huangyuhui 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 . + */ +package org.jackhuang.hmcl.task; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TaskStages { + public static final TaskStages EMPTY = new TaskStages(); + + private final List stages = new ArrayList<>(); + private final Map localization = new HashMap<>(); + + protected void addStage(String stage, String localizedMessage) { + stages.add(stage); + localization.put(stage, localizedMessage); + } + + public List getStages() { + return stages; + } + + public String localize(String stage) { + return localization.get(stage); + } +}