diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index 4c1c1c979..7d6f14a8e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -26,7 +26,6 @@ import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.util.*; -import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.platform.OperatingSystem; import java.io.File; @@ -74,19 +73,14 @@ public final class Launcher extends Application { public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler(CRASH_REPORTER); - if (!FileUtils.makeDirectory(LOG_DIRECTORY)) - System.out.println("Unable to create log directory " + LOG_DIRECTORY + ", log files cannot be generated."); - try { - Logging.start(LOG_DIRECTORY); - LOG.info("*** " + Metadata.TITLE + " ***"); LOG.info("Operating System: " + System.getProperty("os.name") + ' ' + OperatingSystem.SYSTEM_VERSION); 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 Home: " + System.getProperty("java.home")); LOG.info("Current Directory: " + Paths.get("").toAbsolutePath()); - LOG.info("HMCL Directory: " + HMCL_DIRECTORY); + LOG.info("HMCL Directory: " + Metadata.HMCL_DIRECTORY); LOG.info("Memory: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB"); ManagementFactory.getMemoryPoolMXBeans().stream().filter(bean -> bean.getName().equals("Metaspace")).findAny() .ifPresent(bean -> LOG.info("Metaspace: " + bean.getUsage().getUsed() / 1024 / 1024 + "MB")); @@ -143,9 +137,5 @@ public final class Launcher extends Application { return result; } - public static final File MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft"); - public static final File HMCL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl"); - public static final File LOG_DIRECTORY = new File(Launcher.HMCL_DIRECTORY, "logs"); - public static final CrashReporter CRASH_REPORTER = new CrashReporter(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java index de4f9d48f..943ff389c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Main.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Main.java @@ -18,6 +18,8 @@ package org.jackhuang.hmcl; import org.jackhuang.hmcl.upgrade.UpdateHandler; +import org.jackhuang.hmcl.util.Logging; + import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; @@ -42,6 +44,8 @@ public final class Main { checkDirectoryPath(); checkDSTRootCAX3(); + Logging.start(Metadata.HMCL_DIRECTORY.resolve("logs")); + if (UpdateHandler.processArguments(args)) { return; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java b/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java index 9f819bd48..ba20571e5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java @@ -17,7 +17,10 @@ */ package org.jackhuang.hmcl; +import java.nio.file.Path; + import org.jackhuang.hmcl.util.io.JarUtils; +import org.jackhuang.hmcl.util.platform.OperatingSystem; /** * Stores metadata about this application. @@ -33,4 +36,7 @@ public final class Metadata { public static final String CONTACT_URL = "https://hmcl.huangyuhui.net/contact"; public static final String HELP_URL = "https://hmcl.huangyuhui.net/help"; public static final String PUBLISH_URL = "http://www.mcbbs.net/thread-142335-1-1.html"; + + public static final Path MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft"); + public static final Path HMCL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl"); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java index 0f2934c38..f4913b264 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/AccountHelper.java @@ -19,7 +19,7 @@ package org.jackhuang.hmcl.game; import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; -import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.yggdrasil.GameProfile; import org.jackhuang.hmcl.auth.yggdrasil.Texture; @@ -41,7 +41,7 @@ public final class AccountHelper { private AccountHelper() {} - public static final File SKIN_DIR = new File(Launcher.HMCL_DIRECTORY, "skins"); + public static final File SKIN_DIR = Metadata.HMCL_DIRECTORY.resolve("skins").toFile(); public static void loadSkins() { for (Account account : Accounts.getAccounts()) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java index 794c1da90..92fbb985b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java @@ -23,7 +23,7 @@ import javafx.beans.property.ReadOnlyListProperty; import javafx.beans.property.ReadOnlyListWrapper; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ObservableList; -import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.AccountFactory; import org.jackhuang.hmcl.auth.AuthenticationException; @@ -61,7 +61,7 @@ public final class Accounts { public static final OfflineAccountFactory FACTORY_OFFLINE = OfflineAccountFactory.INSTANCE; public static final YggdrasilAccountFactory FACTORY_YGGDRASIL = new YggdrasilAccountFactory(MojangYggdrasilProvider.INSTANCE); public static final AuthlibInjectorAccountFactory FACTORY_AUTHLIB_INJECTOR = new AuthlibInjectorAccountFactory( - new AuthlibInjectorDownloader(Launcher.HMCL_DIRECTORY.toPath(), DownloadProviders::getDownloadProvider)::getArtifactInfo, + new AuthlibInjectorDownloader(Metadata.HMCL_DIRECTORY, DownloadProviders::getDownloadProvider)::getArtifactInfo, Accounts::getOrCreateAuthlibInjectorServer); private static final String TYPE_OFFLINE = "offline"; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index 94e02d81a..19598fb6c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -32,7 +32,7 @@ import org.hildan.fxgson.creators.ObservableListCreator; import org.hildan.fxgson.creators.ObservableMapCreator; import org.hildan.fxgson.creators.ObservableSetCreator; import org.hildan.fxgson.factories.JavaFxPropertyTypeAdapterFactory; -import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; import org.jackhuang.hmcl.upgrade.UpdateChannel; import org.jackhuang.hmcl.util.gson.EnumOrdinalDeserializer; @@ -86,7 +86,7 @@ public final class Config implements Cloneable, Observable { private ObjectProperty commonDirType = new SimpleObjectProperty<>(EnumCommonDirectory.DEFAULT); @SerializedName("commonpath") - private StringProperty commonDirectory = new SimpleStringProperty(Launcher.MINECRAFT_DIRECTORY.getAbsolutePath()); + private StringProperty commonDirectory = new SimpleStringProperty(Metadata.MINECRAFT_DIRECTORY.toString()); @SerializedName("hasProxy") private BooleanProperty hasProxy = new SimpleBooleanProperty(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java index 4d10e2d8f..62fb54f74 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Profiles.java @@ -22,7 +22,7 @@ import javafx.application.Platform; import javafx.beans.Observable; import javafx.beans.property.*; import javafx.collections.ObservableList; -import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.RefreshedVersionsEvent; @@ -104,7 +104,7 @@ public final class Profiles { private static void checkProfiles() { if (profiles.isEmpty()) { Profile current = new Profile(Profiles.DEFAULT_PROFILE, new File(".minecraft"), new VersionSetting(), null, true); - Profile home = new Profile(Profiles.HOME_PROFILE, Launcher.MINECRAFT_DIRECTORY); + Profile home = new Profile(Profiles.HOME_PROFILE, Metadata.MINECRAFT_DIRECTORY.toFile()); Platform.runLater(() -> profiles.addAll(current, home)); } } 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 065c165df..1f46804ab 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java @@ -18,7 +18,7 @@ package org.jackhuang.hmcl.setting; import javafx.beans.binding.Bindings; -import org.jackhuang.hmcl.Launcher; +import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.HMCLCacheRepository; import org.jackhuang.hmcl.util.CacheRepository; @@ -64,7 +64,7 @@ public class Settings { } public static String getDefaultCommonDirectory() { - return Launcher.MINECRAFT_DIRECTORY.getAbsolutePath(); + return Metadata.MINECRAFT_DIRECTORY.toString(); } public String getCommonDirectory() { 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 bbe91a370..4215829c8 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -177,7 +177,7 @@ public final class Controllers { HMCLGameRepository repository = profile.getRepository(); List children = repository.getVersions().parallelStream() .filter(version -> !version.isHidden()) - .sorted(Comparator.comparing((Version version) -> version.getReleaseTime() == null ? new Date() : version.getReleaseTime()) + .sorted(Comparator.comparing((Version version) -> version.getReleaseTime() == null ? new Date(0L) : version.getReleaseTime()) .thenComparing(a -> VersionNumber.asVersion(a.getId()))) .map(version -> { Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId())); 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 44b0789e5..367bcf58d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsPage.java @@ -28,24 +28,35 @@ import javafx.beans.property.*; import javafx.scene.control.ToggleGroup; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.setting.*; +import org.jackhuang.hmcl.ui.construct.MessageBox; import org.jackhuang.hmcl.ui.construct.Validator; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.upgrade.RemoteVersion; import org.jackhuang.hmcl.upgrade.UpdateChannel; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; +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.io.IOException; import java.net.Proxy; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.Collections; import java.util.Optional; +import java.util.logging.Level; import static org.jackhuang.hmcl.setting.ConfigHolder.config; +import static org.jackhuang.hmcl.util.Lang.thread; +import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.reservedSelectedPropertyFor; import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor; @@ -202,8 +213,29 @@ public final class SettingsPage extends SettingsView implements DecoratorPage { } @Override - protected void onOpenLogFolder() { - FXUtils.openFolder(Launcher.LOG_DIRECTORY); + protected void onExportLogs() { + // We cannot determine which file is JUL using. + // So we write all the logs to a new file. + thread(() -> { + Path logFile = Paths.get("hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".log").toAbsolutePath(); + + LOG.info("Exporting logs to " + logFile); + try { + Files.write(logFile, Logging.getRawLogs()); + } catch (IOException e) { + Platform.runLater(() -> Controllers.dialog(i18n("settings.launcher.launcher_log.export.failed") + "\n" + e, null, MessageBox.ERROR_MESSAGE)); + LOG.log(Level.WARNING, "Failed to export logs", e); + return; + } + + Platform.runLater(() -> Controllers.dialog(i18n("settings.launcher.launcher_log.export.success", logFile))); + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().open(logFile.toFile()); + } catch (IOException ignored) { + } + } + }); } @Override 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 5a418b9a8..362b35ba4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SettingsView.java @@ -35,7 +35,6 @@ 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.I18n; import org.jackhuang.hmcl.util.i18n.Locales.SupportedLocale; public abstract class SettingsView extends StackPane { @@ -337,8 +336,8 @@ public abstract class SettingsView extends StackPane { logPane.setTitle(i18n("settings.launcher.log")); { - JFXButton logButton = new JFXButton(i18n("settings.launcher.log.dir")); - logButton.setOnMouseClicked(e -> onOpenLogFolder()); + JFXButton logButton = new JFXButton(i18n("settings.launcher.launcher_log.export")); + logButton.setOnMouseClicked(e -> onExportLogs()); logButton.getStyleClass().setAll("jfx-button-border"); logPane.setHeaderRight(logButton); @@ -492,5 +491,5 @@ public abstract class SettingsView extends StackPane { protected abstract void onUpdate(); protected abstract void onHelp(); - protected abstract void onOpenLogFolder(); + protected abstract void onExportLogs(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateHandler.java b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateHandler.java index 92ac5e7ee..a3410fa41 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateHandler.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/UpdateHandler.java @@ -21,7 +21,6 @@ import com.google.gson.Gson; import com.google.gson.JsonParseException; import javafx.application.Platform; import javafx.scene.layout.Region; -import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Main; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.task.Task; @@ -231,7 +230,7 @@ public final class UpdateHandler { private static boolean isFirstLaunchAfterUpgrade() { Optional currentPath = JarUtils.thisJar(); if (currentPath.isPresent()) { - Path updated = Launcher.HMCL_DIRECTORY.toPath().resolve("HMCL-" + Metadata.VERSION + ".jar"); + Path updated = Metadata.HMCL_DIRECTORY.resolve("HMCL-" + Metadata.VERSION + ".jar"); if (currentPath.get().toAbsolutePath().equals(updated.toAbsolutePath())) { return true; } @@ -240,7 +239,7 @@ public final class UpdateHandler { } private static void breakForceUpdateFeature() { - Path hmclVersionJson = Launcher.HMCL_DIRECTORY.toPath().resolve("hmclver.json"); + Path hmclVersionJson = Metadata.HMCL_DIRECTORY.resolve("hmclver.json"); if (Files.isRegularFile(hmclVersionJson)) { try { Map content = new Gson().fromJson(new String(Files.readAllBytes(hmclVersionJson), UTF_8), Map.class); diff --git a/HMCL/src/main/resources/assets/fxml/account-add.fxml b/HMCL/src/main/resources/assets/fxml/account-add.fxml index 77ae0c6f4..857a4c846 100644 --- a/HMCL/src/main/resources/assets/fxml/account-add.fxml +++ b/HMCL/src/main/resources/assets/fxml/account-add.fxml @@ -67,10 +67,12 @@ diff --git a/HMCL/src/main/resources/assets/fxml/authlib-injector-server-add.fxml b/HMCL/src/main/resources/assets/fxml/authlib-injector-server-add.fxml index 6065f6fe1..cfaad4439 100644 --- a/HMCL/src/main/resources/assets/fxml/authlib-injector-server-add.fxml +++ b/HMCL/src/main/resources/assets/fxml/authlib-injector-server-add.fxml @@ -19,10 +19,12 @@ diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index d40862059..f2478bb93 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -326,9 +326,11 @@ settings.launcher.common_path.tooltip=This app will save all game libraries and settings.launcher.download_source=Download Source settings.launcher.enable_game_list=Display game list in main page settings.launcher.language=Language +settings.launcher.launcher_log.export=Export launcher logs +settings.launcher.launcher_log.export.failed=Failed to export logs +settings.launcher.launcher_log.export.success=Logs have been exported to %s settings.launcher.log=Log settings.launcher.log.font=Log Font -settings.launcher.log.dir=Open Log Directory settings.launcher.proxy=Proxy settings.launcher.proxy.authentication=Proxy Authentication settings.launcher.proxy.disable=Use system proxies diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index ae40dd7c8..ebaa9cce9 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -326,9 +326,11 @@ settings.launcher.common_path.tooltip=啟動器將所有遊戲資源及依賴庫 settings.launcher.download_source=下載來源 settings.launcher.enable_game_list=在首頁內顯示遊戲列表 settings.launcher.language=語言 +settings.launcher.launcher_log.export=導出啟動器日誌 +settings.launcher.launcher_log.export.failed=無法導出日誌 +settings.launcher.launcher_log.export.success=日誌已保存到 %s settings.launcher.log=記錄 settings.launcher.log.font=記錄字體 -settings.launcher.log.dir=打開記錄資料夾 settings.launcher.proxy=代理 settings.launcher.proxy.authentication=身份驗證 settings.launcher.proxy.disable=使用系統代理 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 7674b41e1..afb20d57c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -326,9 +326,11 @@ settings.launcher.common_path.tooltip=启动器将所有游戏资源及依赖库 settings.launcher.download_source=下载源 settings.launcher.enable_game_list=在主页内显示游戏列表 settings.launcher.language=语言 +settings.launcher.launcher_log.export=导出启动器日志 +settings.launcher.launcher_log.export.failed=无法导出日志 +settings.launcher.launcher_log.export.success=日志已保存到 %s settings.launcher.log=日志 settings.launcher.log.font=日志字体 -settings.launcher.log.dir=打开日志文件夹 settings.launcher.proxy=代理 settings.launcher.proxy.authentication=身份验证 settings.launcher.proxy.disable=使用系统代理 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java index dc2414a0a..88df70611 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/DefaultCacheRepository.java @@ -43,7 +43,7 @@ public class DefaultCacheRepository extends CacheRepository { private Index index = null; public DefaultCacheRepository() { - this(OperatingSystem.getWorkingDirectory("minecraft").toPath()); + this(OperatingSystem.getWorkingDirectory("minecraft")); } public DefaultCacheRepository(Path commonDirectory) { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Logging.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Logging.java index 48aaa276f..61c1e4640 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Logging.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Logging.java @@ -18,9 +18,10 @@ package org.jackhuang.hmcl.util; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.*; @@ -31,20 +32,16 @@ import java.util.logging.*; */ public final class Logging { - public static final Logger LOG; - private static final ByteArrayOutputStream OUTPUT_STREAM = new ByteArrayOutputStream(); + public static final Logger LOG = Logger.getLogger("HMCL"); + private static ByteArrayOutputStream storedLogs = new ByteArrayOutputStream(); - static { - LOG = Logger.getLogger("HMCL"); - } - - public static void start(File logFolder) { - LOG.setLevel(Level.FINER); + public static void start(Path logFolder) { + LOG.setLevel(Level.ALL); LOG.setUseParentHandlers(false); try { - FileHandler fileHandler = new FileHandler(new File(logFolder, "hmcl.log").getAbsolutePath()); - fileHandler.setLevel(Level.FINEST); + Files.createDirectories(logFolder); + FileHandler fileHandler = new FileHandler(logFolder.resolve("hmcl.log").toAbsolutePath().toString()); fileHandler.setFormatter(DefaultFormatter.INSTANCE); LOG.addHandler(fileHandler); } catch (IOException e) { @@ -52,31 +49,28 @@ public final class Logging { } ConsoleHandler consoleHandler = new ConsoleHandler(); - consoleHandler.setLevel(Level.FINER); consoleHandler.setFormatter(DefaultFormatter.INSTANCE); LOG.addHandler(consoleHandler); - StreamHandler streamHandler = new StreamHandler(OUTPUT_STREAM, DefaultFormatter.INSTANCE) { + StreamHandler streamHandler = new StreamHandler(storedLogs, DefaultFormatter.INSTANCE) { @Override public synchronized void publish(LogRecord record) { super.publish(record); flush(); } }; - streamHandler.setLevel(Level.FINEST); LOG.addHandler(streamHandler); } - public static void stop() { - for (Handler handler : LOG.getHandlers()) - LOG.removeHandler(handler); + public static byte[] getRawLogs() { + return storedLogs.toByteArray(); } public static String getLogs() { - return OUTPUT_STREAM.toString(); + return storedLogs.toString(); } - static final class DefaultFormatter extends Formatter { + private static final class DefaultFormatter extends Formatter { static final DefaultFormatter INSTANCE = new DefaultFormatter(); private final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss"); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java index 4621fe0b4..84f732e16 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java @@ -17,9 +17,6 @@ */ package org.jackhuang.hmcl.util.platform; -import javafx.scene.input.Clipboard; -import javafx.scene.input.ClipboardContent; - import javax.management.JMException; import javax.management.MBeanServer; import javax.management.ObjectName; @@ -29,6 +26,8 @@ import org.jackhuang.hmcl.util.Lang; import java.io.File; import java.lang.management.ManagementFactory; import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Locale; import java.util.Optional; @@ -135,30 +134,24 @@ public enum OperatingSystem { return Optional.empty(); } - public static void setClipboard(String string) { - ClipboardContent c = new ClipboardContent(); - c.putString(string); - Clipboard.getSystemClipboard().setContent(c); - } - public static void forceGC() { System.gc(); System.runFinalization(); System.gc(); } - public static File getWorkingDirectory(String folder) { + public static Path getWorkingDirectory(String folder) { String home = System.getProperty("user.home", "."); switch (OperatingSystem.CURRENT_OS) { case LINUX: - return new File(home, "." + folder + "/"); + return Paths.get(home, "." + folder); case WINDOWS: String appdata = System.getenv("APPDATA"); - return new File(Lang.nonNull(appdata, home), "." + folder + "/"); + return Paths.get(Lang.nonNull(appdata, home), "." + folder); case OSX: - return new File(home, "Library/Application Support/" + folder); + return Paths.get(home, "Library", "Application Support", folder); default: - return new File(home, folder + "/"); + return Paths.get(home, folder); } } }