Skip to content

Commit

Permalink
fix #2796 (#2804)
Browse files Browse the repository at this point in the history
* fix #2796

* 调整 game.crash.feedback 显示位置

* fix i18n

* 添加导出崩溃信息失败的弹窗

* updata

* 在崩溃窗口的日志窗口添加更多信息

* fix i18n

* Update HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties

Co-authored-by: 何杰豪 <[email protected]>

* Update HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties

Co-authored-by: 何杰豪 <[email protected]>

* Revert "在崩溃窗口的日志窗口添加更多信息"

This reverts commit e8ed432.

* updata

* add log

* updat log

* Update GameCrashWindow.java

* 添加更多日志输出

格式:Processing log file: /home/zkitefly/.minecraft/hs_err_pid20074.log, processStartTime: 1709952457315, lastModifiedTime: 1709952504054

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

---------

Co-authored-by: 何杰豪 <[email protected]>
Co-authored-by: Glavo <[email protected]>
  • Loading branch information
3 people authored Mar 10, 2024
1 parent 37aaf15 commit 389b931
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ public void onLog(String log, boolean isErrorStream) {
@Override
public void onExit(int exitCode, ExitType exitType) {
if (showLogs) {
Platform.runLater(() -> logWindow.logLine(String.format("[HMCL ProcessListener] Minecraft exit with code %d(0x%x).", exitCode, exitCode), Log4jLevel.INFO));
Platform.runLater(() -> logWindow.logLine(String.format("[HMCL ProcessListener] Minecraft exit with code %d(0x%x), type is %s.", exitCode, exitCode, exitType), Log4jLevel.INFO));
}

launchingLatch.countDown();
Expand Down
8 changes: 6 additions & 2 deletions HMCL/src/main/java/org/jackhuang/hmcl/game/LogExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ private static void processLogs(Path directory, String fileExtension, String log
if (Files.isRegularFile(file)) {
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
if (time.toMillis() >= processStartTime) {
String crashLog = Logging.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
zipper.putTextFile(crashLog, file.getFileName().toString());
try {
String crashLog = Logging.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
zipper.putTextFile(crashLog, file.getFileName().toString());
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to read log file: " + file, e);
}
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
Expand Down Expand Up @@ -943,7 +944,14 @@ public static List<Node> parseSegment(String segment, Consumer<String> hyperlink
if ("a".equals(element.getTagName())) {
String href = element.getAttribute("href");
JFXHyperlink hyperlink = new JFXHyperlink(element.getTextContent());
hyperlink.setOnAction(e -> hyperlinkAction.accept(href));
hyperlink.setOnAction(e -> {
String link = href;
try {
link = new URI(href).toASCIIString();
} catch (URISyntaxException ignored) {
}
hyperlinkAction.accept(link);
});
texts.add(hyperlink);
} else if ("b".equals(element.getTagName())) {
Text text = new Text(element.getTextContent());
Expand Down
61 changes: 31 additions & 30 deletions HMCL/src/main/java/org/jackhuang/hmcl/ui/GameCrashWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.jackhuang.hmcl.util.Log4jLevel;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.Pair;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.CommandBuilder;
Expand Down Expand Up @@ -102,7 +103,7 @@ public GameCrashWindow(ManagedProcess managedProcess, ProcessListener.ExitType e

memory = Optional.ofNullable(launchOptions.getMaxMemory()).map(i -> i + " MB").orElse("-");

total_memory = Optional.ofNullable(OperatingSystem.TOTAL_MEMORY).map(i -> i + " MB").orElse("-");
total_memory = OperatingSystem.TOTAL_MEMORY + " MB";

this.java = launchOptions.getJava().getArchitecture() == Architecture.SYSTEM_ARCH
? launchOptions.getJava().getVersion()
Expand Down Expand Up @@ -169,56 +170,51 @@ private void analyzeCrashReport() {
keywords.addAll(pair.getValue());
}

List<Node> segments = new ArrayList<>();
List<Node> segments = new ArrayList<>(FXUtils.parseSegment(i18n("game.crash.feedback"), Controllers::onHyperlinkAction));

boolean hasMultipleRules = results.keySet().stream().distinct().count() > 1;
if (hasMultipleRules) {
segments.addAll(FXUtils.parseSegment(i18n("game.crash.feedback"), Controllers::onHyperlinkAction));
LOG.log(Level.INFO, "Number of reasons: " + results.size());
if (results.size() > 1) {
segments.add(new Text("\n"));
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason.multiple"), Controllers::onHyperlinkAction));
LOG.log(Level.INFO, "Multiple reasons detected");
} else {
segments.add(new Text("\n\n"));
}

for (CrashReportAnalyzer.Result result : results.values()) {
String message;
switch (result.getRule()) {
case TOO_OLD_JAVA:
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason.too_old_java",
CrashReportAnalyzer.getJavaVersionFromMajorVersion(Integer.parseInt(result.getMatcher().group("expected")))), Controllers::onHyperlinkAction));
message = i18n("game.crash.reason.too_old_java", CrashReportAnalyzer.getJavaVersionFromMajorVersion(Integer.parseInt(result.getMatcher().group("expected"))));
break;
case MOD_RESOLUTION_CONFLICT:
case MOD_RESOLUTION_MISSING:
case MOD_RESOLUTION_COLLECTION:
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
message = i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
translateFabricModId(result.getMatcher().group("sourcemod")),
parseFabricModId(result.getMatcher().group("destmod")),
parseFabricModId(result.getMatcher().group("destmod"))), Controllers::onHyperlinkAction));
parseFabricModId(result.getMatcher().group("destmod")));
break;
case MOD_RESOLUTION_MISSING_MINECRAFT:
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
message = i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
translateFabricModId(result.getMatcher().group("mod")),
result.getMatcher().group("version")), Controllers::onHyperlinkAction));
result.getMatcher().group("version"));
break;
case MOD_FOREST_OPTIFINE:
case TWILIGHT_FOREST_OPTIFINE:
case PERFORMANT_FOREST_OPTIFINE:
case JADE_FOREST_OPTIFINE:
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason.mod", "OptiFine"), Controllers::onHyperlinkAction));
message = i18n("game.crash.reason.mod", "OptiFine");
LOG.log(Level.INFO, "Crash cause: " + result.getRule() + ": " + i18n("game.crash.reason.mod", "OptiFine"));
break;
default:
segments.addAll(FXUtils.parseSegment(i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
message = i18n("game.crash.reason." + result.getRule().name().toLowerCase(Locale.ROOT),
Arrays.stream(result.getRule().getGroupNames()).map(groupName -> result.getMatcher().group(groupName))
.toArray()), Controllers::onHyperlinkAction));
.toArray());
break;
}
segments.add(new Text("\n"));
if (hasMultipleRules) {
segments.add(new Text("\n"));
} else {
segments.add(new Text("\n"));
segments.addAll(FXUtils.parseSegment(i18n("game.crash.feedback"), Controllers::onHyperlinkAction));
segments.add(new Text("\n"));
}
LOG.log(Level.INFO, "Crash cause: " + result.getRule());
LOG.log(Level.INFO, "Crash cause: " + result.getRule() + ": " + message);
segments.addAll(FXUtils.parseSegment(message, Controllers::onHyperlinkAction));
segments.add(new Text("\n\n"));
}
if (results.isEmpty()) {
if (!keywords.isEmpty()) {
Expand Down Expand Up @@ -284,15 +280,20 @@ private void exportGameCrashInfo() {
logs.stream().map(Pair::getKey).collect(Collectors.joining(OperatingSystem.LINE_SEPARATOR)))
.thenComposeAsync(logs ->
LogExporter.exportLogs(logFile, repository, launchOptions.getVersionName(), logs, new CommandBuilder().addAll(managedProcess.getCommands()).toString()))
.thenRunAsync(() -> {
FXUtils.showFileInExplorer(logFile);
.handleAsync((result, exception) -> {
Alert alert;

if (exception == null) {
FXUtils.showFileInExplorer(logFile);
alert = new Alert(Alert.AlertType.INFORMATION, i18n("settings.launcher.launcher_log.export.success", logFile));
} else {
LOG.log(Level.WARNING, "Failed to export game crash info", exception);
alert = new Alert(Alert.AlertType.WARNING, i18n("settings.launcher.launcher_log.export.failed") + "\n" + StringUtils.getStackTrace(exception));
}

Alert alert = new Alert(Alert.AlertType.INFORMATION, i18n("settings.launcher.launcher_log.export.success", logFile));
alert.setTitle(i18n("settings.launcher.launcher_log.export"));
alert.showAndWait();
}, Schedulers.javafx())
.exceptionally(e -> {
LOG.log(Level.WARNING, "Failed to export game crash info", e);

return null;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.upgrade.UpdateHandler;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.i18n.Locales;
import org.jackhuang.hmcl.util.io.FileUtils;

Expand Down Expand Up @@ -132,7 +133,7 @@ protected void onExportLogs() {
try {
Files.write(logFile, Logging.getRawLogs());
} catch (IOException e) {
Platform.runLater(() -> Controllers.dialog(i18n("settings.launcher.launcher_log.export.failed") + "\n" + e, null, MessageType.ERROR));
Platform.runLater(() -> Controllers.dialog(i18n("settings.launcher.launcher_log.export.failed") + "\n" + StringUtils.getStackTrace(e), null, MessageType.ERROR));
LOG.log(Level.WARNING, "Failed to export logs", e);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion HMCL/src/main/resources/assets/lang/I18N_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ game.crash.reason.mod_profile_causes_game_crash=El juego actual no puede seguir
game.crash.reason.fabric_reports_an_error_and_gives_a_solution=Forge puede haber dado un mensaje de error.\nPuede ver el registro y realizar las acciones correspondientes de acuerdo con la información de registro en el informe de errores.\nSi no ve un mensaje de error, puede consultar el informe de errores para saber cómo ocurrió el error.
game.crash.reason.java_version_is_too_high=El juego actual se bloqueó porque la versión de Java es demasiado alta y no puede seguir ejecutándose.\nCambie a una versión anterior de Java en la pestaña Java Path de Configuración global del juego o Configuración específica del juego antes de iniciar el juego.\nSi no es así, puede descargarlo desde <a href="https://www.java.com/download/">java.com (Java8)</a> o <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java17)</a> y otras plataformas para descargar e instalar una (reinicie el iniciador después de la instalación).
game.crash.reason.mod_name=El juego actual no puede continuar ejecutándose debido a un problema con el nombre del archivo mod. El nombre del archivo de\nMod solo debe usar mayúsculas y minúsculas (Aa ~ Zz), números (0 ~ 9), líneas horizontales (-), subrayado (_) y puntos (.) en toda la mitad del inglés.\n Por favor, vaya a la carpeta mod para agregar un carácter de Cumplimiento anterior a todos los nombres de archivo mod que no cumplan.
game.crash.reason.incomplete_forge_installation=O jogo atual não pode continuar devido a uma instalação incompleta do Forge / NeoForge.\nDesinstale e reinstale o Forge em Configurações de versão - Instalação automática.
game.crash.reason.incomplete_forge_installation=O jogo atual não pode continuar devido a uma instalação incompleta do Forge / NeoForge.\nDesinstale e reinstale o Forge / NeoForge em Configurações de versão - Instalação automática.
game.crash.reason.forge_error=Forge puede haber proporcionado un mensaje de error. \nPuede ver el registro y realizar las acciones correspondientes de acuerdo con la información de registro en el informe de errores. \nSi no ve un mensaje de error, puede consultar el informe de errores para saber cómo ocurrió el error.\n%1$s
game.crash.reason.mod_solution0=El juego actual no puede seguir ejecutándose debido a algunos problemas de modificación. \nPuede consultar el registro para ver si hay un mod incorrecto.
game.crash.reason.mod_profile_causes_game_crash=El juego actual no puede seguir ejecutándose debido a un problema con el perfil de mod. \nPuede consultar el registro del mod defectuoso y su archivo de configuración.
Expand Down
2 changes: 1 addition & 1 deletion HMCL/src/main/resources/assets/lang/I18N_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ game.crash.reason.mod_profile_causes_game_crash=mod プロファイルに問題
game.crash.reason.fabric_reports_an_error_and_gives_a_solution=Forge がエラー メッセージを表示した可能性があります。 \nログを表示し、エラー レポートのログ情報に従って対応するアクションを実行できます。 \nエラー メッセージが表示されない場合は、エラー レポートをチェックして、エラーがどのように発生したかを知ることができます。
game.crash.reason.java_version_is_too_high=Java のバージョンが高すぎて実行を継続できないため、現在のゲームがクラッシュしました。 \nゲームを起動する前に、グローバル ゲーム設定またはゲーム固有の設定の Java パス タブで Java の以前のバージョンに切り替えてください。 \nそうでない場合は、<a href="https://www.java.com/download/">java.com (Java8)</a> または <a href="https://bell-sw.com/pages/downloads/#downloads">BellSoft Liberica Full JRE (Java17)</a> およびその他のプラットフォームをダウンロードしてインストールします (インストール後にランチャーを再起動します)。
game.crash.reason.mod_name=現在のゲームはModファイル名の問題で続行できません。\nModファイル名は、英文の全半角の大文字と小文字(Aa ~ Zz)、数字(0 ~ 9)、横線(-)、アンダースコア(_)、点(.)のみを使用してください。\n上記のコンプライアンス文字をModフォルダに追加してください。
game.crash.reason.incomplete_forge_installation=Forge / NeoForge のインストールが不完全なため、現在のゲームを続行できません。\nバージョン設定 - 自動インストールで Forge をアンインストールしてから再インストールしてください。
game.crash.reason.incomplete_forge_installation=Forge / NeoForge のインストールが不完全なため、現在のゲームを続行できません。\nバージョン設定 - 自動インストールで Forge / NeoForge をアンインストールしてから再インストールしてください。
game.crash.reason.file_already_exists=ファイル %1$s が既に存在するので、現在のゲームは続行できません。\このファイルを削除してもよいと思われる場合は、このファイルをバックアップして、ゲームを再起動してから削除してみてください。
game.crash.reason.need_jdk11=Java 仮想マシンのバージョンが不適切なため、現在のゲームは実行を続行できません。\nJava 11 をダウンロードしてインストールし、グローバル (特定) ゲーム設定で Java を 11 で始まるバージョンに設定する必要があります。
game.crash.reason.file_changed=ファイルのチェックサムに失敗したため、現在のゲームを続行できません。\nMinecraft.jar ファイルを手動で変更した場合、変更をロールバックするか、ゲームを再度ダウンロードする必要があります。
Expand Down
Loading

0 comments on commit 389b931

Please sign in to comment.