Restore default cache directory if needed. Closes #489

This commit is contained in:
huanghongxun
2018-12-02 20:02:22 +08:00
parent 0671b49c98
commit 91bd67dc26
8 changed files with 71 additions and 34 deletions

View File

@@ -21,9 +21,7 @@ import javafx.beans.binding.Bindings;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.game.HMCLCacheRepository; import org.jackhuang.hmcl.game.HMCLCacheRepository;
import org.jackhuang.hmcl.util.CacheRepository; import org.jackhuang.hmcl.util.CacheRepository;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.setting.ConfigHolder.config;
@@ -53,11 +51,9 @@ public class Settings {
CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY); CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY);
HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> { HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> {
String str = getCommonDirectory(); if (FileUtils.canCreateDirectory(getCommonDirectory())) {
try { return getCommonDirectory();
Paths.get(str); } else {
return str;
} catch (InvalidPathException e) {
return getDefaultCommonDirectory(); return getDefaultCommonDirectory();
} }
}, config().commonDirectoryProperty(), config().commonDirTypeProperty())); }, config().commonDirectoryProperty(), config().commonDirTypeProperty()));

View File

@@ -29,6 +29,7 @@ import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.setting.Accounts;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.task.TaskExecutor;
@@ -211,6 +212,12 @@ public final class Controllers {
leftPaneController = new LeftPaneController(); leftPaneController = new LeftPaneController();
decorator.getDecorator().drawerProperty().setAll(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(); Task.of(JavaVersion::initialize).start();
scene = new Scene(decorator.getDecorator(), 800, 519); scene = new Scene(decorator.getDecorator(), 800, 519);

View File

@@ -24,7 +24,8 @@ import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener; import javafx.beans.WeakInvalidationListener;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.When; 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.control.ToggleGroup;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.text.Font; 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.i18n.Locales;
import org.jackhuang.hmcl.util.javafx.SafeStringConverter; import org.jackhuang.hmcl.util.javafx.SafeStringConverter;
import java.awt.Desktop; import java.awt.*;
import java.io.IOException; import java.io.IOException;
import java.net.Proxy; import java.net.Proxy;
import java.nio.file.Files; import java.nio.file.Files;
@@ -114,13 +115,13 @@ public final class SettingsPage extends SettingsView implements DecoratorPage {
// ==== // ====
fileCommonLocation.loadChildren(Arrays.asList( fileCommonLocation.loadChildren(Arrays.asList(
fileCommonLocation.createChildren(i18n("launcher.common_directory.default"), EnumCommonDirectory.DEFAULT) fileCommonLocation.createChildren(i18n("launcher.cache_directory.default"), EnumCommonDirectory.DEFAULT)
), EnumCommonDirectory.CUSTOM); ), EnumCommonDirectory.CUSTOM);
fileCommonLocation.selectedDataProperty().bindBidirectional(config().commonDirTypeProperty()); fileCommonLocation.selectedDataProperty().bindBidirectional(config().commonDirTypeProperty());
fileCommonLocation.customTextProperty().bindBidirectional(config().commonDirectoryProperty()); fileCommonLocation.customTextProperty().bindBidirectional(config().commonDirectoryProperty());
fileCommonLocation.subtitleProperty().bind( fileCommonLocation.subtitleProperty().bind(
Bindings.createObjectBinding(() -> Optional.ofNullable(Settings.instance().getCommonDirectory()) Bindings.createObjectBinding(() -> Optional.ofNullable(Settings.instance().getCommonDirectory())
.orElse(i18n("launcher.common_directory.disabled")), .orElse(i18n("launcher.cache_directory.disabled")),
config().commonDirectoryProperty(), config().commonDirTypeProperty())); config().commonDirectoryProperty(), config().commonDirTypeProperty()));
// ==== Update ==== // ==== Update ====

View File

@@ -26,17 +26,16 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*; 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 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.EnumBackgroundImage;
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.construct.*; import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale; 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 { public abstract class SettingsView extends StackPane {
protected final JFXTextField txtProxyHost; protected final JFXTextField txtProxyHost;
protected final JFXTextField txtProxyPort; protected final JFXTextField txtProxyPort;
@@ -144,9 +143,9 @@ public abstract class SettingsView extends StackPane {
{ {
fileCommonLocation = new MultiFileItem<>(true); fileCommonLocation = new MultiFileItem<>(true);
fileCommonLocation.setTitle(i18n("launcher.common_directory")); fileCommonLocation.setTitle(i18n("launcher.cache_directory"));
fileCommonLocation.setDirectory(true); fileCommonLocation.setDirectory(true);
fileCommonLocation.setChooserTitle(i18n("launcher.common_directory.choose")); fileCommonLocation.setChooserTitle(i18n("launcher.cache_directory.choose"));
fileCommonLocation.setHasSubtitle(true); fileCommonLocation.setHasSubtitle(true);
fileCommonLocation.setCustomText("settings.custom"); fileCommonLocation.setCustomText("settings.custom");

View File

@@ -167,10 +167,11 @@ launcher=Launcher
launcher.background=Background Image launcher.background=Background Image
launcher.background.choose=Choose background path. launcher.background.choose=Choose background path.
launcher.background.default=Default launcher.background.default=Default
launcher.common_directory=Download Cache Directory launcher.cache_directory=Download Cache Directory
launcher.common_directory.choose=Choose download cache directory launcher.cache_directory.choose=Choose download cache directory
launcher.common_directory.default=Default launcher.cache_directory.default=Default
launcher.common_directory.disabled=Disabled launcher.cache_directory.disabled=Disabled
launcher.cache_directory.invalid=Invalid cache directory. Restore default settings.
launcher.contact=Contact Us launcher.contact=Contact Us
launcher.crash=Hello Minecraft! Launcher has crashed! launcher.crash=Hello Minecraft! Launcher has crashed!
launcher.crash_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it! launcher.crash_out_dated=Hello Minecraft! Launcher has crashed! Your launcher is outdated. Update it!

View File

@@ -167,10 +167,11 @@ launcher=啟動器
launcher.background=背景位址 launcher.background=背景位址
launcher.background.choose=選擇背景路徑 launcher.background.choose=選擇背景路徑
launcher.background.default=預設(自動尋找啟動器同目錄下的 background.png/jpg 及 bg 資料夾內的圖片) launcher.background.default=預設(自動尋找啟動器同目錄下的 background.png/jpg 及 bg 資料夾內的圖片)
launcher.common_directory=檔案下載緩存目錄 launcher.cache_directory=檔案下載快取目錄
launcher.common_directory.choose=選擇檔案下載緩存目錄 launcher.cache_directory.choose=選擇檔案下載快取目錄
launcher.common_directory.default=預設 launcher.cache_directory.default=預設
launcher.common_directory.disabled=停用 launcher.cache_directory.disabled=停用
launcher.cache_directory.invalid=無法創建自訂的快取目錄,恢復預設設定
launcher.contact=聯絡我們 launcher.contact=聯絡我們
launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤,請複製下列內容並透過 MCBBS、貼吧、GitHub 或 Minecraft Forum 回報 bug。 launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤,請複製下列內容並透過 MCBBS、貼吧、GitHub 或 Minecraft Forum 回報 bug。
launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤,已偵測到您的啟動器不是最新版本,請更新後重試! launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤,已偵測到您的啟動器不是最新版本,請更新後重試!

View File

@@ -167,10 +167,11 @@ launcher=启动器
launcher.background=背景地址 launcher.background=背景地址
launcher.background.choose=选择背景路径 launcher.background.choose=选择背景路径
launcher.background.default=默认(自动检索启动器同目录下的 background.png/jpg 及 bg 文件夹内的图片) launcher.background.default=默认(自动检索启动器同目录下的 background.png/jpg 及 bg 文件夹内的图片)
launcher.common_directory=文件下载缓存目录 launcher.cache_directory=文件下载缓存目录
launcher.common_directory.choose=选择文件下载缓存目录 launcher.cache_directory.choose=选择文件下载缓存目录
launcher.common_directory.default=默认(%AppData%/.minecraft 或者 ~/.minecraft launcher.cache_directory.default=默认(%AppData%/.minecraft 或者 ~/.minecraft
launcher.common_directory.disabled=禁用(总是使用游戏路径) launcher.cache_directory.disabled=禁用(总是使用游戏路径)
launcher.cache_directory.invalid=无法创建自定义的缓存目录,恢复默认设置
launcher.contact=联系我们 launcher.contact=联系我们
launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误,请复制下列内容并通过 MCBBS、贴吧、GitHub 或 Minecraft Forum 反馈 bug。 launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误,请复制下列内容并通过 MCBBS、贴吧、GitHub 或 Minecraft Forum 反馈 bug。
launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试! launcher.crash_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误,已检测到您的启动器不是最新版本,请更新后再试!

View File

@@ -17,6 +17,9 @@
*/ */
package org.jackhuang.hmcl.util.io; 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.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@@ -28,9 +31,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
/** /**
@@ -42,6 +42,37 @@ public final class FileUtils {
private 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) { public static String getNameWithoutExtension(File file) {
return StringUtils.substringBeforeLast(file.getName(), '.'); return StringUtils.substringBeforeLast(file.getName(), '.');
} }