From 58876b11357f7f02e2b0ef4267a47b445ab288e6 Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 10:11:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?<10>=20=E6=84=BF=E6=AD=A4=E7=94=9F=E8=8B=A5?= =?UTF-8?q?=E5=8F=AA=E5=A6=82=E5=88=9D=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackhuang/hmcl/countly/CrashReport.java | 46 +++++--------- .../org/jackhuang/hmcl/ui/CrashWindow.java | 31 ++++++---- .../org/jackhuang/hmcl/ui/main/MainPage.java | 5 +- .../jackhuang/hmcl/util/CrashReporter.java | 61 ++----------------- .../resources/assets/lang/I18N.properties | 5 -- .../resources/assets/lang/I18N_ar.properties | 5 -- .../resources/assets/lang/I18N_de.properties | 5 -- .../resources/assets/lang/I18N_es.properties | 5 -- .../resources/assets/lang/I18N_ja.properties | 5 -- .../resources/assets/lang/I18N_lzh.properties | 2 - .../resources/assets/lang/I18N_ru.properties | 5 -- .../resources/assets/lang/I18N_uk.properties | 5 -- .../resources/assets/lang/I18N_zh.properties | 5 -- .../assets/lang/I18N_zh_CN.properties | 5 -- .../org/jackhuang/hmcl/util/StringUtils.java | 2 +- 15 files changed, 45 insertions(+), 147 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/countly/CrashReport.java b/HMCL/src/main/java/org/jackhuang/hmcl/countly/CrashReport.java index 8ab8260fc4e..71ec791dc27 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/countly/CrashReport.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/countly/CrashReport.java @@ -18,29 +18,13 @@ package org.jackhuang.hmcl.countly; import org.jackhuang.hmcl.Metadata; -import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.platform.Architecture; import org.jackhuang.hmcl.util.platform.OperatingSystem; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -public class CrashReport { - - private final Thread thread; - private final Throwable throwable; - private final String stackTrace; - - public CrashReport(Thread thread, Throwable throwable) { - this.thread = thread; - this.throwable = throwable; - stackTrace = StringUtils.getStackTrace(throwable); - } - - public Throwable getThrowable() { - return this.throwable; - } - +public record CrashReport(Thread thread, Throwable throwable, String stackTrace) { public boolean shouldBeReport() { if (!stackTrace.contains("org.jackhuang")) return false; @@ -52,20 +36,20 @@ public boolean shouldBeReport() { } public String getDisplayText() { - return "---- Hello Minecraft! Crash Report ----\n" + - " Version: " + Metadata.VERSION + "\n" + - " Time: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + "\n" + - " Thread: " + thread + "\n" + - "\n Content: \n " + - stackTrace + "\n\n" + + return "---- Hello Minecraft! Launcher Crash Report ----\n" + + "Version: " + Metadata.VERSION + "\n" + + "Time: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + "\n" + + "Thread: " + thread + "\n" + + "\nContent: \n" + + stackTrace + "\n" + "-- System Details --\n" + - " Operating System: " + OperatingSystem.SYSTEM_NAME + ' ' + OperatingSystem.SYSTEM_VERSION.getVersion() + "\n" + - " System Architecture: " + Architecture.SYSTEM_ARCH.getDisplayName() + "\n" + - " Java Architecture: " + Architecture.CURRENT_ARCH.getDisplayName() + "\n" + - " Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor") + "\n" + - " Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor") + "\n" + - " JVM Max Memory: " + Runtime.getRuntime().maxMemory() + "\n" + - " JVM Total Memory: " + Runtime.getRuntime().totalMemory() + "\n" + - " JVM Free Memory: " + Runtime.getRuntime().freeMemory() + "\n"; + "Operating System: " + OperatingSystem.SYSTEM_NAME + ' ' + OperatingSystem.SYSTEM_VERSION.getVersion() + "\n" + + "System Architecture: " + Architecture.SYSTEM_ARCH.getDisplayName() + "\n" + + "Java Architecture: " + Architecture.CURRENT_ARCH.getDisplayName() + "\n" + + "Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor") + "\n" + + "Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor") + "\n" + + "JVM Max Memory: " + Runtime.getRuntime().maxMemory() + "\n" + + "JVM Total Memory: " + Runtime.getRuntime().totalMemory() + "\n" + + "JVM Free Memory: " + Runtime.getRuntime().freeMemory() + "\n"; } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java index 5af27b6a601..66901372adb 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java @@ -17,6 +17,7 @@ */ package org.jackhuang.hmcl.ui; +import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -29,6 +30,7 @@ import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.countly.CrashReport; import org.jackhuang.hmcl.upgrade.UpdateChecker; +import org.jackhuang.hmcl.util.Lazy; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -36,20 +38,18 @@ * @author huangyuhui */ public class CrashWindow extends Stage { + private static final Lazy instance = new Lazy<>(CrashWindow::new); + private final TextArea textArea = new TextArea(); - public CrashWindow(CrashReport report) { + private CrashWindow() { Label lblCrash = new Label(); - if (report.getThrowable() instanceof InternalError) - lblCrash.setText(i18n("launcher.crash.java_internal_error")); - else if (UpdateChecker.isOutdated()) - lblCrash.setText(i18n("launcher.crash.hmcl_out_dated")); - else - lblCrash.setText(i18n("launcher.crash")); lblCrash.setWrapText(true); - TextArea textArea = new TextArea(); - textArea.setText(report.getDisplayText()); - textArea.setEditable(false); + if (UpdateChecker.isOutdated()) { + lblCrash.setText(i18n("launcher.crash.hmcl_out_dated")); + } else { + lblCrash.setText(i18n("launcher.crash")); + } Button btnContact = new Button(); btnContact.setText(i18n("launcher.contact")); @@ -72,7 +72,16 @@ else if (UpdateChecker.isOutdated()) FXUtils.setIcon(this); setTitle(i18n("message.error")); - setOnCloseRequest(e -> javafx.application.Platform.exit()); + setOnCloseRequest(e -> Platform.exit()); } + public static CrashWindow getInstance() { + return instance.get(); + } + + public void addCrashReport(CrashReport report) { + textArea.setText(textArea.getText() + "\n\n" + report.getDisplayText()); + textArea.setEditable(false); + this.requestFocus(); + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java index 52c32536af8..0c274e7ecc1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java @@ -44,8 +44,8 @@ import javafx.scene.text.TextFlow; import javafx.util.Duration; import org.jackhuang.hmcl.Metadata; -import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.ComponentVersionList; +import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.game.*; import org.jackhuang.hmcl.setting.DownloadProviders; import org.jackhuang.hmcl.setting.GameDirectoryManager; @@ -259,6 +259,9 @@ public void accept(@Nullable HMCLGameInstance currentGame) { if (tooltip != null) Tooltip.uninstall(launchButton, tooltip); } + launchButton.setOnAction((e) -> { + throw new AssertionError(); + }); } }); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/CrashReporter.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/CrashReporter.java index 7cd54164d45..558c1e92196 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/util/CrashReporter.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/CrashReporter.java @@ -18,63 +18,15 @@ package org.jackhuang.hmcl.util; import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; import org.jackhuang.hmcl.countly.CrashReport; -import org.jackhuang.hmcl.setting.SettingsManager; import org.jackhuang.hmcl.ui.CrashWindow; -import static org.jackhuang.hmcl.util.Pair.pair; -import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.logging.Logger.LOG; /** * @author huangyuhui */ public final class CrashReporter implements Thread.UncaughtExceptionHandler { - - // Lazy initialization resources - private static final class Hole { - @SuppressWarnings("unchecked") - static final Pair[] SOURCE = (Pair[]) new Pair[]{ - pair("Location is not set", i18n("crash.NoClassDefFound")), - pair("UnsatisfiedLinkError", i18n("crash.user_fault")), - pair("java.time.zone.ZoneRulesException: Unable to load TZDB time-zone rules", i18n("crash.user_fault")), - pair("java.lang.NoClassDefFoundError", i18n("crash.NoClassDefFound")), - pair("org.jackhuang.hmcl.util.ResourceNotFoundError", i18n("crash.NoClassDefFound")), - pair("java.lang.VerifyError", i18n("crash.NoClassDefFound")), - pair("java.lang.NoSuchMethodError", i18n("crash.NoClassDefFound")), - pair("java.lang.NoSuchFieldError", i18n("crash.NoClassDefFound")), - pair("javax.imageio.IIOException", i18n("crash.NoClassDefFound")), - pair("netscape.javascript.JSException", i18n("crash.NoClassDefFound")), - pair("java.lang.IncompatibleClassChangeError", i18n("crash.NoClassDefFound")), - pair("java.lang.ClassFormatError", i18n("crash.NoClassDefFound")), - pair("com.sun.javafx.css.StyleManager.findMatchingStyles", i18n("launcher.update_java")), - pair("NoSuchAlgorithmException", "Has your operating system been installed completely or is a ghost system?") - }; - } - - private boolean checkThrowable(Throwable e) { - String s = StringUtils.getStackTrace(e); - for (Pair entry : Hole.SOURCE) - if (s.contains(entry.getKey())) { - if (StringUtils.isNotBlank(entry.getValue())) { - String info = entry.getValue(); - LOG.error(info); - try { - Alert alert = new Alert(AlertType.INFORMATION, info); - alert.setTitle(i18n("message.info")); - alert.setHeaderText(i18n("message.info")); - alert.showAndWait(); - } catch (Throwable t) { - LOG.error("Unable to show message", t); - } - } - return false; - } - return true; - } - private final boolean showCrashWindow; public CrashReporter(boolean showCrashWindow) { @@ -86,23 +38,20 @@ public void uncaughtException(Thread t, Throwable e) { LOG.error("Uncaught exception in thread " + t.getName(), e); try { - CrashReport report = new CrashReport(t, e); + CrashReport report = new CrashReport(t, e, StringUtils.getStackTrace(e)); if (!report.shouldBeReport()) return; LOG.error(report.getDisplayText()); Platform.runLater(() -> { - if (checkThrowable(e)) { - if (showCrashWindow) { - new CrashWindow(report).show(); - } + if (showCrashWindow) { + var window = CrashWindow.getInstance(); + window.addCrashReport(report); + window.show(); } }); } catch (Throwable handlingException) { LOG.error("Unable to handle uncaught exception", handlingException); } - - SettingsManager.shutdown(); - LOG.shutdown(); } } diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 672b254bb31..ac12860d357 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -239,9 +239,6 @@ contact.feedback.github.statement=Submit an issue on GitHub. color.recent=Recommended color.custom=Custom Color -crash.NoClassDefFound=Please verify the integrity of this software, or try updating your Java. -crash.user_fault=The launcher crashed due to corrupted Java or system environment. Please make sure your Java or OS is installed properly. - curse.category.0=All # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -957,8 +954,6 @@ launcher.contact=Contact Us launcher.crash=Hello Minecraft! Launcher has encountered a fatal error! Please copy the following log and ask for help on our Discord, QQ group, GitHub, or other Minecraft forum. launcher.crash.java_internal_error=Hello Minecraft! Launcher has encountered a fatal error because your Java is corrupted. Please uninstall your Java and download a suitable Java here. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher has encountered a fatal error! Your launcher is outdated. Please update your launcher! -launcher.update_java=Please update your Java version. - libraries.download=Downloading Libraries login.enter_password=Please enter your password. diff --git a/HMCL/src/main/resources/assets/lang/I18N_ar.properties b/HMCL/src/main/resources/assets/lang/I18N_ar.properties index 3b1e9c7f9a7..27b46937891 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ar.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ar.properties @@ -219,9 +219,6 @@ contact.feedback.github.statement=أرسل تقريراً عن مشكلة على color.recent=مقترح color.custom=لون مخصص -crash.NoClassDefFound=يُرجى التحقق من سلامة هذا البرنامج، أو محاولة تحديث Java. -crash.user_fault=تعطّل المشغّل بسبب تلف Java أو بيئة النظام. يُرجى التأكد من تثبيت Java أو نظام التشغيل بشكل صحيح. - curse.category.0=الكل # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -897,8 +894,6 @@ launcher.contact=تواصل معنا launcher.crash=واجه Hello Minecraft! Launcher خطأً فادحاً! يُرجى نسخ السجل التالي وطلب المساعدة على Discord أو مجموعة QQ أو GitHub أو أي منتدى Minecraft آخر. launcher.crash.java_internal_error=واجه Hello Minecraft! Launcher خطأً فادحاً بسبب تلف Java. يُرجى إلغاء تثبيت Java وتنزيل إصدار مناسب من هنا. launcher.crash.hmcl_out_dated=واجه Hello Minecraft! Launcher خطأً فادحاً! المشغّل قديم. يُرجى تحديثه! -launcher.update_java=يُرجى تحديث إصدار Java الخاص بك. - libraries.download=جارٍ تنزيل المكتبات login.enter_password=يُرجى إدخال كلمة المرور. diff --git a/HMCL/src/main/resources/assets/lang/I18N_de.properties b/HMCL/src/main/resources/assets/lang/I18N_de.properties index 059c0fe977a..ba10f9f2130 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_de.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_de.properties @@ -239,9 +239,6 @@ contact.feedback.github.statement=Reichen Sie ein Issue auf GitHub ein. color.recent=Empfohlen color.custom=Benutzerdefinierte Farbe -crash.NoClassDefFound=Bitte überprüfen Sie die Integrität dieser Software oder versuchen Sie, Ihr Java zu aktualisieren. -crash.user_fault=Der Launcher ist aufgrund einer beschädigten Java- oder Systemumgebung abgestürzt. Bitte stellen Sie sicher, dass Ihr Java oder Betriebssystem ordnungsgemäß installiert ist. - curse.category.0=Alle # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -954,8 +951,6 @@ launcher.contact=Kontaktiere uns launcher.crash=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen! Bitte kopieren Sie das folgende Protokoll und bitten Sie in unserem Discord, der QQ-Gruppe, auf GitHub oder in einem anderen Minecraft-Forum um Hilfe. launcher.crash.java_internal_error=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen, da Ihre Java-Installation beschädigt ist. Bitte deinstallieren Sie Java und laden Sie eine geeignete Java-Version hier herunter. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen! Ihr Launcher ist veraltet. Bitte aktualisieren Sie Ihren Launcher! -launcher.update_java=Bitte aktualisieren Sie Ihre Java-Version. - libraries.download=Bibliotheken werden heruntergeladen login.enter_password=Bitte geben Sie Ihr Passwort ein. diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 4d1c14ae69e..4d5d10934d7 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -199,9 +199,6 @@ contact.feedback.github.statement=Envíe una propuesta en GitHub. color.recent=Recomendado color.custom=Color personalizado -crash.NoClassDefFound=Por favor, verifique la integridad de este software, o intente actualizar su Java. -crash.user_fault=El launcher se ha bloqueado debido a que Java o el entorno del sistema están dañados. Por favor, asegúrese de que su Java o sistema operativo está instalado correctamente. - curse.category.0=Todos # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -850,8 +847,6 @@ launcher.contact=Contacta con nosotros launcher.crash=Hello Minecraft! Launcher ha encontrado un error fatal. Por favor, copie el siguiente registro y pida ayuda en nuestra comunidad en Discord, GitHub o Minecraft Forums. launcher.crash.java_internal_error=Hello Minecraft! Launcher ha encontrado un error fatal porque su Java está dañado. Por favor, desinstala tu Java y descarga un Java adecuado aquí. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher ha encontrado un error fatal. Su launcher está desactualizado. Por favor, ¡actualícelo! -launcher.update_java=Por favor, actualice su versión de Java. - libraries.download=Descargando bibliotecas login.enter_password=Por favor, introduzca su contraseña. diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index 5e4fb6d3c35..4eece774183 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -163,9 +163,6 @@ contact.feedback.github.statement=GitHubで問題を送信します。 color.recent=推奨 color.custom=カスタムカラー -crash.NoClassDefFound=このソフトウェアの整合性を確認するか、Javaの更新をお試しください。 -crash.user_fault=JavaまたはOSの環境が壊れているため、ランチャーがクラッシュしました。JavaまたはOSが正しくインストールされているかご確認ください。 - curse.category.0=全て # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -571,8 +568,6 @@ launcher.cache_directory.invalid=無効なディレクトリ。デフォルト launcher.contact=お問い合わせ launcher.crash=Hello Minecraft!ランチャーがクラッシュしました!次のコンテンツをコピーして、MCBBS、Baidu Tieba、GitHub、またはMinecraftForumを介してフィードバックを送信してください。 launcher.crash.hmcl_out_dated=Hello Minecraft!ランチャーがクラッシュしました!ランチャーが古くなっています。ランチャーを更新してください! -launcher.update_java=Javaを更新してください。 - login.enter_password=パスワードを入力してください。 logwindow.show_lines=行を表示 diff --git a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties index 2f517b58983..de2a967aebb 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_lzh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_lzh.properties @@ -199,7 +199,6 @@ contact.feedback=建言之徑 contact.feedback.github=Github 議題 contact.feedback.github.statement=舉一 Github 議題 -crash.NoClassDefFound=宜驗 HMCL 之案全否,抑更迭爪哇。\n君可求助於 https://docs.hmcl.net/help.html。 crash.user_fault=君之械網與爪哇或有謬,是以崩。宜驗爪哇與算機。\n君可求助於 https://docs.hmcl.net/help.html。 curse.category.0=一覽無遺 @@ -681,7 +680,6 @@ launcher.contact=伏惟候告 launcher.crash=HMCL 有謬而弗能正。宜鈔下文而報謬于右下之鈕。 launcher.crash.java_internal_error=HMCL 不能行,以爪哇壞也。宜去是爪哇,而擊以置爪哇之適者。 launcher.crash.hmcl_out_dated=HMCL 有謬而弗能正之。余識君之啟者舊矣,宜新之。 -launcher.update_java=宜迭更爪哇。\n君可求助於 https://docs.hmcl.net/help.html。 libraries.download=引之所依 diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 49735dfe6df..3180600d111 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -195,9 +195,6 @@ contact.feedback.github.statement=Отправить проблему на GitHu color.recent=Рекомендуемые color.custom=Пользовательский цвет -crash.NoClassDefFound=Проверьте целостность этого программного обеспечения или попробуйте обновить версию Java. -crash.user_fault=Лаунчер аварийно завершил работу из-за повреждения Java или системной среды. Убедитесь, что Java или ОС установлены правильно. - curse.category.0=Все # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -843,8 +840,6 @@ launcher.contact=Связаться с нами launcher.crash=Лаунчер столкнулся с фатальной ошибкой! Скопируйте следующий журнал и попросите помощи в нашем Discord, группе QQ, GitHub или на другом форуме Minecraft. launcher.crash.java_internal_error=Лаунчер столкнулся с фатальной ошибкой! Пожалуйста, удалите Java и скачайте подходящую Java здесь. launcher.crash.hmcl_out_dated=Лаунчер столкнулся с фатальной ошибкой! Ваш лаунчер устарел. Обновите его! -launcher.update_java=Пожалуйста, обновите версию Java. - libraries.download=Скачивание библиотек login.enter_password=Введите пароль. diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index 25044542c87..82517c969b5 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -244,9 +244,6 @@ contact.feedback.github.statement=Надіслати проблему на GitHu color.recent=Рекомендовані color.custom=Власний колір -crash.NoClassDefFound=Перевірте цілісність цього програмного забезпечення або спробуйте оновити Java. -crash.user_fault=Лаунчер зазнав збою через пошкоджене середовище Java або системи. Переконайтеся, що ваша Java або ОС встановлені належним чином. - curse.category.0=Усі curse.category.4474=Наукова фантастика @@ -915,8 +912,6 @@ launcher.contact=Зв'яжіться з нами launcher.crash=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою! Скопіюйте наступний журнал та попросіть допомоги на нашому Discord, групі QQ, GitHub або іншому форумі Minecraft. launcher.crash.java_internal_error=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою, оскільки ваша Java пошкоджена. Видаліть вашу Java та завантажте відповідну Java тут. launcher.crash.hmcl_out_dated=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою! Ваш лаунчер застарів. Оновіть ваш лаунчер! -launcher.update_java=Оновіть вашу версію Java. - libraries.download=Завантаження бібліотек login.enter_password=Введіть свій пароль. diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 48e4524a3da..7a3407109ef 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -237,9 +237,6 @@ contact.feedback.github.statement=提交一個 GitHub Issue color.recent=建議 color.custom=自訂顏色 -crash.NoClassDefFound=請確認 Hello Minecraft! Launcher 本體是否完整,或更新你的 Java。 -crash.user_fault=你的系統或 Java 環境可能安裝不當導致本軟體當機,請檢查你的 Java 環境或你的電腦!可以嘗試重新安裝 Java。 - curse.category.0=全部 # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -769,8 +766,6 @@ launcher.contact=聯絡我們 launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤。請複製下列內容並透過 GitHub、Discord 或 HMCL QQ 群回報問題。 launcher.crash.java_internal_error=Hello Minecraft! Launcher 由於目前 Java 損壞而無法繼續執行。請移除目前 Java,點擊 此處 安裝合適的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤。已偵測到你的啟動器不是最新版本,請更新後重試! -launcher.update_java=請更新你的 Java - libraries.download=下載依賴庫 login.enter_password=請輸入你的密碼 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 cc1c47a2dc5..e8ce302cf4c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -239,9 +239,6 @@ contact.chat.qq_group.statement=欢迎加入 HMCL 官方 QQ 群,加入后请 contact.chat.discord=Discord contact.chat.discord.statement=欢迎加入 Discord 服务器,加入后请遵守讨论区规定 -crash.NoClassDefFound=请确认 Hello Minecraft! Launcher 本体是否完整,或更新你的 Java。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。 -crash.user_fault=你的系统或 Java 环境可能安装不当导致本软件崩溃,请检查你的 Java 环境或你的电脑。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。 - curse.category.0=全部 # https://addons-ecs.forgesvc.net/api/v2/category/section/4471 @@ -775,8 +772,6 @@ launcher.contact=联系我们 launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误。请复制下列内容并点击右下角的按钮反馈问题。 launcher.crash.java_internal_error=Hello Minecraft! Launcher 由于当前 Java 损坏而无法继续运行。请卸载当前 Java,点击 此处 安装合适的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误。已检测到你的启动器不是最新版本,请更新后再试。 -launcher.update_java=请更新你的 Java。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。 - libraries.download=下载依赖库 login.enter_password=请输入你的密码 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java index af0cbf1ffe6..2833df0a543 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java @@ -58,7 +58,7 @@ public static String getStackTrace(Throwable throwable) { } public static String getStackTrace(StackTraceElement[] elements) { - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(512); for (StackTraceElement element : elements) builder.append("\tat ").append(element).append(System.lineSeparator()); return builder.toString(); From 1da304b4ea39d88ae56e8be7a88a28f9923a881b Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 10:37:01 +0800 Subject: [PATCH 2/6] =?UTF-8?q?<11>=20=E8=AF=AF=E6=8B=82=E5=BC=A6=E6=82=84?= =?UTF-8?q?=E6=82=84=E5=B0=86=E6=98=A5=E6=B0=B4=E5=90=B9=E7=9A=B1=20?= =?UTF-8?q?=E7=94=BB=E4=B8=AD=E4=BA=BA=E6=8A=8A=E9=9D=92=E6=A2=85=E5=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jackhuang/hmcl/ui/CrashWindow.java | 47 ++++- .../jackhuang/hmcl/ui/main/SettingsPage.java | 145 +-------------- .../hmcl/util/LauncherLogExporter.java | 170 ++++++++++++++++++ 3 files changed, 212 insertions(+), 150 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java index 66901372adb..b108810d06f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java @@ -20,9 +20,7 @@ import javafx.application.Platform; import javafx.geometry.Pos; import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextArea; +import javafx.scene.control.*; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; @@ -30,15 +28,26 @@ import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.countly.CrashReport; import org.jackhuang.hmcl.upgrade.UpdateChecker; +import org.jackhuang.hmcl.util.LauncherLogExporter; import org.jackhuang.hmcl.util.Lazy; +import org.jackhuang.hmcl.util.StringUtils; + +import java.io.IOException; +import java.nio.file.Path; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; /** * @author huangyuhui */ public class CrashWindow extends Stage { private static final Lazy instance = new Lazy<>(CrashWindow::new); + + public static CrashWindow getInstance() { + return instance.get(); + } + private final TextArea textArea = new TextArea(); private CrashWindow() { @@ -51,12 +60,37 @@ private CrashWindow() { lblCrash.setText(i18n("launcher.crash")); } + StackPane exportPane = new StackPane(); + ProgressIndicator progressIndicator = new ProgressIndicator(); + FXUtils.setLimitHeight(progressIndicator, 20); + + Button btnExport = new Button(); + exportPane.getChildren().setAll(btnExport); + btnExport.setText(i18n("settings.launcher.launcher_log.export")); + btnExport.setOnAction(event -> { + exportPane.getChildren().setAll(progressIndicator); + try { + Path path = LauncherLogExporter.exportLogsAsZip(); + FXUtils.showFileInExplorer(path); + Alert alert = new Alert(Alert.AlertType.INFORMATION, i18n("settings.launcher.launcher_log.export.success", path)); + alert.setTitle(i18n("settings.launcher.launcher_log.export")); + alert.showAndWait(); + } catch (IOException e) { + LOG.warning("Failed to export launcher logs", e); + Alert alert = new Alert(Alert.AlertType.WARNING, i18n("settings.launcher.launcher_log.export.failed") + "\n" + StringUtils.getStackTrace(e)); + alert.setTitle(i18n("message.error")); + alert.setContentText(StringUtils.getStackTrace(e)); + alert.showAndWait(); + } + exportPane.getChildren().setAll(btnExport); + }); + Button btnContact = new Button(); btnContact.setText(i18n("launcher.contact")); btnContact.setOnAction(event -> FXUtils.openLink(Metadata.CONTACT_URL)); - HBox box = new HBox(); + HBox box = new HBox(8); box.setStyle("-fx-padding: 8px;"); - box.getChildren().add(btnContact); + box.getChildren().setAll(exportPane, btnContact); box.setAlignment(Pos.CENTER_RIGHT); BorderPane pane = new BorderPane(); @@ -75,9 +109,6 @@ private CrashWindow() { setOnCloseRequest(e -> Platform.exit()); } - public static CrashWindow getInstance() { - return instance.get(); - } public void addCrashReport(CrashReport report) { textArea.setText(textArea.getText() + "\n\n" + report.getDisplayText()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java index ee8ea5593cf..cc22a3ba8c7 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/SettingsPage.java @@ -30,7 +30,6 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; -import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; @@ -42,27 +41,13 @@ import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; import org.jackhuang.hmcl.util.Lang; +import org.jackhuang.hmcl.util.LauncherLogExporter; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.i18n.I18n; import org.jackhuang.hmcl.util.i18n.SupportedLocale; -import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.io.IOUtils; -import org.tukaani.xz.XZInputStream; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashSet; + import java.util.List; -import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.zip.GZIPInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; import static org.jackhuang.hmcl.setting.SettingsManager.settings; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -221,7 +206,7 @@ else if (locale.isSameLanguage(currentLocale)) exportLogPane.setContent(logButton); logButton.setOnAction(e -> { exportLogPane.showSpinner(); - onExportLogs().whenCompleteAsync((result, exception) -> { + CompletableFuture.supplyAsync(Lang.wrap(LauncherLogExporter::exportLogsAsZip), Schedulers.io()).whenCompleteAsync((result, exception) -> { exportLogPane.hideSpinner(); if (exception == null) { Controllers.dialog(i18n("settings.launcher.launcher_log.export.success", result)); @@ -262,128 +247,4 @@ private void onUpdate() { } UpdateHandler.updateFrom(target); } - - private static String getEntryName(Set entryNames, String name) { - if (entryNames.add(name)) { - return name; - } - - for (long i = 1; ; i++) { - String newName = name + "." + i; - if (entryNames.add(newName)) { - return newName; - } - } - } - - /// This method guarantees to close both `input` and the current zip entry. - /// - /// If no exception occurs, this method returns `true`; - /// If an exception occurs while reading from `input`, this method returns `false`; - /// If an exception occurs while writing to `output`, this method will throw it as is. - private static boolean exportLogFile(ZipOutputStream output, - Path file, // For logging - String entryName, - InputStream input, - byte[] buffer) throws IOException { - //noinspection TryFinallyCanBeTryWithResources - try { - output.putNextEntry(new ZipEntry(entryName)); - int read; - while (true) { - try { - read = input.read(buffer); - if (read <= 0) - return true; - } catch (Throwable ex) { - LOG.warning("Failed to decompress log file " + file, ex); - return false; - } - - output.write(buffer, 0, read); - } - } finally { - try { - input.close(); - } catch (Throwable ex) { - LOG.warning("Failed to close log file " + file, ex); - } - output.closeEntry(); - } - } - - private CompletableFuture onExportLogs() { - return CompletableFuture.supplyAsync(Lang.wrap(() -> { - String nameBase = "hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")); - List recentLogFiles = LOG.findRecentLogFiles(5); - - Path outputFile; - if (recentLogFiles.isEmpty()) { - outputFile = Metadata.CURRENT_DIRECTORY.resolve(nameBase + ".log"); - - LOG.info("Exporting latest logs to " + outputFile); - try (OutputStream output = Files.newOutputStream(outputFile)) { - LOG.exportLogs(output); - } - } else { - outputFile = Metadata.CURRENT_DIRECTORY.resolve(nameBase + ".zip"); - - LOG.info("Exporting latest logs to " + outputFile); - - byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE]; - try (var os = Files.newOutputStream(outputFile); - var zos = new ZipOutputStream(os)) { - - Set entryNames = new HashSet<>(); - - for (Path path : recentLogFiles) { - String fileName = FileUtils.getName(path); - String extension = StringUtils.substringAfterLast(fileName, '.'); - - if ("gz".equals(extension) || "xz".equals(extension)) { - // If an exception occurs while decompressing the input file, we should - // ensure the input file and the current zip entry are closed, - // then copy the compressed file content as-is into a new entry in the zip file. - - InputStream input = null; - try { - input = Files.newInputStream(path); - input = "gz".equals(extension) - ? new GZIPInputStream(input) - : new XZInputStream(input); - } catch (Throwable ex) { - LOG.warning("Failed to open log file " + path, ex); - IOUtils.closeQuietly(input, ex); - input = null; - } - - String entryName = getEntryName(entryNames, StringUtils.substringBeforeLast(fileName, ".")); - if (input != null && exportLogFile(zos, path, entryName, input, buffer)) - continue; - } - - // Copy the log file content as-is into a new entry in the zip file. - // If an exception occurs while decompressing the input file, we should - // ensure the input file and the current zip entry are closed. - - InputStream input; - try { - input = Files.newInputStream(path); - } catch (Throwable ex) { - LOG.warning("Failed to open log file " + path, ex); - continue; - } - - exportLogFile(zos, path, getEntryName(entryNames, fileName), input, buffer); - } - - zos.putNextEntry(new ZipEntry(getEntryName(entryNames, "hmcl-latest.log"))); - LOG.exportLogs(zos); - zos.closeEntry(); - } - } - - return outputFile; - }), Schedulers.io()); - } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java new file mode 100644 index 00000000000..4c946764b63 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java @@ -0,0 +1,170 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2026 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.util; + +import org.jackhuang.hmcl.Metadata; +import org.jackhuang.hmcl.util.io.FileUtils; +import org.jackhuang.hmcl.util.io.IOUtils; +import org.tukaani.xz.XZInputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.zip.GZIPInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static org.jackhuang.hmcl.util.logging.Logger.LOG; + +public final class LauncherLogExporter { + private LauncherLogExporter() { + throw new AssertionError(); + } + + + + public static Path exportLogsAsZip() throws IOException { + String nameBase = "hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")); + List recentLogFiles = LOG.findRecentLogFiles(5); + + Path outputFile; + if (recentLogFiles.isEmpty()) { + outputFile = Metadata.CURRENT_DIRECTORY.resolve(nameBase + ".log"); + + LOG.info("Exporting latest logs to " + outputFile); + try (OutputStream output = Files.newOutputStream(outputFile)) { + LOG.exportLogs(output); + } + } else { + outputFile = Metadata.CURRENT_DIRECTORY.resolve(nameBase + ".zip"); + + LOG.info("Exporting latest logs to " + outputFile); + + byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE]; + try (var os = Files.newOutputStream(outputFile); + var zos = new ZipOutputStream(os)) { + + Set entryNames = new HashSet<>(); + + for (Path path : recentLogFiles) { + String fileName = FileUtils.getName(path); + String extension = StringUtils.substringAfterLast(fileName, '.'); + + if ("gz".equals(extension) || "xz".equals(extension)) { + // If an exception occurs while decompressing the input file, we should + // ensure the input file and the current zip entry are closed, + // then copy the compressed file content as-is into a new entry in the zip file. + + InputStream input = null; + try { + input = Files.newInputStream(path); + input = "gz".equals(extension) + ? new GZIPInputStream(input) + : new XZInputStream(input); + } catch (Throwable ex) { + LOG.warning("Failed to open log file " + path, ex); + IOUtils.closeQuietly(input, ex); + input = null; + } + + String entryName = getEntryName(entryNames, StringUtils.substringBeforeLast(fileName, ".")); + if (input != null && exportLogFile(zos, path, entryName, input, buffer)) + continue; + } + + // Copy the log file content as-is into a new entry in the zip file. + // If an exception occurs while decompressing the input file, we should + // ensure the input file and the current zip entry are closed. + + InputStream input; + try { + input = Files.newInputStream(path); + } catch (Throwable ex) { + LOG.warning("Failed to open log file " + path, ex); + continue; + } + + exportLogFile(zos, path, getEntryName(entryNames, fileName), input, buffer); + } + + zos.putNextEntry(new ZipEntry(getEntryName(entryNames, "hmcl-latest.log"))); + LOG.exportLogs(zos); + zos.closeEntry(); + } + } + + return outputFile; + } + + + private static String getEntryName(Set entryNames, String name) { + if (entryNames.add(name)) { + return name; + } + + for (long i = 1; ; i++) { + String newName = name + "." + i; + if (entryNames.add(newName)) { + return newName; + } + } + } + + /// This method guarantees to close both `input` and the current zip entry. + /// + /// If no exception occurs, this method returns `true`; + /// If an exception occurs while reading from `input`, this method returns `false`; + /// If an exception occurs while writing to `output`, this method will throw it as is. + private static boolean exportLogFile(ZipOutputStream output, + Path file, // For logging + String entryName, + InputStream input, + byte[] buffer) throws IOException { + //noinspection TryFinallyCanBeTryWithResources + try { + output.putNextEntry(new ZipEntry(entryName)); + int read; + while (true) { + try { + read = input.read(buffer); + if (read <= 0) + return true; + } catch (Throwable ex) { + LOG.warning("Failed to decompress log file " + file, ex); + return false; + } + + output.write(buffer, 0, read); + } + } finally { + try { + input.close(); + } catch (Throwable ex) { + LOG.warning("Failed to close log file " + file, ex); + } + output.closeEntry(); + } + } +} From c7f0a8fd4688cbefc6df019c92021df0fd09c529 Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 10:39:12 +0800 Subject: [PATCH 3/6] =?UTF-8?q?<12>=20=E6=9C=B1=E7=A0=82=E5=88=92=E4=B9=B1?= =?UTF-8?q?=20=E5=A5=88=E4=BD=95=E5=A4=A9=E6=B6=AF=E8=BF=9C=E8=B5=B0=20?= =?UTF-8?q?=E7=BA=A2=E5=A6=86=E8=89=B3=E8=89=B2=20=E9=9A=BE=E6=8E=A9?= =?UTF-8?q?=E6=82=B2=E6=84=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HMCL/src/main/resources/assets/lang/I18N.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_ar.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_de.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_es.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_ru.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_uk.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_zh.properties | 1 - HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties | 1 - 8 files changed, 8 deletions(-) diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index ac12860d357..7c256ea0dae 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -952,7 +952,6 @@ launcher.cache_directory.disabled=Disabled launcher.cache_directory.invalid=Failed to create a cache directory, falling back to default. launcher.contact=Contact Us launcher.crash=Hello Minecraft! Launcher has encountered a fatal error! Please copy the following log and ask for help on our Discord, QQ group, GitHub, or other Minecraft forum. -launcher.crash.java_internal_error=Hello Minecraft! Launcher has encountered a fatal error because your Java is corrupted. Please uninstall your Java and download a suitable Java here. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher has encountered a fatal error! Your launcher is outdated. Please update your launcher! libraries.download=Downloading Libraries diff --git a/HMCL/src/main/resources/assets/lang/I18N_ar.properties b/HMCL/src/main/resources/assets/lang/I18N_ar.properties index 27b46937891..4e594d19a14 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ar.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ar.properties @@ -892,7 +892,6 @@ launcher.cache_directory.disabled=معطّل launcher.cache_directory.invalid=فشل إنشاء مجلد الذاكرة المؤقتة، جارٍ الرجوع إلى الافتراضي. launcher.contact=تواصل معنا launcher.crash=واجه Hello Minecraft! Launcher خطأً فادحاً! يُرجى نسخ السجل التالي وطلب المساعدة على Discord أو مجموعة QQ أو GitHub أو أي منتدى Minecraft آخر. -launcher.crash.java_internal_error=واجه Hello Minecraft! Launcher خطأً فادحاً بسبب تلف Java. يُرجى إلغاء تثبيت Java وتنزيل إصدار مناسب من هنا. launcher.crash.hmcl_out_dated=واجه Hello Minecraft! Launcher خطأً فادحاً! المشغّل قديم. يُرجى تحديثه! libraries.download=جارٍ تنزيل المكتبات diff --git a/HMCL/src/main/resources/assets/lang/I18N_de.properties b/HMCL/src/main/resources/assets/lang/I18N_de.properties index ba10f9f2130..bfaa837b54e 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_de.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_de.properties @@ -949,7 +949,6 @@ launcher.cache_directory.disabled=Deaktiviert launcher.cache_directory.invalid=Fehler beim Erstellen des Cache-Verzeichnisses, Rückgriff auf Standard. launcher.contact=Kontaktiere uns launcher.crash=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen! Bitte kopieren Sie das folgende Protokoll und bitten Sie in unserem Discord, der QQ-Gruppe, auf GitHub oder in einem anderen Minecraft-Forum um Hilfe. -launcher.crash.java_internal_error=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen, da Ihre Java-Installation beschädigt ist. Bitte deinstallieren Sie Java und laden Sie eine geeignete Java-Version hier herunter. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher ist auf einen fatalen Fehler gestoßen! Ihr Launcher ist veraltet. Bitte aktualisieren Sie Ihren Launcher! libraries.download=Bibliotheken werden heruntergeladen diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 4d5d10934d7..eeec1aaaf10 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -845,7 +845,6 @@ launcher.cache_directory.disabled=Desactivado launcher.cache_directory.invalid=No se ha podido crear el directorio de la caché, volviendo a los valores por defecto. launcher.contact=Contacta con nosotros launcher.crash=Hello Minecraft! Launcher ha encontrado un error fatal. Por favor, copie el siguiente registro y pida ayuda en nuestra comunidad en Discord, GitHub o Minecraft Forums. -launcher.crash.java_internal_error=Hello Minecraft! Launcher ha encontrado un error fatal porque su Java está dañado. Por favor, desinstala tu Java y descarga un Java adecuado aquí. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher ha encontrado un error fatal. Su launcher está desactualizado. Por favor, ¡actualícelo! libraries.download=Descargando bibliotecas diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 3180600d111..cdf7f8395ee 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -838,7 +838,6 @@ launcher.cache_directory.disabled=Отключено launcher.cache_directory.invalid=Не удалось создать папку для кэша, возвращаем к значению по умолчанию. launcher.contact=Связаться с нами launcher.crash=Лаунчер столкнулся с фатальной ошибкой! Скопируйте следующий журнал и попросите помощи в нашем Discord, группе QQ, GitHub или на другом форуме Minecraft. -launcher.crash.java_internal_error=Лаунчер столкнулся с фатальной ошибкой! Пожалуйста, удалите Java и скачайте подходящую Java здесь. launcher.crash.hmcl_out_dated=Лаунчер столкнулся с фатальной ошибкой! Ваш лаунчер устарел. Обновите его! libraries.download=Скачивание библиотек diff --git a/HMCL/src/main/resources/assets/lang/I18N_uk.properties b/HMCL/src/main/resources/assets/lang/I18N_uk.properties index 82517c969b5..8810da0b643 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_uk.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_uk.properties @@ -910,7 +910,6 @@ launcher.cache_directory.disabled=Вимкнено launcher.cache_directory.invalid=Не вдалося створити каталог кешу, повернення до типового. launcher.contact=Зв'яжіться з нами launcher.crash=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою! Скопіюйте наступний журнал та попросіть допомоги на нашому Discord, групі QQ, GitHub або іншому форумі Minecraft. -launcher.crash.java_internal_error=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою, оскільки ваша Java пошкоджена. Видаліть вашу Java та завантажте відповідну Java тут. launcher.crash.hmcl_out_dated=Hello Minecraft! Лаунчер зіткнувся з фатальною помилкою! Ваш лаунчер застарів. Оновіть ваш лаунчер! libraries.download=Завантаження бібліотек diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 7a3407109ef..4517b6626b2 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -764,7 +764,6 @@ launcher.cache_directory.disabled=停用 launcher.cache_directory.invalid=無法建立自訂的快取目錄。已還原至預設設定。 launcher.contact=聯絡我們 launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤。請複製下列內容並透過 GitHub、Discord 或 HMCL QQ 群回報問題。 -launcher.crash.java_internal_error=Hello Minecraft! Launcher 由於目前 Java 損壞而無法繼續執行。請移除目前 Java,點擊 此處 安裝合適的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤。已偵測到你的啟動器不是最新版本,請更新後重試! libraries.download=下載依賴庫 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 e8ce302cf4c..ac3c12eabd8 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -770,7 +770,6 @@ launcher.cache_directory.disabled=禁用 (总是使用游戏文件夹路径) launcher.cache_directory.invalid=无法创建自定义的缓存文件夹。已经恢复到默认设置。 launcher.contact=联系我们 launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误。请复制下列内容并点击右下角的按钮反馈问题。 -launcher.crash.java_internal_error=Hello Minecraft! Launcher 由于当前 Java 损坏而无法继续运行。请卸载当前 Java,点击 此处 安装合适的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误。已检测到你的启动器不是最新版本,请更新后再试。 libraries.download=下载依赖库 From db23a39e7b41a03ac961c00e9761d891166cace4 Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 10:42:24 +0800 Subject: [PATCH 4/6] =?UTF-8?q?<13>=20=E6=BC=AB=E9=95=BF=E8=B7=AF=E5=90=91?= =?UTF-8?q?=E7=9D=80=20=E9=AB=98=E5=B1=B1=E6=82=AC=E6=9C=88=20(=E7=9B=9B?= =?UTF-8?q?=E5=A4=8F=E7=8A=B9=E8=8B=A6=E5=AF=92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java index 2833df0a543..af0cbf1ffe6 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/StringUtils.java @@ -58,7 +58,7 @@ public static String getStackTrace(Throwable throwable) { } public static String getStackTrace(StackTraceElement[] elements) { - StringBuilder builder = new StringBuilder(512); + StringBuilder builder = new StringBuilder(); for (StackTraceElement element : elements) builder.append("\tat ").append(element).append(System.lineSeparator()); return builder.toString(); From 44f646b7bdf01365ef7f8b2a164bed5b0235f6e3 Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 11:11:06 +0800 Subject: [PATCH 5/6] =?UTF-8?q?<15>=20=E9=93=BA=E9=99=88=E7=94=BB=E5=8D=B7?= =?UTF-8?q?=20=E5=BF=83=E4=B8=AD=E7=89=B5=E5=BF=B5=20=E4=BB=A5=E4=B8=B9?= =?UTF-8?q?=E9=9D=92=E4=BD=9C=E7=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java index 0c274e7ecc1..7bab18073db 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java @@ -259,9 +259,6 @@ public void accept(@Nullable HMCLGameInstance currentGame) { if (tooltip != null) Tooltip.uninstall(launchButton, tooltip); } - launchButton.setOnAction((e) -> { - throw new AssertionError(); - }); } }); From b6a36d69dcc85b6be269980261091fd8140b59c2 Mon Sep 17 00:00:00 2001 From: CiiLu <109708109+CiiLu@users.noreply.github.com> Date: Sun, 6 Sep 2026 11:40:37 +0800 Subject: [PATCH 6/6] =?UTF-8?q?<17>=20=E7=90=B5=E7=90=B6=E6=B3=AA=20?= =?UTF-8?q?=E6=8B=A8=E6=96=AD=E4=BA=94=E5=8D=81=E5=BC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java | 3 +-- .../main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java index b108810d06f..130503faabe 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/CrashWindow.java @@ -41,7 +41,7 @@ /** * @author huangyuhui */ -public class CrashWindow extends Stage { +public final class CrashWindow extends Stage { private static final Lazy instance = new Lazy<>(CrashWindow::new); public static CrashWindow getInstance() { @@ -109,7 +109,6 @@ private CrashWindow() { setOnCloseRequest(e -> Platform.exit()); } - public void addCrashReport(CrashReport report) { textArea.setText(textArea.getText() + "\n\n" + report.getDisplayText()); textArea.setEditable(false); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java index 4c946764b63..5c4752f87c9 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/LauncherLogExporter.java @@ -43,8 +43,6 @@ private LauncherLogExporter() { throw new AssertionError(); } - - public static Path exportLogsAsZip() throws IOException { String nameBase = "hmcl-exported-logs-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")); List recentLogFiles = LOG.findRecentLogFiles(5); @@ -118,7 +116,6 @@ public static Path exportLogsAsZip() throws IOException { return outputFile; } - private static String getEntryName(Set entryNames, String name) { if (entryNames.add(name)) { return name;