add: forbids installation buttons for incompatible libraries. Closes #720.
This commit is contained in:
@@ -19,94 +19,198 @@ package org.jackhuang.hmcl.ui;
|
|||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.effects.JFXDepthManager;
|
import com.jfoenix.effects.JFXDepthManager;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.property.*;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.Cursor;
|
||||||
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Skin;
|
||||||
|
import javafx.scene.control.SkinBase;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
|
||||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
public class InstallerItem extends BorderPane {
|
public class InstallerItem extends Control {
|
||||||
|
private final String id;
|
||||||
|
private final String imageUrl;
|
||||||
|
public final StringProperty libraryVersion = new SimpleStringProperty();
|
||||||
|
public final StringProperty incompatibleLibraryName = new SimpleStringProperty();
|
||||||
|
public final BooleanProperty incompatibleWithGame = new SimpleBooleanProperty();
|
||||||
|
public final BooleanProperty removable = new SimpleBooleanProperty();
|
||||||
|
public final BooleanProperty upgradable = new SimpleBooleanProperty(false);
|
||||||
|
public final BooleanProperty installable = new SimpleBooleanProperty(true);
|
||||||
|
public final ObjectProperty<EventHandler<? super MouseEvent>> removeAction = new SimpleObjectProperty<>();
|
||||||
|
public final ObjectProperty<EventHandler<? super MouseEvent>> action = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
public InstallerItem(String libraryId, String libraryVersion, @Nullable Runnable upgrade, @Nullable Consumer<InstallerItem> deleteCallback) {
|
public InstallerItem(LibraryAnalyzer.LibraryType id) {
|
||||||
getStyleClass().addAll("two-line-list-item", "card");
|
this(id.getPatchId());
|
||||||
JFXDepthManager.setDepth(this, 1);
|
}
|
||||||
|
|
||||||
String[] urls = new String[]{"/assets/img/grass.png", "/assets/img/fabric.png", "/assets/img/forge.png", "/assets/img/chicken.png", "/assets/img/command.png"};
|
public InstallerItem(String id) {
|
||||||
String[] libraryIds = new String[]{"game", "fabric", "forge", "liteloader", "optifine"};
|
this.id = id;
|
||||||
|
|
||||||
boolean regularLibrary = false;
|
switch (id) {
|
||||||
for (int i = 0; i < 5; ++i) {
|
case "game":
|
||||||
if (libraryIds[i].equals(libraryId)) {
|
imageUrl = "/assets/img/grass.png";
|
||||||
setLeft(FXUtils.limitingSize(new ImageView(new Image(urls[i], 32, 32, true, true)), 32, 32));
|
break;
|
||||||
Label label = new Label();
|
case "fabric":
|
||||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
imageUrl = "/assets/img/fabric.png";
|
||||||
BorderPane.setMargin(label, new Insets(0, 0, 0, 8));
|
break;
|
||||||
if (libraryVersion == null) {
|
case "forge":
|
||||||
label.setText(i18n("install.installer.not_installed", i18n("install.installer." + libraryId)));
|
imageUrl = "/assets/img/forge.png";
|
||||||
} else {
|
break;
|
||||||
label.setText(i18n("install.installer.version", i18n("install.installer." + libraryId), libraryVersion));
|
case "liteloader":
|
||||||
}
|
imageUrl = "/assets/img/chicken.png";
|
||||||
setCenter(label);
|
break;
|
||||||
regularLibrary = true;
|
case "optifine":
|
||||||
|
imageUrl = "/assets/img/command.png";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
imageUrl = null;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!regularLibrary) {
|
|
||||||
String title = I18n.hasKey("install.installer." + libraryId) ? i18n("install.installer." + libraryId) : libraryId;
|
|
||||||
if (libraryVersion != null) {
|
|
||||||
TwoLineListItem item = new TwoLineListItem();
|
|
||||||
item.setTitle(title);
|
|
||||||
item.setSubtitle(i18n("archive.version") + ": " + libraryVersion);
|
|
||||||
setCenter(item);
|
|
||||||
} else {
|
|
||||||
Label label = new Label();
|
|
||||||
label.setStyle("-fx-font-size: 15px;");
|
|
||||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
|
||||||
setCenter(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
HBox hBox = new HBox();
|
|
||||||
|
|
||||||
if (upgrade != null) {
|
|
||||||
JFXButton upgradeButton = new JFXButton();
|
|
||||||
if (libraryVersion == null) {
|
|
||||||
upgradeButton.setGraphic(SVG.arrowRight(Theme.blackFillBinding(), -1, -1));
|
|
||||||
} else {
|
|
||||||
upgradeButton.setGraphic(SVG.update(Theme.blackFillBinding(), -1, -1));
|
|
||||||
}
|
|
||||||
upgradeButton.getStyleClass().add("toggle-icon4");
|
|
||||||
FXUtils.installFastTooltip(upgradeButton, i18n("install.change_version"));
|
|
||||||
upgradeButton.setOnMouseClicked(e -> upgrade.run());
|
|
||||||
hBox.getChildren().add(upgradeButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleteCallback != null) {
|
|
||||||
JFXButton deleteButton = new JFXButton();
|
|
||||||
deleteButton.setGraphic(SVG.close(Theme.blackFillBinding(), -1, -1));
|
|
||||||
deleteButton.getStyleClass().add("toggle-icon4");
|
|
||||||
deleteButton.setOnMouseClicked(e -> deleteCallback.accept(this));
|
|
||||||
hBox.getChildren().add(deleteButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
hBox.setAlignment(Pos.CENTER_RIGHT);
|
|
||||||
setRight(hBox);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setState(String libraryVersion, boolean incompatibleWithGame, boolean removable) {
|
||||||
|
this.libraryVersion.set(libraryVersion);
|
||||||
|
this.incompatibleWithGame.set(incompatibleWithGame);
|
||||||
|
this.removable.set(removable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLibraryId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Skin<?> createDefaultSkin() {
|
||||||
|
return new InstallerItemSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InstallerItemGroup {
|
||||||
|
public InstallerItem game = new InstallerItem(MINECRAFT);
|
||||||
|
public InstallerItem fabric = new InstallerItem(FABRIC);
|
||||||
|
public InstallerItem forge = new InstallerItem(FORGE);
|
||||||
|
public InstallerItem liteLoader = new InstallerItem(LITELOADER);
|
||||||
|
public InstallerItem optiFine = new InstallerItem(OPTIFINE);
|
||||||
|
|
||||||
|
public InstallerItemGroup() {
|
||||||
|
forge.incompatibleLibraryName.bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (fabric.libraryVersion.get() != null) return FABRIC.getPatchId();
|
||||||
|
return null;
|
||||||
|
}, fabric.libraryVersion));
|
||||||
|
|
||||||
|
liteLoader.incompatibleLibraryName.bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (fabric.libraryVersion.get() != null) return FABRIC.getPatchId();
|
||||||
|
return null;
|
||||||
|
}, fabric.libraryVersion));
|
||||||
|
|
||||||
|
optiFine.incompatibleLibraryName.bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (fabric.libraryVersion.get() != null) return FABRIC.getPatchId();
|
||||||
|
return null;
|
||||||
|
}, fabric.libraryVersion));
|
||||||
|
|
||||||
|
fabric.incompatibleLibraryName.bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (liteLoader.libraryVersion.get() != null) return LITELOADER.getPatchId();
|
||||||
|
if (optiFine.libraryVersion.get() != null) return OPTIFINE.getPatchId();
|
||||||
|
if (forge.libraryVersion.get() != null) return FORGE.getPatchId();
|
||||||
|
return null;
|
||||||
|
}, optiFine.libraryVersion, forge.libraryVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstallerItem[] getLibraries() {
|
||||||
|
return new InstallerItem[]{game, fabric, forge, liteLoader, optiFine};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InstallerItemSkin extends SkinBase<InstallerItem> {
|
||||||
|
|
||||||
|
InstallerItemSkin(InstallerItem control) {
|
||||||
|
super(control);
|
||||||
|
|
||||||
|
HBox hbox = new HBox();
|
||||||
|
getChildren().setAll(hbox);
|
||||||
|
JFXDepthManager.setDepth(hbox, 1);
|
||||||
|
|
||||||
|
hbox.getStyleClass().add("card");
|
||||||
|
|
||||||
|
hbox.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
if (control.imageUrl != null) {
|
||||||
|
hbox.getChildren().add(FXUtils.limitingSize(new ImageView(new Image(control.imageUrl, 32, 32, true, true)), 32, 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
Label nameLabel = new Label();
|
||||||
|
hbox.getChildren().add(nameLabel);
|
||||||
|
nameLabel.setPrefWidth(80);
|
||||||
|
nameLabel.textProperty().set(I18n.hasKey("install.installer." + control.id) ? i18n("install.installer." + control.id) : control.id);
|
||||||
|
HBox.setMargin(nameLabel, new Insets(0, 4, 0, 4));
|
||||||
|
|
||||||
|
Label label = new Label();
|
||||||
|
hbox.getChildren().add(label);
|
||||||
|
label.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
HBox.setHgrow(label, Priority.ALWAYS);
|
||||||
|
label.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||||
|
String incompatibleWith = control.incompatibleLibraryName.get();
|
||||||
|
String version = control.libraryVersion.get();
|
||||||
|
if (control.incompatibleWithGame.get()) {
|
||||||
|
return i18n("install.installer.change_version", version);
|
||||||
|
} else if (incompatibleWith != null) {
|
||||||
|
return i18n("install.installer.incompatible", i18n("install.installer." + incompatibleWith));
|
||||||
|
} else if (version == null) {
|
||||||
|
return i18n("install.installer.not_installed");
|
||||||
|
} else {
|
||||||
|
return i18n("install.installer.version", version);
|
||||||
|
}
|
||||||
|
}, control.incompatibleLibraryName, control.incompatibleWithGame, control.libraryVersion));
|
||||||
|
BorderPane.setMargin(label, new Insets(0, 0, 0, 8));
|
||||||
|
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
JFXButton closeButton = new JFXButton();
|
||||||
|
closeButton.setGraphic(SVG.close(Theme.blackFillBinding(), -1, -1));
|
||||||
|
closeButton.getStyleClass().add("toggle-icon4");
|
||||||
|
closeButton.visibleProperty().bind(control.removable);
|
||||||
|
closeButton.managedProperty().bind(closeButton.visibleProperty());
|
||||||
|
closeButton.onMouseClickedProperty().bind(control.removeAction);
|
||||||
|
hbox.getChildren().add(closeButton);
|
||||||
|
|
||||||
|
JFXButton arrowButton = new JFXButton();
|
||||||
|
arrowButton.graphicProperty().bind(Bindings.createObjectBinding(() -> control.upgradable.get()
|
||||||
|
? SVG.update(Theme.blackFillBinding(), -1, -1)
|
||||||
|
: SVG.arrowRight(Theme.blackFillBinding(), -1, -1),
|
||||||
|
control.upgradable));
|
||||||
|
arrowButton.getStyleClass().add("toggle-icon4");
|
||||||
|
arrowButton.visibleProperty().bind(Bindings.createBooleanBinding(
|
||||||
|
() -> control.installable.get() && control.incompatibleLibraryName.get() == null,
|
||||||
|
control.installable, control.incompatibleLibraryName));
|
||||||
|
arrowButton.managedProperty().bind(arrowButton.visibleProperty());
|
||||||
|
arrowButton.onMouseClickedProperty().bind(control.action);
|
||||||
|
hbox.getChildren().add(arrowButton);
|
||||||
|
|
||||||
|
FXUtils.onChangeAndOperate(arrowButton.visibleProperty(), clickable -> {
|
||||||
|
if (clickable) {
|
||||||
|
hbox.onMouseClickedProperty().bind(control.action);
|
||||||
|
hbox.setCursor(Cursor.HAND);
|
||||||
|
} else {
|
||||||
|
hbox.onMouseClickedProperty().unbind();
|
||||||
|
hbox.onMouseClickedProperty().set(null);
|
||||||
|
hbox.setCursor(Cursor.DEFAULT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
|||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
|
import org.jackhuang.hmcl.ui.InstallerItem;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
@@ -53,10 +54,8 @@ class AdditionalInstallersPage extends InstallersPage {
|
|||||||
() -> compatible.get() && txtName.validate(),
|
() -> compatible.get() && txtName.validate(),
|
||||||
txtName.textProperty(), compatible));
|
txtName.textProperty(), compatible));
|
||||||
|
|
||||||
InstallerPageItem[] libraries = new InstallerPageItem[]{game, fabric, forge, liteLoader, optiFine};
|
for (InstallerItem library : group.getLibraries()) {
|
||||||
|
String libraryId = library.getLibraryId();
|
||||||
for (InstallerPageItem library : libraries) {
|
|
||||||
String libraryId = library.id;
|
|
||||||
if (libraryId.equals("game")) continue;
|
if (libraryId.equals("game")) continue;
|
||||||
library.removeAction.set(e -> {
|
library.removeAction.set(e -> {
|
||||||
controller.getSettings().put(libraryId, new UpdateInstallerWizardProvider.RemoveVersionAction(libraryId));
|
controller.getSettings().put(libraryId, new UpdateInstallerWizardProvider.RemoveVersionAction(libraryId));
|
||||||
@@ -90,28 +89,25 @@ class AdditionalInstallersPage extends InstallersPage {
|
|||||||
String liteLoader = analyzer.getVersion(LITELOADER).orElse(null);
|
String liteLoader = analyzer.getVersion(LITELOADER).orElse(null);
|
||||||
String optiFine = analyzer.getVersion(OPTIFINE).orElse(null);
|
String optiFine = analyzer.getVersion(OPTIFINE).orElse(null);
|
||||||
|
|
||||||
InstallerPageItem[] libraries = new InstallerPageItem[]{this.game, this.fabric, this.forge, this.liteLoader, this.optiFine};
|
InstallerItem[] libraries = group.getLibraries();
|
||||||
String[] versions = new String[]{game, fabric, forge, liteLoader, optiFine};
|
String[] versions = new String[]{game, fabric, forge, liteLoader, optiFine};
|
||||||
|
|
||||||
String currentGameVersion = Lang.nonNull(getVersion("game"), game);
|
String currentGameVersion = Lang.nonNull(getVersion("game"), game);
|
||||||
|
|
||||||
boolean compatible = true;
|
boolean compatible = true;
|
||||||
for (int i = 0; i < libraries.length; ++i) {
|
for (int i = 0; i < libraries.length; ++i) {
|
||||||
String libraryId = libraries[i].id;
|
String libraryId = libraries[i].getLibraryId();
|
||||||
String libraryVersion = Lang.nonNull(getVersion(libraryId), versions[i]);
|
String libraryVersion = Lang.nonNull(getVersion(libraryId), versions[i]);
|
||||||
boolean alreadyInstalled = versions[i] != null && !(controller.getSettings().get(libraryId) instanceof UpdateInstallerWizardProvider.RemoveVersionAction);
|
boolean alreadyInstalled = versions[i] != null && !(controller.getSettings().get(libraryId) instanceof UpdateInstallerWizardProvider.RemoveVersionAction);
|
||||||
if (!"game".equals(libraryId) && currentGameVersion != null && !currentGameVersion.equals(game) && getVersion(libraryId) == null && alreadyInstalled) {
|
if (!"game".equals(libraryId) && currentGameVersion != null && !currentGameVersion.equals(game) && getVersion(libraryId) == null && alreadyInstalled) {
|
||||||
// For third-party libraries, if game version is being changed, and the library is not being reinstalled,
|
// For third-party libraries, if game version is being changed, and the library is not being reinstalled,
|
||||||
// warns the user that we should update the library.
|
// warns the user that we should update the library.
|
||||||
libraries[i].label.set(i18n("install.installer.change_version", i18n("install.installer." + libraryId), libraryVersion));
|
libraries[i].setState(libraryVersion, /* incompatibleWithGame */ true, /* removable */ true);
|
||||||
libraries[i].removable.set(true);
|
|
||||||
compatible = false;
|
compatible = false;
|
||||||
} else if (alreadyInstalled || getVersion(libraryId) != null) {
|
} else if (alreadyInstalled || getVersion(libraryId) != null) {
|
||||||
libraries[i].label.set(i18n("install.installer.version", i18n("install.installer." + libraryId), libraryVersion));
|
libraries[i].setState(libraryVersion, /* incompatibleWithGame */ false, /* removable */ true);
|
||||||
libraries[i].removable.set(true);
|
|
||||||
} else {
|
} else {
|
||||||
libraries[i].label.set(i18n("install.installer.not_installed", i18n("install.installer." + libraryId)));
|
libraries[i].setState(/* libraryVersion */ null, /* incompatibleWithGame */ false, /* removable */ false);
|
||||||
libraries[i].removable.set(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.compatible.set(compatible);
|
this.compatible.set(compatible);
|
||||||
|
|||||||
@@ -19,29 +19,21 @@ package org.jackhuang.hmcl.ui.download;
|
|||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.controls.JFXTextField;
|
import com.jfoenix.controls.JFXTextField;
|
||||||
import com.jfoenix.effects.JFXDepthManager;
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.event.EventHandler;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Cursor;
|
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.scene.control.SkinBase;
|
import javafx.scene.control.SkinBase;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.scene.image.ImageView;
|
|
||||||
import javafx.scene.input.MouseEvent;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
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 org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.ui.InstallerItem;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||||
@@ -55,11 +47,7 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|||||||
public class InstallersPage extends Control implements WizardPage {
|
public class InstallersPage extends Control implements WizardPage {
|
||||||
protected final WizardController controller;
|
protected final WizardController controller;
|
||||||
|
|
||||||
protected InstallerPageItem game = new InstallerPageItem("game");
|
protected InstallerItem.InstallerItemGroup group = new InstallerItem.InstallerItemGroup();
|
||||||
protected InstallerPageItem fabric = new InstallerPageItem("fabric");
|
|
||||||
protected InstallerPageItem forge = new InstallerPageItem("forge");
|
|
||||||
protected InstallerPageItem liteLoader = new InstallerPageItem("liteloader");
|
|
||||||
protected InstallerPageItem optiFine = new InstallerPageItem("optifine");
|
|
||||||
protected JFXTextField txtName = new JFXTextField();
|
protected JFXTextField txtName = new JFXTextField();
|
||||||
protected BooleanProperty installable = new SimpleBooleanProperty();
|
protected BooleanProperty installable = new SimpleBooleanProperty();
|
||||||
|
|
||||||
@@ -75,13 +63,15 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
txtName.textProperty()));
|
txtName.textProperty()));
|
||||||
txtName.setText(gameVersion);
|
txtName.setText(gameVersion);
|
||||||
|
|
||||||
InstallerPageItem[] libraries = new InstallerPageItem[]{game, fabric, forge, liteLoader, optiFine};
|
group.game.installable.setValue(false);
|
||||||
|
|
||||||
for (InstallerPageItem library : libraries) {
|
for (InstallerItem library : group.getLibraries()) {
|
||||||
String libraryId = library.id;
|
String libraryId = library.getLibraryId();
|
||||||
if (libraryId.equals("game")) continue;
|
if (libraryId.equals("game")) continue;
|
||||||
library.action.set(e ->
|
library.action.set(e -> {
|
||||||
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false))));
|
if (library.incompatibleLibraryName.get() == null)
|
||||||
|
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)));
|
||||||
|
});
|
||||||
library.removeAction.set(e -> {
|
library.removeAction.set(e -> {
|
||||||
controller.getSettings().remove(libraryId);
|
controller.getSettings().remove(libraryId);
|
||||||
reload();
|
reload();
|
||||||
@@ -99,15 +89,13 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void reload() {
|
protected void reload() {
|
||||||
InstallerPageItem[] libraries = new InstallerPageItem[]{game, fabric, forge, liteLoader, optiFine};
|
for (InstallerItem library : group.getLibraries()) {
|
||||||
|
String libraryId = library.getLibraryId();
|
||||||
for (InstallerPageItem library : libraries) {
|
|
||||||
String libraryId = library.id;
|
|
||||||
if (controller.getSettings().containsKey(libraryId)) {
|
if (controller.getSettings().containsKey(libraryId)) {
|
||||||
library.label.set(i18n("install.installer.version", i18n("install.installer." + libraryId), getVersion(libraryId)));
|
library.libraryVersion.set(getVersion(libraryId));
|
||||||
library.removable.set(true);
|
library.removable.set(true);
|
||||||
} else {
|
} else {
|
||||||
library.label.setValue(i18n("install.installer.not_installed", i18n("install.installer." + libraryId)));
|
library.libraryVersion.set(null);
|
||||||
library.removable.set(false);
|
library.removable.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,54 +121,8 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
return new InstallersPageSkin(this);
|
return new InstallersPageSkin(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class InstallerPageItem {
|
|
||||||
String id;
|
|
||||||
StringProperty label = new SimpleStringProperty();
|
|
||||||
BooleanProperty removable = new SimpleBooleanProperty();
|
|
||||||
ObjectProperty<EventHandler<? super MouseEvent>> removeAction = new SimpleObjectProperty<>();
|
|
||||||
ObjectProperty<EventHandler<? super MouseEvent>> action = new SimpleObjectProperty<>();
|
|
||||||
|
|
||||||
public InstallerPageItem(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class InstallersPageSkin extends SkinBase<InstallersPage> {
|
protected static class InstallersPageSkin extends SkinBase<InstallersPage> {
|
||||||
|
|
||||||
protected static class InstallersPageItemSkin extends BorderPane {
|
|
||||||
final ImageView imageView;
|
|
||||||
final Label label;
|
|
||||||
|
|
||||||
InstallersPageItemSkin(String imageUrl, InstallerPageItem item, boolean clickable) {
|
|
||||||
getStyleClass().add("card");
|
|
||||||
|
|
||||||
setLeft(FXUtils.limitingSize(imageView = new ImageView(new Image(imageUrl, 32, 32, true, true)), 32, 32));
|
|
||||||
setCenter(label = new Label());
|
|
||||||
label.textProperty().bind(item.label);
|
|
||||||
BorderPane.setMargin(label, new Insets(0, 0, 0, 8));
|
|
||||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
|
||||||
|
|
||||||
if (clickable) {
|
|
||||||
HBox right = new HBox();
|
|
||||||
right.setAlignment(Pos.CENTER_RIGHT);
|
|
||||||
setRight(right);
|
|
||||||
JFXButton closeButton = new JFXButton();
|
|
||||||
closeButton.setGraphic(SVG.close(Theme.blackFillBinding(), -1, -1));
|
|
||||||
right.getChildren().add(closeButton);
|
|
||||||
closeButton.getStyleClass().add("toggle-icon4");
|
|
||||||
closeButton.visibleProperty().bind(item.removable);
|
|
||||||
closeButton.onMouseClickedProperty().bind(item.removeAction);
|
|
||||||
onMouseClickedProperty().bind(item.action);
|
|
||||||
JFXButton arrowButton = new JFXButton();
|
|
||||||
arrowButton.setGraphic(SVG.arrowRight(Theme.blackFillBinding(), -1, -1));
|
|
||||||
arrowButton.onMouseClickedProperty().bind(item.action);
|
|
||||||
arrowButton.getStyleClass().add("toggle-icon4");
|
|
||||||
right.getChildren().add(arrowButton);
|
|
||||||
setCursor(Cursor.HAND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for all SkinBase instances.
|
* Constructor for all SkinBase instances.
|
||||||
*
|
*
|
||||||
@@ -207,13 +149,7 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
list.getChildren().add(versionNamePane);
|
list.getChildren().add(versionNamePane);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallersPageItemSkin game = new InstallersPageItemSkin("/assets/img/grass.png", control.game, false);
|
list.getChildren().addAll(control.group.getLibraries());
|
||||||
InstallersPageItemSkin fabric = new InstallersPageItemSkin("/assets/img/fabric.png", control.fabric, true);
|
|
||||||
InstallersPageItemSkin forge = new InstallersPageItemSkin("/assets/img/forge.png", control.forge, true);
|
|
||||||
InstallersPageItemSkin liteLoader = new InstallersPageItemSkin("/assets/img/chicken.png", control.liteLoader, true);
|
|
||||||
InstallersPageItemSkin optiFine = new InstallersPageItemSkin("/assets/img/command.png", control.optiFine, true);
|
|
||||||
list.getChildren().addAll(game, fabric, forge, liteLoader, optiFine);
|
|
||||||
list.getChildren().forEach(node -> JFXDepthManager.setDepth(node, 1));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
JFXButton installButton = new JFXButton(i18n("button.install"));
|
JFXButton installButton = new JFXButton(i18n("button.install"));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.ui.versions;
|
package org.jackhuang.hmcl.ui.versions;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
@@ -42,6 +43,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*;
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
@@ -74,7 +76,7 @@ public class InstallerListPage extends ListPageBase<InstallerItem> {
|
|||||||
|
|
||||||
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));
|
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));
|
||||||
}).thenAcceptAsync(analyzer -> {
|
}).thenAcceptAsync(analyzer -> {
|
||||||
Function<String, Consumer<InstallerItem>> removeAction = libraryId -> x -> {
|
Function<String, Runnable> removeAction = libraryId -> () -> {
|
||||||
profile.getDependency().removeLibraryAsync(version, libraryId)
|
profile.getDependency().removeLibraryAsync(version, libraryId)
|
||||||
.thenComposeAsync(profile.getRepository()::saveAsync)
|
.thenComposeAsync(profile.getRepository()::saveAsync)
|
||||||
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
|
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
|
||||||
@@ -84,15 +86,28 @@ public class InstallerListPage extends ListPageBase<InstallerItem> {
|
|||||||
|
|
||||||
itemsProperty().clear();
|
itemsProperty().clear();
|
||||||
|
|
||||||
for (LibraryAnalyzer.LibraryType type : LibraryAnalyzer.LibraryType.values()) {
|
InstallerItem.InstallerItemGroup group = new InstallerItem.InstallerItemGroup();
|
||||||
String libraryId = type.getPatchId();
|
|
||||||
String libraryVersion = analyzer.getVersion(type).orElse(null);
|
// Conventional libraries: game, fabric, forge, liteloader, optifine
|
||||||
Consumer<InstallerItem> action = "game".equals(libraryId) || libraryVersion == null ? null : removeAction.apply(libraryId);
|
for (InstallerItem installerItem : group.getLibraries()) {
|
||||||
itemsProperty().add(new InstallerItem(libraryId, libraryVersion, () -> {
|
String libraryId = installerItem.getLibraryId();
|
||||||
|
String libraryVersion = analyzer.getVersion(libraryId).orElse(null);
|
||||||
|
installerItem.libraryVersion.set(libraryVersion);
|
||||||
|
installerItem.upgradable.set(libraryVersion != null);
|
||||||
|
installerItem.installable.set(true);
|
||||||
|
installerItem.action.set(e -> {
|
||||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
||||||
}, action));
|
});
|
||||||
|
boolean removable = !"game".equals(libraryId) && libraryVersion != null;
|
||||||
|
installerItem.removable.set(removable);
|
||||||
|
if (removable) {
|
||||||
|
Runnable action = removeAction.apply(libraryId);
|
||||||
|
installerItem.removeAction.set(e -> action.run());
|
||||||
|
}
|
||||||
|
itemsProperty().add(installerItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// other third-party libraries which are unable to manage.
|
||||||
for (LibraryAnalyzer.LibraryMark mark : analyzer) {
|
for (LibraryAnalyzer.LibraryMark mark : analyzer) {
|
||||||
String libraryId = mark.getLibraryId();
|
String libraryId = mark.getLibraryId();
|
||||||
String libraryVersion = mark.getLibraryVersion();
|
String libraryVersion = mark.getLibraryVersion();
|
||||||
@@ -101,14 +116,23 @@ public class InstallerListPage extends ListPageBase<InstallerItem> {
|
|||||||
if (LibraryAnalyzer.LibraryType.fromPatchId(libraryId) != null)
|
if (LibraryAnalyzer.LibraryType.fromPatchId(libraryId) != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Consumer<InstallerItem> action = removeAction.apply(libraryId);
|
Runnable action = removeAction.apply(libraryId);
|
||||||
if (libraryVersion != null && Lang.test(() -> profile.getDependency().getVersionList(libraryId)))
|
|
||||||
itemsProperty().add(
|
InstallerItem installerItem = new InstallerItem(libraryId);
|
||||||
new InstallerItem(libraryId, libraryVersion, () -> {
|
installerItem.libraryVersion.set(libraryVersion);
|
||||||
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
installerItem.installable.set(false);
|
||||||
}, action));
|
installerItem.upgradable.bind(installerItem.installable);
|
||||||
else
|
installerItem.removable.set(true);
|
||||||
itemsProperty().add(new InstallerItem(libraryId, libraryVersion, null, action));
|
installerItem.removeAction.set(e -> action.run());
|
||||||
|
|
||||||
|
if (libraryVersion != null && Lang.test(() -> profile.getDependency().getVersionList(libraryId))) {
|
||||||
|
installerItem.installable.set(true);
|
||||||
|
installerItem.action.set(e -> {
|
||||||
|
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsProperty().add(installerItem);
|
||||||
}
|
}
|
||||||
}, Platform::runLater);
|
}, Platform::runLater);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,11 +139,12 @@ install.failed.install_online=Unable to recognize the provided installer file
|
|||||||
install.failed.malformed=The files just downloaded a moment ago is malformed. You may switch to other download provider to resolve this problem.
|
install.failed.malformed=The files just downloaded a moment ago is malformed. You may switch to other download provider to resolve this problem.
|
||||||
install.failed.optifine_conflict=Fabric, OptiFine and Forge are installed simultaneously on Minecraft 1.13
|
install.failed.optifine_conflict=Fabric, OptiFine and Forge are installed simultaneously on Minecraft 1.13
|
||||||
install.failed.version_mismatch=The library requires the game version %s, but the actual version is %s.
|
install.failed.version_mismatch=The library requires the game version %s, but the actual version is %s.
|
||||||
install.installer.change_version=%s version: %s, this version is not compatible with current game version. Click here to choose another one.
|
install.installer.change_version=%s, this version is not compatible with current game version. Click here to choose another one.
|
||||||
install.installer.choose=Choose a %s version
|
install.installer.choose=Choose a %s version
|
||||||
install.installer.fabric=Fabric
|
install.installer.fabric=Fabric
|
||||||
install.installer.forge=Forge
|
install.installer.forge=Forge
|
||||||
install.installer.game=Minecraft
|
install.installer.game=Minecraft
|
||||||
|
install.installer.incompatible=Incompatible with %s
|
||||||
install.installer.install=Install %s
|
install.installer.install=Install %s
|
||||||
install.installer.install_offline=Install/Upgrade from file
|
install.installer.install_offline=Install/Upgrade from file
|
||||||
install.installer.install_offline.extension=Forge/OptiFine installer
|
install.installer.install_offline.extension=Forge/OptiFine installer
|
||||||
@@ -151,9 +152,9 @@ install.installer.install_offline.tooltip=Supports import of Forge/OptiFine inst
|
|||||||
install.installer.install_online=Install Online
|
install.installer.install_online=Install Online
|
||||||
install.installer.install_online.tooltip=Support installation of Fabric, Forge, OptiFine, LiteLoader.
|
install.installer.install_online.tooltip=Support installation of Fabric, Forge, OptiFine, LiteLoader.
|
||||||
install.installer.liteloader=LiteLoader
|
install.installer.liteloader=LiteLoader
|
||||||
install.installer.not_installed=%s Version: not installed
|
install.installer.not_installed=Not installed
|
||||||
install.installer.optifine=OptiFine
|
install.installer.optifine=OptiFine
|
||||||
install.installer.version=%s Version: %s
|
install.installer.version=%s
|
||||||
install.modpack=Install a modpack
|
install.modpack=Install a modpack
|
||||||
install.new_game=Install a New Game
|
install.new_game=Install a New Game
|
||||||
install.new_game.already_exists=This version already exists.
|
install.new_game.already_exists=This version already exists.
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ install.installer.choose=Escoja una versión de %s
|
|||||||
install.installer.fabric=Fabric
|
install.installer.fabric=Fabric
|
||||||
install.installer.forge=Forge
|
install.installer.forge=Forge
|
||||||
install.installer.game=Minecraft
|
install.installer.game=Minecraft
|
||||||
|
install.installer.incompatible=Incompatible with %s
|
||||||
install.installer.install=Instalar %s
|
install.installer.install=Instalar %s
|
||||||
install.installer.install_offline=Instalar/actualizar con archivo local
|
install.installer.install_offline=Instalar/actualizar con archivo local
|
||||||
install.installer.install_offline.extension=Instalador de Forge/OptiFine
|
install.installer.install_offline.extension=Instalador de Forge/OptiFine
|
||||||
@@ -147,9 +148,9 @@ install.installer.install_offline.tooltip=Soporta importación de archivo instal
|
|||||||
install.installer.install_online=Instalar en línea
|
install.installer.install_online=Instalar en línea
|
||||||
install.installer.install_online.tooltip=Soporta instalación de Fabric, Forge, OptiFine, LiteLoader
|
install.installer.install_online.tooltip=Soporta instalación de Fabric, Forge, OptiFine, LiteLoader
|
||||||
install.installer.liteloader=LiteLoader
|
install.installer.liteloader=LiteLoader
|
||||||
install.installer.not_installed=%s no está instalado
|
install.installer.not_installed=no está instalado
|
||||||
install.installer.optifine=OptiFine
|
install.installer.optifine=OptiFine
|
||||||
install.installer.version=Versión %s: %s
|
install.installer.version=%s
|
||||||
install.modpack=Instalar un modpack
|
install.modpack=Instalar un modpack
|
||||||
install.new_game=Instalar un juego nuevo
|
install.new_game=Instalar un juego nuevo
|
||||||
install.new_game.already_exists=Esta versión ya existe.
|
install.new_game.already_exists=Esta versión ya existe.
|
||||||
|
|||||||
@@ -139,11 +139,12 @@ install.failed.install_online=Невозможно распознать пред
|
|||||||
install.failed.malformed=Файлы, скачаные минуту назад, неправильно сформированы. Для решения этой проблемы можно переключиться на другого поставщика скачивания.
|
install.failed.malformed=Файлы, скачаные минуту назад, неправильно сформированы. Для решения этой проблемы можно переключиться на другого поставщика скачивания.
|
||||||
install.failed.optifine_conflict=Fabric, OptiFine и Forge установлены одновременно на Minecraft 1.13
|
install.failed.optifine_conflict=Fabric, OptiFine и Forge установлены одновременно на Minecraft 1.13
|
||||||
install.failed.version_mismatch=Библиотека требует версию игры %s, но фактическая версия %s.
|
install.failed.version_mismatch=Библиотека требует версию игры %s, но фактическая версия %s.
|
||||||
install.installer.change_version=Версия %s: %s, эта версия не совместима с текущей версией игры. Что бы выбрать другую, нажмите здесь.
|
install.installer.change_version=%s, эта версия не совместима с текущей версией игры. Что бы выбрать другую, нажмите здесь.
|
||||||
install.installer.choose=Выберите версию %s
|
install.installer.choose=Выберите версию %s
|
||||||
install.installer.fabric=Fabric
|
install.installer.fabric=Fabric
|
||||||
install.installer.forge=Forge
|
install.installer.forge=Forge
|
||||||
install.installer.game=Minecraft
|
install.installer.game=Minecraft
|
||||||
|
install.installer.incompatible=Incompatible with %s
|
||||||
install.installer.install=Установка %s
|
install.installer.install=Установка %s
|
||||||
install.installer.install_offline=Установить/обновить из файла
|
install.installer.install_offline=Установить/обновить из файла
|
||||||
install.installer.install_offline.extension=Установщик Forge/OptiFine
|
install.installer.install_offline.extension=Установщик Forge/OptiFine
|
||||||
@@ -151,9 +152,9 @@ install.installer.install_offline.tooltip=Поддерживает импорт
|
|||||||
install.installer.install_online=Установить из сети
|
install.installer.install_online=Установить из сети
|
||||||
install.installer.install_online.tooltip=Поддерживается установка Fabric, Forge, OptiFine, LiteLoader.
|
install.installer.install_online.tooltip=Поддерживается установка Fabric, Forge, OptiFine, LiteLoader.
|
||||||
install.installer.liteloader=LiteLoader
|
install.installer.liteloader=LiteLoader
|
||||||
install.installer.not_installed=%s не установлен
|
install.installer.not_installed=не установлен
|
||||||
install.installer.optifine=OptiFine
|
install.installer.optifine=OptiFine
|
||||||
install.installer.version=%s - версия: %s
|
install.installer.version=%s
|
||||||
install.modpack=Установить модпак
|
install.modpack=Установить модпак
|
||||||
install.new_game=Установка новой игры
|
install.new_game=Установка новой игры
|
||||||
install.new_game.already_exists=Эта версия уже существует.
|
install.new_game.already_exists=Эта версия уже существует.
|
||||||
|
|||||||
@@ -139,11 +139,12 @@ install.failed.install_online=無法識別要安裝的軟體
|
|||||||
install.failed.malformed=剛才下載的檔案格式損壞。您可以切換到其他下載來源以解決此問題。
|
install.failed.malformed=剛才下載的檔案格式損壞。您可以切換到其他下載來源以解決此問題。
|
||||||
install.failed.optifine_conflict=暫不支援 OptiFine 與 Forge 同時安裝在 Minecraft 1.13 上
|
install.failed.optifine_conflict=暫不支援 OptiFine 與 Forge 同時安裝在 Minecraft 1.13 上
|
||||||
install.failed.version_mismatch=該軟體需要的遊戲版本為 %s,但實際的遊戲版本為 %s。
|
install.failed.version_mismatch=該軟體需要的遊戲版本為 %s,但實際的遊戲版本為 %s。
|
||||||
install.installer.change_version=%s 版本: %s,該版本與當前遊戲不相容,您需要點擊此處更換版本或刪除
|
install.installer.change_version=%s,該版本與當前遊戲不相容,您需要點擊此處更換版本或刪除
|
||||||
install.installer.choose=選擇 %s 版本
|
install.installer.choose=選擇 %s 版本
|
||||||
install.installer.fabric=Fabric
|
install.installer.fabric=Fabric
|
||||||
install.installer.forge=Forge
|
install.installer.forge=Forge
|
||||||
install.installer.game=Minecraft
|
install.installer.game=Minecraft
|
||||||
|
install.installer.incompatible=與 %s 不相容
|
||||||
install.installer.install=安裝%s
|
install.installer.install=安裝%s
|
||||||
install.installer.install_offline=從本機檔案安裝或升級
|
install.installer.install_offline=從本機檔案安裝或升級
|
||||||
install.installer.install_offline.extension=Forge/OptiFine 安裝器
|
install.installer.install_offline.extension=Forge/OptiFine 安裝器
|
||||||
@@ -151,9 +152,9 @@ install.installer.install_offline.tooltip=支援匯入已經下載好的 Forge/O
|
|||||||
install.installer.install_online=線上安裝
|
install.installer.install_online=線上安裝
|
||||||
install.installer.install_online.tooltip=支援安裝 Fabric、Forge、OptiFine、LiteLoader
|
install.installer.install_online.tooltip=支援安裝 Fabric、Forge、OptiFine、LiteLoader
|
||||||
install.installer.liteloader=LiteLoader
|
install.installer.liteloader=LiteLoader
|
||||||
install.installer.not_installed=%s 版本: 不安裝
|
install.installer.not_installed=不安裝
|
||||||
install.installer.optifine=OptiFine
|
install.installer.optifine=OptiFine
|
||||||
install.installer.version=%s 版本: %s
|
install.installer.version=%s
|
||||||
install.modpack=安裝整合包
|
install.modpack=安裝整合包
|
||||||
install.new_game=安裝新遊戲版本
|
install.new_game=安裝新遊戲版本
|
||||||
install.new_game.already_exists=此版本已經存在,請重新命名
|
install.new_game.already_exists=此版本已經存在,請重新命名
|
||||||
|
|||||||
@@ -139,11 +139,12 @@ install.failed.install_online=无法识别要安装的软件
|
|||||||
install.failed.malformed=刚才下载的文件格式损坏。您可以切换到其他下载源来解决此问题。
|
install.failed.malformed=刚才下载的文件格式损坏。您可以切换到其他下载源来解决此问题。
|
||||||
install.failed.optifine_conflict=暂不支持 OptiFine, Fabric 与 Forge 同时安装在 Minecraft 1.13 及以上版本
|
install.failed.optifine_conflict=暂不支持 OptiFine, Fabric 与 Forge 同时安装在 Minecraft 1.13 及以上版本
|
||||||
install.failed.version_mismatch=该软件需要的游戏版本为 %s,但实际的游戏版本为 %s。
|
install.failed.version_mismatch=该软件需要的游戏版本为 %s,但实际的游戏版本为 %s。
|
||||||
install.installer.change_version=%s 版本: %s,该版本与当前游戏不兼容,您需要点击此处更换版本或删除
|
install.installer.change_version=%s,该版本与当前游戏不兼容,您需要点击此处更换版本或删除
|
||||||
install.installer.choose=选择 %s 版本
|
install.installer.choose=选择 %s 版本
|
||||||
install.installer.fabric=Fabric
|
install.installer.fabric=Fabric
|
||||||
install.installer.forge=Forge
|
install.installer.forge=Forge
|
||||||
install.installer.game=Minecraft
|
install.installer.game=Minecraft
|
||||||
|
install.installer.incompatible=与 %s 不兼容
|
||||||
install.installer.install=安装 %s
|
install.installer.install=安装 %s
|
||||||
install.installer.install_offline=从本地文件安装/升级
|
install.installer.install_offline=从本地文件安装/升级
|
||||||
install.installer.install_offline.extension=Forge/OptiFine 安装器
|
install.installer.install_offline.extension=Forge/OptiFine 安装器
|
||||||
@@ -151,9 +152,9 @@ install.installer.install_offline.tooltip=支持导入已经下载好的 Forge/O
|
|||||||
install.installer.install_online=在线安装
|
install.installer.install_online=在线安装
|
||||||
install.installer.install_online.tooltip=支持安装 Fabric、Forge、OptiFine、LiteLoader
|
install.installer.install_online.tooltip=支持安装 Fabric、Forge、OptiFine、LiteLoader
|
||||||
install.installer.liteloader=LiteLoader
|
install.installer.liteloader=LiteLoader
|
||||||
install.installer.not_installed=%s 版本: 不安装
|
install.installer.not_installed=不安装
|
||||||
install.installer.optifine=OptiFine
|
install.installer.optifine=OptiFine
|
||||||
install.installer.version=%s 版本: %s
|
install.installer.version=%s
|
||||||
install.modpack=安装整合包
|
install.modpack=安装整合包
|
||||||
install.new_game=安装新游戏版本
|
install.new_game=安装新游戏版本
|
||||||
install.new_game.already_exists=此版本已经存在,请换一个名字
|
install.new_game.already_exists=此版本已经存在,请换一个名字
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public final class ForgeInstallTask extends Task<Version> {
|
|||||||
public void execute() throws IOException, VersionMismatchException, OptiFineInstallTask.UnsupportedOptiFineInstallationException {
|
public void execute() throws IOException, VersionMismatchException, OptiFineInstallTask.UnsupportedOptiFineInstallationException {
|
||||||
String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass();
|
String originalMainClass = version.resolve(dependencyManager.getGameRepository()).getMainClass();
|
||||||
if (VersionNumber.VERSION_COMPARATOR.compare("1.13", remote.getGameVersion()) <= 0) {
|
if (VersionNumber.VERSION_COMPARATOR.compare("1.13", remote.getGameVersion()) <= 0) {
|
||||||
// Forge 1.13 is not compatible with any other libraries.
|
// Forge 1.13 is not compatible with fabric.
|
||||||
if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass) && !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass) && !LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass))
|
if (!LibraryAnalyzer.VANILLA_MAIN.equals(originalMainClass) && !LibraryAnalyzer.MOD_LAUNCHER_MAIN.equals(originalMainClass) && !LibraryAnalyzer.LAUNCH_WRAPPER_MAIN.equals(originalMainClass))
|
||||||
throw new OptiFineInstallTask.UnsupportedOptiFineInstallationException();
|
throw new OptiFineInstallTask.UnsupportedOptiFineInstallationException();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip
|
||||||
|
|||||||
Reference in New Issue
Block a user