From 7cbe24b35bb67a99a05325a5afe94c4c96d65f51 Mon Sep 17 00:00:00 2001 From: yaoxi-std Date: Thu, 27 May 2021 22:58:55 +0800 Subject: [PATCH] add: allow customize LWJGL path (runs on M1) --- .gitignore | 5 ++- .../jackhuang/hmcl/game/HMCLGameLauncher.java | 10 +++-- .../jackhuang/hmcl/game/LauncherHelper.java | 5 ++- .../hmcl/setting/VersionSetting.java | 40 +++++++++++++++++++ .../hmcl/ui/versions/VersionSettingsPage.java | 18 +++++++++ .../assets/fxml/version/version-settings.fxml | 5 ++- .../resources/assets/lang/I18N.properties | 3 ++ .../resources/assets/lang/I18N_es.properties | 3 ++ .../resources/assets/lang/I18N_ru.properties | 3 ++ .../resources/assets/lang/I18N_zh.properties | 3 ++ .../assets/lang/I18N_zh_CN.properties | 3 ++ .../hmcl/game/NativesDirectoryType.java | 12 ++++++ .../hmcl/launch/DefaultLauncher.java | 25 ++++++++---- .../org/jackhuang/hmcl/launch/Launcher.java | 12 +++++- 14 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/game/NativesDirectoryType.java diff --git a/.gitignore b/.gitignore index 4800fd3d3..b226c50ca 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,7 @@ NVIDIA .nb-gradle *.exe -!/HMCL/src/main/resources/assets/HMCLauncher.exe \ No newline at end of file +!/HMCL/src/main/resources/assets/HMCLauncher.exe + +# macos +.DS_Store \ No newline at end of file diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java index 24caabc4f..d96823d0e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java @@ -42,11 +42,15 @@ public final class HMCLGameLauncher extends DefaultLauncher { } public HMCLGameLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener) { - this(repository, version, authInfo, options, listener, true); + this(repository, version, authInfo, options, listener, false, null, true); } - public HMCLGameLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean daemon) { - super(repository, version, authInfo, options, listener, daemon); + public HMCLGameLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean customized_natives, String customized_natives_path) { + this(repository, version, authInfo, options, listener, customized_natives, customized_natives_path, true); + } + + public HMCLGameLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean customized_natives, String customized_natives_path, boolean daemon) { + super(repository, version, authInfo, options, listener, customized_natives, customized_natives_path, daemon); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 438558cd2..64b39efad 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -178,7 +178,10 @@ public final class LauncherHelper { repository.getLaunchOptions(selectedVersion, profile.getGameDir(), !setting.isNotCheckJVM()), launcherVisibility == LauncherVisibility.CLOSE ? null // Unnecessary to start listening to game process output when close launcher immediately after game launched. - : new HMCLProcessListener(repository, selectedVersion, authInfo, launchingLatch, gameVersion.isPresent()) + : new HMCLProcessListener(repository, selectedVersion, authInfo, launchingLatch, gameVersion.isPresent()), + NativesDirectoryType.CUSTOM.equals(setting.getNativesDirType()), + setting.getNativesDir() + // TODO: yaoxi-std ADD custom natives path checking ); }).thenComposeAsync(launcher -> { // launcher is prev task's result if (scriptFile == null) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java index 390a415a6..4cdd9b600 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java @@ -22,6 +22,7 @@ import com.google.gson.annotations.JsonAdapter; import javafx.beans.InvalidationListener; import javafx.beans.property.*; import org.jackhuang.hmcl.game.GameDirectoryType; +import org.jackhuang.hmcl.game.NativesDirectoryType; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.platform.JavaVersion; @@ -119,6 +120,39 @@ public final class VersionSetting implements Cloneable { defaultJavaPathProperty.set(defaultJavaPath); } + /** + * 0 - .minecraft/versions/<version>/natives/
+ */ + private final ObjectProperty nativesDirTypeProperty = new SimpleObjectProperty<>(this, "nativesDirType", NativesDirectoryType.VERSION_FOLDER); + + public ObjectProperty nativesDirTypeProperty() { + return nativesDirTypeProperty; + } + + public NativesDirectoryType getNativesDirType() { + return nativesDirTypeProperty.get(); + } + + public void setNativesDirType(NativesDirectoryType nativesDirType) { + nativesDirTypeProperty.set(nativesDirType); + } + + // Path to lwjgl natives directory + + private final StringProperty nativesDirProperty = new SimpleStringProperty(this, "nativesDirProperty", ""); + + public StringProperty nativesDirProperty(){ + return nativesDirProperty; + } + + public String getNativesDir(){ + return nativesDirProperty.get(); + } + + public void setNativesDir(String nativesDir){ + nativesDirProperty.set(nativesDir); + } + private final StringProperty javaDirProperty = new SimpleStringProperty(this, "javaDir", ""); public StringProperty javaDirProperty() { @@ -526,6 +560,7 @@ public final class VersionSetting implements Cloneable { gameDirProperty.addListener(listener); launcherVisibilityProperty.addListener(listener); defaultJavaPathProperty.addListener(listener); + nativesDirProperty.addListener(listener); } @Override @@ -553,6 +588,7 @@ public final class VersionSetting implements Cloneable { versionSetting.setGameDirType(getGameDirType()); versionSetting.setGameDir(getGameDir()); versionSetting.setLauncherVisibility(getLauncherVisibility()); + versionSetting.setNativesDir(getNativesDir()); return versionSetting; } @@ -584,6 +620,8 @@ public final class VersionSetting implements Cloneable { obj.addProperty("launcherVisibility", src.getLauncherVisibility().ordinal()); obj.addProperty("gameDirType", src.getGameDirType().ordinal()); obj.addProperty("defaultJavaPath", src.getDefaultJavaPath()); + obj.addProperty("nativesDir", src.getNativesDir()); + obj.addProperty("nativesDirType", src.getNativesDirType().ordinal()); return obj; } @@ -613,6 +651,7 @@ public final class VersionSetting implements Cloneable { vs.setJava(Optional.ofNullable(obj.get("java")).map(JsonElement::getAsString).orElse("")); vs.setWrapper(Optional.ofNullable(obj.get("wrapper")).map(JsonElement::getAsString).orElse("")); vs.setGameDir(Optional.ofNullable(obj.get("gameDir")).map(JsonElement::getAsString).orElse("")); + vs.setNativesDir(Optional.ofNullable(obj.get("nativesDir")).map(JsonElement::getAsString).orElse("")); vs.setFullscreen(Optional.ofNullable(obj.get("fullscreen")).map(JsonElement::getAsBoolean).orElse(false)); vs.setNoJVMArgs(Optional.ofNullable(obj.get("noJVMArgs")).map(JsonElement::getAsBoolean).orElse(false)); vs.setNotCheckGame(Optional.ofNullable(obj.get("notCheckGame")).map(JsonElement::getAsBoolean).orElse(false)); @@ -621,6 +660,7 @@ public final class VersionSetting implements Cloneable { vs.setLauncherVisibility(LauncherVisibility.values()[Optional.ofNullable(obj.get("launcherVisibility")).map(JsonElement::getAsInt).orElse(1)]); vs.setGameDirType(GameDirectoryType.values()[Optional.ofNullable(obj.get("gameDirType")).map(JsonElement::getAsInt).orElse(0)]); vs.setDefaultJavaPath(Optional.ofNullable(obj.get("defaultJavaPath")).map(JsonElement::getAsString).orElse(null)); + vs.setNativesDirType(NativesDirectoryType.values()[Optional.ofNullable(obj.get("nativesDirType")).map(JsonElement::getAsInt).orElse(0)]); return vs; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java index 8a1fe7c73..29d44c622 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionSettingsPage.java @@ -35,6 +35,7 @@ import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import org.jackhuang.hmcl.game.GameDirectoryType; +import org.jackhuang.hmcl.game.NativesDirectoryType; import org.jackhuang.hmcl.setting.*; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; @@ -76,6 +77,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag @FXML private JFXTextField txtWidth; @FXML private JFXTextField txtHeight; @FXML private JFXTextField txtMaxMemory; + @FXML private JFXTextField txtNativesPath; @FXML private JFXTextField txtJVMArgs; @FXML private JFXTextField txtGameArgs; @FXML private JFXTextField txtMetaspace; @@ -88,11 +90,13 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag @FXML private JFXComboBox cboLauncherVisibility; @FXML private JFXCheckBox chkFullscreen; @FXML private Label lblPhysicalMemory; + @FXML private Label lblCustomizedNativesPath; @FXML private JFXToggleButton chkNoJVMArgs; @FXML private JFXToggleButton chkNoGameCheck; @FXML private JFXToggleButton chkNoJVMCheck; @FXML private MultiFileItem javaItem; @FXML private MultiFileItem gameDirItem; + @FXML private MultiFileItem nativesDirItem; @FXML private JFXToggleButton chkShowLogs; @FXML private ImagePickerItem iconPickerItem; @FXML private JFXCheckBox chkEnableSpecificSettings; @@ -138,6 +142,11 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag gameDirItem.createChildren(i18n("settings.advanced.game_dir.independent"), GameDirectoryType.VERSION_FOLDER) )); + nativesDirItem.setCustomUserData(NativesDirectoryType.CUSTOM); + nativesDirItem.loadChildren(Arrays.asList( + nativesDirItem.createChildren(i18n("settings.advanced.natives_dir.default"), NativesDirectoryType.VERSION_FOLDER) + )); + chkEnableSpecificSettings.selectedProperty().addListener((a, b, newValue) -> { if (versionId == null) return; @@ -179,6 +188,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.unbindInt(txtMaxMemory, lastVersionSetting.maxMemoryProperty()); FXUtils.unbindString(javaItem.getTxtCustom(), lastVersionSetting.javaDirProperty()); FXUtils.unbindString(gameDirItem.getTxtCustom(), lastVersionSetting.gameDirProperty()); + FXUtils.unbindString(nativesDirItem.getTxtCustom(), lastVersionSetting.nativesDirProperty()); FXUtils.unbindString(txtJVMArgs, lastVersionSetting.javaArgsProperty()); FXUtils.unbindString(txtGameArgs, lastVersionSetting.minecraftArgsProperty()); FXUtils.unbindString(txtMetaspace, lastVersionSetting.permSizeProperty()); @@ -198,6 +208,9 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag gameDirItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.gameDirTypeProperty()); gameDirItem.subtitleProperty().unbind(); + + nativesDirItem.selectedDataProperty().unbindBidirectional(lastVersionSetting.nativesDirTypeProperty()); + nativesDirItem.subtitleProperty().unbind(); } // unbind data fields @@ -209,6 +222,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.bindInt(txtMaxMemory, versionSetting.maxMemoryProperty()); FXUtils.bindString(javaItem.getTxtCustom(), versionSetting.javaDirProperty()); FXUtils.bindString(gameDirItem.getTxtCustom(), versionSetting.gameDirProperty()); + FXUtils.bindString(nativesDirItem.getTxtCustom(), versionSetting.nativesDirProperty()); FXUtils.bindString(txtJVMArgs, versionSetting.javaArgsProperty()); FXUtils.bindString(txtGameArgs, versionSetting.minecraftArgsProperty()); FXUtils.bindString(txtMetaspace, versionSetting.permSizeProperty()); @@ -240,6 +254,10 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag gameDirItem.selectedDataProperty().bindBidirectional(versionSetting.gameDirTypeProperty()); gameDirItem.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath()).normalize().toString(), versionSetting.gameDirProperty(), versionSetting.gameDirTypeProperty())); + + nativesDirItem.selectedDataProperty().bindBidirectional(versionSetting.nativesDirTypeProperty()); + nativesDirItem.subtitleProperty().bind(Bindings.createStringBinding(() -> Paths.get(profile.getRepository().getRunDirectory(versionId).getAbsolutePath() + "/natives").normalize().toString(), + versionSetting.nativesDirProperty(), versionSetting.nativesDirTypeProperty())); lastVersionSetting = versionSetting; diff --git a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml index d5b4c5c93..fcd8378b6 100644 --- a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml +++ b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml @@ -38,6 +38,9 @@ + + @@ -53,7 +56,7 @@ - +