Install initial modpack

This commit is contained in:
huangyuhui 2018-01-27 21:23:24 +08:00
parent b776015b36
commit b783f3bae9
19 changed files with 209 additions and 105 deletions

View File

@ -57,7 +57,7 @@ public final class Main extends Application {
Logging.LOG.info("*** " + TITLE + " ***"); Logging.LOG.info("*** " + TITLE + " ***");
UPDATE_CHECKER.process(false) UPDATE_CHECKER.process(false)
.then(Task.of(Controllers::showUpdate)) .then(Task.of(Schedulers.javafx(), Controllers::showUpdate))
.start(); .start();
launch(args); launch(args);

View File

@ -49,6 +49,10 @@ public class HMCLGameRepository extends DefaultGameRepository {
this.profile = profile; this.profile = profile;
} }
public Profile getProfile() {
return profile;
}
private boolean useSelf(String version, String assetId) { private boolean useSelf(String version, String assetId) {
VersionSetting vs = profile.getVersionSetting(version); VersionSetting vs = profile.getVersionSetting(version);
return new File(getBaseDirectory(), "assets/indexes/" + assetId + ".json").exists() || vs.isNoCommon(); return new File(getBaseDirectory(), "assets/indexes/" + assetId + ".json").exists() || vs.isNoCommon();
@ -94,8 +98,6 @@ public class HMCLGameRepository extends DefaultGameRepository {
super.refreshVersionsImpl(); super.refreshVersionsImpl();
versions.keySet().forEach(this::loadVersionSetting); versions.keySet().forEach(this::loadVersionSetting);
checkModpack();
try { try {
File file = new File(getBaseDirectory(), "launcher_profiles.json"); File file = new File(getBaseDirectory(), "launcher_profiles.json");
if (!file.exists() && !versions.isEmpty()) if (!file.exists() && !versions.isEmpty())
@ -117,26 +119,6 @@ public class HMCLGameRepository extends DefaultGameRepository {
refreshVersionsAsync().start(); refreshVersionsAsync().start();
} }
private void checkModpack() {
if (!checkingModpack) {
checkingModpack = true;
if (getVersionCount() == 0) {
File modpack = new File("modpack.zip").getAbsoluteFile();
if (modpack.exists()) {
// TODO
}
/*
SwingUtilities.invokeLater(() -> {
if (TaskWindow.factory().execute(ModpackManager.install(MainFrame.INSTANCE, modpack, this, null)))
refreshVersions();
checkedModpack = true;
});
*/
}
}
}
private File getVersionSettingFile(String id) { private File getVersionSettingFile(String id) {
return new File(getVersionRoot(id), "hmclversion.cfg"); return new File(getVersionRoot(id), "hmclversion.cfg");
} }

View File

@ -159,8 +159,8 @@ public final class LauncherHelper {
if (state == LoadingState.DONE) if (state == LoadingState.DONE)
Controllers.closeDialog(); Controllers.closeDialog();
launchingStepsPane.setCurrentState(state.getLocalizedMessage()); launchingStepsPane.setTitle(state.getLocalizedMessage());
launchingStepsPane.setSteps((state.ordinal() + 1) + " / " + LoadingState.values().length); launchingStepsPane.setSubtitle((state.ordinal() + 1) + " / " + LoadingState.values().length);
Controllers.dialog(launchingStepsPane); Controllers.dialog(launchingStepsPane);
} }

View File

@ -81,6 +81,30 @@ public final class ModpackHelper {
throw new UnsupportedModpackException(); throw new UnsupportedModpackException();
} }
public static Task getInstallTask(Profile profile, File zipFile, String name, Modpack modpack) {
profile.getRepository().markVersionAsModpack(name);
Task finalizeTask = Task.of(() -> {
profile.getRepository().refreshVersions();
VersionSetting vs = profile.specializeVersionSetting(name);
profile.getRepository().undoMark(name);
if (vs != null)
vs.setGameDirType(EnumGameDirectory.VERSION_FOLDER);
});
if (modpack.getManifest() instanceof CurseManifest)
return new CurseInstallTask(profile.getDependency(), zipFile, ((CurseManifest) modpack.getManifest()), name)
.finalized(finalizeTask);
else if (modpack.getManifest() instanceof HMCLModpackManifest)
return new HMCLModpackInstallTask(profile, zipFile, modpack, name)
.finalized(finalizeTask);
else if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
return new MultiMCModpackInstallTask(profile.getDependency(), zipFile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name)
.finalized(finalizeTask)
.with(new MultiMCInstallVersionSettingTask(profile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name));
else throw new IllegalStateException("Unrecognized modpack: " + modpack);
}
public static Task getUpdateTask(Profile profile, File zipFile, String name, ModpackConfiguration configuration) throws UnsupportedModpackException, MismatchedModpackTypeException, IOException { public static Task getUpdateTask(Profile profile, File zipFile, String name, ModpackConfiguration configuration) throws UnsupportedModpackException, MismatchedModpackTypeException, IOException {
Modpack modpack = ModpackHelper.readModpackManifest(zipFile); Modpack modpack = ModpackHelper.readModpackManifest(zipFile);

View File

@ -26,9 +26,11 @@ import javafx.stage.Stage;
import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Main;
import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.setting.Settings;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.task.TaskExecutor;
import org.jackhuang.hmcl.ui.construct.InputDialogPane; import org.jackhuang.hmcl.ui.construct.InputDialogPane;
import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.ui.construct.MessageBox;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
import org.jackhuang.hmcl.util.JavaVersion; import org.jackhuang.hmcl.util.JavaVersion;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -132,6 +134,15 @@ public final class Controllers {
dialog(new InputDialogPane(text, decorator.getDialog(), onResult)); dialog(new InputDialogPane(text, decorator.getDialog(), onResult));
} }
public static void taskDialog(TaskExecutor executor, String title, String subtitle, Runnable onCancel) {
TaskExecutorDialogPane pane = new TaskExecutorDialogPane(onCancel);
pane.setTitle(title);
pane.setSubtitle(subtitle);
pane.setExecutor(executor);
executor.start();
dialog(pane);
}
public static void closeDialog() { public static void closeDialog() {
decorator.getDialog().close(); decorator.getDialog().close();
} }
@ -141,6 +152,6 @@ public final class Controllers {
} }
public static void showUpdate() { public static void showUpdate() {
getDecorator().showUpdate();
} }
} }

View File

@ -83,9 +83,9 @@ public class InstallerController {
public void onAdd() { public void onAdd() {
String gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)); String gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version));
// TODO: if minecraftVersion returns null. if (gameVersion == null)
if (gameVersion == null) return; Controllers.dialog("version.cannot_read");
else
Controllers.getDecorator().startWizard(new InstallerWizardProvider(profile, gameVersion, version, forge, liteLoader, optiFine)); Controllers.getDecorator().startWizard(new InstallerWizardProvider(profile, gameVersion, version, forge, liteLoader, optiFine));
} }
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hmcl.ui; package org.jackhuang.hmcl.ui;
import com.jfoenix.concurrency.JFXUtilities;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
@ -26,14 +27,23 @@ import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.EventBus;
import org.jackhuang.hmcl.event.ProfileChangedEvent; import org.jackhuang.hmcl.event.ProfileChangedEvent;
import org.jackhuang.hmcl.event.ProfileLoadingEvent; import org.jackhuang.hmcl.event.ProfileLoadingEvent;
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
import org.jackhuang.hmcl.game.AccountHelper; import org.jackhuang.hmcl.game.AccountHelper;
import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.game.ModpackHelper;
import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Settings; import org.jackhuang.hmcl.setting.Settings;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.construct.IconedItem; import org.jackhuang.hmcl.ui.construct.IconedItem;
import org.jackhuang.hmcl.ui.construct.RipplerContainer; import org.jackhuang.hmcl.ui.construct.RipplerContainer;
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.Pair;
import java.io.File;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Objects; import java.util.Objects;
@ -60,6 +70,7 @@ public final class LeftPaneController {
EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading); EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading);
EventBus.EVENT_BUS.channel(ProfileChangedEvent.class).register(this::onProfileChanged); EventBus.EVENT_BUS.channel(ProfileChangedEvent.class).register(this::onProfileChanged);
EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(this::onRefreshedVersions);
Controllers.getDecorator().getAddMenuButton().setOnMouseClicked(e -> Controllers.getDecorator().getAddMenuButton().setOnMouseClicked(e ->
Controllers.getDecorator().showPage(new ProfilePage(null)) Controllers.getDecorator().showPage(new ProfilePage(null))
@ -79,12 +90,9 @@ public final class LeftPaneController {
else else
accountItem.setImage(FXUtils.DEFAULT_ICON, null); accountItem.setImage(FXUtils.DEFAULT_ICON, null);
}); });
if (Settings.INSTANCE.getAccounts().isEmpty())
Controllers.navigate(new AccountsPage());
} }
public void onProfileChanged(ProfileChangedEvent event) { private void onProfileChanged(ProfileChangedEvent event) {
Profile profile = event.getProfile(); Profile profile = event.getProfile();
for (Node node : profilePane.getChildren()) { for (Node node : profilePane.getChildren()) {
@ -94,7 +102,7 @@ public final class LeftPaneController {
} }
} }
public void onProfilesLoading() { private void onProfilesLoading() {
LinkedList<RipplerContainer> list = new LinkedList<>(); LinkedList<RipplerContainer> list = new LinkedList<>();
for (Profile profile : Settings.INSTANCE.getProfiles()) { for (Profile profile : Settings.INSTANCE.getProfiles()) {
VersionListItem item = new VersionListItem(profile.getName()); VersionListItem item = new VersionListItem(profile.getName());
@ -115,4 +123,41 @@ public final class LeftPaneController {
} }
Platform.runLater(() -> profilePane.getChildren().setAll(list)); Platform.runLater(() -> profilePane.getChildren().setAll(list));
} }
private boolean checkedModpack = false;
private void onRefreshedVersions(RefreshedVersionsEvent event) {
JFXUtilities.runInFX(() -> {
boolean flag = true;
HMCLGameRepository repository = (HMCLGameRepository) event.getSource();
if (!checkedModpack) {
checkedModpack = true;
if (repository.getVersionCount() == 0) {
File modpackFile = new File("modpack.zip").getAbsoluteFile();
if (modpackFile.exists()) {
try {
Modpack modpack = ModpackHelper.readModpackManifest(modpackFile);
Controllers.taskDialog(ModpackHelper.getInstallTask(repository.getProfile(), modpackFile, modpack.getName(), modpack)
.with(Task.of(Schedulers.javafx(), () -> {
Controllers.closeDialog();
checkAccount();
})).executor(),
Main.i18n("modpack.installing"), "", null);
flag = false;
} catch (UnsupportedModpackException ignore) {
}
}
}
}
if (flag)
checkAccount();
});
}
private void checkAccount() {
if (Settings.INSTANCE.getAccounts().isEmpty())
Controllers.navigate(new AccountsPage());
}
} }

View File

@ -137,7 +137,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
TaskExecutor executor = ModpackHelper.getUpdateTask(profile, selectedFile, version, ModpackHelper.readModpackConfiguration(profile.getRepository().getModpackConfiguration(version))) TaskExecutor executor = ModpackHelper.getUpdateTask(profile, selectedFile, version, ModpackHelper.readModpackConfiguration(profile.getRepository().getModpackConfiguration(version)))
.then(Task.of(Schedulers.javafx(), Controllers::closeDialog)).executor(); .then(Task.of(Schedulers.javafx(), Controllers::closeDialog)).executor();
pane.setExecutor(executor); pane.setExecutor(executor);
pane.setCurrentState(Main.i18n("modpack.update")); pane.setTitle(Main.i18n("modpack.update"));
executor.start(); executor.start();
Controllers.dialog(pane); Controllers.dialog(pane);
} catch (UnsupportedModpackException e) { } catch (UnsupportedModpackException e) {

View File

@ -112,6 +112,9 @@ public final class VersionSettingsController {
javaItem.loadChildren(variables.<Collection<Node>>get("list")) javaItem.loadChildren(variables.<Collection<Node>>get("list"))
); );
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS)
javaItem.getExtensionFilters().add(new FileChooser.ExtensionFilter("Java", "java.exe", "javaw.exe"));
gameDirItem.loadChildren(Arrays.asList( gameDirItem.loadChildren(Arrays.asList(
gameDirItem.createChildren(Main.i18n("settings.advanced.game_dir.default"), EnumGameDirectory.ROOT_FOLDER), gameDirItem.createChildren(Main.i18n("settings.advanced.game_dir.default"), EnumGameDirectory.ROOT_FOLDER),
gameDirItem.createChildren(Main.i18n("settings.advanced.game_dir.independent"), EnumGameDirectory.VERSION_FOLDER) gameDirItem.createChildren(Main.i18n("settings.advanced.game_dir.independent"), EnumGameDirectory.VERSION_FOLDER)

View File

@ -63,8 +63,16 @@ public class FileItem extends BorderPane {
public void onExplore() { public void onExplore() {
DirectoryChooser chooser = new DirectoryChooser(); DirectoryChooser chooser = new DirectoryChooser();
if (property.getValue() != null) if (property.getValue() != null) {
chooser.setInitialDirectory(new File(property.getValue())); File file = new File(property.getValue());
if (file.exists()) {
if (file.isFile())
file = file.getAbsoluteFile().getParentFile();
else if (file.isDirectory())
file = file.getAbsoluteFile();
chooser.setInitialDirectory(file);
}
}
chooser.titleProperty().bind(titleProperty()); chooser.titleProperty().bind(titleProperty());
File selectedDir = chooser.showDialog(Controllers.getStage()); File selectedDir = chooser.showDialog(Controllers.getStage());
if (selectedDir != null) if (selectedDir != null)

View File

@ -20,8 +20,12 @@ package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXRadioButton; import com.jfoenix.controls.JFXRadioButton;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@ -30,6 +34,7 @@ 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 javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Main;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
@ -39,8 +44,10 @@ import java.io.File;
import java.util.Collection; import java.util.Collection;
public class MultiFileItem extends ComponentList { public class MultiFileItem extends ComponentList {
private final StringProperty customText = new SimpleStringProperty(this, "customText", "Custom"); private final StringProperty customTitle = new SimpleStringProperty(this, "customTitle", Main.i18n("selector.custom"));
private final StringProperty chooserTitle = new SimpleStringProperty(this, "chooserTitle", "Select a file"); private final StringProperty chooserTitle = new SimpleStringProperty(this, "chooserTitle", Main.i18n("selector.choose_file"));
private final BooleanProperty directory = new SimpleBooleanProperty(this, "directory", false);
private ObservableList<FileChooser.ExtensionFilter> extensionFilters = FXCollections.observableArrayList();
private final ToggleGroup group = new ToggleGroup(); private final ToggleGroup group = new ToggleGroup();
private final JFXTextField txtCustom = new JFXTextField(); private final JFXTextField txtCustom = new JFXTextField();
@ -54,10 +61,23 @@ public class MultiFileItem extends ComponentList {
btnSelect.setGraphic(SVG.folderOpen("black", 15, 15)); btnSelect.setGraphic(SVG.folderOpen("black", 15, 15));
btnSelect.setOnMouseClicked(e -> { btnSelect.setOnMouseClicked(e -> {
// TODO if (isDirectory()) {
DirectoryChooser chooser = new DirectoryChooser();
chooser.titleProperty().bind(chooserTitle);
File dir = chooser.showDialog(Controllers.getStage());
if (dir != null)
txtCustom.setText(dir.getAbsolutePath());
} else {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().addAll(getExtensionFilters());
chooser.titleProperty().bind(chooserTitle);
File file = chooser.showOpenDialog(Controllers.getStage());
if (file != null)
txtCustom.setText(file.getAbsolutePath());
}
}); });
radioCustom.textProperty().bind(customTextProperty()); radioCustom.textProperty().bind(customTitleProperty());
radioCustom.setToggleGroup(group); radioCustom.setToggleGroup(group);
txtCustom.disableProperty().bind(radioCustom.selectedProperty().not()); txtCustom.disableProperty().bind(radioCustom.selectedProperty().not());
btnSelect.disableProperty().bind(radioCustom.selectedProperty().not()); btnSelect.disableProperty().bind(radioCustom.selectedProperty().not());
@ -119,16 +139,16 @@ public class MultiFileItem extends ComponentList {
return group; return group;
} }
public String getCustomText() { public String getCustomTitle() {
return customText.get(); return customTitle.get();
} }
public StringProperty customTextProperty() { public StringProperty customTitleProperty() {
return customText; return customTitle;
} }
public void setCustomText(String customText) { public void setCustomTitle(String customTitle) {
this.customText.set(customText); this.customTitle.set(customTitle);
} }
public String getChooserTitle() { public String getChooserTitle() {
@ -151,7 +171,35 @@ public class MultiFileItem extends ComponentList {
return radioCustom; return radioCustom;
} }
public StringProperty customTextProperty() {
return txtCustom.textProperty();
}
public String getCustomText() {
return txtCustom.getText();
}
public void setCustomText(String customText) {
txtCustom.setText(customText);
}
public JFXTextField getTxtCustom() { public JFXTextField getTxtCustom() {
return txtCustom; return txtCustom;
} }
public boolean isDirectory() {
return directory.get();
}
public BooleanProperty directoryProperty() {
return directory;
}
public void setDirectory(boolean directory) {
this.directory.set(directory);
}
public ObservableList<FileChooser.ExtensionFilter> getExtensionFilters() {
return extensionFilters;
}
} }

View File

@ -23,10 +23,8 @@ import javafx.beans.property.StringProperty;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
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.construct.TaskListPane;
import java.util.Optional; import java.util.Optional;
@ -34,18 +32,18 @@ public class TaskExecutorDialogPane extends StackPane {
private TaskExecutor executor; private TaskExecutor executor;
@FXML @FXML
private JFXProgressBar pgsTasks; private JFXProgressBar progressBar;
@FXML @FXML
private Label lblCurrentState; private Label lblTitle;
@FXML @FXML
private Label lblSteps; private Label lblSubtitle;
@FXML @FXML
private JFXButton btnCancel; private JFXButton btnCancel;
@FXML @FXML
private TaskListPane taskListPane; private TaskListPane taskListPane;
public TaskExecutorDialogPane(Runnable cancel) { public TaskExecutorDialogPane(Runnable cancel) {
FXUtils.loadFXML(this, "/assets/fxml/launching-steps.fxml"); FXUtils.loadFXML(this, "/assets/fxml/task-dialog.fxml");
FXUtils.limitHeight(this, 200); FXUtils.limitHeight(this, 200);
FXUtils.limitWidth(this, 400); FXUtils.limitWidth(this, 400);
@ -64,34 +62,34 @@ public class TaskExecutorDialogPane extends StackPane {
taskListPane.setExecutor(executor); taskListPane.setExecutor(executor);
} }
public StringProperty currentStateProperty() { public StringProperty titleProperty() {
return lblCurrentState.textProperty(); return lblTitle.textProperty();
} }
public String getCurrentState() { public String getTitle() {
return lblCurrentState.getText(); return lblTitle.getText();
} }
public void setCurrentState(String currentState) { public void setTitle(String currentState) {
lblCurrentState.setText(currentState); lblTitle.setText(currentState);
} }
public StringProperty stepsProperty() { public StringProperty subtitleProperty() {
return lblSteps.textProperty(); return lblSubtitle.textProperty();
} }
public String getSteps() { public String getSubtitle() {
return lblSteps.getText(); return lblSubtitle.getText();
} }
public void setSteps(String steps) { public void setSubtitle(String subtitle) {
lblSteps.setText(steps); lblSubtitle.setText(subtitle);
} }
public void setProgress(double progress) { public void setProgress(double progress) {
if (progress == Double.MAX_VALUE) if (progress == Double.MAX_VALUE)
pgsTasks.setVisible(false); progressBar.setVisible(false);
else else
pgsTasks.setProgress(progress); progressBar.setProgress(progress);
} }
} }

View File

@ -25,7 +25,6 @@ import org.jackhuang.hmcl.task.TaskExecutor;
import org.jackhuang.hmcl.task.TaskListener; import org.jackhuang.hmcl.task.TaskListener;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.wizard.AbstractWizardDisplayer; import org.jackhuang.hmcl.ui.wizard.AbstractWizardDisplayer;
import org.jackhuang.hmcl.util.OperatingSystem;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import java.util.Map; import java.util.Map;
@ -39,22 +38,22 @@ public interface TaskExecutorDialogWizardDisplayer extends AbstractWizardDisplay
Controllers.navigate(null); Controllers.navigate(null);
}); });
pane.setCurrentState(Main.i18n("message.doing")); pane.setTitle(Main.i18n("message.doing"));
pane.setProgress(Double.MAX_VALUE); pane.setProgress(Double.MAX_VALUE);
if (settings.containsKey("title")) { if (settings.containsKey("title")) {
Object title = settings.get("title"); Object title = settings.get("title");
if (title instanceof StringProperty) if (title instanceof StringProperty)
pane.currentStateProperty().bind((StringProperty) title); pane.titleProperty().bind((StringProperty) title);
else if (title instanceof String) else if (title instanceof String)
pane.setCurrentState((String) title); pane.setTitle((String) title);
} }
if (settings.containsKey("subtitle")) { if (settings.containsKey("subtitle")) {
Object subtitle = settings.get("subtitle"); Object subtitle = settings.get("subtitle");
if (subtitle instanceof StringProperty) if (subtitle instanceof StringProperty)
pane.stepsProperty().bind((StringProperty) subtitle); pane.subtitleProperty().bind((StringProperty) subtitle);
else if (subtitle instanceof String) else if (subtitle instanceof String)
pane.setSteps((String) subtitle); pane.setSubtitle((String) subtitle);
} }
JFXUtilities.runInFX(() -> { JFXUtilities.runInFX(() -> {

View File

@ -23,6 +23,7 @@ import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.GameBuilder; import org.jackhuang.hmcl.download.GameBuilder;
import org.jackhuang.hmcl.game.HMCLModpackInstallTask; import org.jackhuang.hmcl.game.HMCLModpackInstallTask;
import org.jackhuang.hmcl.game.HMCLModpackManifest; import org.jackhuang.hmcl.game.HMCLModpackManifest;
import org.jackhuang.hmcl.game.ModpackHelper;
import org.jackhuang.hmcl.game.MultiMCInstallVersionSettingTask; import org.jackhuang.hmcl.game.MultiMCInstallVersionSettingTask;
import org.jackhuang.hmcl.mod.*; import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.setting.EnumGameDirectory; import org.jackhuang.hmcl.setting.EnumGameDirectory;
@ -75,27 +76,7 @@ public final class DownloadWizardProvider implements WizardProvider {
String name = Lang.get(settings, ModpackPage.MODPACK_NAME, String.class, null); String name = Lang.get(settings, ModpackPage.MODPACK_NAME, String.class, null);
if (selected == null || modpack == null || name == null) return null; if (selected == null || modpack == null || name == null) return null;
profile.getRepository().markVersionAsModpack(name); return ModpackHelper.getInstallTask(profile, selected, name, modpack);
Task finalizeTask = Task.of(() -> {
profile.getRepository().refreshVersions();
VersionSetting vs = profile.specializeVersionSetting(name);
profile.getRepository().undoMark(name);
if (vs != null)
vs.setGameDirType(EnumGameDirectory.VERSION_FOLDER);
});
if (modpack.getManifest() instanceof CurseManifest)
return new CurseInstallTask(profile.getDependency(), selected, ((CurseManifest) modpack.getManifest()), name)
.finalized(finalizeTask);
else if (modpack.getManifest() instanceof HMCLModpackManifest)
return new HMCLModpackInstallTask(profile, selected, modpack, name)
.finalized(finalizeTask);
else if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
return new MultiMCModpackInstallTask(profile.getDependency(), selected, ((MultiMCInstanceConfiguration) modpack.getManifest()), name)
.finalized(finalizeTask)
.with(new MultiMCInstallVersionSettingTask(profile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name));
else throw new IllegalStateException("Unrecognized modpack: " + modpack);
} }
@Override @Override

View File

@ -28,6 +28,7 @@ import javafx.stage.FileChooser;
import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Main;
import org.jackhuang.hmcl.game.ModpackHelper; import org.jackhuang.hmcl.game.ModpackHelper;
import org.jackhuang.hmcl.mod.Modpack; import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
@ -79,7 +80,6 @@ public final class ModpackPage extends StackPane implements WizardPage {
File selectedFile = chooser.showOpenDialog(Controllers.getStage()); File selectedFile = chooser.showOpenDialog(Controllers.getStage());
if (selectedFile == null) Platform.runLater(() -> Controllers.navigate(null)); if (selectedFile == null) Platform.runLater(() -> Controllers.navigate(null));
else { else {
// TODO: original HMCL modpack support.
controller.getSettings().put(MODPACK_FILE, selectedFile); controller.getSettings().put(MODPACK_FILE, selectedFile);
lblModpackLocation.setText(selectedFile.getAbsolutePath()); lblModpackLocation.setText(selectedFile.getAbsolutePath());
txtModpackName.getValidators().addAll( txtModpackName.getValidators().addAll(
@ -95,8 +95,7 @@ public final class ModpackPage extends StackPane implements WizardPage {
lblVersion.setText(manifest.getVersion()); lblVersion.setText(manifest.getVersion());
lblAuthor.setText(manifest.getAuthor()); lblAuthor.setText(manifest.getAuthor());
txtModpackName.setText(manifest.getName() + (StringUtils.isBlank(manifest.getVersion()) ? "" : "-" + manifest.getVersion())); txtModpackName.setText(manifest.getName() + (StringUtils.isBlank(manifest.getVersion()) ? "" : "-" + manifest.getVersion()));
} catch (Exception e) { } catch (UnsupportedModpackException e) {
// TODO
txtModpackName.setText(Main.i18n("modpack.task.install.error")); txtModpackName.setText(Main.i18n("modpack.task.install.error"));
} }
} }

View File

@ -10,10 +10,10 @@
<fx:root xmlns="http://javafx.com/javafx" <fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml" xmlns:fx="http://javafx.com/fxml"
type="StackPane"> type="StackPane">
<JFXProgressBar fx:id="pgsTasks" StackPane.alignment="TOP_CENTER" /> <JFXProgressBar fx:id="progressBar" StackPane.alignment="TOP_CENTER" />
<VBox alignment="TOP_CENTER" style="-fx-padding: 16px;"> <VBox alignment="TOP_CENTER" style="-fx-padding: 16px;">
<Label fx:id="lblCurrentState" style="-fx-font-size: 20px;" /> <Label fx:id="lblTitle" style="-fx-font-size: 20px;" />
<Label fx:id="lblSteps" style="-fx-font-size: 14px;" /> <Label fx:id="lblSubtitle" style="-fx-font-size: 14px;" />
<TaskListPane fx:id="taskListPane" /> <TaskListPane fx:id="taskListPane" />
</VBox> </VBox>
<StackPane pickOnBounds="false" style="-fx-padding: 8px;"> <StackPane pickOnBounds="false" style="-fx-padding: 8px;">

View File

@ -41,10 +41,10 @@
</BorderPane> </BorderPane>
<MultiFileItem fx:id="javaItem" title="%settings.game.java_directory" chooserTitle="%settings.choose_javapath" <MultiFileItem fx:id="javaItem" title="%settings.game.java_directory" chooserTitle="%settings.choose_javapath"
hasSubtitle="true" customText="%settings.custom" /> hasSubtitle="true" customText="%settings.custom" directory="false" />
<MultiFileItem fx:id="gameDirItem" title="%profile.instance_directory" chooserTitle="%settings.choose_gamedir" <MultiFileItem fx:id="gameDirItem" title="%profile.instance_directory" chooserTitle="%settings.choose_gamedir"
hasSubtitle="true" customText="%settings.custom" /> hasSubtitle="true" customText="%settings.custom" directory="true" />
<BorderPane> <!-- Max Memory --> <BorderPane> <!-- Max Memory -->
<left> <left>

View File

@ -218,7 +218,6 @@ minecraft.not_readable=Not readable
minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path. minecraft.wrong_path=Wrong Minecraft path, the launcher could not find the path.
modpack=Mod pack modpack=Mod pack
modpack.cannot_read_version=Failed to gather the game version
modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update. modpack.choose=Choose a modpack zip file which you want to import. If you want to update the modpack, please enter the version you want to update.
modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures). modpack.desc=Describe your modpack, including precautions, changlog, supporting Markdown(also supporting online pictures).
modpack.enter_name=Enter your desired name for this game. modpack.enter_name=Enter your desired name for this game.
@ -239,6 +238,7 @@ modpack.files.scripts=MineTweaker configuration
modpack.files.servers_dat=Multiplayer servers list modpack.files.servers_dat=Multiplayer servers list
modpack.included_launcher=The modpack is included the launcher, you can publish it directly. modpack.included_launcher=The modpack is included the launcher, you can publish it directly.
modpack.install=Install %s modpack modpack.install=Install %s modpack
modpack.installing=Installing modpack
modpack.invalid=Invalid modpack file. modpack.invalid=Invalid modpack file.
modpack.mismatched_type=Mismatched modpack type, your current game is %s modpack, but your update file is %s modpack. modpack.mismatched_type=Mismatched modpack type, your current game is %s modpack, but your update file is %s modpack.
modpack.name=Modpack Name modpack.name=Modpack Name
@ -285,6 +285,8 @@ profile.new_name=New Profile Name:
profile.remove=Sure to remove profile %s? profile.remove=Sure to remove profile %s?
selector.choose=Choose selector.choose=Choose
selector.choose_file=Select a file
selector.custom=Custom
settings=Settings settings=Settings
@ -355,6 +357,7 @@ update.newest_version=Newest version:
update.no_browser=Cannot open any browser. The link has been copied to the clipboard. Paste it to a browser address bar to update. update.no_browser=Cannot open any browser. The link has been copied to the clipboard. Paste it to a browser address bar to update.
update.should_open_link=Are you willing to update the launcher? update.should_open_link=Are you willing to update the launcher?
version.cannot_read=Unable to gather the game version. Cannot continue auto-installing.
version.forbidden_name=Forbidden name, do not use this. version.forbidden_name=Forbidden name, do not use this.
version.game.old_alpha=Old Alpha version.game.old_alpha=Old Alpha
version.game.old_beta=Beta version.game.old_beta=Beta

View File

@ -218,7 +218,6 @@ minecraft.not_readable=minecraft.jar不可读
minecraft.wrong_path=错误的Minecraft路径启动器未找到设定的Minecraft路径请检查。 minecraft.wrong_path=错误的Minecraft路径启动器未找到设定的Minecraft路径请检查。
modpack=整合包 modpack=整合包
modpack.cannot_read_version=读取游戏版本失败
modpack.choose=选择要导入的游戏整合包文件,如果您希望更新整合包,请输入要更新的版本名 modpack.choose=选择要导入的游戏整合包文件,如果您希望更新整合包,请输入要更新的版本名
modpack.desc=描述你要制作的整合包比如整合包注意事项和更新记录支持Markdown(图片请用网络图片)。 modpack.desc=描述你要制作的整合包比如整合包注意事项和更新记录支持Markdown(图片请用网络图片)。
modpack.enter_name=给游戏起个你喜欢的名字 modpack.enter_name=给游戏起个你喜欢的名字
@ -239,6 +238,7 @@ modpack.files.scripts=MineTweaker配置
modpack.files.servers_dat=多人游戏服务器列表 modpack.files.servers_dat=多人游戏服务器列表
modpack.included_launcher=整合包已包含启动器,可直接发布 modpack.included_launcher=整合包已包含启动器,可直接发布
modpack.install=安装%s整合包 modpack.install=安装%s整合包
modpack.installing=正在安装整合包
modpack.invalid=无效的整合包升级文件,可能是下载时出现问题。 modpack.invalid=无效的整合包升级文件,可能是下载时出现问题。
modpack.mismatched_type=整合包类型不匹配,当前游戏是 %s 整合包,但是提供的整合包更新文件是 %s 整合包。 modpack.mismatched_type=整合包类型不匹配,当前游戏是 %s 整合包,但是提供的整合包更新文件是 %s 整合包。
modpack.name=整合包名称 modpack.name=整合包名称
@ -285,6 +285,8 @@ profile.new_name=新配置名:
profile.remove=真的要删除配置%s吗 profile.remove=真的要删除配置%s吗
selector.choose=选择 selector.choose=选择
selector.choose_file=选择文件
selector.custom=自定义
settings=普通设置 settings=普通设置
@ -355,6 +357,7 @@ update.newest_version=最新版本为:
update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面 update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面
update.should_open_link=是否更新? update.should_open_link=是否更新?
version.cannot_read=读取游戏版本失败,无法进行自动安装
version.forbidden_name=此版本名称不受支持,请换一个名字 version.forbidden_name=此版本名称不受支持,请换一个名字
version.game.old_alpha=远古版 version.game.old_alpha=远古版
version.game.old_beta=测试版 version.game.old_beta=测试版