add: stages of modpack installation
This commit is contained in:
@@ -35,6 +35,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class HMCLModpackInstallTask extends Task<Void> {
|
||||
private final File zipFile;
|
||||
@@ -102,7 +104,15 @@ public final class HMCLModpackInstallTask extends Task<Void> {
|
||||
}
|
||||
|
||||
dependencies.add(libraryTask.thenComposeAsync(repository::save));
|
||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/minecraft", modpack, MODPACK_TYPE, repository.getModpackConfiguration(name)));
|
||||
dependencies.add(new MinecraftInstanceTask<>(zipFile, modpack.getEncoding(), "/minecraft", modpack, MODPACK_TYPE, repository.getModpackConfiguration(name)).withStage("hmcl.modpack"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStages() {
|
||||
return Stream.concat(
|
||||
dependents.stream().flatMap(task -> task.getStages().stream()),
|
||||
Stream.of("hmcl.modpack")
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static final String MODPACK_TYPE = "HMCL";
|
||||
|
||||
@@ -49,7 +49,6 @@ 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;
|
||||
@@ -128,28 +127,26 @@ public final class LauncherHelper {
|
||||
Version version = MaintainTask.maintain(repository, repository.getResolvedVersion(selectedVersion));
|
||||
Optional<String> gameVersion = GameVersion.minecraftVersion(repository.getVersionJar(version));
|
||||
|
||||
TaskExecutor executor = Task.runAsync(() -> {
|
||||
})
|
||||
.thenComposeAsync(() -> Task.allOf(
|
||||
Task.composeAsync(null, () -> {
|
||||
if (setting.isNotCheckGame())
|
||||
return null;
|
||||
else
|
||||
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
|
||||
}), Task.composeAsync(null, () -> {
|
||||
try {
|
||||
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
||||
if ("Curse".equals(configuration.getType()))
|
||||
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
||||
else if ("Server".equals(configuration.getType()))
|
||||
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
||||
else
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
})).withStage("launch.state.dependencies"))
|
||||
.thenComposeAsync(() -> Task.supplyAsync((String) null, () -> {
|
||||
TaskExecutor executor = Task.allOf(
|
||||
Task.composeAsync(null, () -> {
|
||||
if (setting.isNotCheckGame())
|
||||
return null;
|
||||
else
|
||||
return dependencyManager.checkGameCompletionAsync(version, repository.unmarkVersionLaunchedAbnormally(selectedVersion));
|
||||
}), Task.composeAsync(null, () -> {
|
||||
try {
|
||||
ModpackConfiguration<?> configuration = ModpackHelper.readModpackConfiguration(repository.getModpackConfiguration(selectedVersion));
|
||||
if ("Curse".equals(configuration.getType()))
|
||||
return new CurseCompletionTask(dependencyManager, selectedVersion);
|
||||
else if ("Server".equals(configuration.getType()))
|
||||
return new ServerModpackCompletionTask(dependencyManager, selectedVersion);
|
||||
else
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
})).withStage("launch.state.dependencies")
|
||||
.thenComposeAsync(Task.supplyAsync((String) null, () -> {
|
||||
try {
|
||||
return account.logIn();
|
||||
} catch (CredentialExpiredException e) {
|
||||
@@ -199,11 +196,11 @@ public final class LauncherHelper {
|
||||
launchingLatch = new CountDownLatch(1);
|
||||
launchingLatch.await();
|
||||
}).withStage("launch.state.waiting_launching"))
|
||||
.withStagesHint(Lang.immutableListOf(
|
||||
"launch.state.dependencies",
|
||||
"launch.state.logging_in",
|
||||
"launch.state.waiting_launching"))
|
||||
.cancellableExecutor();
|
||||
executor.setStages(new LocalizedTaskStages(Lang.immutableListOf(
|
||||
"launch.state.dependencies",
|
||||
"launch.state.logging_in",
|
||||
"launch.state.waiting_launching")));
|
||||
launchingStepsPane.setExecutor(executor, false);
|
||||
executor.addTaskListener(new TaskListener() {
|
||||
|
||||
|
||||
@@ -46,9 +46,10 @@ 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;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -72,7 +73,7 @@ public final class TaskListPane extends StackPane {
|
||||
}
|
||||
|
||||
public void setExecutor(TaskExecutor executor) {
|
||||
TaskStages stages = executor.getStages();
|
||||
List<String> stages = Lang.removingDuplicates(executor.getStages());
|
||||
this.executor = executor;
|
||||
executor.addTaskListener(new TaskListener() {
|
||||
@Override
|
||||
@@ -80,10 +81,10 @@ public final class TaskListPane extends StackPane {
|
||||
Platform.runLater(() -> {
|
||||
stageNodes.clear();
|
||||
listBox.clear();
|
||||
stageNodes.addAll(stages.getStages().stream().map(StageNode::new).collect(Collectors.toList()));
|
||||
stageNodes.addAll(stages.stream().map(StageNode::new).collect(Collectors.toList()));
|
||||
stageNodes.forEach(listBox::add);
|
||||
|
||||
if (stages.getStages().isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0));
|
||||
if (stages.isEmpty()) progressNodePadding.setValue(new Insets(0, 0, 8, 0));
|
||||
else progressNodePadding.setValue(new Insets(0, 0, 8, 26));
|
||||
});
|
||||
}
|
||||
@@ -182,7 +183,25 @@ public final class TaskListPane extends StackPane {
|
||||
public StageNode(String stage) {
|
||||
this.stage = stage;
|
||||
|
||||
title.setText(executor.getStages().localize(stage));
|
||||
String stageKey = StringUtils.substringBefore(stage, ':');
|
||||
String stageValue = StringUtils.substringAfter(stage, ':');
|
||||
String message;
|
||||
|
||||
// @formatter:off
|
||||
switch (stageKey) {
|
||||
case "hmcl.modpack": message = i18n("install.modpack"); break;
|
||||
case "hmcl.modpack.download": message = i18n("launch.state.modpack"); break;
|
||||
case "hmcl.install.assets": message = i18n("assets.download"); break;
|
||||
case "hmcl.install.game": message = i18n("install.installer.install", i18n("install.installer.game") + " " + stageValue); break;
|
||||
case "hmcl.install.forge": message = i18n("install.installer.install", i18n("install.installer.forge") + " " + stageValue); break;
|
||||
case "hmcl.install.liteloader": message = i18n("install.installer.install", i18n("install.installer.liteloader") + " " + stageValue); break;
|
||||
case "hmcl.install.optifine": message = i18n("install.installer.install", i18n("install.installer.optifine") + " " + stageValue); break;
|
||||
case "hmcl.install.fabric": message = i18n("install.installer.install", i18n("install.installer.fabric") + " " + stageValue); break;
|
||||
default: message = i18n(stageKey); break;
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
title.setText(message);
|
||||
BorderPane.setAlignment(title, Pos.CENTER_LEFT);
|
||||
BorderPane.setMargin(title, new Insets(0, 0, 0, 8));
|
||||
setPadding(new Insets(0, 0, 8, 4));
|
||||
@@ -210,7 +229,7 @@ public final class TaskListPane extends StackPane {
|
||||
private final Label title = new Label();
|
||||
private final Label state = new Label();
|
||||
private final DoubleBinding binding = Bindings.createDoubleBinding(() ->
|
||||
getWidth() - getPadding().getLeft() - getPadding().getRight() - 100,
|
||||
getWidth() - getPadding().getLeft() - getPadding().getRight(),
|
||||
paddingProperty(), widthProperty());
|
||||
|
||||
public ProgressListNode(Task<?> task) {
|
||||
|
||||
@@ -30,7 +30,6 @@ 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;
|
||||
@@ -41,6 +40,8 @@ import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@@ -77,35 +78,18 @@ public final class InstallerWizardProvider implements WizardProvider {
|
||||
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<Version> ret = Task.supplyAsync(() -> version);
|
||||
|
||||
List<String> stages = new ArrayList<>();
|
||||
for (Object value : settings.values()) {
|
||||
if (value instanceof RemoteVersion)
|
||||
ret = ret.thenComposeAsync(version -> profile.getDependency().installLibraryAsync(version, (RemoteVersion) value));
|
||||
if (value instanceof RemoteVersion) {
|
||||
RemoteVersion remoteVersion = (RemoteVersion) value;
|
||||
ret = ret.thenComposeAsync(version -> profile.getDependency().installLibraryAsync(version, remoteVersion));
|
||||
stages.add(String.format("hmcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
return ret.thenComposeAsync(profile.getRepository().refreshVersionsAsync());
|
||||
return ret.thenComposeAsync(profile.getRepository().refreshVersionsAsync()).withStagesHint(stages);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,7 +22,6 @@ 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;
|
||||
@@ -57,26 +56,6 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
||||
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.
|
||||
|
||||
@@ -24,7 +24,6 @@ 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;
|
||||
|
||||
@@ -64,31 +63,6 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ 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;
|
||||
@@ -76,8 +75,6 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay
|
||||
});
|
||||
}
|
||||
});
|
||||
if (settings.containsKey("stages"))
|
||||
executor.setStages((TaskStages) settings.get("stages"));
|
||||
pane.setExecutor(executor);
|
||||
Controllers.dialog(pane);
|
||||
executor.start();
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.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<String> stages) {
|
||||
for (String stage : stages) {
|
||||
addStage(stage, i18n(stage));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user