From 91bd67dc26f7b6aa5ef83b2449b687c19bfe679a Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Sun, 2 Dec 2018 20:02:22 +0800 Subject: [PATCH] Restore default cache directory if needed. Closes #489 --- .../org/jackhuang/hmcl/setting/Settings.java | 12 ++---- .../org/jackhuang/hmcl/ui/Controllers.java | 7 ++++ .../org/jackhuang/hmcl/ui/SettingsPage.java | 9 +++-- .../org/jackhuang/hmcl/ui/SettingsView.java | 13 +++---- .../resources/assets/lang/I18N.properties | 9 +++-- .../resources/assets/lang/I18N_zh.properties | 9 +++-- .../assets/lang/I18N_zh_CN.properties | 9 +++-- .../org/jackhuang/hmcl/util/io/FileUtils.java | 37 +++++++++++++++++-- 8 files changed, 71 insertions(+), 34 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java index 1f46804ab..f7ce2ce1c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -21,9 +21,7 @@ import javafx.beans.binding.Bindings; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.HMCLCacheRepository; import org.jackhuang.hmcl.util.CacheRepository; - -import java.nio.file.InvalidPathException; -import java.nio.file.Paths; +import org.jackhuang.hmcl.util.io.FileUtils; import static org.jackhuang.hmcl.setting.ConfigHolder.config; @@ -53,11 +51,9 @@ public class Settings { CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY); HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> { - String str = getCommonDirectory(); - try { - Paths.get(str); - return str; - } catch (InvalidPathException e) { + if (FileUtils.canCreateDirectory(getCommonDirectory())) { + return getCommonDirectory(); + } else { return getDefaultCommonDirectory(); } }, config().commonDirectoryProperty(), config().commonDirTypeProperty())); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index aa500f36b..eb92d04ee 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -29,6 +29,7 @@ import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Accounts; +import org.jackhuang.hmcl.setting.EnumCommonDirectory; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; @@ -211,6 +212,12 @@ public final class Controllers { leftPaneController = new LeftPaneController(); decorator.getDecorator().drawerProperty().setAll(leftPaneController); + if (config().getCommonDirType() == EnumCommonDirectory.CUSTOM && + !FileUtils.canCreateDirectory(config().getCommonDirectory())) { + config().setCommonDirType(EnumCommonDirectory.DEFAULT); + dialog(i18n("launcher.cache_directory.invalid")); + } + Task.of(JavaVersion::initialize).start(); scene = new Scene(decorator.getDecorator(), 800, 519); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java index 367bcf58d..8997f22bf 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java @@ -24,7 +24,8 @@ import javafx.beans.InvalidationListener; import javafx.beans.WeakInvalidationListener; import javafx.beans.binding.Bindings; import javafx.beans.binding.When; -import javafx.beans.property.*; +import javafx.beans.property.ReadOnlyStringProperty; +import javafx.beans.property.ReadOnlyStringWrapper; import javafx.scene.control.ToggleGroup; import javafx.scene.paint.Color; import javafx.scene.text.Font; @@ -41,7 +42,7 @@ import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.i18n.Locales; import org.jackhuang.hmcl.util.javafx.SafeStringConverter; -import java.awt.Desktop; +import java.awt.*; import java.io.IOException; import java.net.Proxy; import java.nio.file.Files; @@ -114,13 +115,13 @@ public final class SettingsPage extends SettingsView implements DecoratorPage { // ==== fileCommonLocation.loadChildren(Arrays.asList( - fileCommonLocation.createChildren(i18n("launcher.common_directory.default"), EnumCommonDirectory.DEFAULT) + fileCommonLocation.createChildren(i18n("launcher.cache_directory.default"), EnumCommonDirectory.DEFAULT) ), EnumCommonDirectory.CUSTOM); fileCommonLocation.selectedDataProperty().bindBidirectional(config().commonDirTypeProperty()); fileCommonLocation.customTextProperty().bindBidirectional(config().commonDirectoryProperty()); fileCommonLocation.subtitleProperty().bind( Bindings.createObjectBinding(() -> Optional.ofNullable(Settings.instance().getCommonDirectory()) - .orElse(i18n("launcher.common_directory.disabled")), + .orElse(i18n("launcher.cache_directory.disabled")), config().commonDirectoryProperty(), config().commonDirTypeProperty())); // ==== Update ==== diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java index 362b35ba4..1cf349aba 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java @@ -26,17 +26,16 @@ import javafx.scene.control.ScrollPane; import javafx.scene.layout.*; import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; - -import static org.jackhuang.hmcl.setting.ConfigHolder.config; -import static org.jackhuang.hmcl.ui.FXUtils.stringConverter; -import static org.jackhuang.hmcl.util.i18n.I18n.i18n; - import org.jackhuang.hmcl.setting.EnumBackgroundImage; import org.jackhuang.hmcl.setting.EnumCommonDirectory; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.construct.*; import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale; +import static org.jackhuang.hmcl.setting.ConfigHolder.config; +import static org.jackhuang.hmcl.ui.FXUtils.stringConverter; +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; + public abstract class SettingsView extends StackPane { protected final JFXTextField txtProxyHost; protected final JFXTextField txtProxyPort; @@ -144,9 +143,9 @@ public abstract class SettingsView extends StackPane { { fileCommonLocation = new MultiFileItem<>(true); - fileCommonLocation.setTitle(i18n("launcher.common_directory")); + fileCommonLocation.setTitle(i18n("launcher.cache_directory")); fileCommonLocation.setDirectory(true); - fileCommonLocation.setChooserTitle(i18n("launcher.common_directory.choose")); + fileCommonLocation.setChooserTitle(i18n("launcher.cache_directory.choose")); fileCommonLocation.setHasSubtitle(true); fileCommonLocation.setCustomText("settings.custom"); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index eb0007dd4..374773ff7 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -167,10 +167,11 @@ launcher=Launcher launcher.background=Background Image launcher.background.choose=Choose background path. launcher.background.default=Default -launcher.common_directory=Download Cache Directory -launcher.common_directory.choose=Choose download cache directory -launcher.common_directory.default=Default -launcher.common_directory.disabled=Disabled +launcher.cache_directory=Download Cache Directory +launcher.cache_directory.choose=Choose download cache directory +launcher.cache_directory.default=Default +launcher.cache_directory.disabled=Disabled +launcher.cache_directory.invalid=Invalid cache directory. Restore default settings. launcher.contact=Contact Us launcher.crash=Hello Minecraft! Launcher has crashed! launcher.crash_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it! diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 1002bd4ed..3fc39de7c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -167,10 +167,11 @@ launcher=啟動器 launcher.background=背景位址 launcher.background.choose=選擇背景路徑 launcher.background.default=預設(自動尋找啟動器同目錄下的 background.png/jpg 及 bg 資料夾內的圖片) -launcher.common_directory=檔案下載緩存目錄 -launcher.common_directory.choose=選擇檔案下載緩存目錄 -launcher.common_directory.default=預設 -launcher.common_directory.disabled=停用 +launcher.cache_directory=檔案下載快取目錄 +launcher.cache_directory.choose=選擇檔案下載快取目錄 +launcher.cache_directory.default=預設 +launcher.cache_directory.disabled=停用 +launcher.cache_directory.invalid=無法創建自訂的快取目錄,恢復預設設定 launcher.contact=聯絡我們 launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤,請複製下列內容並透過 MCBBS、貼吧、GitHub 或 Minecraft Forum 回報 bug。 launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤,已偵測到您的啟動器不是最新版本,請更新後重試! 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 14d6cf727..533934709 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -167,10 +167,11 @@ launcher=启动器 launcher.background=背景地址 launcher.background.choose=选择背景路径 launcher.background.default=默认(自动检索启动器同目录下的 background.png/jpg 及 bg 文件夹内的图片) -launcher.common_directory=文件下载缓存目录 -launcher.common_directory.choose=选择文件下载缓存目录 -launcher.common_directory.default=默认(%AppData%/.minecraft 或者 ~/.minecraft) -launcher.common_directory.disabled=禁用(总是使用游戏路径) +launcher.cache_directory=文件下载缓存目录 +launcher.cache_directory.choose=选择文件下载缓存目录 +launcher.cache_directory.default=默认(%AppData%/.minecraft 或者 ~/.minecraft) +launcher.cache_directory.disabled=禁用(总是使用游戏路径) +launcher.cache_directory.invalid=无法创建自定义的缓存目录,恢复默认设置 launcher.contact=联系我们 launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误,请复制下列内容并通过 MCBBS、贴吧、GitHub 或 Minecraft Forum 反馈 bug。 launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试! diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java index f1130336f..338fc77da 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java @@ -17,6 +17,9 @@ */ package org.jackhuang.hmcl.util.io; +import org.jackhuang.hmcl.util.Lang; +import org.jackhuang.hmcl.util.StringUtils; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -28,9 +31,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; -import org.jackhuang.hmcl.util.Lang; -import org.jackhuang.hmcl.util.StringUtils; - import static java.nio.charset.StandardCharsets.UTF_8; /** @@ -42,6 +42,37 @@ public final class FileUtils { private FileUtils() { } + public static boolean canCreateDirectory(String path) { + try { + return canCreateDirectory(Paths.get(path)); + } catch (InvalidPathException e) { + return false; + } + } + + public static boolean canCreateDirectory(Path path) { + if (Files.isDirectory(path)) return true; + else if (Files.exists(path)) return false; + else { + Path lastPath = path; // always not exist + path = path.getParent(); + // find existent ancestor + while (path != null && !Files.exists(path)) { + lastPath = path; + path = path.getParent(); + } + if (path == null) return false; // all ancestors are nonexistent + if (!Files.isDirectory(path)) return false; // ancestor is file + try { + Files.createDirectory(lastPath); // check permission + Files.delete(lastPath); // safely delete empty directory + return true; + } catch (IOException e) { + return false; + } + } + } + public static String getNameWithoutExtension(File file) { return StringUtils.substringBeforeLast(file.getName(), '.'); }