mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-08 03:15:17 -04:00
使用工作路径下的 .hmcl 文件夹存放所有配置文件 (#3875)
This commit is contained in:
parent
dc5ebcf64d
commit
9a37d412a3
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,3 +52,4 @@ minecraft-exported-crash-info*
|
|||||||
# test
|
# test
|
||||||
/hmcl.json
|
/hmcl.json
|
||||||
/.hmcl.json
|
/.hmcl.json
|
||||||
|
/.hmcl/
|
@ -100,7 +100,7 @@ public final class Launcher extends Application {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Metadata.HMCL_DIRECTORY.toString().indexOf('=') >= 0) {
|
if (Metadata.HMCL_CURRENT_DIRECTORY.toString().indexOf('=') >= 0) {
|
||||||
Main.showWarningAndContinue(i18n("fatal.illegal_char"));
|
Main.showWarningAndContinue(i18n("fatal.illegal_char"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +186,10 @@ public final class Launcher extends Application {
|
|||||||
|
|
||||||
ArrayList<String> files = new ArrayList<>();
|
ArrayList<String> files = new ArrayList<>();
|
||||||
files.add(ConfigHolder.configLocation().toString());
|
files.add(ConfigHolder.configLocation().toString());
|
||||||
if (Files.exists(Metadata.HMCL_DIRECTORY))
|
if (Files.exists(Metadata.HMCL_GLOBAL_DIRECTORY))
|
||||||
files.add(Metadata.HMCL_DIRECTORY.toString());
|
files.add(Metadata.HMCL_GLOBAL_DIRECTORY.toString());
|
||||||
|
if (Files.exists(Metadata.HMCL_CURRENT_DIRECTORY))
|
||||||
|
files.add(Metadata.HMCL_CURRENT_DIRECTORY.toString());
|
||||||
|
|
||||||
Path mcDir = Paths.get(".minecraft").toAbsolutePath().normalize();
|
Path mcDir = Paths.get(".minecraft").toAbsolutePath().normalize();
|
||||||
if (Files.exists(mcDir))
|
if (Files.exists(mcDir))
|
||||||
@ -238,8 +240,9 @@ public final class Launcher extends Application {
|
|||||||
LOG.info("Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor"));
|
LOG.info("Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor"));
|
||||||
LOG.info("Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor"));
|
LOG.info("Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor"));
|
||||||
LOG.info("Java Home: " + System.getProperty("java.home"));
|
LOG.info("Java Home: " + System.getProperty("java.home"));
|
||||||
LOG.info("Current Directory: " + System.getProperty("user.dir"));
|
LOG.info("Current Directory: " + Metadata.CURRENT_DIRECTORY);
|
||||||
LOG.info("HMCL Directory: " + Metadata.HMCL_DIRECTORY);
|
LOG.info("HMCL Global Directory: " + Metadata.HMCL_GLOBAL_DIRECTORY);
|
||||||
|
LOG.info("HMCL Current Directory: " + Metadata.HMCL_CURRENT_DIRECTORY);
|
||||||
LOG.info("HMCL Jar Path: " + Lang.requireNonNullElse(JarUtils.thisJarPath(), "Not Found"));
|
LOG.info("HMCL Jar Path: " + Lang.requireNonNullElse(JarUtils.thisJarPath(), "Not Found"));
|
||||||
LOG.info("HMCL Log File: " + Lang.requireNonNullElse(LOG.getLogFile(), "In Memory"));
|
LOG.info("HMCL Log File: " + Lang.requireNonNullElse(LOG.getLogFile(), "In Memory"));
|
||||||
LOG.info("Memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
|
LOG.info("Memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");
|
||||||
|
@ -58,7 +58,8 @@ public final class Main {
|
|||||||
System.getProperties().putIfAbsent("javafx.autoproxy.disable", "true");
|
System.getProperties().putIfAbsent("javafx.autoproxy.disable", "true");
|
||||||
System.getProperties().putIfAbsent("http.agent", "HMCL/" + Metadata.VERSION);
|
System.getProperties().putIfAbsent("http.agent", "HMCL/" + Metadata.VERSION);
|
||||||
|
|
||||||
LOG.start(Metadata.HMCL_DIRECTORY.resolve("logs"));
|
createHMCLCurrentDirectory();
|
||||||
|
LOG.start(Metadata.HMCL_CURRENT_DIRECTORY.resolve("logs"));
|
||||||
|
|
||||||
checkDirectoryPath();
|
checkDirectoryPath();
|
||||||
|
|
||||||
@ -82,6 +83,24 @@ public final class Main {
|
|||||||
System.exit(exitCode);
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void createHMCLCurrentDirectory() {
|
||||||
|
if (!Files.isDirectory(Metadata.HMCL_CURRENT_DIRECTORY)) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Metadata.HMCL_CURRENT_DIRECTORY);
|
||||||
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||||
|
try {
|
||||||
|
Files.setAttribute(Metadata.HMCL_CURRENT_DIRECTORY, "dos:hidden", true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("Failed to set hidden attribute of " + Metadata.HMCL_CURRENT_DIRECTORY, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
showErrorAndExit(i18n("fatal.create_hmcl_current_directory_failure", Metadata.HMCL_CURRENT_DIRECTORY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void initIcon() {
|
private static void initIcon() {
|
||||||
java.awt.Image image = java.awt.Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/assets/img/icon-mac.png"));
|
java.awt.Image image = java.awt.Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/assets/img/icon-mac.png"));
|
||||||
AwtUtils.setAppleIcon(image);
|
AwtUtils.setAppleIcon(image);
|
||||||
|
@ -28,7 +28,8 @@ import java.nio.file.Paths;
|
|||||||
* Stores metadata about this application.
|
* Stores metadata about this application.
|
||||||
*/
|
*/
|
||||||
public final class Metadata {
|
public final class Metadata {
|
||||||
private Metadata() {}
|
private Metadata() {
|
||||||
|
}
|
||||||
|
|
||||||
public static final String NAME = "HMCL";
|
public static final String NAME = "HMCL";
|
||||||
public static final String FULL_NAME = "Hello Minecraft! Launcher";
|
public static final String FULL_NAME = "Hello Minecraft! Launcher";
|
||||||
@ -51,8 +52,11 @@ public final class Metadata {
|
|||||||
public static final String BUILD_CHANNEL = JarUtils.getManifestAttribute("Build-Channel", "nightly");
|
public static final String BUILD_CHANNEL = JarUtils.getManifestAttribute("Build-Channel", "nightly");
|
||||||
public static final String GITHUB_SHA = JarUtils.getManifestAttribute("GitHub-SHA", null);
|
public static final String GITHUB_SHA = JarUtils.getManifestAttribute("GitHub-SHA", null);
|
||||||
|
|
||||||
|
public static final Path CURRENT_DIRECTORY = Paths.get(System.getProperty("user.dir")).toAbsolutePath().normalize();
|
||||||
public static final Path MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft");
|
public static final Path MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft");
|
||||||
public static final Path HMCL_DIRECTORY;
|
public static final Path HMCL_GLOBAL_DIRECTORY;
|
||||||
|
public static final Path HMCL_CURRENT_DIRECTORY;
|
||||||
|
public static final Path DEPENDENCIES_DIRECTORY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
String hmclHome = System.getProperty("hmcl.home");
|
String hmclHome = System.getProperty("hmcl.home");
|
||||||
@ -60,16 +64,22 @@ public final class Metadata {
|
|||||||
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD()) {
|
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD()) {
|
||||||
String xdgData = System.getenv("XDG_DATA_HOME");
|
String xdgData = System.getenv("XDG_DATA_HOME");
|
||||||
if (StringUtils.isNotBlank(xdgData)) {
|
if (StringUtils.isNotBlank(xdgData)) {
|
||||||
HMCL_DIRECTORY = Paths.get(xdgData, "hmcl").toAbsolutePath();
|
HMCL_GLOBAL_DIRECTORY = Paths.get(xdgData, "hmcl").toAbsolutePath().normalize();
|
||||||
} else {
|
} else {
|
||||||
HMCL_DIRECTORY = Paths.get(System.getProperty("user.home", "."), ".local", "share", "hmcl").toAbsolutePath();
|
HMCL_GLOBAL_DIRECTORY = Paths.get(System.getProperty("user.home"), ".local", "share", "hmcl").toAbsolutePath().normalize();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HMCL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl");
|
HMCL_GLOBAL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HMCL_DIRECTORY = Paths.get(hmclHome).toAbsolutePath().normalize();
|
HMCL_GLOBAL_DIRECTORY = Paths.get(hmclHome).toAbsolutePath().normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String hmclCurrentDir = System.getProperty("hmcl.dir");
|
||||||
|
HMCL_CURRENT_DIRECTORY = hmclCurrentDir != null
|
||||||
|
? Paths.get(hmclCurrentDir).toAbsolutePath().normalize()
|
||||||
|
: CURRENT_DIRECTORY.resolve(".hmcl");
|
||||||
|
DEPENDENCIES_DIRECTORY = HMCL_CURRENT_DIRECTORY.resolve("dependencies");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isStable() {
|
public static boolean isStable() {
|
||||||
|
@ -87,7 +87,7 @@ public final class TexturesLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final ThreadPoolExecutor POOL = threadPool("TexturesDownload", true, 2, 10, TimeUnit.SECONDS);
|
private static final ThreadPoolExecutor POOL = threadPool("TexturesDownload", true, 2, 10, TimeUnit.SECONDS);
|
||||||
private static final Path TEXTURES_DIR = Metadata.HMCL_DIRECTORY.resolve("skins");
|
private static final Path TEXTURES_DIR = Metadata.HMCL_GLOBAL_DIRECTORY.resolve("skins");
|
||||||
|
|
||||||
private static Path getTexturePath(Texture texture) {
|
private static Path getTexturePath(Texture texture) {
|
||||||
String url = texture.getUrl();
|
String url = texture.getUrl();
|
||||||
|
@ -58,7 +58,7 @@ public final class JavaManager {
|
|||||||
private JavaManager() {
|
private JavaManager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final HMCLJavaRepository REPOSITORY = new HMCLJavaRepository(Metadata.HMCL_DIRECTORY.resolve("java"));
|
public static final HMCLJavaRepository REPOSITORY = new HMCLJavaRepository(Metadata.HMCL_GLOBAL_DIRECTORY.resolve("java"));
|
||||||
|
|
||||||
public static String getMojangJavaPlatform(Platform platform) {
|
public static String getMojangJavaPlatform(Platform platform) {
|
||||||
if (platform.getOperatingSystem() == OperatingSystem.WINDOWS) {
|
if (platform.getOperatingSystem() == OperatingSystem.WINDOWS) {
|
||||||
|
@ -175,7 +175,7 @@ public final class Accounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void loadGlobalAccountStorages() {
|
private static void loadGlobalAccountStorages() {
|
||||||
Path globalAccountsFile = Metadata.HMCL_DIRECTORY.resolve("accounts.json");
|
Path globalAccountsFile = Metadata.HMCL_GLOBAL_DIRECTORY.resolve("accounts.json");
|
||||||
if (Files.exists(globalAccountsFile)) {
|
if (Files.exists(globalAccountsFile)) {
|
||||||
try (Reader reader = Files.newBufferedReader(globalAccountsFile)) {
|
try (Reader reader = Files.newBufferedReader(globalAccountsFile)) {
|
||||||
globalAccountStorages.setAll(Config.CONFIG_GSON.fromJson(reader, listTypeOf(mapTypeOf(Object.class, Object.class))));
|
globalAccountStorages.setAll(Config.CONFIG_GSON.fromJson(reader, listTypeOf(mapTypeOf(Object.class, Object.class))));
|
||||||
@ -388,7 +388,7 @@ public final class Accounts {
|
|||||||
String authlibinjectorLocation = System.getProperty("hmcl.authlibinjector.location");
|
String authlibinjectorLocation = System.getProperty("hmcl.authlibinjector.location");
|
||||||
if (authlibinjectorLocation == null) {
|
if (authlibinjectorLocation == null) {
|
||||||
return new AuthlibInjectorDownloader(
|
return new AuthlibInjectorDownloader(
|
||||||
Metadata.HMCL_DIRECTORY.resolve("authlib-injector.jar"),
|
Metadata.DEPENDENCIES_DIRECTORY.resolve("authlib-injector.jar"),
|
||||||
DownloadProviders::getDownloadProvider) {
|
DownloadProviders::getDownloadProvider) {
|
||||||
@Override
|
@Override
|
||||||
public Optional<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately() {
|
public Optional<AuthlibInjectorArtifactInfo> getArtifactInfoImmediately() {
|
||||||
@ -397,7 +397,7 @@ public final class Accounts {
|
|||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
// search authlib-injector.jar in current directory, it's used as a fallback
|
// search authlib-injector.jar in current directory, it's used as a fallback
|
||||||
return parseArtifact(Paths.get("authlib-injector.jar"));
|
return parseArtifact(Metadata.CURRENT_DIRECTORY.resolve("authlib-injector.jar"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,7 +39,7 @@ public final class ConfigHolder {
|
|||||||
|
|
||||||
public static final String CONFIG_FILENAME = "hmcl.json";
|
public static final String CONFIG_FILENAME = "hmcl.json";
|
||||||
public static final String CONFIG_FILENAME_LINUX = ".hmcl.json";
|
public static final String CONFIG_FILENAME_LINUX = ".hmcl.json";
|
||||||
public static final Path GLOBAL_CONFIG_PATH = Metadata.HMCL_DIRECTORY.resolve("config.json");
|
public static final Path GLOBAL_CONFIG_PATH = Metadata.HMCL_GLOBAL_DIRECTORY.resolve("config.json");
|
||||||
|
|
||||||
private static Path configLocation;
|
private static Path configLocation;
|
||||||
private static Config configInstance;
|
private static Config configInstance;
|
||||||
@ -93,19 +93,9 @@ public final class ConfigHolder {
|
|||||||
LOG.setLogRetention(globalConfig().getLogRetention());
|
LOG.setLogRetention(globalConfig().getLogRetention());
|
||||||
Settings.init();
|
Settings.init();
|
||||||
|
|
||||||
if (newlyCreated) {
|
if (newlyCreated)
|
||||||
saveConfigSync();
|
saveConfigSync();
|
||||||
|
|
||||||
// hide the config file on windows
|
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
|
||||||
try {
|
|
||||||
Files.setAttribute(configLocation, "dos:hidden", true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.warning("Failed to set hidden attribute of " + configLocation, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Files.isWritable(configLocation)) {
|
if (!Files.isWritable(configLocation)) {
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
|
||||||
&& configLocation.getFileSystem() == FileSystems.getDefault()
|
&& configLocation.getFileSystem() == FileSystems.getDefault()
|
||||||
@ -121,12 +111,14 @@ public final class ConfigHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Path locateConfig() {
|
private static Path locateConfig() {
|
||||||
Path exePath = Paths.get("").toAbsolutePath();
|
Path defaultConfigFile = Metadata.HMCL_CURRENT_DIRECTORY.resolve(CONFIG_FILENAME);
|
||||||
|
if (Files.isRegularFile(defaultConfigFile))
|
||||||
|
return defaultConfigFile;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Path jarPath = JarUtils.thisJarPath();
|
Path jarPath = JarUtils.thisJarPath();
|
||||||
if (jarPath != null && Files.isRegularFile(jarPath) && Files.isWritable(jarPath)) {
|
if (jarPath != null && Files.isRegularFile(jarPath) && Files.isWritable(jarPath)) {
|
||||||
jarPath = jarPath.getParent();
|
jarPath = jarPath.getParent();
|
||||||
exePath = jarPath;
|
|
||||||
|
|
||||||
Path config = jarPath.resolve(CONFIG_FILENAME);
|
Path config = jarPath.resolve(CONFIG_FILENAME);
|
||||||
if (Files.isRegularFile(config))
|
if (Files.isRegularFile(config))
|
||||||
@ -149,7 +141,7 @@ public final class ConfigHolder {
|
|||||||
return dotConfig;
|
return dotConfig;
|
||||||
|
|
||||||
// create new
|
// create new
|
||||||
return exePath.resolve(OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? CONFIG_FILENAME : CONFIG_FILENAME_LINUX);
|
return defaultConfigFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Config loadConfig() throws IOException {
|
private static Config loadConfig() throws IOException {
|
||||||
|
@ -37,7 +37,6 @@ import java.nio.charset.Charset;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -59,26 +58,11 @@ public class Theme {
|
|||||||
Color.web("#B71C1C") // red
|
Color.web("#B71C1C") // red
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Lazy<Font> FONT = new Lazy<>(() -> {
|
private static Font tryLoadDefaultFont(Path dir) {
|
||||||
String[] fileNames = {"font.ttf", "font.otf", "font.woff"};
|
String[] fileNames = {"font.ttf", "font.otf", "font.woff"};
|
||||||
|
|
||||||
for (String fileName : fileNames) {
|
for (String fileName : fileNames) {
|
||||||
Path path = Paths.get(fileName).toAbsolutePath();
|
Path path = dir.resolve(fileName);
|
||||||
if (Files.isRegularFile(path)) {
|
|
||||||
try {
|
|
||||||
Font font = Font.loadFont(path.toUri().toURL().toExternalForm(), 0);
|
|
||||||
if (font != null) {
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
} catch (MalformedURLException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.warning("Failed to load font " + path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String fileName : fileNames) {
|
|
||||||
Path path = Metadata.HMCL_DIRECTORY.resolve(fileName);
|
|
||||||
if (Files.isRegularFile(path)) {
|
if (Files.isRegularFile(path)) {
|
||||||
try {
|
try {
|
||||||
Font font = Font.loadFont(path.toUri().toURL().toExternalForm(), 0);
|
Font font = Font.loadFont(path.toUri().toURL().toExternalForm(), 0);
|
||||||
@ -93,6 +77,18 @@ public class Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Lazy<Font> FONT = new Lazy<>(() -> {
|
||||||
|
Font font = tryLoadDefaultFont(Metadata.HMCL_CURRENT_DIRECTORY);
|
||||||
|
if (font != null)
|
||||||
|
return font;
|
||||||
|
|
||||||
|
font = tryLoadDefaultFont(Metadata.CURRENT_DIRECTORY);
|
||||||
|
if (font != null)
|
||||||
|
return font;
|
||||||
|
|
||||||
|
return tryLoadDefaultFont(Metadata.HMCL_GLOBAL_DIRECTORY);
|
||||||
});
|
});
|
||||||
|
|
||||||
public static Theme getTheme() {
|
public static Theme getTheme() {
|
||||||
|
@ -40,6 +40,7 @@ import javafx.scene.paint.Color;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.jackhuang.hmcl.Launcher;
|
import org.jackhuang.hmcl.Launcher;
|
||||||
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDnD;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorDnD;
|
||||||
import org.jackhuang.hmcl.setting.EnumBackgroundImage;
|
import org.jackhuang.hmcl.setting.EnumBackgroundImage;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
@ -235,12 +236,22 @@ public class DecoratorController {
|
|||||||
* Load background image from bg/, background.png, background.jpg, background.gif
|
* Load background image from bg/, background.png, background.jpg, background.gif
|
||||||
*/
|
*/
|
||||||
private Image loadDefaultBackgroundImage() {
|
private Image loadDefaultBackgroundImage() {
|
||||||
Image image = randomImageIn(Paths.get("bg"));
|
Image image = randomImageIn(Metadata.HMCL_CURRENT_DIRECTORY.resolve("background"));
|
||||||
if (image != null)
|
if (image != null)
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
for (String extension : FXUtils.IMAGE_EXTENSIONS) {
|
for (String extension : FXUtils.IMAGE_EXTENSIONS) {
|
||||||
image = tryLoadImage(Paths.get("background." + extension));
|
image = tryLoadImage(Metadata.HMCL_CURRENT_DIRECTORY.resolve("background." + extension));
|
||||||
|
if (image != null)
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = randomImageIn(Metadata.CURRENT_DIRECTORY.resolve("bg"));
|
||||||
|
if (image != null)
|
||||||
|
return image;
|
||||||
|
|
||||||
|
for (String extension : FXUtils.IMAGE_EXTENSIONS) {
|
||||||
|
image = tryLoadImage(Metadata.CURRENT_DIRECTORY.resolve("background." + extension));
|
||||||
if (image != null)
|
if (image != null)
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import javafx.scene.layout.*;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.text.TextAlignment;
|
import javafx.scene.text.TextAlignment;
|
||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
|
||||||
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
|
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
@ -46,6 +45,7 @@ import java.util.Arrays;
|
|||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
public abstract class SettingsView extends StackPane {
|
public abstract class SettingsView extends StackPane {
|
||||||
protected final JFXComboBox<SupportedLocale> cboLanguage;
|
protected final JFXComboBox<SupportedLocale> cboLanguage;
|
||||||
@ -195,6 +195,8 @@ public abstract class SettingsView extends StackPane {
|
|||||||
JFXButton openLogFolderButton = new JFXButton(i18n("settings.launcher.launcher_log.reveal"));
|
JFXButton openLogFolderButton = new JFXButton(i18n("settings.launcher.launcher_log.reveal"));
|
||||||
openLogFolderButton.setOnAction(e -> openLogFolder());
|
openLogFolderButton.setOnAction(e -> openLogFolder());
|
||||||
openLogFolderButton.getStyleClass().add("jfx-button-border");
|
openLogFolderButton.getStyleClass().add("jfx-button-border");
|
||||||
|
if (LOG.getLogFile() == null)
|
||||||
|
openLogFolderButton.setDisable(true);
|
||||||
|
|
||||||
JFXButton logButton = new JFXButton(i18n("settings.launcher.launcher_log.export"));
|
JFXButton logButton = new JFXButton(i18n("settings.launcher.launcher_log.export"));
|
||||||
logButton.setOnAction(e -> onExportLogs());
|
logButton.setOnAction(e -> onExportLogs());
|
||||||
@ -216,7 +218,7 @@ public abstract class SettingsView extends StackPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void openLogFolder() {
|
public void openLogFolder() {
|
||||||
FXUtils.openFolder(Metadata.HMCL_DIRECTORY.resolve("logs").toFile());
|
FXUtils.openFolder(LOG.getLogFile().getParent().toFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void onUpdate();
|
protected abstract void onUpdate();
|
||||||
|
@ -252,7 +252,7 @@ public final class UpdateHandler {
|
|||||||
private static boolean isFirstLaunchAfterUpgrade() {
|
private static boolean isFirstLaunchAfterUpgrade() {
|
||||||
Path currentPath = JarUtils.thisJarPath();
|
Path currentPath = JarUtils.thisJarPath();
|
||||||
if (currentPath != null) {
|
if (currentPath != null) {
|
||||||
Path updated = Metadata.HMCL_DIRECTORY.resolve("HMCL-" + Metadata.VERSION + ".jar");
|
Path updated = Metadata.HMCL_GLOBAL_DIRECTORY.resolve("HMCL-" + Metadata.VERSION + ".jar");
|
||||||
if (currentPath.equals(updated.toAbsolutePath())) {
|
if (currentPath.equals(updated.toAbsolutePath())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ public final class UpdateHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void breakForceUpdateFeature() {
|
private static void breakForceUpdateFeature() {
|
||||||
Path hmclVersionJson = Metadata.HMCL_DIRECTORY.resolve("hmclver.json");
|
Path hmclVersionJson = Metadata.HMCL_GLOBAL_DIRECTORY.resolve("hmclver.json");
|
||||||
if (Files.isRegularFile(hmclVersionJson)) {
|
if (Files.isRegularFile(hmclVersionJson)) {
|
||||||
try {
|
try {
|
||||||
Map<?, ?> content = new Gson().fromJson(FileUtils.readText(hmclVersionJson), Map.class);
|
Map<?, ?> content = new Gson().fromJson(FileUtils.readText(hmclVersionJson), Map.class);
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
package org.jackhuang.hmcl.util;
|
package org.jackhuang.hmcl.util;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.ui.SwingUtils;
|
import org.jackhuang.hmcl.ui.SwingUtils;
|
||||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||||
import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
|
import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
|
||||||
@ -66,7 +67,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
import static org.jackhuang.hmcl.Metadata.HMCL_DIRECTORY;
|
|
||||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
import static org.jackhuang.hmcl.util.gson.JsonUtils.listTypeOf;
|
||||||
import static org.jackhuang.hmcl.util.gson.JsonUtils.mapTypeOf;
|
import static org.jackhuang.hmcl.util.gson.JsonUtils.mapTypeOf;
|
||||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
@ -102,7 +102,7 @@ public final class SelfDependencyPatcher {
|
|||||||
|
|
||||||
private static final class DependencyDescriptor {
|
private static final class DependencyDescriptor {
|
||||||
private static final String DEPENDENCIES_LIST_FILE = "/assets/openjfx-dependencies.json";
|
private static final String DEPENDENCIES_LIST_FILE = "/assets/openjfx-dependencies.json";
|
||||||
private static final Path DEPENDENCIES_DIR_PATH = HMCL_DIRECTORY.resolve("dependencies").resolve(Platform.getPlatform().toString()).resolve("openjfx");
|
private static final Path DEPENDENCIES_DIR_PATH = Metadata.DEPENDENCIES_DIRECTORY.resolve(Platform.getPlatform().toString()).resolve("openjfx");
|
||||||
|
|
||||||
static List<DependencyDescriptor> readDependencies() {
|
static List<DependencyDescriptor> readDependencies() {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
|
@ -365,6 +365,7 @@ extension.png=Image File
|
|||||||
extension.ps1=Windows PowerShell Script
|
extension.ps1=Windows PowerShell Script
|
||||||
extension.sh=Shell Script
|
extension.sh=Shell Script
|
||||||
|
|
||||||
|
fatal.create_hmcl_current_directory_failure=Hello Minecraft! Launcher cannot create the HMCL directory (%s). Please move HMCL to another location and reopen it.
|
||||||
fatal.javafx.incompatible=Missing JavaFX environment.\n\
|
fatal.javafx.incompatible=Missing JavaFX environment.\n\
|
||||||
Hello Minecraft! Launcher cannot automatically install JavaFX on Java <11.\n\
|
Hello Minecraft! Launcher cannot automatically install JavaFX on Java <11.\n\
|
||||||
Please update your Java to version 11 or later.
|
Please update your Java to version 11 or later.
|
||||||
|
@ -363,6 +363,7 @@ extension.png=圖片檔案
|
|||||||
extension.ps1=PowerShell 指令碼
|
extension.ps1=PowerShell 指令碼
|
||||||
extension.sh=Bash 指令碼
|
extension.sh=Bash 指令碼
|
||||||
|
|
||||||
|
fatal.create_hmcl_current_directory_failure=Hello Minecraft! Launcher 無法創建 HMCL 資料夾(%s),請將 HMCL 移動至其他位置再啟動。
|
||||||
fatal.javafx.incompatible=缺少 JavaFX 執行環境。\nHMCL 無法在低於 Java 11 的 Java 環境上自行補全 JavaFX 執行環境,請更新到 Java 11 或更高版本。
|
fatal.javafx.incompatible=缺少 JavaFX 執行環境。\nHMCL 無法在低於 Java 11 的 Java 環境上自行補全 JavaFX 執行環境,請更新到 Java 11 或更高版本。
|
||||||
fatal.javafx.incomplete=JavaFX 執行環境不完整,請嘗試更換你的 Java 或者重新安裝 OpenJFX。
|
fatal.javafx.incomplete=JavaFX 執行環境不完整,請嘗試更換你的 Java 或者重新安裝 OpenJFX。
|
||||||
fatal.javafx.missing=缺少 JavaFX 執行環境,請使用包含 OpenJFX 的 Java 執行環境開啟 Hello Minecraft! Launcher。
|
fatal.javafx.missing=缺少 JavaFX 執行環境,請使用包含 OpenJFX 的 Java 執行環境開啟 Hello Minecraft! Launcher。
|
||||||
|
@ -372,6 +372,7 @@ extension.png=图片文件
|
|||||||
extension.ps1=PowerShell 脚本
|
extension.ps1=PowerShell 脚本
|
||||||
extension.sh=Bash 脚本
|
extension.sh=Bash 脚本
|
||||||
|
|
||||||
|
fatal.create_hmcl_current_directory_failure=Hello Minecraft! Launcher 无法创建 HMCL 文件夹(%s),请将 HMCL 移动至其他位置再启动。\n如遇到问题,你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
|
||||||
fatal.javafx.incompatible=缺少 JavaFX 运行环境。\nHello Minecraft! Launcher 无法在低于 Java 11 的 Java 环境上自行补全 JavaFX 运行环境,请更新到 Java 11 或更高版本。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
|
fatal.javafx.incompatible=缺少 JavaFX 运行环境。\nHello Minecraft! Launcher 无法在低于 Java 11 的 Java 环境上自行补全 JavaFX 运行环境,请更新到 Java 11 或更高版本。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
|
||||||
fatal.javafx.incomplete=JavaFX 运行环境不完整,请尝试更换你的 Java 或者重新安装 OpenJFX。
|
fatal.javafx.incomplete=JavaFX 运行环境不完整,请尝试更换你的 Java 或者重新安装 OpenJFX。
|
||||||
fatal.javafx.missing=缺少 JavaFX 运行环境,请使用包含 OpenJFX 的 Java 运行环境启动 Hello Minecraft! Launcher。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
|
fatal.javafx.missing=缺少 JavaFX 运行环境,请使用包含 OpenJFX 的 Java 运行环境启动 Hello Minecraft! Launcher。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user