mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-18 00:10:33 -04:00
Cached Minecraft jars
This commit is contained in:
parent
1a572be52e
commit
418be689f2
@ -69,10 +69,10 @@ public class HMCLGameDownloadTask extends Task {
|
|||||||
|
|
||||||
dependencies.add(new FileDownloadTask(
|
dependencies.add(new FileDownloadTask(
|
||||||
NetworkUtils.toURL(profile.getDependency().getDownloadProvider().injectURL(version.getDownloadInfo().getUrl())),
|
NetworkUtils.toURL(profile.getDependency().getDownloadProvider().injectURL(version.getDownloadInfo().getUrl())),
|
||||||
jar,
|
cache,
|
||||||
profile.getDependency().getProxy(),
|
profile.getDependency().getProxy(),
|
||||||
version.getDownloadInfo().getSha1()
|
version.getDownloadInfo().getSha1()
|
||||||
));
|
).then(Task.of(v -> FileUtils.copyFile(cache, jar))));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.google.gson.GsonBuilder;
|
|||||||
import org.jackhuang.hmcl.event.EventBus;
|
import org.jackhuang.hmcl.event.EventBus;
|
||||||
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
||||||
import org.jackhuang.hmcl.event.RefreshingVersionsEvent;
|
import org.jackhuang.hmcl.event.RefreshingVersionsEvent;
|
||||||
|
import org.jackhuang.hmcl.setting.EnumGameDirectory;
|
||||||
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.setting.VersionSetting;
|
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||||
@ -63,7 +64,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getRunDirectory(String id) {
|
public File getRunDirectory(String id) {
|
||||||
if (beingModpackVersions.contains(id))
|
if (beingModpackVersions.contains(id) || isModpack(id))
|
||||||
return getVersionRoot(id);
|
return getVersionRoot(id);
|
||||||
else {
|
else {
|
||||||
VersionSetting vs = profile.getVersionSetting(id);
|
VersionSetting vs = profile.getVersionSetting(id);
|
||||||
@ -155,7 +156,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
if (!hasVersion(id))
|
if (!hasVersion(id))
|
||||||
return null;
|
return null;
|
||||||
if (versionSettings.containsKey(id))
|
if (versionSettings.containsKey(id))
|
||||||
return versionSettings.get(id);
|
return getVersionSetting(id);
|
||||||
else
|
else
|
||||||
return initVersionSetting(id, new VersionSetting());
|
return initVersionSetting(id, new VersionSetting());
|
||||||
}
|
}
|
||||||
@ -176,7 +177,10 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
public VersionSetting getVersionSetting(String id) {
|
public VersionSetting getVersionSetting(String id) {
|
||||||
if (!versionSettings.containsKey(id))
|
if (!versionSettings.containsKey(id))
|
||||||
loadVersionSetting(id);
|
loadVersionSetting(id);
|
||||||
return versionSettings.get(id);
|
VersionSetting setting = versionSettings.get(id);
|
||||||
|
if (setting != null && isModpack(id))
|
||||||
|
setting.setGameDirType(EnumGameDirectory.VERSION_FOLDER);
|
||||||
|
return setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getVersionIcon(String id) {
|
public File getVersionIcon(String id) {
|
||||||
@ -195,7 +199,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getModpackConfiguration(String version) {
|
public File getModpackConfiguration(String version) {
|
||||||
return new File(getRunDirectory(version), "modpack.cfg");
|
return new File(getVersionRoot(version), "modpack.cfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markVersionAsModpack(String id) {
|
public void markVersionAsModpack(String id) {
|
||||||
|
@ -115,6 +115,11 @@ public final class LauncherHelper {
|
|||||||
launchingStepsPane.setProgress(1.0 * finished.get() / executor.getRunningTasks());
|
launchingStepsPane.setProgress(1.0 * finished.get() / executor.getRunningTasks());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTerminate() {
|
||||||
|
Controllers.closeDialog();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
executor.start();
|
executor.start();
|
||||||
|
@ -44,7 +44,6 @@ public final class MultiMCInstallVersionSettingTask extends Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
profile.getRepository().refreshVersions();
|
|
||||||
VersionSetting vs = Objects.requireNonNull(profile.specializeVersionSetting(version));
|
VersionSetting vs = Objects.requireNonNull(profile.specializeVersionSetting(version));
|
||||||
ModpackHelper.toVersionSetting(manifest, vs);
|
ModpackHelper.toVersionSetting(manifest, vs);
|
||||||
}
|
}
|
||||||
|
@ -426,11 +426,9 @@ public final class Decorator extends StackPane implements TaskExecutorDialogWiza
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JFXDialog showDialog(Region content) {
|
public JFXDialog showDialog(Region content) {
|
||||||
if (dialog.getContent() != content) {
|
dialog.setContent(content);
|
||||||
dialog.setContent(content);
|
if (!dialogShown)
|
||||||
if (!dialogShown)
|
dialog.show();
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
package org.jackhuang.hmcl.ui;
|
package org.jackhuang.hmcl.ui;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXListView;
|
||||||
import com.jfoenix.controls.JFXMasonryPane;
|
import com.jfoenix.controls.JFXMasonryPane;
|
||||||
|
import com.jfoenix.controls.JFXPopup;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
@ -26,6 +28,7 @@ import javafx.fxml.FXML;
|
|||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
@ -61,6 +64,9 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
|
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title", Main.i18n("main_page"));
|
private final StringProperty title = new SimpleStringProperty(this, "title", Main.i18n("main_page"));
|
||||||
|
|
||||||
|
private Profile profile;
|
||||||
|
private String rightClickedVersion;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton btnRefresh;
|
private JFXButton btnRefresh;
|
||||||
|
|
||||||
@ -70,6 +76,11 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
@FXML
|
@FXML
|
||||||
private JFXMasonryPane masonryPane;
|
private JFXMasonryPane masonryPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXListView versionList;
|
||||||
|
|
||||||
|
private JFXPopup versionPopup;
|
||||||
|
|
||||||
{
|
{
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/main.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/main.fxml");
|
||||||
|
|
||||||
@ -77,6 +88,9 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
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);
|
||||||
|
|
||||||
|
versionPopup = new JFXPopup(versionList);
|
||||||
|
getChildren().remove(versionList);
|
||||||
|
|
||||||
btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), Main.i18n("install")));
|
btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), Main.i18n("install")));
|
||||||
FXUtils.installTooltip(btnAdd, 0, 5000, 0, new Tooltip(Main.i18n("install")));
|
FXUtils.installTooltip(btnAdd, 0, 5000, 0, new Tooltip(Main.i18n("install")));
|
||||||
btnRefresh.setOnMouseClicked(e -> Settings.INSTANCE.getSelectedProfile().getRepository().refreshVersionsAsync().start());
|
btnRefresh.setOnMouseClicked(e -> Settings.INSTANCE.getSelectedProfile().getRepository().refreshVersionsAsync().start());
|
||||||
@ -136,6 +150,13 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
item.setOnMouseClicked(event -> {
|
||||||
|
if (event.getButton() == MouseButton.SECONDARY) {
|
||||||
|
rightClickedVersion = version;
|
||||||
|
versionList.getSelectionModel().select(-1);
|
||||||
|
versionPopup.show(item, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, event.getX(), event.getY());
|
||||||
|
}
|
||||||
|
});
|
||||||
File iconFile = profile.getRepository().getVersionIcon(version);
|
File iconFile = profile.getRepository().getVersionIcon(version);
|
||||||
if (iconFile.exists())
|
if (iconFile.exists())
|
||||||
item.setImage(new Image("file:" + iconFile.getAbsolutePath()));
|
item.setImage(new Image("file:" + iconFile.getAbsolutePath()));
|
||||||
@ -155,6 +176,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadVersions(Profile profile) {
|
private void loadVersions(Profile profile) {
|
||||||
|
this.profile = profile;
|
||||||
List<Node> children = new LinkedList<>();
|
List<Node> children = new LinkedList<>();
|
||||||
for (Version version : profile.getRepository().getVersions()) {
|
for (Version version : profile.getRepository().getVersions()) {
|
||||||
children.add(buildNode(profile, version.getId(), Lang.nonNull(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version.getId())), "Unknown")));
|
children.add(buildNode(profile, version.getId(), Lang.nonNull(GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version.getId())), "Unknown")));
|
||||||
@ -162,6 +184,21 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
FXUtils.resetChildren(masonryPane, children);
|
FXUtils.resetChildren(masonryPane, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onVersionManagement() {
|
||||||
|
versionPopup.hide();
|
||||||
|
switch (versionList.getSelectionModel().getSelectedIndex()) {
|
||||||
|
case 0:
|
||||||
|
VersionPage.renameVersion(profile, rightClickedVersion);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
VersionPage.deleteVersion(profile, rightClickedVersion);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
VersionPage.exportVersion(profile, rightClickedVersion);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title.get();
|
return title.get();
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
|||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public final class VersionPage extends StackPane implements DecoratorPage {
|
public final class VersionPage extends StackPane implements DecoratorPage {
|
||||||
@ -112,16 +113,11 @@ public final class VersionPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDelete() {
|
public void onDelete() {
|
||||||
Controllers.confirmDialog(Main.i18n("version.manage.remove.confirm", version), Main.i18n("message.confirm"), () -> {
|
deleteVersion(profile, version);
|
||||||
if (profile.getRepository().removeVersionFromDisk(version)) {
|
|
||||||
profile.getRepository().refreshVersionsAsync().start();
|
|
||||||
Controllers.navigate(null);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onExport() {
|
public void onExport() {
|
||||||
Controllers.getDecorator().startWizard(new ExportWizardProvider(profile, version), Main.i18n("modpack.wizard"));
|
exportVersion(profile, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBrowse() {
|
public void onBrowse() {
|
||||||
@ -157,16 +153,10 @@ public final class VersionPage extends StackPane implements DecoratorPage {
|
|||||||
public void onManagement() {
|
public void onManagement() {
|
||||||
switch (managementList.getSelectionModel().getSelectedIndex()) {
|
switch (managementList.getSelectionModel().getSelectedIndex()) {
|
||||||
case 0: // rename a version
|
case 0: // rename a version
|
||||||
Optional<String> res = FXUtils.inputDialog("Input", Main.i18n("version.manage.rename.message"), null, version);
|
renameVersion(profile, version);
|
||||||
if (res.isPresent()) {
|
|
||||||
if (profile.getRepository().renameVersion(version, res.get())) {
|
|
||||||
profile.getRepository().refreshVersionsAsync().start();
|
|
||||||
Controllers.navigate(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 1: // remove a version
|
case 1: // remove a version
|
||||||
onDelete();
|
deleteVersion(profile, version);
|
||||||
break;
|
break;
|
||||||
case 2: // redownload asset index
|
case 2: // redownload asset index
|
||||||
new GameAssetIndexDownloadTask(profile.getDependency(), profile.getRepository().getVersion(version).resolve(profile.getRepository())).start();
|
new GameAssetIndexDownloadTask(profile.getDependency(), profile.getRepository().getVersion(version).resolve(profile.getRepository())).start();
|
||||||
@ -191,4 +181,26 @@ public final class VersionPage extends StackPane implements DecoratorPage {
|
|||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title.set(title);
|
this.title.set(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deleteVersion(Profile profile, String version) {
|
||||||
|
Controllers.confirmDialog(Main.i18n("version.manage.remove.confirm", version), Main.i18n("message.confirm"), () -> {
|
||||||
|
if (profile.getRepository().removeVersionFromDisk(version)) {
|
||||||
|
profile.getRepository().refreshVersionsAsync().start();
|
||||||
|
Controllers.navigate(null);
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renameVersion(Profile profile, String version) {
|
||||||
|
Controllers.inputDialog(Main.i18n("version.manage.rename.message"), res -> {
|
||||||
|
if (profile.getRepository().renameVersion(version, res)) {
|
||||||
|
profile.getRepository().refreshVersionsAsync().start();
|
||||||
|
Controllers.navigate(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exportVersion(Profile profile, String version) {
|
||||||
|
Controllers.getDecorator().startWizard(new ExportWizardProvider(profile, version), Main.i18n("modpack.wizard"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,8 @@ public final class VersionSettingsController {
|
|||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.versionId = versionId;
|
this.versionId = versionId;
|
||||||
|
|
||||||
|
gameDirItem.setDisable(profile.getRepository().isModpack(versionId));
|
||||||
|
|
||||||
if (lastVersionSetting != null) {
|
if (lastVersionSetting != null) {
|
||||||
lastVersionSetting.widthProperty().unbind();
|
lastVersionSetting.widthProperty().unbind();
|
||||||
lastVersionSetting.heightProperty().unbind();
|
lastVersionSetting.heightProperty().unbind();
|
||||||
|
@ -92,6 +92,9 @@ public final class TransitionHandler implements AnimationHandler {
|
|||||||
} else
|
} else
|
||||||
previousNode = NULL;
|
previousNode = NULL;
|
||||||
|
|
||||||
|
if (previousNode == currentNode)
|
||||||
|
previousNode = NULL;
|
||||||
|
|
||||||
currentNode = newView;
|
currentNode = newView;
|
||||||
|
|
||||||
view.getChildren().setAll(previousNode, currentNode);
|
view.getChildren().setAll(previousNode, currentNode);
|
||||||
|
@ -78,7 +78,7 @@ public final class DownloadWizardProvider implements WizardProvider {
|
|||||||
profile.getRepository().markVersionAsModpack(name);
|
profile.getRepository().markVersionAsModpack(name);
|
||||||
|
|
||||||
Task finalizeTask = Task.of(() -> {
|
Task finalizeTask = Task.of(() -> {
|
||||||
profile.getRepository().refreshVersionsAsync().start();
|
profile.getRepository().refreshVersions();
|
||||||
VersionSetting vs = profile.specializeVersionSetting(name);
|
VersionSetting vs = profile.specializeVersionSetting(name);
|
||||||
profile.getRepository().undoMark(name);
|
profile.getRepository().undoMark(name);
|
||||||
if (vs != null)
|
if (vs != null)
|
||||||
@ -87,14 +87,14 @@ public final class DownloadWizardProvider implements WizardProvider {
|
|||||||
|
|
||||||
if (modpack.getManifest() instanceof CurseManifest)
|
if (modpack.getManifest() instanceof CurseManifest)
|
||||||
return new CurseInstallTask(profile.getDependency(), selected, ((CurseManifest) modpack.getManifest()), name)
|
return new CurseInstallTask(profile.getDependency(), selected, ((CurseManifest) modpack.getManifest()), name)
|
||||||
.with(finalizeTask);
|
.finalized(finalizeTask);
|
||||||
else if (modpack.getManifest() instanceof HMCLModpackManifest)
|
else if (modpack.getManifest() instanceof HMCLModpackManifest)
|
||||||
return new HMCLModpackInstallTask(profile, selected, modpack, name)
|
return new HMCLModpackInstallTask(profile, selected, modpack, name)
|
||||||
.with(finalizeTask);
|
.finalized(finalizeTask);
|
||||||
else if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
|
else if (modpack.getManifest() instanceof MultiMCInstanceConfiguration)
|
||||||
return new MultiMCModpackInstallTask(profile.getDependency(), selected, ((MultiMCInstanceConfiguration) modpack.getManifest()), name)
|
return new MultiMCModpackInstallTask(profile.getDependency(), selected, ((MultiMCInstanceConfiguration) modpack.getManifest()), name)
|
||||||
.with(new MultiMCInstallVersionSettingTask(profile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name))
|
.finalized(finalizeTask)
|
||||||
.with(finalizeTask);
|
.with(new MultiMCInstallVersionSettingTask(profile, ((MultiMCInstanceConfiguration) modpack.getManifest()), name));
|
||||||
else throw new IllegalStateException("Unrecognized modpack: " + modpack);
|
else throw new IllegalStateException("Unrecognized modpack: " + modpack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public final class ModpackPage extends StackPane implements WizardPage {
|
|||||||
chooser.setTitle(Main.i18n("modpack.choose"));
|
chooser.setTitle(Main.i18n("modpack.choose"));
|
||||||
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(Main.i18n("modpack"), "*.zip"));
|
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(Main.i18n("modpack"), "*.zip"));
|
||||||
File selectedFile = chooser.showOpenDialog(Controllers.getStage());
|
File selectedFile = chooser.showOpenDialog(Controllers.getStage());
|
||||||
if (selectedFile == null) Platform.runLater(controller::onFinish);
|
if (selectedFile == null) Platform.runLater(() -> Controllers.navigate(null));
|
||||||
else {
|
else {
|
||||||
// TODO: original HMCL modpack support.
|
// TODO: original HMCL modpack support.
|
||||||
controller.getSettings().put(MODPACK_FILE, selectedFile);
|
controller.getSettings().put(MODPACK_FILE, selectedFile);
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<?import javafx.scene.control.ScrollPane?>
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
<?import javafx.scene.layout.StackPane?>
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import com.jfoenix.controls.JFXListView?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
<fx:root
|
<fx:root
|
||||||
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||||
type="StackPane" pickOnBounds="false"
|
type="StackPane" pickOnBounds="false"
|
||||||
@ -28,4 +30,11 @@
|
|||||||
</JFXButton>
|
</JFXButton>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
||||||
|
|
||||||
|
<JFXListView fx:id="versionList" styleClass="option-list-view" onMouseClicked="#onVersionManagement"
|
||||||
|
maxWidth="150.0" minWidth="150.0">
|
||||||
|
<Label text="%version.manage.rename"/>
|
||||||
|
<Label text="%version.manage.remove"/>
|
||||||
|
<Label text="%modpack.export"/>
|
||||||
|
</JFXListView>
|
||||||
</fx:root>
|
</fx:root>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<Label fx:id="content" wrapText="true" />
|
<Label fx:id="content" wrapText="true" />
|
||||||
</body>
|
</body>
|
||||||
<actions>
|
<actions>
|
||||||
<HBox fx:id="actions">
|
<HBox fx:id="actions" alignment="CENTER_RIGHT">
|
||||||
<JFXButton fx:id="acceptButton" styleClass="dialog-accept" text="%button.ok" />
|
<JFXButton fx:id="acceptButton" styleClass="dialog-accept" text="%button.ok" />
|
||||||
<JFXButton fx:id="cancelButton" visible="false" styleClass="dialog-cancel" text="%button.cancel" />
|
<JFXButton fx:id="cancelButton" visible="false" styleClass="dialog-cancel" text="%button.cancel" />
|
||||||
</HBox>
|
</HBox>
|
||||||
|
@ -311,7 +311,7 @@ public class DefaultGameRepository implements GameRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public File getModpackConfiguration(String version) {
|
public File getModpackConfiguration(String version) {
|
||||||
return new File(getRunDirectory(version), "modpack.json");
|
return new File(getVersionRoot(version), "modpack.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModpack(String version) {
|
public boolean isModpack(String version) {
|
||||||
|
@ -34,6 +34,7 @@ import java.util.function.Function;
|
|||||||
final class CoupleTask<P extends Task> extends Task {
|
final class CoupleTask<P extends Task> extends Task {
|
||||||
|
|
||||||
private final boolean relyingOnDependents;
|
private final boolean relyingOnDependents;
|
||||||
|
private final boolean failIfDependentsFail;
|
||||||
private final Collection<Task> dependents;
|
private final Collection<Task> dependents;
|
||||||
private final List<Task> dependencies = new LinkedList<>();
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
private final ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ;
|
private final ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ;
|
||||||
@ -45,10 +46,11 @@ final class CoupleTask<P extends Task> extends Task {
|
|||||||
* @param succ a callback that returns the task runs after pred, succ will be executed asynchronously. You can do something that relies on the result of pred.
|
* @param succ a callback that returns the task runs after pred, succ will be executed asynchronously. You can do something that relies on the result of pred.
|
||||||
* @param relyingOnDependents true if this task chain will be broken when task pred fails.
|
* @param relyingOnDependents true if this task chain will be broken when task pred fails.
|
||||||
*/
|
*/
|
||||||
public CoupleTask(P pred, ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ, boolean relyingOnDependents) {
|
public CoupleTask(P pred, ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ, boolean relyingOnDependents, boolean failIfDependentsFail) {
|
||||||
this.dependents = Collections.singleton(pred);
|
this.dependents = Collections.singleton(pred);
|
||||||
this.succ = succ;
|
this.succ = succ;
|
||||||
this.relyingOnDependents = relyingOnDependents;
|
this.relyingOnDependents = relyingOnDependents;
|
||||||
|
this.failIfDependentsFail = failIfDependentsFail;
|
||||||
|
|
||||||
setSignificance(TaskSignificance.MODERATE);
|
setSignificance(TaskSignificance.MODERATE);
|
||||||
}
|
}
|
||||||
@ -58,6 +60,9 @@ final class CoupleTask<P extends Task> extends Task {
|
|||||||
Task task = succ.apply(getVariables());
|
Task task = succ.apply(getVariables());
|
||||||
if (task != null)
|
if (task != null)
|
||||||
dependencies.add(task);
|
dependencies.add(task);
|
||||||
|
|
||||||
|
if (failIfDependentsFail && !isDependentsSucceeded())
|
||||||
|
throw new SilentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +69,16 @@ public abstract class Task {
|
|||||||
return Schedulers.defaultScheduler();
|
return Schedulers.defaultScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean dependentsSucceeded = false;
|
||||||
|
|
||||||
|
public boolean isDependentsSucceeded() {
|
||||||
|
return dependentsSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDependentsSucceeded() {
|
||||||
|
dependentsSucceeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if requires all {@link #getDependents} finishing successfully.
|
* True if requires all {@link #getDependents} finishing successfully.
|
||||||
* <p>
|
* <p>
|
||||||
@ -239,7 +249,7 @@ public abstract class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Task then(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
public final Task then(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||||
return new CoupleTask<>(this, b, true);
|
return new CoupleTask<>(this, b, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Task with(Task b) {
|
public final Task with(Task b) {
|
||||||
@ -247,7 +257,15 @@ public abstract class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Task with(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
public final Task with(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||||
return new CoupleTask<>(this, b, false);
|
return new CoupleTask<>(this, b, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Task finalized(Task b) {
|
||||||
|
return finalized(s -> b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Task finalized(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||||
|
return new CoupleTask<>(this, b, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task empty() {
|
public static Task empty() {
|
||||||
|
@ -159,6 +159,9 @@ public final class TaskExecutor {
|
|||||||
if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled)
|
if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled)
|
||||||
throw new SilentException();
|
throw new SilentException();
|
||||||
|
|
||||||
|
if (doDependentsSucceeded)
|
||||||
|
task.setDependentsSucceeded();
|
||||||
|
|
||||||
task.setVariables(variables);
|
task.setVariables(variables);
|
||||||
task.execute();
|
task.execute();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user