Compare commits
13
Commits
v3.5.3.230
...
v3.5.4.232
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af36a0ac2a | ||
|
|
7356335106 | ||
|
|
d8c96769ea | ||
|
|
d71815aa3d | ||
|
|
9a4286620f | ||
|
|
0eac7b5d12 | ||
|
|
af63c3aa3a | ||
|
|
72a8199453 | ||
|
|
090b83bf9c | ||
|
|
6f70da51f9 | ||
|
|
ed0a4c8cf4 | ||
|
|
5fa066de6b | ||
|
|
1454ea8358 |
No files matched your search
@@ -48,11 +48,13 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.newImage;
|
||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public class HMCLGameRepository extends DefaultGameRepository {
|
||||
private final Profile profile;
|
||||
@@ -335,6 +337,16 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
) / 1024 / 1024))
|
||||
.setMinMemory(vs.getMinMemory())
|
||||
.setMetaspace(Lang.toIntOrNull(vs.getPermSize()))
|
||||
.setEnvironmentVariables(
|
||||
Lang.mapOf(StringUtils.tokenize(vs.getEnvironmentVariables())
|
||||
.stream()
|
||||
.map(it -> {
|
||||
int idx = it.indexOf('=');
|
||||
return idx >= 0 ? pair(it.substring(0, idx), it.substring(idx + 1)) : pair(it, "");
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
)
|
||||
)
|
||||
.setWidth(vs.getWidth())
|
||||
.setHeight(vs.getHeight())
|
||||
.setFullscreen(vs.isFullscreen())
|
||||
@@ -346,7 +358,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
|
||||
.setNativesDirType(vs.getNativesDirType())
|
||||
.setNativesDir(vs.getNativesDir())
|
||||
.setProcessPriority(vs.getProcessPriority())
|
||||
.setUseSoftwareRenderer(vs.isUseSoftwareRenderer())
|
||||
.setRenderer(vs.getRenderer())
|
||||
.setUseNativeGLFW(vs.isUseNativeGLFW())
|
||||
.setUseNativeOpenAL(vs.isUseNativeOpenAL())
|
||||
.setDaemon(!makeLaunchScript && vs.getLauncherVisibility().isDaemon())
|
||||
|
||||
@@ -150,8 +150,9 @@ public final class LauncherHelper {
|
||||
}
|
||||
}),
|
||||
Task.composeAsync(() -> {
|
||||
if (setting.isUseSoftwareRenderer() && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
Library lib = NativePatcher.getSoftwareRendererLoader(javaVersion);
|
||||
Renderer renderer = setting.getRenderer();
|
||||
if (renderer != Renderer.DEFAULT && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
Library lib = NativePatcher.getMesaLoader(javaVersion, renderer);
|
||||
if (lib == null)
|
||||
return null;
|
||||
File file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib);
|
||||
@@ -160,11 +161,13 @@ public final class LauncherHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
String agent = file.getAbsolutePath() + "=" + renderer.name().toLowerCase(Locale.ROOT);
|
||||
|
||||
if (GameLibrariesTask.shouldDownloadLibrary(repository, version.get(), lib, integrityCheck)) {
|
||||
return new LibraryDownloadTask(dependencyManager, file, lib)
|
||||
.thenRunAsync(() -> javaAgents.add(file.getAbsolutePath()));
|
||||
.thenRunAsync(() -> javaAgents.add(agent));
|
||||
} else {
|
||||
javaAgents.add(file.getAbsolutePath());
|
||||
javaAgents.add(agent);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.lang.reflect.Type;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -340,6 +341,20 @@ public final class VersionSetting implements Cloneable {
|
||||
minecraftArgsProperty.set(minecraftArgs);
|
||||
}
|
||||
|
||||
private final StringProperty environmentVariablesProperty = new SimpleStringProperty(this, "environmentVariables", "");
|
||||
|
||||
public StringProperty environmentVariablesProperty() {
|
||||
return environmentVariablesProperty;
|
||||
}
|
||||
|
||||
public String getEnvironmentVariables() {
|
||||
return environmentVariablesProperty.get();
|
||||
}
|
||||
|
||||
public void setEnvironmentVariables(String env) {
|
||||
environmentVariablesProperty.set(env);
|
||||
}
|
||||
|
||||
private final BooleanProperty noJVMArgsProperty = new SimpleBooleanProperty(this, "noJVMArgs", false);
|
||||
|
||||
public BooleanProperty noJVMArgsProperty() {
|
||||
@@ -482,7 +497,6 @@ public final class VersionSetting implements Cloneable {
|
||||
widthProperty.set(width);
|
||||
}
|
||||
|
||||
|
||||
private final IntegerProperty heightProperty = new SimpleIntegerProperty(this, "height", 480);
|
||||
|
||||
public IntegerProperty heightProperty() {
|
||||
@@ -553,18 +567,18 @@ public final class VersionSetting implements Cloneable {
|
||||
processPriorityProperty.set(processPriority);
|
||||
}
|
||||
|
||||
private final BooleanProperty useSoftwareRenderer = new SimpleBooleanProperty(this, "softwareRenderer", false);
|
||||
private final ObjectProperty<Renderer> rendererProperty = new SimpleObjectProperty<>(this, "renderer", Renderer.DEFAULT);
|
||||
|
||||
public boolean isUseSoftwareRenderer() {
|
||||
return useSoftwareRenderer.get();
|
||||
public Renderer getRenderer() {
|
||||
return rendererProperty.get();
|
||||
}
|
||||
|
||||
public BooleanProperty useSoftwareRendererProperty() {
|
||||
return useSoftwareRenderer;
|
||||
public ObjectProperty<Renderer> rendererProperty() {
|
||||
return rendererProperty;
|
||||
}
|
||||
|
||||
public void setUseSoftwareRenderer(boolean useSoftwareRenderer) {
|
||||
this.useSoftwareRenderer.set(useSoftwareRenderer);
|
||||
public void setRenderer(Renderer renderer) {
|
||||
this.rendererProperty.set(renderer);
|
||||
}
|
||||
|
||||
private final BooleanProperty useNativeGLFW = new SimpleBooleanProperty(this, "nativeGLFW", false);
|
||||
@@ -692,6 +706,7 @@ public final class VersionSetting implements Cloneable {
|
||||
postExitCommand.addListener(listener);
|
||||
javaArgsProperty.addListener(listener);
|
||||
minecraftArgsProperty.addListener(listener);
|
||||
environmentVariablesProperty.addListener(listener);
|
||||
noJVMArgsProperty.addListener(listener);
|
||||
notCheckGameProperty.addListener(listener);
|
||||
notCheckJVMProperty.addListener(listener);
|
||||
@@ -704,7 +719,7 @@ public final class VersionSetting implements Cloneable {
|
||||
gameDirTypeProperty.addListener(listener);
|
||||
gameDirProperty.addListener(listener);
|
||||
processPriorityProperty.addListener(listener);
|
||||
useSoftwareRenderer.addListener(listener);
|
||||
rendererProperty.addListener(listener);
|
||||
useNativeGLFW.addListener(listener);
|
||||
useNativeOpenAL.addListener(listener);
|
||||
launcherVisibilityProperty.addListener(listener);
|
||||
@@ -730,6 +745,7 @@ public final class VersionSetting implements Cloneable {
|
||||
versionSetting.setPostExitCommand(getPostExitCommand());
|
||||
versionSetting.setJavaArgs(getJavaArgs());
|
||||
versionSetting.setMinecraftArgs(getMinecraftArgs());
|
||||
versionSetting.setEnvironmentVariables(getEnvironmentVariables());
|
||||
versionSetting.setNoJVMArgs(isNoJVMArgs());
|
||||
versionSetting.setNotCheckGame(isNotCheckGame());
|
||||
versionSetting.setNotCheckJVM(isNotCheckJVM());
|
||||
@@ -742,7 +758,7 @@ public final class VersionSetting implements Cloneable {
|
||||
versionSetting.setGameDirType(getGameDirType());
|
||||
versionSetting.setGameDir(getGameDir());
|
||||
versionSetting.setProcessPriority(getProcessPriority());
|
||||
versionSetting.setUseSoftwareRenderer(isUseSoftwareRenderer());
|
||||
versionSetting.setRenderer(getRenderer());
|
||||
versionSetting.setUseNativeGLFW(isUseNativeGLFW());
|
||||
versionSetting.setUseNativeOpenAL(isUseNativeOpenAL());
|
||||
versionSetting.setLauncherVisibility(getLauncherVisibility());
|
||||
@@ -760,6 +776,7 @@ public final class VersionSetting implements Cloneable {
|
||||
obj.addProperty("usesGlobal", src.isUsesGlobal());
|
||||
obj.addProperty("javaArgs", src.getJavaArgs());
|
||||
obj.addProperty("minecraftArgs", src.getMinecraftArgs());
|
||||
obj.addProperty("environmentVariables", src.getEnvironmentVariables());
|
||||
obj.addProperty("maxMemory", src.getMaxMemory() <= 0 ? OperatingSystem.SUGGESTED_MEMORY : src.getMaxMemory());
|
||||
obj.addProperty("minMemory", src.getMinMemory());
|
||||
obj.addProperty("autoMemory", src.isAutoMemory());
|
||||
@@ -781,7 +798,6 @@ public final class VersionSetting implements Cloneable {
|
||||
obj.addProperty("gameDir", src.getGameDir());
|
||||
obj.addProperty("launcherVisibility", src.getLauncherVisibility().ordinal());
|
||||
obj.addProperty("processPriority", src.getProcessPriority().ordinal());
|
||||
obj.addProperty("useSoftwareRenderer", src.isUseSoftwareRenderer());
|
||||
obj.addProperty("useNativeGLFW", src.isUseNativeGLFW());
|
||||
obj.addProperty("useNativeOpenAL", src.isUseNativeOpenAL());
|
||||
obj.addProperty("gameDirType", src.getGameDirType().ordinal());
|
||||
@@ -790,6 +806,10 @@ public final class VersionSetting implements Cloneable {
|
||||
obj.addProperty("nativesDirType", src.getNativesDirType().ordinal());
|
||||
obj.addProperty("versionIcon", src.getVersionIcon().ordinal());
|
||||
|
||||
obj.addProperty("renderer", src.getRenderer().name());
|
||||
if (src.getRenderer() == Renderer.LLVMPIPE)
|
||||
obj.addProperty("useSoftwareRenderer", true);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -815,6 +835,7 @@ public final class VersionSetting implements Cloneable {
|
||||
vs.setUsesGlobal(Optional.ofNullable(obj.get("usesGlobal")).map(JsonElement::getAsBoolean).orElse(false));
|
||||
vs.setJavaArgs(Optional.ofNullable(obj.get("javaArgs")).map(JsonElement::getAsString).orElse(""));
|
||||
vs.setMinecraftArgs(Optional.ofNullable(obj.get("minecraftArgs")).map(JsonElement::getAsString).orElse(""));
|
||||
vs.setEnvironmentVariables(Optional.ofNullable(obj.get("environmentVariables")).map(JsonElement::getAsString).orElse(""));
|
||||
vs.setMaxMemory(maxMemoryN);
|
||||
vs.setMinMemory(Optional.ofNullable(obj.get("minMemory")).map(JsonElement::getAsInt).orElse(null));
|
||||
vs.setAutoMemory(Optional.ofNullable(obj.get("autoMemory")).map(JsonElement::getAsBoolean).orElse(true));
|
||||
@@ -836,7 +857,6 @@ public final class VersionSetting implements Cloneable {
|
||||
vs.setShowLogs(Optional.ofNullable(obj.get("showLogs")).map(JsonElement::getAsBoolean).orElse(false));
|
||||
vs.setLauncherVisibility(getOrDefault(LauncherVisibility.values(), obj.get("launcherVisibility"), LauncherVisibility.HIDE));
|
||||
vs.setProcessPriority(getOrDefault(ProcessPriority.values(), obj.get("processPriority"), ProcessPriority.NORMAL));
|
||||
vs.setUseSoftwareRenderer(Optional.ofNullable(obj.get("useSoftwareRenderer")).map(JsonElement::getAsBoolean).orElse(false));
|
||||
vs.setUseNativeGLFW(Optional.ofNullable(obj.get("useNativeGLFW")).map(JsonElement::getAsBoolean).orElse(false));
|
||||
vs.setUseNativeOpenAL(Optional.ofNullable(obj.get("useNativeOpenAL")).map(JsonElement::getAsBoolean).orElse(false));
|
||||
vs.setGameDirType(getOrDefault(GameDirectoryType.values(), obj.get("gameDirType"), GameDirectoryType.ROOT_FOLDER));
|
||||
@@ -844,6 +864,18 @@ public final class VersionSetting implements Cloneable {
|
||||
vs.setNativesDirType(getOrDefault(NativesDirectoryType.values(), obj.get("nativesDirType"), NativesDirectoryType.VERSION_FOLDER));
|
||||
vs.setVersionIcon(getOrDefault(VersionIconType.values(), obj.get("versionIcon"), VersionIconType.DEFAULT));
|
||||
|
||||
vs.setRenderer(Optional.ofNullable(obj.get("renderer")).map(JsonElement::getAsString)
|
||||
.flatMap(name -> {
|
||||
try {
|
||||
return Optional.of(Renderer.valueOf(name.toUpperCase(Locale.ROOT)));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}).orElseGet(() -> {
|
||||
boolean useSoftwareRenderer = Optional.ofNullable(obj.get("useSoftwareRenderer")).map(JsonElement::getAsBoolean).orElse(false);
|
||||
return useSoftwareRenderer ? Renderer.LLVMPIPE : Renderer.DEFAULT;
|
||||
}));
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ public final class Controllers {
|
||||
agreementPane.setHeading(new Label(i18n("launcher.agreement")));
|
||||
agreementPane.setBody(new Label(i18n("launcher.agreement.hint")));
|
||||
JFXHyperlink agreementLink = new JFXHyperlink(i18n("launcher.agreement"));
|
||||
agreementLink.setOnAction(e -> FXUtils.openLink(Metadata.EULA_URL));
|
||||
agreementLink.setExternalLink(Metadata.EULA_URL);
|
||||
JFXButton yesButton = new JFXButton(i18n("launcher.agreement.accept"));
|
||||
yesButton.getStyleClass().add("dialog-accept");
|
||||
yesButton.setOnAction(e -> {
|
||||
@@ -236,9 +236,7 @@ public final class Controllers {
|
||||
});
|
||||
JFXButton noButton = new JFXButton(i18n("launcher.agreement.decline"));
|
||||
noButton.getStyleClass().add("dialog-cancel");
|
||||
noButton.setOnAction(e -> {
|
||||
System.exit(1);
|
||||
});
|
||||
noButton.setOnAction(e -> System.exit(1));
|
||||
agreementPane.setActions(agreementLink, yesButton, noButton);
|
||||
Controllers.dialog(agreementPane);
|
||||
}
|
||||
|
||||
@@ -625,16 +625,17 @@ public final class FXUtils {
|
||||
* @param comboBox the combo box being bound with {@code property}.
|
||||
* @param property the property being bound with {@code combo box}.
|
||||
* @see #unbindEnum(JFXComboBox)
|
||||
* @deprecated Use {@link ExtendedProperties#selectedItemPropertyFor(ComboBox)}
|
||||
* @see ExtendedProperties#selectedItemPropertyFor(ComboBox)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public static void bindEnum(JFXComboBox<?> comboBox, Property<? extends Enum<?>> property) {
|
||||
public static <T extends Enum<T>> void bindEnum(JFXComboBox<T> comboBox, Property<T> property) {
|
||||
unbindEnum(comboBox);
|
||||
@SuppressWarnings("rawtypes")
|
||||
ChangeListener<Number> listener = (a, b, newValue) ->
|
||||
((Property) property).setValue(property.getValue().getClass().getEnumConstants()[newValue.intValue()]);
|
||||
comboBox.getSelectionModel().select(property.getValue().ordinal());
|
||||
|
||||
T currentValue = property.getValue();
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] enumConstants = (T[]) currentValue.getClass().getEnumConstants();
|
||||
ChangeListener<Number> listener = (a, b, newValue) -> property.setValue(enumConstants[newValue.intValue()]);
|
||||
|
||||
comboBox.getSelectionModel().select(currentValue.ordinal());
|
||||
comboBox.getProperties().put("FXUtils.bindEnum.listener", listener);
|
||||
comboBox.getSelectionModel().selectedIndexProperty().addListener(listener);
|
||||
}
|
||||
@@ -645,15 +646,13 @@ public final class FXUtils {
|
||||
*
|
||||
* @param comboBox the combo box being bound with the property which can be inferred by {@code bindEnum}.
|
||||
* @see #bindEnum(JFXComboBox, Property)
|
||||
* @deprecated Use {@link ExtendedProperties#selectedItemPropertyFor(ComboBox)}
|
||||
* @see ExtendedProperties#selectedItemPropertyFor(ComboBox)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public static void unbindEnum(JFXComboBox<?> comboBox) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
ChangeListener listener = tryCast(comboBox.getProperties().get("FXUtils.bindEnum.listener"), ChangeListener.class).orElse(null);
|
||||
if (listener == null) return;
|
||||
comboBox.getSelectionModel().selectedIndexProperty().removeListener(listener);
|
||||
public static void unbindEnum(JFXComboBox<? extends Enum<?>> comboBox) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ChangeListener<Number> listener = (ChangeListener<Number>) comboBox.getProperties().remove("FXUtils.bindEnum.listener");
|
||||
if (listener != null)
|
||||
comboBox.getSelectionModel().selectedIndexProperty().removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
@@ -347,9 +348,20 @@ public class GameCrashWindow extends Stage {
|
||||
Label reasonTitle = new Label(i18n("game.crash.reason"));
|
||||
reasonTitle.getStyleClass().add("two-line-item-second-large-title");
|
||||
|
||||
ScrollPane reasonPane = new ScrollPane(reasonTextFlow);
|
||||
reasonPane.setFitToWidth(true);
|
||||
reasonPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
||||
reasonPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
||||
|
||||
gameDirPane.setPadding(new Insets(8));
|
||||
VBox.setVgrow(gameDirPane, Priority.ALWAYS);
|
||||
gameDirPane.getChildren().setAll(gameDir, javaDir, new VBox(reasonTitle, reasonTextFlow, feedbackTextFlow));
|
||||
FXUtils.onChangeAndOperate(feedbackTextFlow.visibleProperty(), visible -> {
|
||||
if (visible) {
|
||||
gameDirPane.getChildren().setAll(gameDir, javaDir, new VBox(reasonTitle, reasonPane, feedbackTextFlow));
|
||||
} else {
|
||||
gameDirPane.getChildren().setAll(gameDir, javaDir, new VBox(reasonTitle, reasonPane));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
HBox toolBar = new HBox();
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||
@@ -91,10 +90,10 @@ public class ClassicAccountLoginDialog extends StackPane {
|
||||
body.getChildren().add(linkPane);
|
||||
|
||||
JFXHyperlink migrationLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration"));
|
||||
migrationLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PROFILE_URL));
|
||||
migrationLink.setExternalLink(YggdrasilService.PROFILE_URL);
|
||||
|
||||
JFXHyperlink migrationHowLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration.how"));
|
||||
migrationHowLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.MIGRATION_FAQ_URL));
|
||||
migrationHowLink.setExternalLink(YggdrasilService.MIGRATION_FAQ_URL);
|
||||
|
||||
linkPane.getChildren().setAll(migrationLink, migrationHowLink);
|
||||
}
|
||||
|
||||
@@ -512,13 +512,13 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
||||
GridPane.setColumnSpan(box, 2);
|
||||
|
||||
JFXHyperlink migrationLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration"));
|
||||
migrationLink.setOnAction(e -> FXUtils.openLink("https://aka.ms/MinecraftMigration"));
|
||||
migrationLink.setExternalLink("https://aka.ms/MinecraftMigration");
|
||||
|
||||
JFXHyperlink migrationHowLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration.how"));
|
||||
migrationHowLink.setOnAction(e -> FXUtils.openLink("https://help.minecraft.net/hc/articles/4411173197709"));
|
||||
migrationHowLink.setExternalLink("https://help.minecraft.net/hc/articles/4411173197709");
|
||||
|
||||
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
||||
purchaseLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PURCHASE_URL));
|
||||
purchaseLink.setExternalLink(YggdrasilService.PURCHASE_URL);
|
||||
|
||||
box.getChildren().setAll(migrationLink, migrationHowLink, purchaseLink);
|
||||
add(box, 0, rowIndex);
|
||||
@@ -530,7 +530,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
||||
txtUsername.setPromptText(i18n("account.methods.offline.name.special_characters"));
|
||||
|
||||
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
||||
purchaseLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PURCHASE_URL));
|
||||
purchaseLink.setExternalLink(YggdrasilService.PURCHASE_URL);
|
||||
HBox linkPane = new HBox(purchaseLink);
|
||||
GridPane.setColumnSpan(linkPane, 2);
|
||||
add(linkPane, 0, rowIndex);
|
||||
|
||||
@@ -38,7 +38,8 @@ import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@DefaultProperty("content")
|
||||
public class ComponentList extends Control {
|
||||
@@ -47,13 +48,17 @@ public class ComponentList extends Control {
|
||||
private final IntegerProperty depth = new SimpleIntegerProperty(this, "depth", 0);
|
||||
private boolean hasSubtitle = false;
|
||||
public final ObservableList<Node> content = FXCollections.observableArrayList();
|
||||
private boolean expanded = false;
|
||||
private Consumer<ComponentList> lazyInitializer;
|
||||
private Supplier<List<? extends Node>> lazyInitializer;
|
||||
|
||||
public ComponentList() {
|
||||
getStyleClass().add("options-list");
|
||||
}
|
||||
|
||||
public ComponentList(Supplier<List<? extends Node>> lazyInitializer) {
|
||||
this();
|
||||
this.lazyInitializer = lazyInitializer;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
}
|
||||
@@ -102,17 +107,12 @@ public class ComponentList extends Control {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setLazyInitializer(Consumer<ComponentList> lazyInitializer) {
|
||||
this.lazyInitializer = lazyInitializer;
|
||||
}
|
||||
|
||||
public void onExpand() {
|
||||
if (!expanded && lazyInitializer != null) {
|
||||
lazyInitializer.accept(this);
|
||||
void doLazyInit() {
|
||||
if (lazyInitializer != null) {
|
||||
this.getContent().setAll(lazyInitializer.get());
|
||||
setNeedsLayout(true);
|
||||
lazyInitializer = null;
|
||||
}
|
||||
|
||||
expanded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +125,7 @@ public class ComponentList extends Control {
|
||||
return new Skin(this);
|
||||
}
|
||||
|
||||
protected static class Skin extends ControlSkinBase<ComponentList> {
|
||||
private static final class Skin extends ControlSkinBase<ComponentList> {
|
||||
private static final PseudoClass PSEUDO_CLASS_FIRST = PseudoClass.getPseudoClass("first");
|
||||
private static final PseudoClass PSEUDO_CLASS_LAST = PseudoClass.getPseudoClass("last");
|
||||
|
||||
@@ -133,7 +133,7 @@ public class ComponentList extends Control {
|
||||
private final ObjectBinding<Node> firstItem;
|
||||
private final ObjectBinding<Node> lastItem;
|
||||
|
||||
protected Skin(ComponentList control) {
|
||||
Skin(ComponentList control) {
|
||||
super(control);
|
||||
|
||||
list = MappedObservableList.create(control.getContent(), node -> {
|
||||
|
||||
@@ -43,7 +43,7 @@ import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||
/**
|
||||
* @author huangyuhui
|
||||
*/
|
||||
class ComponentListCell extends StackPane {
|
||||
final class ComponentListCell extends StackPane {
|
||||
private final Node content;
|
||||
private Animation expandAnimation;
|
||||
private Rectangle clipRect;
|
||||
@@ -139,69 +139,53 @@ class ComponentListCell extends StackPane {
|
||||
container.getChildren().setAll(content);
|
||||
groupNode.getChildren().add(container);
|
||||
|
||||
EventHandler<Event> onExpand;
|
||||
if (AnimationUtils.isAnimationEnabled()) {
|
||||
onExpand = e -> {
|
||||
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
|
||||
expandAnimation.stop();
|
||||
EventHandler<Event> onExpand = e -> {
|
||||
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
|
||||
expandAnimation.stop();
|
||||
}
|
||||
|
||||
boolean expanded = !isExpanded();
|
||||
setExpanded(expanded);
|
||||
if (expanded) {
|
||||
list.doLazyInit();
|
||||
list.layout();
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
double newAnimatedHeight = (list.prefHeight(-1) + 8 + 10) * (expanded ? 1 : -1);
|
||||
double newHeight = expanded ? getHeight() + newAnimatedHeight : prefHeight(-1);
|
||||
double contentHeight = expanded ? newAnimatedHeight : 0;
|
||||
|
||||
if (expanded) {
|
||||
updateClip(newHeight);
|
||||
}
|
||||
|
||||
setExpanded(!isExpanded());
|
||||
|
||||
if (isExpanded()) {
|
||||
list.onExpand();
|
||||
list.layout();
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
double newAnimatedHeight = (content.prefHeight(-1) + 8 + 10) * (isExpanded() ? 1 : -1);
|
||||
double newHeight = isExpanded() ? getHeight() + newAnimatedHeight : prefHeight(-1);
|
||||
double contentHeight = isExpanded() ? newAnimatedHeight : 0;
|
||||
|
||||
if (isExpanded()) {
|
||||
updateClip(newHeight);
|
||||
}
|
||||
|
||||
if (AnimationUtils.isAnimationEnabled()) {
|
||||
expandAnimation = new Timeline(new KeyFrame(new Duration(320.0),
|
||||
new KeyValue(container.minHeightProperty(), contentHeight, FXUtils.SINE),
|
||||
new KeyValue(container.maxHeightProperty(), contentHeight, FXUtils.SINE)
|
||||
));
|
||||
|
||||
if (!isExpanded()) {
|
||||
if (!expanded) {
|
||||
expandAnimation.setOnFinished(e2 -> updateClip(newHeight));
|
||||
}
|
||||
|
||||
expandAnimation.play();
|
||||
});
|
||||
};
|
||||
} else {
|
||||
onExpand = e -> {
|
||||
setExpanded(!isExpanded());
|
||||
} else {
|
||||
container.setMinHeight(contentHeight);
|
||||
container.setMaxHeight(contentHeight);
|
||||
|
||||
double newAnimatedHeight = (content.prefHeight(-1) + 8 + 10) * (isExpanded() ? 1 : -1);
|
||||
double newHeight = isExpanded() ? getHeight() + newAnimatedHeight : prefHeight(-1);
|
||||
double contentHeight = isExpanded() ? newAnimatedHeight : 0;
|
||||
|
||||
if (isExpanded()) {
|
||||
list.onExpand();
|
||||
list.layout();
|
||||
updateClip(newHeight);
|
||||
if (!expanded) {
|
||||
updateClip(newHeight);
|
||||
}
|
||||
}
|
||||
|
||||
container.setMinHeight(contentHeight);
|
||||
container.setMaxHeight(contentHeight);
|
||||
|
||||
if (!isExpanded()) {
|
||||
updateClip(newHeight);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
headerRippler.setOnMouseClicked(onExpand);
|
||||
expandButton.setOnAction((EventHandler<ActionEvent>) (Object) onExpand);
|
||||
|
||||
expandedProperty().addListener((a, b, newValue) ->
|
||||
expandIcon.setRotate(newValue ? 180 : 0));
|
||||
expandedProperty().addListener((a, b, newValue) -> expandIcon.setRotate(newValue ? 180 : 0));
|
||||
|
||||
getChildren().setAll(groupNode);
|
||||
} else {
|
||||
|
||||
@@ -157,7 +157,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||
multiplayerItem.setActionButtonVisible(false);
|
||||
multiplayerItem.setTitle(i18n("multiplayer"));
|
||||
JFXHyperlink link = new JFXHyperlink(i18n("multiplayer.hint.details"));
|
||||
link.setOnAction(e -> FXUtils.openLink("https://hmcl.huangyuhui.net/api/redirect/multiplayer-migrate"));
|
||||
link.setExternalLink("https://hmcl.huangyuhui.net/api/redirect/multiplayer-migrate");
|
||||
multiplayerItem.setOnAction(e -> Controllers.dialog(
|
||||
new MessageDialogPane.Builder(i18n("multiplayer.hint"), null, MessageDialogPane.MessageType.INFO)
|
||||
.addAction(link)
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
package org.jackhuang.hmcl.ui.versions;
|
||||
|
||||
import com.jfoenix.controls.JFXComboBox;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.*;
|
||||
import org.jackhuang.hmcl.game.NativesDirectoryType;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.game.Renderer;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.*;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class AdvancedVersionSettingPage extends StackPane implements DecoratorPage {
|
||||
|
||||
private final ObjectProperty<State> stateProperty;
|
||||
|
||||
private final Profile profile;
|
||||
private final String versionId;
|
||||
private final VersionSetting versionSetting;
|
||||
|
||||
private final JFXTextField txtJVMArgs;
|
||||
private final JFXTextField txtGameArgs;
|
||||
private final JFXTextField txtEnvironmentVariables;
|
||||
private final JFXTextField txtMetaspace;
|
||||
private final JFXTextField txtWrapper;
|
||||
private final JFXTextField txtPreLaunchCommand;
|
||||
private final JFXTextField txtPostExitCommand;
|
||||
private final OptionToggleButton noJVMArgsPane;
|
||||
private final OptionToggleButton noGameCheckPane;
|
||||
private final OptionToggleButton noJVMCheckPane;
|
||||
private final OptionToggleButton noNativesPatchPane;
|
||||
private final OptionToggleButton useNativeGLFWPane;
|
||||
private final OptionToggleButton useNativeOpenALPane;
|
||||
private final ComponentSublist nativesDirSublist;
|
||||
private final MultiFileItem<NativesDirectoryType> nativesDirItem;
|
||||
private final MultiFileItem.FileOption<NativesDirectoryType> nativesDirCustomOption;
|
||||
private final JFXComboBox<Renderer> cboRenderer;
|
||||
|
||||
public AdvancedVersionSettingPage(Profile profile, String versionId, VersionSetting versionSetting) {
|
||||
this.profile = profile;
|
||||
this.versionId = versionId;
|
||||
this.versionSetting = versionSetting;
|
||||
this.stateProperty = new SimpleObjectProperty<>(State.fromTitle(
|
||||
versionId == null ? i18n("settings.advanced") : i18n("settings.advanced.title", versionId)
|
||||
));
|
||||
|
||||
ScrollPane scrollPane = new ScrollPane();
|
||||
scrollPane.setFitToHeight(true);
|
||||
scrollPane.setFitToWidth(true);
|
||||
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
|
||||
getChildren().setAll(scrollPane);
|
||||
|
||||
VBox rootPane = new VBox();
|
||||
rootPane.setFillWidth(true);
|
||||
scrollPane.setContent(rootPane);
|
||||
FXUtils.smoothScrolling(scrollPane);
|
||||
rootPane.getStyleClass().add("card-list");
|
||||
|
||||
ComponentList customCommandsPane = new ComponentList();
|
||||
{
|
||||
GridPane pane = new GridPane();
|
||||
pane.setHgap(16);
|
||||
pane.setVgap(8);
|
||||
pane.getColumnConstraints().setAll(new ColumnConstraints(), FXUtils.getColumnHgrowing());
|
||||
|
||||
txtGameArgs = new JFXTextField();
|
||||
txtGameArgs.setPromptText(i18n("settings.advanced.minecraft_arguments.prompt"));
|
||||
txtGameArgs.getStyleClass().add("fit-width");
|
||||
pane.addRow(0, new Label(i18n("settings.advanced.minecraft_arguments")), txtGameArgs);
|
||||
|
||||
txtPreLaunchCommand = new JFXTextField();
|
||||
txtPreLaunchCommand.setPromptText(i18n("settings.advanced.precall_command.prompt"));
|
||||
txtPreLaunchCommand.getStyleClass().add("fit-width");
|
||||
pane.addRow(1, new Label(i18n("settings.advanced.precall_command")), txtPreLaunchCommand);
|
||||
|
||||
txtWrapper = new JFXTextField();
|
||||
txtWrapper.setPromptText(i18n("settings.advanced.wrapper_launcher.prompt"));
|
||||
txtWrapper.getStyleClass().add("fit-width");
|
||||
pane.addRow(2, new Label(i18n("settings.advanced.wrapper_launcher")), txtWrapper);
|
||||
|
||||
txtPostExitCommand = new JFXTextField();
|
||||
txtPostExitCommand.setPromptText(i18n("settings.advanced.post_exit_command.prompt"));
|
||||
txtPostExitCommand.getStyleClass().add("fit-width");
|
||||
pane.addRow(3, new Label(i18n("settings.advanced.post_exit_command")), txtPostExitCommand);
|
||||
|
||||
HintPane hintPane = new HintPane();
|
||||
hintPane.setText(i18n("settings.advanced.custom_commands.hint"));
|
||||
GridPane.setColumnSpan(hintPane, 2);
|
||||
pane.addRow(4, hintPane);
|
||||
|
||||
customCommandsPane.getContent().setAll(pane);
|
||||
}
|
||||
|
||||
ComponentList jvmPane = new ComponentList();
|
||||
{
|
||||
GridPane pane = new GridPane();
|
||||
ColumnConstraints title = new ColumnConstraints();
|
||||
ColumnConstraints value = new ColumnConstraints();
|
||||
value.setFillWidth(true);
|
||||
value.setHgrow(Priority.ALWAYS);
|
||||
pane.setHgap(16);
|
||||
pane.setVgap(8);
|
||||
pane.getColumnConstraints().setAll(title, value);
|
||||
|
||||
txtJVMArgs = new JFXTextField();
|
||||
txtJVMArgs.getStyleClass().add("fit-width");
|
||||
pane.addRow(0, new Label(i18n("settings.advanced.jvm_args")), txtJVMArgs);
|
||||
|
||||
HintPane hintPane = new HintPane();
|
||||
hintPane.setText(i18n("settings.advanced.jvm_args.prompt"));
|
||||
GridPane.setColumnSpan(hintPane, 2);
|
||||
pane.addRow(4, hintPane);
|
||||
|
||||
txtMetaspace = new JFXTextField();
|
||||
txtMetaspace.setPromptText(i18n("settings.advanced.java_permanent_generation_space.prompt"));
|
||||
txtMetaspace.getStyleClass().add("fit-width");
|
||||
FXUtils.setValidateWhileTextChanged(txtMetaspace, true);
|
||||
txtMetaspace.setValidators(new NumberValidator(i18n("input.number"), true));
|
||||
pane.addRow(1, new Label(i18n("settings.advanced.java_permanent_generation_space")), txtMetaspace);
|
||||
|
||||
txtEnvironmentVariables = new JFXTextField();
|
||||
txtEnvironmentVariables.getStyleClass().add("fit-width");
|
||||
pane.addRow(2, new Label(i18n("settings.advanced.environment_variables")), txtEnvironmentVariables);
|
||||
|
||||
jvmPane.getContent().setAll(pane);
|
||||
}
|
||||
|
||||
ComponentList workaroundPane = new ComponentList();
|
||||
|
||||
HintPane workaroundWarning = new HintPane(MessageDialogPane.MessageType.WARNING);
|
||||
workaroundWarning.setText(i18n("settings.advanced.workaround.warning"));
|
||||
|
||||
{
|
||||
nativesDirItem = new MultiFileItem<>();
|
||||
nativesDirSublist = new ComponentSublist();
|
||||
nativesDirSublist.getContent().add(nativesDirItem);
|
||||
nativesDirSublist.setTitle(i18n("settings.advanced.natives_directory"));
|
||||
nativesDirSublist.setHasSubtitle(true);
|
||||
nativesDirCustomOption = new MultiFileItem.FileOption<>(i18n("settings.advanced.natives_directory.custom"), NativesDirectoryType.CUSTOM)
|
||||
.setChooserTitle(i18n("settings.advanced.natives_directory.choose"))
|
||||
.setDirectory(true);
|
||||
nativesDirItem.loadChildren(Arrays.asList(
|
||||
new MultiFileItem.Option<>(i18n("settings.advanced.natives_directory.default"), NativesDirectoryType.VERSION_FOLDER),
|
||||
nativesDirCustomOption
|
||||
));
|
||||
HintPane nativesDirHint = new HintPane(MessageDialogPane.MessageType.WARNING);
|
||||
nativesDirHint.setText(i18n("settings.advanced.natives_directory.hint"));
|
||||
nativesDirItem.getChildren().add(nativesDirHint);
|
||||
|
||||
BorderPane rendererPane = new BorderPane();
|
||||
{
|
||||
Label label = new Label(i18n("settings.advanced.renderer"));
|
||||
rendererPane.setLeft(label);
|
||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
||||
|
||||
cboRenderer = new JFXComboBox<>();
|
||||
cboRenderer.getItems().setAll(Renderer.values());
|
||||
cboRenderer.setConverter(stringConverter(e -> i18n("settings.advanced.renderer." + e.name().toLowerCase(Locale.ROOT))));
|
||||
rendererPane.setRight(cboRenderer);
|
||||
BorderPane.setAlignment(cboRenderer, Pos.CENTER_RIGHT);
|
||||
FXUtils.setLimitWidth(cboRenderer, 300);
|
||||
}
|
||||
|
||||
noJVMArgsPane = new OptionToggleButton();
|
||||
noJVMArgsPane.setTitle(i18n("settings.advanced.no_jvm_args"));
|
||||
|
||||
noGameCheckPane = new OptionToggleButton();
|
||||
noGameCheckPane.setTitle(i18n("settings.advanced.dont_check_game_completeness"));
|
||||
|
||||
noJVMCheckPane = new OptionToggleButton();
|
||||
noJVMCheckPane.setTitle(i18n("settings.advanced.dont_check_jvm_validity"));
|
||||
|
||||
noNativesPatchPane = new OptionToggleButton();
|
||||
noNativesPatchPane.setTitle(i18n("settings.advanced.dont_patch_natives"));
|
||||
|
||||
useNativeGLFWPane = new OptionToggleButton();
|
||||
useNativeGLFWPane.setTitle(i18n("settings.advanced.use_native_glfw"));
|
||||
|
||||
useNativeOpenALPane = new OptionToggleButton();
|
||||
useNativeOpenALPane.setTitle(i18n("settings.advanced.use_native_openal"));
|
||||
|
||||
workaroundPane.getContent().setAll(
|
||||
nativesDirSublist, rendererPane,
|
||||
noJVMArgsPane, noGameCheckPane, noJVMCheckPane, noNativesPatchPane,
|
||||
useNativeGLFWPane, useNativeOpenALPane);
|
||||
}
|
||||
|
||||
rootPane.getChildren().addAll(
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.custom_commands")), customCommandsPane,
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.jvm")), jvmPane,
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.workaround")), workaroundWarning, workaroundPane
|
||||
);
|
||||
|
||||
bindProperties();
|
||||
}
|
||||
|
||||
void bindProperties() {
|
||||
nativesDirCustomOption.bindBidirectional(versionSetting.nativesDirProperty());
|
||||
FXUtils.bindString(txtJVMArgs, versionSetting.javaArgsProperty());
|
||||
FXUtils.bindString(txtGameArgs, versionSetting.minecraftArgsProperty());
|
||||
FXUtils.bindString(txtMetaspace, versionSetting.permSizeProperty());
|
||||
FXUtils.bindString(txtEnvironmentVariables, versionSetting.environmentVariablesProperty());
|
||||
FXUtils.bindString(txtWrapper, versionSetting.wrapperProperty());
|
||||
FXUtils.bindString(txtPreLaunchCommand, versionSetting.preLaunchCommandProperty());
|
||||
FXUtils.bindEnum(cboRenderer, versionSetting.rendererProperty());
|
||||
noGameCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().bindBidirectional(versionSetting.noJVMArgsProperty());
|
||||
noNativesPatchPane.selectedProperty().bindBidirectional(versionSetting.notPatchNativesProperty());
|
||||
useNativeGLFWPane.selectedProperty().bindBidirectional(versionSetting.useNativeGLFWProperty());
|
||||
useNativeOpenALPane.selectedProperty().bindBidirectional(versionSetting.useNativeOpenALProperty());
|
||||
|
||||
nativesDirItem.selectedDataProperty().bindBidirectional(versionSetting.nativesDirTypeProperty());
|
||||
nativesDirSublist.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath() + "/natives").normalize().toString(),
|
||||
versionSetting.nativesDirProperty(), versionSetting.nativesDirTypeProperty()));
|
||||
}
|
||||
|
||||
void unbindProperties() {
|
||||
nativesDirCustomOption.valueProperty().unbindBidirectional(versionSetting.nativesDirProperty());
|
||||
FXUtils.unbind(txtJVMArgs, versionSetting.javaArgsProperty());
|
||||
FXUtils.unbind(txtGameArgs, versionSetting.minecraftArgsProperty());
|
||||
FXUtils.unbind(txtMetaspace, versionSetting.permSizeProperty());
|
||||
FXUtils.unbind(txtEnvironmentVariables, versionSetting.environmentVariablesProperty());
|
||||
FXUtils.unbind(txtWrapper, versionSetting.wrapperProperty());
|
||||
FXUtils.unbind(txtPreLaunchCommand, versionSetting.preLaunchCommandProperty());
|
||||
FXUtils.unbind(txtPostExitCommand, versionSetting.postExitCommandProperty());
|
||||
FXUtils.unbindEnum(cboRenderer);
|
||||
noGameCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().unbindBidirectional(versionSetting.noJVMArgsProperty());
|
||||
noNativesPatchPane.selectedProperty().unbindBidirectional(versionSetting.notPatchNativesProperty());
|
||||
useNativeGLFWPane.selectedProperty().unbindBidirectional(versionSetting.useNativeGLFWProperty());
|
||||
useNativeOpenALPane.selectedProperty().unbindBidirectional(versionSetting.useNativeOpenALProperty());
|
||||
|
||||
nativesDirItem.selectedDataProperty().unbindBidirectional(versionSetting.nativesDirTypeProperty());
|
||||
nativesDirSublist.subtitleProperty().unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<State> stateProperty() {
|
||||
return stateProperty;
|
||||
}
|
||||
}
|
||||
@@ -260,18 +260,18 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
|
||||
if (getSkinnable().mod != null) {
|
||||
JFXHyperlink openMcmodButton = new JFXHyperlink(i18n("mods.mcmod"));
|
||||
openMcmodButton.setOnAction(e -> FXUtils.openLink(getSkinnable().translations.getMcmodUrl(getSkinnable().mod)));
|
||||
openMcmodButton.setExternalLink(getSkinnable().translations.getMcmodUrl(getSkinnable().mod));
|
||||
descriptionPane.getChildren().add(openMcmodButton);
|
||||
|
||||
if (StringUtils.isNotBlank(getSkinnable().mod.getMcbbs())) {
|
||||
JFXHyperlink openMcbbsButton = new JFXHyperlink(i18n("mods.mcbbs"));
|
||||
openMcbbsButton.setOnAction(e -> FXUtils.openLink(ModManager.getMcbbsUrl(getSkinnable().mod.getMcbbs())));
|
||||
openMcbbsButton.setExternalLink(ModManager.getMcbbsUrl(getSkinnable().mod.getMcbbs()));
|
||||
descriptionPane.getChildren().add(openMcbbsButton);
|
||||
}
|
||||
}
|
||||
|
||||
JFXHyperlink openUrlButton = new JFXHyperlink(control.page.getLocalizedOfficialPage());
|
||||
openUrlButton.setOnAction(e -> FXUtils.openLink(getSkinnable().addon.getPageUrl()));
|
||||
openUrlButton.setExternalLink(getSkinnable().addon.getPageUrl());
|
||||
descriptionPane.getChildren().add(openUrlButton);
|
||||
}
|
||||
|
||||
@@ -322,12 +322,10 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
for (String gameVersion : control.versions.keys().stream()
|
||||
.sorted(VersionNumber.VERSION_COMPARATOR.reversed())
|
||||
.collect(Collectors.toList())) {
|
||||
ComponentList sublist = new ComponentList();
|
||||
sublist.setLazyInitializer(self -> {
|
||||
self.getContent().setAll(control.versions.get(gameVersion).stream()
|
||||
.map(version -> new ModItem(version, control))
|
||||
.collect(Collectors.toList()));
|
||||
});
|
||||
ComponentList sublist = new ComponentList(() ->
|
||||
control.versions.get(gameVersion).stream()
|
||||
.map(version -> new ModItem(version, control))
|
||||
.collect(Collectors.toList()));
|
||||
sublist.getStyleClass().add("no-padding");
|
||||
sublist.setTitle(gameVersion);
|
||||
|
||||
@@ -369,6 +367,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
}
|
||||
|
||||
private static final class ModItem extends StackPane {
|
||||
|
||||
ModItem(RemoteMod.Version dataItem, DownloadPage selfPage) {
|
||||
HBox pane = new HBox(8);
|
||||
pane.setPadding(new Insets(8));
|
||||
@@ -378,9 +377,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
JFXButton saveAsButton = new JFXButton();
|
||||
|
||||
RipplerContainer container = new RipplerContainer(pane);
|
||||
container.setOnMouseClicked(e -> {
|
||||
selfPage.download(dataItem);
|
||||
});
|
||||
container.setOnMouseClicked(e -> selfPage.download(dataItem));
|
||||
getChildren().setAll(container);
|
||||
|
||||
saveAsButton.getStyleClass().add("toggle-icon4");
|
||||
@@ -391,7 +388,7 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
|
||||
content.setTitle(dataItem.getName());
|
||||
content.setSubtitle(FORMATTER.format(dataItem.getDatePublished().toInstant()));
|
||||
saveAsButton.setOnMouseClicked(e -> selfPage.saveAs(dataItem));
|
||||
saveAsButton.setOnAction(e -> selfPage.saveAs(dataItem));
|
||||
|
||||
switch (dataItem.getVersionType()) {
|
||||
case Release:
|
||||
@@ -407,6 +404,9 @@ public class DownloadPage extends Control implements DecoratorPage {
|
||||
content.getTags().add(i18n("version.game.snapshot"));
|
||||
break;
|
||||
}
|
||||
|
||||
// Workaround for https://github.com/huanghongxun/HMCL/issues/2129
|
||||
this.setMinHeight(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.versions;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
@@ -82,8 +83,8 @@ public class GameItem extends Control {
|
||||
ModpackConfiguration<?> config = profile.getRepository().readModpackConfiguration(version);
|
||||
if (config == null) return;
|
||||
tag.set(config.getVersion());
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read modpack configuration from ", e);
|
||||
} catch (IOException | JsonParseException e) {
|
||||
LOG.log(Level.WARNING, "Failed to read modpack configuration from " + version, e);
|
||||
}
|
||||
}, Platform::runLater)
|
||||
.exceptionally(handleUncaught);
|
||||
|
||||
@@ -308,8 +308,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
setBody(description);
|
||||
|
||||
if (StringUtils.isNotBlank(modInfo.getModInfo().getUrl())) {
|
||||
JFXHyperlink officialPageButton = new JFXHyperlink();
|
||||
officialPageButton.setText(i18n("mods.url"));
|
||||
JFXHyperlink officialPageButton = new JFXHyperlink(i18n("mods.url"));
|
||||
officialPageButton.setOnAction(e -> {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
FXUtils.openLink(modInfo.getModInfo().getUrl());
|
||||
@@ -319,8 +318,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
}
|
||||
|
||||
if (modInfo.getMod() != null && StringUtils.isNotBlank(modInfo.getMod().getMcbbs())) {
|
||||
JFXHyperlink mcbbsButton = new JFXHyperlink();
|
||||
mcbbsButton.setText(i18n("mods.mcbbs"));
|
||||
JFXHyperlink mcbbsButton = new JFXHyperlink(i18n("mods.mcbbs"));
|
||||
mcbbsButton.setOnAction(e -> {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
FXUtils.openLink(ModManager.getMcbbsUrl(modInfo.getMod().getMcbbs()));
|
||||
@@ -329,8 +327,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
}
|
||||
|
||||
if (modInfo.getMod() == null || StringUtils.isBlank(modInfo.getMod().getMcmod())) {
|
||||
JFXHyperlink searchButton = new JFXHyperlink();
|
||||
searchButton.setText(i18n("mods.mcmod.search"));
|
||||
JFXHyperlink searchButton = new JFXHyperlink(i18n("mods.mcmod.search"));
|
||||
searchButton.setOnAction(e -> {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
FXUtils.openLink(NetworkUtils.withQuery("https://search.mcmod.cn/s", mapOf(
|
||||
@@ -341,8 +338,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
});
|
||||
getActions().add(searchButton);
|
||||
} else {
|
||||
JFXHyperlink mcmodButton = new JFXHyperlink();
|
||||
mcmodButton.setText(i18n("mods.mcmod.page"));
|
||||
JFXHyperlink mcmodButton = new JFXHyperlink(i18n("mods.mcmod.page"));
|
||||
mcmodButton.setOnAction(e -> {
|
||||
fireEvent(new DialogCloseEvent());
|
||||
FXUtils.openLink(ModTranslations.MOD.getMcmodUrl(modInfo.getMod()));
|
||||
|
||||
@@ -66,7 +66,7 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
public final class VersionSettingsPage extends StackPane implements DecoratorPage, VersionPage.VersionLoadable, PageAware {
|
||||
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State("", null, false, false, false));
|
||||
|
||||
private final boolean globalSetting;
|
||||
private AdvancedVersionSettingPage advancedVersionSettingPage;
|
||||
|
||||
private VersionSetting lastVersionSetting = null;
|
||||
private Profile profile;
|
||||
@@ -77,24 +77,11 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
private final VBox rootPane;
|
||||
private final JFXTextField txtWidth;
|
||||
private final JFXTextField txtHeight;
|
||||
private final JFXTextField txtJVMArgs;
|
||||
private final JFXTextField txtGameArgs;
|
||||
private final JFXTextField txtMetaspace;
|
||||
private final JFXTextField txtWrapper;
|
||||
private final JFXTextField txtPreLaunchCommand;
|
||||
private final JFXTextField txtPostExitCommand;
|
||||
private final JFXTextField txtServerIP;
|
||||
private final ComponentList componentList;
|
||||
private final JFXComboBox<LauncherVisibility> cboLauncherVisibility;
|
||||
private final JFXCheckBox chkAutoAllocate;
|
||||
private final JFXCheckBox chkFullscreen;
|
||||
private final OptionToggleButton noJVMArgsPane;
|
||||
private final OptionToggleButton noGameCheckPane;
|
||||
private final OptionToggleButton noJVMCheckPane;
|
||||
private final OptionToggleButton noNativesPatchPane;
|
||||
private final OptionToggleButton useSoftwareRenderer;
|
||||
private final OptionToggleButton useNativeGLFWPane;
|
||||
private final OptionToggleButton useNativeOpenALPane;
|
||||
private final ComponentSublist javaSublist;
|
||||
private final MultiFileItem<Pair<JavaVersionType, JavaVersion>> javaItem;
|
||||
private final MultiFileItem.Option<Pair<JavaVersionType, JavaVersion>> javaAutoDeterminedOption;
|
||||
@@ -102,12 +89,9 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
private final ComponentSublist gameDirSublist;
|
||||
private final MultiFileItem<GameDirectoryType> gameDirItem;
|
||||
private final MultiFileItem.FileOption<GameDirectoryType> gameDirCustomOption;
|
||||
private final ComponentSublist nativesDirSublist;
|
||||
private final MultiFileItem<NativesDirectoryType> nativesDirItem;
|
||||
private final MultiFileItem.FileOption<NativesDirectoryType> nativesDirCustomOption;
|
||||
private final JFXComboBox<ProcessPriority> cboProcessPriority;
|
||||
private final OptionToggleButton showLogsPane;
|
||||
private ImagePickerItem iconPickerItem;
|
||||
private final ImagePickerItem iconPickerItem;
|
||||
|
||||
private final InvalidationListener specificSettingsListener;
|
||||
|
||||
@@ -121,8 +105,6 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
private final BooleanProperty modpack = new SimpleBooleanProperty();
|
||||
|
||||
public VersionSettingsPage(boolean globalSetting) {
|
||||
this.globalSetting = globalSetting;
|
||||
|
||||
ScrollPane scrollPane = new ScrollPane();
|
||||
scrollPane.setFitToHeight(true);
|
||||
scrollPane.setFitToWidth(true);
|
||||
@@ -145,18 +127,17 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
text.textProperty().bind(BindingMapping.of(selectedVersion)
|
||||
.map(selectedVersion -> i18n("settings.type.special.edit.hint", selectedVersion)));
|
||||
|
||||
JFXHyperlink specificSettingsLink = new JFXHyperlink();
|
||||
specificSettingsLink.setText(i18n("settings.type.special.edit"));
|
||||
specificSettingsLink.setOnMouseClicked(e -> editSpecificSettings());
|
||||
JFXHyperlink specificSettingsLink = new JFXHyperlink(i18n("settings.type.special.edit"));
|
||||
specificSettingsLink.setOnAction(e -> editSpecificSettings());
|
||||
|
||||
specificSettingsHint.setChildren(text, specificSettingsLink);
|
||||
specificSettingsHint.managedProperty().bind(navigateToSpecificSettings);
|
||||
specificSettingsHint.visibleProperty().bind(navigateToSpecificSettings);
|
||||
|
||||
rootPane.getChildren().addAll(specificSettingsHint);
|
||||
}
|
||||
iconPickerItem = null;
|
||||
|
||||
if (!globalSetting) {
|
||||
rootPane.getChildren().addAll(specificSettingsHint);
|
||||
} else {
|
||||
HintPane gameDirHint = new HintPane(MessageDialogPane.MessageType.INFO);
|
||||
gameDirHint.setText(i18n("settings.game.working_directory.hint"));
|
||||
rootPane.getChildren().add(gameDirHint);
|
||||
@@ -171,7 +152,6 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
iconPickerItem.setOnDeleteButtonClicked(e -> onDeleteIcon());
|
||||
iconPickerItemWrapper.getContent().setAll(iconPickerItem);
|
||||
|
||||
|
||||
BorderPane settingsTypePane = new BorderPane();
|
||||
settingsTypePane.disableProperty().bind(modpack);
|
||||
rootPane.getChildren().add(settingsTypePane);
|
||||
@@ -186,7 +166,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
settingsTypePane.setRight(editGlobalSettingsButton);
|
||||
editGlobalSettingsButton.disableProperty().bind(enableSpecificCheckBox.selectedProperty());
|
||||
BorderPane.setAlignment(editGlobalSettingsButton, Pos.CENTER_RIGHT);
|
||||
editGlobalSettingsButton.setOnMouseClicked(e -> editGlobalSettings());
|
||||
editGlobalSettingsButton.setOnAction(e -> editGlobalSettings());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -401,146 +381,43 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
serverPane.addRow(0, new Label(i18n("settings.advanced.server_ip")), txtServerIP);
|
||||
}
|
||||
|
||||
componentList.getContent().setAll(javaSublist, gameDirSublist, maxMemoryPane, launcherVisibilityPane, dimensionPane, showLogsPane, processPriorityPane, serverPane);
|
||||
BorderPane showAdvancedSettingPane = new BorderPane();
|
||||
{
|
||||
Label label = new Label(i18n("settings.advanced"));
|
||||
showAdvancedSettingPane.setLeft(label);
|
||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
||||
|
||||
JFXButton button = new JFXButton(i18n("settings.advanced.modify"));
|
||||
button.setOnAction(e -> {
|
||||
if (lastVersionSetting != null) {
|
||||
if (advancedVersionSettingPage == null)
|
||||
advancedVersionSettingPage = new AdvancedVersionSettingPage(profile, versionId, lastVersionSetting);
|
||||
|
||||
Controllers.navigate(advancedVersionSettingPage);
|
||||
}
|
||||
});
|
||||
button.getStyleClass().add("jfx-button-border");
|
||||
showAdvancedSettingPane.setRight(button);
|
||||
}
|
||||
|
||||
componentList.getContent().setAll(
|
||||
javaSublist,
|
||||
gameDirSublist,
|
||||
maxMemoryPane,
|
||||
launcherVisibilityPane,
|
||||
dimensionPane,
|
||||
showLogsPane,
|
||||
processPriorityPane,
|
||||
serverPane,
|
||||
showAdvancedSettingPane
|
||||
);
|
||||
}
|
||||
|
||||
HBox advancedHintPane = new HBox();
|
||||
advancedHintPane.setAlignment(Pos.CENTER);
|
||||
advancedHintPane.setPadding(new Insets(16, 0, 8, 0));
|
||||
{
|
||||
Label advanced = new Label(i18n("settings.advanced"));
|
||||
advanced.setStyle("-fx-font-size: 12px;");
|
||||
advancedHintPane.getChildren().setAll(advanced);
|
||||
}
|
||||
|
||||
ComponentList customCommandsPane = new ComponentList();
|
||||
customCommandsPane.disableProperty().bind(enableSpecificSettings.not());
|
||||
{
|
||||
GridPane pane = new GridPane();
|
||||
pane.setHgap(16);
|
||||
pane.setVgap(8);
|
||||
pane.getColumnConstraints().setAll(new ColumnConstraints(), FXUtils.getColumnHgrowing());
|
||||
|
||||
txtGameArgs = new JFXTextField();
|
||||
txtGameArgs.setPromptText(i18n("settings.advanced.minecraft_arguments.prompt"));
|
||||
txtGameArgs.getStyleClass().add("fit-width");
|
||||
pane.addRow(0, new Label(i18n("settings.advanced.minecraft_arguments")), txtGameArgs);
|
||||
|
||||
txtPreLaunchCommand = new JFXTextField();
|
||||
txtPreLaunchCommand.setPromptText(i18n("settings.advanced.precall_command.prompt"));
|
||||
txtPreLaunchCommand.getStyleClass().add("fit-width");
|
||||
pane.addRow(1, new Label(i18n("settings.advanced.precall_command")), txtPreLaunchCommand);
|
||||
|
||||
txtWrapper = new JFXTextField();
|
||||
txtWrapper.setPromptText(i18n("settings.advanced.wrapper_launcher.prompt"));
|
||||
txtWrapper.getStyleClass().add("fit-width");
|
||||
pane.addRow(2, new Label(i18n("settings.advanced.wrapper_launcher")), txtWrapper);
|
||||
|
||||
txtPostExitCommand = new JFXTextField();
|
||||
txtPostExitCommand.setPromptText(i18n("settings.advanced.post_exit_command.prompt"));
|
||||
txtPostExitCommand.getStyleClass().add("fit-width");
|
||||
pane.addRow(3, new Label(i18n("settings.advanced.post_exit_command")), txtPostExitCommand);
|
||||
|
||||
HintPane hintPane = new HintPane();
|
||||
hintPane.setText(i18n("settings.advanced.custom_commands.hint"));
|
||||
GridPane.setColumnSpan(hintPane, 2);
|
||||
pane.addRow(4, hintPane);
|
||||
|
||||
customCommandsPane.getContent().setAll(pane);
|
||||
}
|
||||
|
||||
ComponentList jvmPane = new ComponentList();
|
||||
jvmPane.disableProperty().bind(enableSpecificSettings.not());
|
||||
{
|
||||
GridPane pane = new GridPane();
|
||||
ColumnConstraints title = new ColumnConstraints();
|
||||
ColumnConstraints value = new ColumnConstraints();
|
||||
value.setFillWidth(true);
|
||||
value.setHgrow(Priority.ALWAYS);
|
||||
pane.setHgap(16);
|
||||
pane.setVgap(8);
|
||||
pane.getColumnConstraints().setAll(title, value);
|
||||
|
||||
txtJVMArgs = new JFXTextField();
|
||||
txtJVMArgs.getStyleClass().add("fit-width");
|
||||
pane.addRow(0, new Label(i18n("settings.advanced.jvm_args")), txtJVMArgs);
|
||||
|
||||
HintPane hintPane = new HintPane();
|
||||
hintPane.setText(i18n("settings.advanced.jvm_args.prompt"));
|
||||
GridPane.setColumnSpan(hintPane, 2);
|
||||
pane.addRow(4, hintPane);
|
||||
|
||||
txtMetaspace = new JFXTextField();
|
||||
txtMetaspace.setPromptText(i18n("settings.advanced.java_permanent_generation_space.prompt"));
|
||||
txtMetaspace.getStyleClass().add("fit-width");
|
||||
FXUtils.setValidateWhileTextChanged(txtMetaspace, true);
|
||||
txtMetaspace.setValidators(new NumberValidator(i18n("input.number"), true));
|
||||
pane.addRow(1, new Label(i18n("settings.advanced.java_permanent_generation_space")), txtMetaspace);
|
||||
|
||||
jvmPane.getContent().setAll(pane);
|
||||
}
|
||||
|
||||
ComponentList workaroundPane = new ComponentList();
|
||||
workaroundPane.disableProperty().bind(enableSpecificSettings.not());
|
||||
|
||||
HintPane workaroundWarning = new HintPane(MessageDialogPane.MessageType.WARNING);
|
||||
workaroundWarning.setText(i18n("settings.advanced.workaround.warning"));
|
||||
|
||||
{
|
||||
nativesDirItem = new MultiFileItem<>();
|
||||
nativesDirSublist = new ComponentSublist();
|
||||
nativesDirSublist.getContent().add(nativesDirItem);
|
||||
nativesDirSublist.setTitle(i18n("settings.advanced.natives_directory"));
|
||||
nativesDirSublist.setHasSubtitle(true);
|
||||
nativesDirCustomOption = new MultiFileItem.FileOption<>(i18n("settings.advanced.natives_directory.custom"), NativesDirectoryType.CUSTOM)
|
||||
.setChooserTitle(i18n("settings.advanced.natives_directory.choose"))
|
||||
.setDirectory(true);
|
||||
nativesDirItem.loadChildren(Arrays.asList(
|
||||
new MultiFileItem.Option<>(i18n("settings.advanced.natives_directory.default"), NativesDirectoryType.VERSION_FOLDER),
|
||||
nativesDirCustomOption
|
||||
));
|
||||
HintPane nativesDirHint = new HintPane(MessageDialogPane.MessageType.WARNING);
|
||||
nativesDirHint.setText(i18n("settings.advanced.natives_directory.hint"));
|
||||
nativesDirItem.getChildren().add(nativesDirHint);
|
||||
|
||||
noJVMArgsPane = new OptionToggleButton();
|
||||
noJVMArgsPane.setTitle(i18n("settings.advanced.no_jvm_args"));
|
||||
|
||||
noGameCheckPane = new OptionToggleButton();
|
||||
noGameCheckPane.setTitle(i18n("settings.advanced.dont_check_game_completeness"));
|
||||
|
||||
noJVMCheckPane = new OptionToggleButton();
|
||||
noJVMCheckPane.setTitle(i18n("settings.advanced.dont_check_jvm_validity"));
|
||||
|
||||
noNativesPatchPane = new OptionToggleButton();
|
||||
noNativesPatchPane.setTitle(i18n("settings.advanced.dont_patch_natives"));
|
||||
|
||||
useSoftwareRenderer = new OptionToggleButton();
|
||||
useSoftwareRenderer.setTitle(i18n("settings.advanced.use_software_renderer"));
|
||||
|
||||
useNativeGLFWPane = new OptionToggleButton();
|
||||
useNativeGLFWPane.setTitle(i18n("settings.advanced.use_native_glfw"));
|
||||
|
||||
useNativeOpenALPane = new OptionToggleButton();
|
||||
useNativeOpenALPane.setTitle(i18n("settings.advanced.use_native_openal"));
|
||||
|
||||
workaroundPane.getContent().setAll(
|
||||
nativesDirSublist,
|
||||
noJVMArgsPane, noGameCheckPane, noJVMCheckPane, noNativesPatchPane,
|
||||
useSoftwareRenderer, useNativeGLFWPane, useNativeOpenALPane);
|
||||
}
|
||||
|
||||
rootPane.getChildren().addAll(componentList,
|
||||
advancedHintPane,
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.custom_commands")), customCommandsPane,
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.jvm")), jvmPane,
|
||||
ComponentList.createComponentListTitle(i18n("settings.advanced.workaround")), workaroundWarning, workaroundPane);
|
||||
rootPane.getChildren().add(componentList);
|
||||
|
||||
initialize();
|
||||
|
||||
specificSettingsListener = any -> {
|
||||
enableSpecificSettings.set(!lastVersionSetting.isUsesGlobal());
|
||||
};
|
||||
specificSettingsListener = any -> enableSpecificSettings.set(!lastVersionSetting.isUsesGlobal());
|
||||
|
||||
addEventHandler(Navigator.NavigationEvent.NAVIGATED, this::onDecoratorPageNavigating);
|
||||
|
||||
@@ -631,24 +508,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
maxMemory.unbindBidirectional(lastVersionSetting.maxMemoryProperty());
|
||||
javaCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.javaDirProperty());
|
||||
gameDirCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.gameDirProperty());
|
||||
nativesDirCustomOption.valueProperty().unbindBidirectional(lastVersionSetting.nativesDirProperty());
|
||||
FXUtils.unbind(txtJVMArgs, lastVersionSetting.javaArgsProperty());
|
||||
FXUtils.unbind(txtGameArgs, lastVersionSetting.minecraftArgsProperty());
|
||||
FXUtils.unbind(txtMetaspace, lastVersionSetting.permSizeProperty());
|
||||
FXUtils.unbind(txtWrapper, lastVersionSetting.wrapperProperty());
|
||||
FXUtils.unbind(txtPreLaunchCommand, lastVersionSetting.preLaunchCommandProperty());
|
||||
FXUtils.unbind(txtPostExitCommand, lastVersionSetting.postExitCommandProperty());
|
||||
FXUtils.unbind(txtServerIP, lastVersionSetting.serverIpProperty());
|
||||
FXUtils.unbindBoolean(chkAutoAllocate, lastVersionSetting.autoMemoryProperty());
|
||||
FXUtils.unbindBoolean(chkFullscreen, lastVersionSetting.fullscreenProperty());
|
||||
noGameCheckPane.selectedProperty().unbindBidirectional(lastVersionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().unbindBidirectional(lastVersionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().unbindBidirectional(lastVersionSetting.noJVMArgsProperty());
|
||||
noNativesPatchPane.selectedProperty().unbindBidirectional(lastVersionSetting.notPatchNativesProperty());
|
||||
showLogsPane.selectedProperty().unbindBidirectional(lastVersionSetting.showLogsProperty());
|
||||
useSoftwareRenderer.selectedProperty().unbindBidirectional(lastVersionSetting.useSoftwareRendererProperty());
|
||||
useNativeGLFWPane.selectedProperty().unbindBidirectional(lastVersionSetting.useNativeGLFWProperty());
|
||||
useNativeOpenALPane.selectedProperty().unbindBidirectional(lastVersionSetting.useNativeOpenALProperty());
|
||||
FXUtils.unbindEnum(cboLauncherVisibility);
|
||||
FXUtils.unbindEnum(cboProcessPriority);
|
||||
|
||||
@@ -659,8 +522,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
gameDirItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.gameDirTypeProperty());
|
||||
gameDirSublist.subtitleProperty().unbind();
|
||||
|
||||
nativesDirItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.nativesDirTypeProperty());
|
||||
nativesDirSublist.subtitleProperty().unbind();
|
||||
if (advancedVersionSettingPage != null) {
|
||||
advancedVersionSettingPage.unbindProperties();
|
||||
advancedVersionSettingPage = null;
|
||||
}
|
||||
}
|
||||
|
||||
// unbind data fields
|
||||
@@ -673,23 +538,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
|
||||
javaCustomOption.bindBidirectional(versionSetting.javaDirProperty());
|
||||
gameDirCustomOption.bindBidirectional(versionSetting.gameDirProperty());
|
||||
nativesDirCustomOption.bindBidirectional(versionSetting.nativesDirProperty());
|
||||
FXUtils.bindString(txtJVMArgs, versionSetting.javaArgsProperty());
|
||||
FXUtils.bindString(txtGameArgs, versionSetting.minecraftArgsProperty());
|
||||
FXUtils.bindString(txtMetaspace, versionSetting.permSizeProperty());
|
||||
FXUtils.bindString(txtWrapper, versionSetting.wrapperProperty());
|
||||
FXUtils.bindString(txtPreLaunchCommand, versionSetting.preLaunchCommandProperty());
|
||||
FXUtils.bindString(txtServerIP, versionSetting.serverIpProperty());
|
||||
FXUtils.bindBoolean(chkAutoAllocate, versionSetting.autoMemoryProperty());
|
||||
FXUtils.bindBoolean(chkFullscreen, versionSetting.fullscreenProperty());
|
||||
noGameCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().bindBidirectional(versionSetting.noJVMArgsProperty());
|
||||
noNativesPatchPane.selectedProperty().bindBidirectional(versionSetting.notPatchNativesProperty());
|
||||
showLogsPane.selectedProperty().bindBidirectional(versionSetting.showLogsProperty());
|
||||
useSoftwareRenderer.selectedProperty().bindBidirectional(versionSetting.useSoftwareRendererProperty());
|
||||
useNativeGLFWPane.selectedProperty().bindBidirectional(versionSetting.useNativeGLFWProperty());
|
||||
useNativeOpenALPane.selectedProperty().bindBidirectional(versionSetting.useNativeOpenALProperty());
|
||||
FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty());
|
||||
FXUtils.bindEnum(cboProcessPriority, versionSetting.processPriorityProperty());
|
||||
|
||||
@@ -716,10 +568,6 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
gameDirSublist.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath()).normalize().toString(),
|
||||
versionSetting.gameDirProperty(), versionSetting.gameDirTypeProperty()));
|
||||
|
||||
nativesDirItem.selectedDataProperty().bindBidirectional(versionSetting.nativesDirTypeProperty());
|
||||
nativesDirSublist.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath() + "/natives").normalize().toString(),
|
||||
versionSetting.nativesDirProperty(), versionSetting.nativesDirTypeProperty()));
|
||||
|
||||
lastVersionSetting = versionSetting;
|
||||
|
||||
initJavaSubtitle();
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.jackhuang.hmcl.game.Library;
|
||||
import org.jackhuang.hmcl.game.NativesDirectoryType;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.game.*;
|
||||
import org.jackhuang.hmcl.setting.VersionSetting;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
@@ -92,9 +90,9 @@ public final class NativePatcher {
|
||||
return version.setLibraries(newLibraries);
|
||||
}
|
||||
|
||||
public static Library getSoftwareRendererLoader(JavaVersion javaVersion) {
|
||||
public static Library getMesaLoader(JavaVersion javaVersion, Renderer renderer) {
|
||||
Map<String, Library> map = Hole.nativeReplacement.get(javaVersion.getPlatform().toString());
|
||||
return map != null ? map.get("software-renderer-loader") : null;
|
||||
return map != null ? map.get(renderer == Renderer.LLVMPIPE ? "software-renderer-loader" : "mesa-loader") : null;
|
||||
}
|
||||
|
||||
private static final class Hole {
|
||||
|
||||
@@ -952,6 +952,8 @@ selector.custom=Custom
|
||||
settings=Settings
|
||||
|
||||
settings.advanced=Advanced Settings
|
||||
settings.advanced.modify=Modify Advanced Settings
|
||||
settings.advanced.title=Advanced Settings - %s
|
||||
settings.advanced.custom_commands=Custom Commands
|
||||
settings.advanced.custom_commands.hint=The following environment variables are provided\:\n\
|
||||
- $INST_NAME: version name\n\
|
||||
@@ -967,6 +969,7 @@ settings.advanced.custom_commands.hint=The following environment variables are p
|
||||
settings.advanced.dont_check_game_completeness=Do not check game integrity
|
||||
settings.advanced.dont_check_jvm_validity=Do not check JVM compatibility
|
||||
settings.advanced.dont_patch_natives=Do not attempt to automatically replace native libraries
|
||||
settings.advanced.environment_variables=Environment Variables
|
||||
settings.advanced.game_dir.default=Default (.minecraft/)
|
||||
settings.advanced.game_dir.independent=Isolated (.minecraft/versions/<instance name>/, except for assets and libraries)
|
||||
settings.advanced.java_permanent_generation_space=PermGen Space
|
||||
@@ -1001,11 +1004,15 @@ settings.advanced.process_priority.above_normal=Above Normal
|
||||
settings.advanced.process_priority.high=High
|
||||
settings.advanced.post_exit_command=Post-exit Command
|
||||
settings.advanced.post_exit_command.prompt=Commands to execute after the game exits
|
||||
settings.advanced.renderer=Renderer
|
||||
settings.advanced.renderer.default=OpenGL (Default)
|
||||
settings.advanced.renderer.d3d12=DirectX 12 (Poor performance and compatibility)
|
||||
settings.advanced.renderer.llvmpipe=軟渲染器 (Poor efficiency and best compatibility)
|
||||
settings.advanced.renderer.zink=Vulkan (Best performance and poor compatibility)
|
||||
settings.advanced.server_ip=Server Address
|
||||
settings.advanced.server_ip.prompt=Join automatically after launching the game.
|
||||
settings.advanced.use_native_glfw=[Linux Only] Use system GLFW
|
||||
settings.advanced.use_native_openal=[Linux Only] Use system OpenAL
|
||||
settings.advanced.use_software_renderer=Use OpenGL software renderer (better compatibility, but less performance)
|
||||
settings.advanced.workaround=Workarounds
|
||||
settings.advanced.workaround.warning=Workaround options are intended only for expert users. Tweaking with these options may crash the game. Unless you know what you are doing, please do not modify these options.
|
||||
settings.advanced.wrapper_launcher=Wrapper Command
|
||||
|
||||
@@ -869,6 +869,7 @@ selector.custom=Personalizar
|
||||
settings=Configuración
|
||||
|
||||
settings.advanced=Configuración avanzada
|
||||
settings.advanced.title=Configuración avanzada - %s
|
||||
settings.advanced.custom_commands=Comandos personalizados
|
||||
settings.advanced.custom_commands.hint=Se proporcionan las siguientes variables de entorno\:\n\
|
||||
- $INST_NAME: nombre de la versión\n\
|
||||
|
||||
@@ -703,6 +703,7 @@ selector.custom=カスタム
|
||||
settings=設定
|
||||
|
||||
settings.advanced=詳細設定
|
||||
settings.advanced.title=詳細設定 - %s
|
||||
settings.advanced.custom_commands=カスタムコマンド
|
||||
settings.advanced.custom_commands.hint=カスタムコマンドは、次の環境変数を使用して実行されます。\n \
|
||||
\-$ INST_NAME:バージョンの名前\n \
|
||||
|
||||
@@ -708,6 +708,7 @@ selector.custom=Пользовательский
|
||||
settings=Настройки
|
||||
|
||||
settings.advanced=Расширенные настройки
|
||||
settings.advanced.title=Расширенные настройки - %s
|
||||
settings.advanced.custom_commands=Пользовательские команды
|
||||
settings.advanced.custom_commands.hint=Пользовательские команды выполняются со следующими переменными окружения:\n\
|
||||
\ - $INST_NAME: название версии\n\
|
||||
|
||||
@@ -827,6 +827,8 @@ selector.custom=自訂
|
||||
settings=遊戲設定
|
||||
|
||||
settings.advanced=進階設定
|
||||
settings.advanced.modify=修改進階設定
|
||||
settings.advanced.title=進階設定 - %s
|
||||
settings.advanced.custom_commands=自訂命令
|
||||
settings.advanced.custom_commands.hint=自訂命令被調用時將包含如下的環境變數:\n\
|
||||
\ - $INST_NAME: 版本名稱\n\
|
||||
@@ -842,6 +844,7 @@ settings.advanced.custom_commands.hint=自訂命令被調用時將包含如下
|
||||
settings.advanced.dont_check_game_completeness=不檢查遊戲完整性
|
||||
settings.advanced.dont_check_jvm_validity=不檢查 JVM 與遊戲的相容性
|
||||
settings.advanced.dont_patch_natives=不嘗試自動替換本機庫
|
||||
settings.advanced.environment_variables=環境變數
|
||||
settings.advanced.game_dir.default=預設(.minecraft/)
|
||||
settings.advanced.game_dir.independent=各版本獨立(.minecraft/versions/<版本名>/,除 assets、libraries)
|
||||
settings.advanced.java_permanent_generation_space=記憶體永久儲存區域
|
||||
@@ -874,13 +877,17 @@ settings.advanced.process_priority.above_normal=較高(優先保證遊戲運
|
||||
settings.advanced.process_priority.high=高(優先保證遊戲運行,但可能會導致其他程式卡頓)
|
||||
settings.advanced.post_exit_command=遊戲結束後執行命令
|
||||
settings.advanced.post_exit_command.prompt=將在遊戲結束後呼叫使用
|
||||
settings.advanced.renderer=渲染器
|
||||
settings.advanced.renderer.default=OpenGL(默認)
|
||||
settings.advanced.renderer.d3d12=DirectX 12(效能與相容性較差,用於調試)
|
||||
settings.advanced.renderer.llvmpipe=軟渲染器(效能較差,相容性最好)
|
||||
settings.advanced.renderer.zink=Vulkan(效能最好,相容性較差)
|
||||
settings.advanced.server_ip=伺服器位址
|
||||
settings.advanced.server_ip.prompt=預設,啟動遊戲後直接進入對應伺服器
|
||||
settings.advanced.use_native_glfw=[Linux] 使用系統 GLFW
|
||||
settings.advanced.use_native_openal=[Linux] 使用系統 OpenAL
|
||||
settings.advanced.use_software_renderer=使用 OpenGL 軟渲染器(相容性更好,但效能較差)
|
||||
settings.advanced.workaround=除錯選項
|
||||
settings.advanced.workaround.warning=除錯選項僅提供給專業玩家使用。修改除錯選項可能會導致遊戲無法啟動。除非你知道你在做什麼,否則請你不要修改這些選項。
|
||||
settings.advanced.workaround.warning=除錯選項僅提供給專業玩家使用。修改除錯選項可能會導致遊戲無法啟動。除非你知道你在做什麼,否則請不要修改這些選項。
|
||||
settings.advanced.wrapper_launcher=前置指令
|
||||
settings.advanced.wrapper_launcher.prompt=如填寫 optirun 後,啟動命令將從 "java ..." 變為 "optirun java ..."
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ account.methods.yggdrasil.migration.hint=自 2022 年 3 月 10 日起,Mojang
|
||||
account.methods.yggdrasil.purchase=购买 Minecraft
|
||||
account.missing=没有游戏帐户
|
||||
account.missing.add=点击此处添加帐户
|
||||
account.move_to_global=转换为全局账户
|
||||
account.move_to_portable=转换为便携账户
|
||||
account.move_to_global=转换为全局账户\n该账户的信息会保存至用户目录的配置文件中
|
||||
account.move_to_portable=转换为便携账户\n该账户的信息会保存至 HMCL 同目录的配置文件中
|
||||
account.not_logged_in=未登录
|
||||
account.password=密码
|
||||
account.portable=便携账户
|
||||
@@ -398,12 +398,12 @@ game.crash.reason.fabric_warnings=Fabric 提供了一些警告信息:\n%1$s \n
|
||||
game.crash.reason.file_already_exists=当前游戏因为文件 %1$s 已经存在,无法继续运行。\n如果你认为这个文件可以删除,你可以在备份这个文件后尝试删除它,并重新启动游戏。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.file_changed=当前游戏因为文件校验失败,无法继续运行。\n如果你手动修改了 Minecraft.jar 文件,你需要回退修改,或者重新下载游戏。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.gl_operation_failure=当前游戏因为你使用的某些 Mod、光影包、材质包,无法继续运行。\n请先尝试禁用你所使用的Mod/光影包/材质包再试。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.graphics_driver=当前游戏因为你的显卡驱动存在问题崩溃了,请尝试:\n\
|
||||
game.crash.reason.graphics_driver=当前游戏因为显卡驱动问题而崩溃,请尝试以下操作:\n\
|
||||
- 如果你的电脑存在独立显卡,请尝试使用 独立显卡 而非 Intel 核显启动 HMCL 与游戏 <a href="https://www.bing.com/search?q=用独立显卡运行程序">详情</a>;\n\
|
||||
- <a href="https://minecrafthopper.net/help/pixel-format-not-accelerated/">尝试升级你的 显卡驱动 到最新版本</a>,或回退到出厂版本;\n\
|
||||
- 如果你确实需要使用核芯显卡,请检查你的电脑的 CPU 是否是 Intel(R) Core(TM) 3000 系列或更旧的处理器,如果是,对于 Minecraft 1.16.5 及更旧版本,请你将游戏所使用的 Java 版本降级至 1.8.0_51 及以下版本 <a href="https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html">Java 1.8.0 历史版本</a> ,否则请跳过;\n\
|
||||
- 在全局(特定)游戏设置,菜单底部中打开“使用 OpenGL 软渲染器”选项可以尝试解决此问题,但打开此选项后在 CPU 性能不足的情况下帧数会显著降低,请慎重选择(仅推荐以调试为目的或应急时开启)\n\
|
||||
如果仍有问题,你可能需要考虑换一个新显卡或新电脑。\n\
|
||||
- 在游戏设置中打开“使用 OpenGL 软渲染器”(开启此选项后帧数会显著降低,仅推荐在以调试为目的或应急时开启)。\n\
|
||||
如果仍有问题,你可能需要考虑换一张新显卡或一台新电脑。\n\
|
||||
你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.illegal_access_error=当前游戏因为某些 Mod 的问题,无法继续运行。\n如果你认识:%1$s,你可以更新或删除对应 Mod 再试。\n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.jdk_9=当前游戏因为 Java 版本过高,无法继续运行。\n你需要下载安装 <a href="https://bell-sw.com/pages/downloads/#downloads">Java 8</a>,并在全局(特定)游戏设置中将 Java 设置为 1.8 的版本。\n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
@@ -436,7 +436,7 @@ game.crash.reason.no_class_def_found_error=当前游戏因为代码不完整,
|
||||
game.crash.reason.no_such_method_error=当前游戏因为代码不完整,无法继续运行。\n你的游戏可能缺失了某个 Mod,或者某些 Mod 文件不完整,或者 Mod 与游戏的版本不匹配。\n你可能需要重新安装游戏和 Mod,或请求他人帮助。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.opengl_not_supported=当前游戏因为你的显卡驱动存在问题,无法继续运行。\n原因是 OpenGL 不受支持,你现在是否在远程桌面或者串流模式下?如果是,请直接使用原电脑启动游戏。\n或者尝试升级你的显卡驱动到最新版本后再尝试启动游戏。如果你的电脑存在独立显卡,你需要检查游戏是否使用集成/核心显卡启动,如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.openj9=当前游戏无法运行在 OpenJ9 虚拟机上,请你在全局(特定)游戏设置中更换 Hotspot Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.out_of_memory=当前游戏因为内存不足,无法继续运行。\n这可能是内存分配太小,或者 Mod 数量过多导致的。\n你可以在全局(特定)游戏设置中调大游戏内存分配值以允许游戏在更大的内存下运行。\n如果仍然出现该错误,你可能需要换一台更好的电脑。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.out_of_memory=当前游戏因为内存不足,无法继续运行。\n这可能是内存分配太小,或者 Mod 数量过多导致的。\n你可以在全局(特定)游戏设置中调大游戏内存分配值以允许游戏在更大的内存下运行。\n如果仍然出现该错误,你可能需要换一台更好的电脑。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.resolution_too_high=当前游戏因为材质包分辨率过高,无法继续运行\n你可以更换一个分辨率更低的材质,或者更换一个显存更大的显卡。 \n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
game.crash.reason.stacktrace=原因未知,请点击日志按钮查看详细信息。\n下面是一些关键词,其中可能包含 Mod 名称,你可以通过搜索的方式查找有关信息。\n%s
|
||||
game.crash.reason.too_old_java=当前游戏因为 Java 虚拟机版本过低,无法继续运行。\n你需要在全局(特定)游戏设置中更换 Java %1$s 或更新版本的 Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以点击 <a href="https://bell-sw.com/pages/downloads/#downloads">此处</a> 下载 Liberica JDK。\n你可以在 <a href="https://docs.hmcl.net/help.html ">此处</a> 寻求帮助。
|
||||
@@ -825,6 +825,8 @@ selector.custom=自定义
|
||||
settings=设置
|
||||
|
||||
settings.advanced=高级设置
|
||||
settings.advanced.modify=修改高级设置
|
||||
settings.advanced.title=高级设置 - %s
|
||||
settings.advanced.custom_commands=自定义命令
|
||||
settings.advanced.custom_commands.hint=自定义命令被调用时将包含如下的环境变量:\n\
|
||||
\ - $INST_NAME: 版本名称\n\
|
||||
@@ -840,6 +842,7 @@ settings.advanced.custom_commands.hint=自定义命令被调用时将包含如
|
||||
settings.advanced.dont_check_game_completeness=不检查游戏完整性
|
||||
settings.advanced.dont_check_jvm_validity=不检查 JVM 与游戏的兼容性
|
||||
settings.advanced.dont_patch_natives=不尝试自动替换本地库
|
||||
settings.advanced.environment_variables=环境变量
|
||||
settings.advanced.game_dir.default=默认(.minecraft/)
|
||||
settings.advanced.game_dir.independent=各版本独立(存放在 .minecraft/versions/<版本名>/,除 assets、libraries 外)
|
||||
settings.advanced.java_permanent_generation_space=内存永久保存区域
|
||||
@@ -872,13 +875,17 @@ settings.advanced.process_priority.above_normal=较高(优先保证游戏运
|
||||
settings.advanced.process_priority.high=高(优先保证游戏运行,但可能会导致其他程序卡顿)
|
||||
settings.advanced.post_exit_command=游戏结束后执行命令
|
||||
settings.advanced.post_exit_command.prompt=将在游戏结束后调用
|
||||
settings.advanced.renderer=渲染器
|
||||
settings.advanced.renderer.default=OpenGL(默认)
|
||||
settings.advanced.renderer.d3d12=DirectX 12(性能与兼容性较差,用于调试)
|
||||
settings.advanced.renderer.llvmpipe=软渲染器(性能较差,兼容性最好)
|
||||
settings.advanced.renderer.zink=Vulkan(性能最好,兼容性较差)
|
||||
settings.advanced.server_ip=服务器地址
|
||||
settings.advanced.server_ip.prompt=默认,启动游戏后可以直接进入对应服务器
|
||||
settings.advanced.use_native_glfw=[Linux] 使用系统 GLFW
|
||||
settings.advanced.use_native_openal=[Linux] 使用系统 OpenAL
|
||||
settings.advanced.use_software_renderer=使用 OpenGL 软渲染器(兼容性更好,但性能较差)
|
||||
settings.advanced.workaround=调试选项
|
||||
settings.advanced.workaround.warning=调试选项仅提供给专业玩家使用。调试选项可能会导致游戏无法启动。除非你知道你在做什么,否则请你不要修改这些选项!
|
||||
settings.advanced.workaround.warning=调试选项仅提供给专业玩家使用。调试选项可能会导致游戏无法启动。除非你知道你在做什么,否则请不要修改这些选项!
|
||||
settings.advanced.wrapper_launcher=包装命令
|
||||
settings.advanced.wrapper_launcher.prompt=如填写 optirun 后,启动命令将从 "java ..." 变为 "optirun java ..."
|
||||
|
||||
|
||||
@@ -1530,6 +1530,30 @@
|
||||
"size": 12964773
|
||||
}
|
||||
}
|
||||
},
|
||||
"mesa-loader": {
|
||||
"name": "org.glavo:mesa-loader-windows:0.2.0:x64",
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/glavo/mesa-loader-windows/0.2.0/mesa-loader-windows-0.2.0-x64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/0.2.0/mesa-loader-windows-0.2.0-x64.jar",
|
||||
"sha1": "adb4a16ecb95c8944a016829b05d70f934ea1a29",
|
||||
"size": 22823052
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"windows-x86": {
|
||||
"mesa-loader": {
|
||||
"name": "org.glavo:mesa-loader-windows:0.2.0:x86",
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/glavo/mesa-loader-windows/0.2.0/mesa-loader-windows-0.2.0-x86.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/0.2.0/mesa-loader-windows-0.2.0-x86.jar",
|
||||
"sha1": "93c0b9b7382d984e713d3aa299ceb337fde2897b",
|
||||
"size": 18273286
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"windows-arm64": {
|
||||
@@ -2074,7 +2098,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "71d0d5e469c9c95351eb949064497e3391616ac9",
|
||||
"size": 42693
|
||||
}
|
||||
@@ -2096,7 +2120,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "e577b87d8ad2ade361aaea2fcf226c660b15dee8",
|
||||
"size": 103475
|
||||
}
|
||||
@@ -2118,7 +2142,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "23d55e7490b57495320f6c9e1936d78fd72c4ef8",
|
||||
"size": 346125
|
||||
}
|
||||
@@ -2140,7 +2164,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "eafe34b871d966292e8db0f1f3d6b8b110d4e91d",
|
||||
"size": 41665
|
||||
}
|
||||
@@ -2162,7 +2186,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "cac0d3f712a3da7641fa174735a5f315de7ffe0a",
|
||||
"size": 129077
|
||||
}
|
||||
@@ -2184,7 +2208,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "fcf073ed911752abdca5f0b00a53cfdf17ff8e8b",
|
||||
"size": 178408
|
||||
}
|
||||
@@ -2206,7 +2230,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "972ecc17bad3571e81162153077b4d47b7b9eaa9",
|
||||
"size": 41380
|
||||
}
|
||||
@@ -2228,7 +2252,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "71d0d5e469c9c95351eb949064497e3391616ac9",
|
||||
"size": 42693
|
||||
}
|
||||
@@ -2250,7 +2274,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.3.1/lwjgl-jemalloc-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "e577b87d8ad2ade361aaea2fcf226c660b15dee8",
|
||||
"size": 103475
|
||||
}
|
||||
@@ -2272,7 +2296,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.3.1/lwjgl-openal-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "23d55e7490b57495320f6c9e1936d78fd72c4ef8",
|
||||
"size": 346125
|
||||
}
|
||||
@@ -2294,7 +2318,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.3.1/lwjgl-opengl-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "eafe34b871d966292e8db0f1f3d6b8b110d4e91d",
|
||||
"size": 41665
|
||||
}
|
||||
@@ -2316,7 +2340,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.3.1/lwjgl-glfw-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "cac0d3f712a3da7641fa174735a5f315de7ffe0a",
|
||||
"size": 129077
|
||||
}
|
||||
@@ -2338,7 +2362,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.3.1/lwjgl-stb-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "fcf073ed911752abdca5f0b00a53cfdf17ff8e8b",
|
||||
"size": 178408
|
||||
}
|
||||
@@ -2360,7 +2384,7 @@
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"url": "https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.3.1/lwjgl-tinyfd-3.3.1-natives-macos-arm64.jar",
|
||||
"sha1": "972ecc17bad3571e81162153077b4d47b7b9eaa9",
|
||||
"size": 41380
|
||||
}
|
||||
|
||||
@@ -4,16 +4,13 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
api("org.glavo:simple-png-javafx:0.3.0")
|
||||
api("com.google.code.gson:gson:2.8.1")
|
||||
api("com.google.code.gson:gson:2.10.1")
|
||||
api("com.moandjiezana.toml:toml4j:0.7.2")
|
||||
api("org.tukaani:xz:1.8")
|
||||
api("org.hildan.fxgson:fx-gson:3.1.0") {
|
||||
exclude(group = "org.jetbrains", module = "annotations")
|
||||
}
|
||||
api("org.tukaani:xz:1.9")
|
||||
api("org.hildan.fxgson:fx-gson:5.0.0")
|
||||
api("org.jenkins-ci:constant-pool-scanner:1.2")
|
||||
api("com.github.steveice10:opennbt:1.1")
|
||||
api("com.nqzero:permit-reflect:0.3")
|
||||
api("com.github.steveice10:opennbt:1.4")
|
||||
api("org.nanohttpd:nanohttpd:2.3.1")
|
||||
api("org.apache.commons:commons-compress:1.21")
|
||||
compileOnlyApi("org.jetbrains:annotations:16.0.3")
|
||||
api("org.apache.commons:commons-compress:1.22")
|
||||
compileOnlyApi("org.jetbrains:annotations:24.0.0")
|
||||
}
|
||||
@@ -31,8 +31,7 @@ public final class EventBus {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Event> EventManager<T> channel(Class<T> clazz) {
|
||||
events.putIfAbsent(clazz, new EventManager<>());
|
||||
return (EventManager<T>) events.get(clazz);
|
||||
return (EventManager<T>) events.computeIfAbsent(clazz, ignored -> new EventManager<>());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -23,9 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.net.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,6 +40,7 @@ public class LaunchOptions implements Serializable {
|
||||
private final List<String> overrideJavaArguments = new ArrayList<>();
|
||||
private final List<String> javaArguments = new ArrayList<>();
|
||||
private final List<String> javaAgents = new ArrayList<>(0);
|
||||
private final Map<String, String> environmentVariables = new LinkedHashMap<>();
|
||||
private Integer minMemory;
|
||||
private Integer maxMemory;
|
||||
private Integer metaspace;
|
||||
@@ -59,7 +58,7 @@ public class LaunchOptions implements Serializable {
|
||||
private NativesDirectoryType nativesDirType;
|
||||
private String nativesDir;
|
||||
private ProcessPriority processPriority = ProcessPriority.NORMAL;
|
||||
private boolean useSoftwareRenderer;
|
||||
private Renderer renderer = Renderer.DEFAULT;
|
||||
private boolean useNativeGLFW;
|
||||
private boolean useNativeOpenAL;
|
||||
private boolean daemon;
|
||||
@@ -130,6 +129,10 @@ public class LaunchOptions implements Serializable {
|
||||
return Collections.unmodifiableList(javaAgents);
|
||||
}
|
||||
|
||||
public Map<String, String> getEnvironmentVariables() {
|
||||
return environmentVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum memory that the JVM can allocate.
|
||||
*/
|
||||
@@ -252,8 +255,8 @@ public class LaunchOptions implements Serializable {
|
||||
return processPriority;
|
||||
}
|
||||
|
||||
public boolean isUseSoftwareRenderer() {
|
||||
return useSoftwareRenderer;
|
||||
public Renderer getRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public boolean isUseNativeGLFW() {
|
||||
@@ -279,43 +282,6 @@ public class LaunchOptions implements Serializable {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* The game directory
|
||||
*/
|
||||
public File getGameDir() {
|
||||
return options.gameDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java Environment that Minecraft runs on.
|
||||
*/
|
||||
public JavaVersion getJava() {
|
||||
return options.java;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will shown in the left bottom corner of the main menu of Minecraft.
|
||||
* null if use the id of launch version.
|
||||
*/
|
||||
public String getVersionName() {
|
||||
return options.versionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will shown in the left bottom corner of the main menu of Minecraft.
|
||||
* null if use Version.versionType.
|
||||
*/
|
||||
public String getVersionType() {
|
||||
return options.versionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't know what the hell this is.
|
||||
*/
|
||||
public String getProfileName() {
|
||||
return options.profileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* User custom additional minecraft command line arguments.
|
||||
*/
|
||||
@@ -341,123 +307,6 @@ public class LaunchOptions implements Serializable {
|
||||
return options.javaAgents;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum memory that the JVM can allocate.
|
||||
*/
|
||||
public Integer getMinMemory() {
|
||||
return options.minMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum memory that the JVM can allocate.
|
||||
*/
|
||||
public Integer getMaxMemory() {
|
||||
return options.maxMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum metaspace memory that the JVM can allocate.
|
||||
* For Java 7 -XX:PermSize and Java 8 -XX:MetaspaceSize
|
||||
* Containing class instances.
|
||||
*/
|
||||
public Integer getMetaspace() {
|
||||
return options.metaspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial game window width
|
||||
*/
|
||||
public Integer getWidth() {
|
||||
return options.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial game window height
|
||||
*/
|
||||
public Integer getHeight() {
|
||||
return options.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is inital game window fullscreen.
|
||||
*/
|
||||
public boolean isFullscreen() {
|
||||
return options.fullscreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* The server ip that will connect to when enter game main menu.
|
||||
*/
|
||||
public String getServerIp() {
|
||||
return options.serverIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* i.e. optirun
|
||||
*/
|
||||
public String getWrapper() {
|
||||
return options.wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy settings
|
||||
*/
|
||||
public Proxy getProxy() {
|
||||
return options.proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user name of the proxy, optional.
|
||||
*/
|
||||
public String getProxyUser() {
|
||||
return options.proxyUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* The password of the proxy, optional
|
||||
*/
|
||||
public String getProxyPass() {
|
||||
return options.proxyPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent game launcher from generating default JVM arguments like max memory.
|
||||
*/
|
||||
public boolean isNoGeneratedJVMArgs() {
|
||||
return options.noGeneratedJVMArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called command line before launching the game.
|
||||
*/
|
||||
public String getPreLaunchCommand() {
|
||||
return options.preLaunchCommand;
|
||||
}
|
||||
|
||||
public NativesDirectoryType getNativesDirType() {
|
||||
return options.nativesDirType;
|
||||
}
|
||||
|
||||
public String getNativesDir() {
|
||||
return options.nativesDir;
|
||||
}
|
||||
|
||||
public boolean isUseSoftwareRenderer() {
|
||||
return options.useSoftwareRenderer;
|
||||
}
|
||||
|
||||
public boolean isUseNativeGLFW() {
|
||||
return options.useNativeGLFW;
|
||||
}
|
||||
|
||||
public boolean isUseNativeOpenAL() {
|
||||
return options.useNativeOpenAL;
|
||||
}
|
||||
|
||||
public boolean isDaemon() {
|
||||
return options.daemon;
|
||||
}
|
||||
|
||||
public Builder setGameDir(File gameDir) {
|
||||
options.gameDir = gameDir;
|
||||
return this;
|
||||
@@ -507,6 +356,12 @@ public class LaunchOptions implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setEnvironmentVariables(Map<String, String> env) {
|
||||
options.environmentVariables.clear();
|
||||
options.environmentVariables.putAll(env);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMinMemory(Integer minMemory) {
|
||||
options.minMemory = minMemory;
|
||||
return this;
|
||||
@@ -592,8 +447,8 @@ public class LaunchOptions implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUseSoftwareRenderer(boolean useSoftwareRenderer) {
|
||||
options.useSoftwareRenderer = useSoftwareRenderer;
|
||||
public Builder setRenderer(@NotNull Renderer renderer) {
|
||||
options.renderer = renderer;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
public enum Renderer {
|
||||
DEFAULT,
|
||||
ZINK,
|
||||
LLVMPIPE,
|
||||
D3D12
|
||||
}
|
||||
@@ -462,16 +462,29 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
private Map<String, String> getEnvVars() {
|
||||
String versionName = Optional.ofNullable(options.getVersionName()).orElse(version.getId());
|
||||
Map<String, String> env = new HashMap<>();
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("INST_NAME", versionName);
|
||||
env.put("INST_ID", versionName);
|
||||
env.put("INST_DIR", repository.getVersionRoot(version.getId()).getAbsolutePath());
|
||||
env.put("INST_MC_DIR", repository.getRunDirectory(version.getId()).getAbsolutePath());
|
||||
env.put("INST_JAVA", options.getJava().getBinary().toString());
|
||||
|
||||
if (options.isUseSoftwareRenderer() && OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
|
||||
env.put("LIBGL_ALWAYS_SOFTWARE", "1");
|
||||
env.put("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||
Renderer renderer = options.getRenderer();
|
||||
if (renderer != Renderer.DEFAULT) {
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
if (renderer != Renderer.LLVMPIPE)
|
||||
env.put("GALLIUM_DRIVER", renderer.name().toLowerCase(Locale.ROOT));
|
||||
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
|
||||
env.put("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||
switch (renderer) {
|
||||
case LLVMPIPE:
|
||||
env.put("LIBGL_ALWAYS_SOFTWARE", "1");
|
||||
break;
|
||||
case ZINK:
|
||||
env.put("MESA_LOADER_DRIVER_OVERRIDE", "zink");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version);
|
||||
@@ -490,6 +503,9 @@ public class DefaultLauncher extends Launcher {
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.QUILT)) {
|
||||
env.put("INST_QUILT", "1");
|
||||
}
|
||||
|
||||
env.putAll(options.getEnvironmentVariables());
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
|
||||
Reference in new issue
Block a user