diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java index de9d11b82..a523e6080 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java @@ -311,7 +311,9 @@ public class HMCLGameRepository extends DefaultGameRepository { .setNoGeneratedJVMArgs(vs.isNoJVMArgs()) .setNativesDirType(vs.getNativesDirType()) .setNativesDir(vs.getNativesDir()) - .setProcessPriority(vs.getProcessPriority()); + .setProcessPriority(vs.getProcessPriority()) + .setUseNativeGLFW(vs.isUseNativeGLFW()) + .setUseNativeOpenAL(vs.isUseNativeOpenAL()); if (config().hasProxy()) { builder.setProxy(ProxyManager.getProxy()); if (config().hasProxyAuth()) { 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 a47e4e0b7..328cc715b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/VersionSetting.java @@ -504,6 +504,34 @@ public final class VersionSetting implements Cloneable { processPriorityProperty.set(processPriority); } + private final BooleanProperty useNativeGLFW = new SimpleBooleanProperty(this, "nativeGLFW", false); + + public boolean isUseNativeGLFW() { + return useNativeGLFW.get(); + } + + public BooleanProperty useNativeGLFWProperty() { + return useNativeGLFW; + } + + public void setUseNativeGLFW(boolean useNativeGLFW) { + this.useNativeGLFW.set(useNativeGLFW); + } + + private final BooleanProperty useNativeOpenAL = new SimpleBooleanProperty(this, "nativeOpenAL", false); + + public boolean isUseNativeOpenAL() { + return useNativeOpenAL.get(); + } + + public BooleanProperty useNativeOpenALProperty() { + return useNativeOpenAL; + } + + public void setUseNativeOpenAL(boolean useNativeOpenAL) { + this.useNativeOpenAL.set(useNativeOpenAL); + } + // launcher settings /** @@ -587,6 +615,8 @@ public final class VersionSetting implements Cloneable { gameDirTypeProperty.addListener(listener); gameDirProperty.addListener(listener); processPriorityProperty.addListener(listener); + useNativeGLFW.addListener(listener); + useNativeOpenAL.addListener(listener); launcherVisibilityProperty.addListener(listener); defaultJavaPathProperty.addListener(listener); nativesDirProperty.addListener(listener); @@ -619,6 +649,8 @@ public final class VersionSetting implements Cloneable { versionSetting.setGameDirType(getGameDirType()); versionSetting.setGameDir(getGameDir()); versionSetting.setProcessPriority(getProcessPriority()); + versionSetting.setUseNativeGLFW(isUseNativeGLFW()); + versionSetting.setUseNativeOpenAL(isUseNativeOpenAL()); versionSetting.setLauncherVisibility(getLauncherVisibility()); versionSetting.setNativesDir(getNativesDir()); return versionSetting; @@ -652,6 +684,8 @@ 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("useNativeGLFW", src.isUseNativeGLFW()); + obj.addProperty("useNativeOpenAL", src.isUseNativeOpenAL()); obj.addProperty("gameDirType", src.getGameDirType().ordinal()); obj.addProperty("defaultJavaPath", src.getDefaultJavaPath()); obj.addProperty("nativesDir", src.getNativesDir()); @@ -694,6 +728,8 @@ public final class VersionSetting implements Cloneable { vs.setShowLogs(Optional.ofNullable(obj.get("showLogs")).map(JsonElement::getAsBoolean).orElse(false)); vs.setLauncherVisibility(LauncherVisibility.values()[Optional.ofNullable(obj.get("launcherVisibility")).map(JsonElement::getAsInt).orElse(LauncherVisibility.HIDE.ordinal())]); vs.setProcessPriority(ProcessPriority.values()[Optional.ofNullable(obj.get("processPriority")).map(JsonElement::getAsInt).orElse(ProcessPriority.NORMAL.ordinal())]); + 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(GameDirectoryType.values()[Optional.ofNullable(obj.get("gameDirType")).map(JsonElement::getAsInt).orElse(GameDirectoryType.ROOT_FOLDER.ordinal())]); 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)]); 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 c456cfabd..a04a622c2 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 @@ -91,6 +91,8 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag private final JFXToggleButton chkNoJVMArgs; private final JFXToggleButton chkNoGameCheck; private final JFXToggleButton chkNoJVMCheck; + private final JFXToggleButton chkUseNativeGLFW; + private final JFXToggleButton chkUseNativeOpenAL; private final MultiFileItem javaItem; private final MultiFileItem gameDirItem; private final MultiFileItem nativesDirItem; @@ -449,7 +451,31 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.setLimitHeight(chkNoJVMCheck, 20); } - advancedSettingsPane.getContent().setAll(processPriorityPane, txtJVMArgs, txtGameArgs, txtMetaspace, txtWrapper, txtPrecallingCommand, txtServerIP, nativesDirItem, noJVMArgsPane, noGameCheckPane, noJVMCheckPane); + BorderPane useNativeGLFWPane = new BorderPane(); + { + Label label = new Label(i18n("settings.advanced.use_native_glfw")); + useNativeGLFWPane.setLeft(label); + BorderPane.setAlignment(label, Pos.CENTER_LEFT); + + chkUseNativeGLFW = new JFXToggleButton(); + useNativeGLFWPane.setRight(chkUseNativeGLFW); + chkUseNativeGLFW.setSize(8); + FXUtils.setLimitHeight(chkUseNativeGLFW, 20); + } + + BorderPane useNativeOpenALPane = new BorderPane(); + { + Label label = new Label(i18n("settings.advanced.use_native_openal")); + useNativeOpenALPane.setLeft(label); + BorderPane.setAlignment(label, Pos.CENTER_LEFT); + + chkUseNativeOpenAL = new JFXToggleButton(); + useNativeOpenALPane.setRight(chkUseNativeOpenAL); + chkUseNativeOpenAL.setSize(8); + FXUtils.setLimitHeight(chkUseNativeOpenAL, 20); + } + + advancedSettingsPane.getContent().setAll(processPriorityPane, txtJVMArgs, txtGameArgs, txtMetaspace, txtWrapper, txtPrecallingCommand, txtServerIP, nativesDirItem, noJVMArgsPane, noGameCheckPane, noJVMCheckPane, useNativeGLFWPane, useNativeOpenALPane); } rootPane.getChildren().setAll(iconPickerItemWrapper, settingsTypePane, componentList, advancedHintPane, advancedSettingsPane); @@ -552,6 +578,8 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.unbindBoolean(chkNoJVMCheck, lastVersionSetting.notCheckJVMProperty()); FXUtils.unbindBoolean(chkNoJVMArgs, lastVersionSetting.noJVMArgsProperty()); FXUtils.unbindBoolean(chkShowLogs, lastVersionSetting.showLogsProperty()); + FXUtils.unbindBoolean(chkUseNativeGLFW, lastVersionSetting.useNativeGLFWProperty()); + FXUtils.unbindBoolean(chkUseNativeOpenAL, lastVersionSetting.useNativeOpenALProperty()); FXUtils.unbindEnum(cboLauncherVisibility); FXUtils.unbindEnum(cboProcessPriority); @@ -588,6 +616,8 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag FXUtils.bindBoolean(chkNoJVMCheck, versionSetting.notCheckJVMProperty()); FXUtils.bindBoolean(chkNoJVMArgs, versionSetting.noJVMArgsProperty()); FXUtils.bindBoolean(chkShowLogs, versionSetting.showLogsProperty()); + FXUtils.bindBoolean(chkUseNativeGLFW, versionSetting.useNativeGLFWProperty()); + FXUtils.bindBoolean(chkUseNativeOpenAL, versionSetting.useNativeOpenALProperty()); FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty()); FXUtils.bindEnum(cboProcessPriority, versionSetting.processPriorityProperty()); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 50f2e194c..329818b67 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -473,6 +473,8 @@ settings.advanced.process_priority.normal=Normal settings.advanced.process_priority.above_normal=Above Normal settings.advanced.process_priority.high=High settings.advanced.server_ip=Server Address +settings.advanced.use_native_glfw=[Linux] Use system GLFW +settings.advanced.use_native_openal=[Linux] Use system OpenAL settings.advanced.wrapper_launcher=Wrapper Launcher (i.e. optirun...) settings.custom=Custom diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index d054313c0..2cc74d7dc 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -478,6 +478,8 @@ settings.advanced.process_priority.normal=中(平衡) settings.advanced.process_priority.above_normal=较高(优先保证游戏运行,但可能会导致其他程序卡顿) settings.advanced.process_priority.high=高(优先保证游戏运行,但可能会导致其他程序卡顿) settings.advanced.server_ip=直入服务器 IP 地址(不必填写,启动游戏后直接进入对应服务器) +settings.advanced.use_native_glfw=[Linux] 使用系统 GLFW +settings.advanced.use_native_openal=[Linux] 使用系统 OpenAL settings.advanced.wrapper_launcher=前置指令(不必填写,如 optirun) settings.custom=自定义 @@ -542,7 +544,7 @@ settings.type.special.enable=启用游戏特定设置(不影响其他游戏版 sponsor=赞助 sponsor.bmclapi=国内下载源由 BMCLAPI 和我的世界中文论坛 (MCBBS) 提供高速下载服务。BMCLAPI 是公益服务,请赞助 BMCLAPI 以获得稳定高速的下载服务,点击此处查阅详细信息。 -sponsor.hmcl=Hello Minecraft! Launcher 是一个免费、开源的 Minecraft 启动器,允许玩家方便快捷地安装、管理、运行游戏。您的赞助将帮助 Hello Minecraft! Launcher 获得更好的发展、支持稳定高速的游戏安装与文件下载服务。点击此处查阅更多详细信息。 +sponsor.hmcl=Hello Minecraft! Launcher 是一个免费、自由、开放源代码的 Minecraft 启动器。您的赞助将帮助 Hello Minecraft! Launcher 获得更好的发展,还可以获得 HMCL 的开发进展。点击此处查阅更多详细信息。 update=启动器更新 update.accept=更新 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java index ab39645d6..7eaf3a71b 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java @@ -56,6 +56,8 @@ public class LaunchOptions implements Serializable { private NativesDirectoryType nativesDirType; private String nativesDir; private ProcessPriority processPriority = ProcessPriority.NORMAL; + private boolean useNativeGLFW; + private boolean useNativeOpenAL; /** * The game directory @@ -225,6 +227,14 @@ public class LaunchOptions implements Serializable { return processPriority; } + public boolean isUseNativeGLFW() { + return useNativeGLFW; + } + + public boolean isUseNativeOpenAL() { + return useNativeOpenAL; + } + public static class Builder { private final LaunchOptions options = new LaunchOptions(); @@ -385,6 +395,14 @@ public class LaunchOptions implements Serializable { return options.nativesDir; } + public boolean isUseNativeGLFW() { + return options.useNativeGLFW; + } + + public boolean isUseNativeOpenAL() { + return options.useNativeOpenAL; + } + public Builder setGameDir(File gameDir) { options.gameDir = gameDir; return this; @@ -502,5 +520,15 @@ public class LaunchOptions implements Serializable { return this; } + public Builder setUseNativeGLFW(boolean useNativeGLFW) { + options.useNativeGLFW = useNativeGLFW; + return this; + } + + public Builder setUseNativeOpenAL(boolean useNativeOpenAL) { + options.useNativeOpenAL = useNativeOpenAL; + return this; + } + } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java index c11e1e5fc..b1496d5a9 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java @@ -303,6 +303,14 @@ public class DefaultLauncher extends Launcher { String ext = FileUtils.getExtension(destFile); if (ext.equals("sha1") || ext.equals("git")) return false; + + if (options.isUseNativeGLFW() && FileUtils.getName(destFile).toLowerCase(Locale.ROOT).contains("glfw")) { + return false; + } + if (options.isUseNativeOpenAL() && FileUtils.getName(destFile).toLowerCase(Locale.ROOT).contains("openal")) { + return false; + } + return library.getExtract().shouldExtract(path); }) .setReplaceExistentFile(false).unzip();