feat: game crash window.

This commit is contained in:
huanghongxun 2021-09-19 16:15:36 +08:00
parent 3c797252d8
commit 43236049ac
8 changed files with 334 additions and 94 deletions

View File

@ -292,6 +292,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
.setGameDir(gameDir)
.setJava(javaVersion)
.setVersionType(Metadata.TITLE)
.setVersionName(version)
.setProfileName(Metadata.TITLE)
.setGameArguments(StringUtils.tokenize(vs.getMinecraftArgs()))
.setJavaArguments(StringUtils.tokenize(vs.getJavaArgs()))

View File

@ -46,10 +46,7 @@ import org.jackhuang.hmcl.setting.LauncherVisibility;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.VersionSetting;
import org.jackhuang.hmcl.task.*;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.DialogController;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.LogWindow;
import org.jackhuang.hmcl.ui.*;
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
@ -60,18 +57,11 @@ import org.jackhuang.hmcl.util.io.ResponseCodeException;
import org.jackhuang.hmcl.util.platform.*;
import org.jackhuang.hmcl.util.versioning.VersionNumber;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Queue;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
@ -180,14 +170,15 @@ public final class LauncherHelper {
}
}).withStage("launch.state.logging_in"))
.thenComposeAsync(authInfo -> Task.supplyAsync(() -> {
LaunchOptions launchOptions = repository.getLaunchOptions(selectedVersion, profile.getGameDir(), !setting.isNotCheckJVM());
return new HMCLGameLauncher(
repository,
version,
authInfo,
repository.getLaunchOptions(selectedVersion, profile.getGameDir(), !setting.isNotCheckJVM()),
launchOptions,
launcherVisibility == LauncherVisibility.CLOSE
? null // Unnecessary to start listening to game process output when close launcher immediately after game launched.
: new HMCLProcessListener(repository, selectedVersion, authInfo, launchingLatch, gameVersion.isPresent())
: new HMCLProcessListener(repository, selectedVersion, authInfo, launchOptions, launchingLatch, gameVersion.isPresent())
);
}).thenComposeAsync(launcher -> { // launcher is prev task's result
if (scriptFile == null) {
@ -584,6 +575,7 @@ public final class LauncherHelper {
private final HMCLGameRepository repository;
private final String version;
private final Map<String, String> forbiddenTokens;
private final LaunchOptions launchOptions;
private ManagedProcess process;
private boolean lwjgl;
private LogWindow logWindow;
@ -592,9 +584,10 @@ public final class LauncherHelper {
private final CountDownLatch logWindowLatch = new CountDownLatch(1);
private final CountDownLatch launchingLatch;
public HMCLProcessListener(HMCLGameRepository repository, String version, AuthInfo authInfo, CountDownLatch launchingLatch, boolean detectWindow) {
public HMCLProcessListener(HMCLGameRepository repository, String version, AuthInfo authInfo, LaunchOptions launchOptions, CountDownLatch launchingLatch, boolean detectWindow) {
this.repository = repository;
this.version = version;
this.launchOptions = launchOptions;
this.launchingLatch = launchingLatch;
this.detectWindow = detectWindow;
@ -704,42 +697,7 @@ public final class LauncherHelper {
if (exitType != ExitType.NORMAL) {
repository.markVersionLaunchedAbnormally(version);
Platform.runLater(() -> {
if (logWindow == null) {
logWindow = new LogWindow();
logWindow.logLine("Command: " + new CommandBuilder().addAll(process.getCommands()).toString(), Log4jLevel.INFO);
for (Map.Entry<String, Log4jLevel> entry : logs)
logWindow.logLine(entry.getKey(), entry.getValue());
}
switch (exitType) {
case JVM_ERROR:
logWindow.setTitle(i18n("launch.failed.cannot_create_jvm"));
break;
case APPLICATION_ERROR:
logWindow.setTitle(i18n("launch.failed.exited_abnormally"));
break;
}
logWindow.showGameCrashReport(logs -> {
Path logFile = Paths.get("minecraft-exported-crash-info-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".zip").toAbsolutePath();
LogExporter.exportLogs(logFile, repository, version, logs, new CommandBuilder().addAll(process.getCommands()).toString())
.thenRunAsync(() -> {
JOptionPane.showMessageDialog(null, i18n("settings.launcher.launcher_log.export.success", logFile), i18n("settings.launcher.launcher_log.export"), JOptionPane.INFORMATION_MESSAGE);
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().open(logFile.toFile());
} catch (IOException | IllegalArgumentException ignored) {
}
}
}, Schedulers.javafx())
.exceptionally(e -> {
LOG.log(Level.WARNING, "Failed to export game crash info", e);
return null;
});
});
});
Platform.runLater(() -> new GameCrashWindow(process, exitType, repository, launchOptions, logs).show());
}
checkExit();

View File

@ -0,0 +1,234 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.ui;
import com.jfoenix.controls.JFXButton;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.LaunchOptions;
import org.jackhuang.hmcl.game.LogExporter;
import org.jackhuang.hmcl.launch.ProcessListener;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
import org.jackhuang.hmcl.util.Log4jLevel;
import org.jackhuang.hmcl.util.Pair;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.CommandBuilder;
import org.jackhuang.hmcl.util.platform.ManagedProcess;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.awt.*;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.newImage;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameCrashWindow extends Stage {
private final StringProperty version = new SimpleStringProperty();
private final StringProperty memory = new SimpleStringProperty();
private final StringProperty java = new SimpleStringProperty();
private final StringProperty os = new SimpleStringProperty(System.getProperty("os.name"));
private final StringProperty arch = new SimpleStringProperty(Architecture.SYSTEM_ARCHITECTURE);
private final ManagedProcess managedProcess;
private final DefaultGameRepository repository;
private final ProcessListener.ExitType exitType;
private final LaunchOptions launchOptions;
private final View view;
private final LinkedList<Pair<String, Log4jLevel>> logs;
public GameCrashWindow(ManagedProcess managedProcess, ProcessListener.ExitType exitType, DefaultGameRepository repository, LaunchOptions launchOptions, LinkedList<Pair<String, Log4jLevel>> logs) {
this.managedProcess = managedProcess;
this.exitType = exitType;
this.repository = repository;
this.launchOptions = launchOptions;
this.logs = logs;
this.view = new View();
setScene(new Scene(view, 800, 480));
getScene().getStylesheets().addAll(config().getTheme().getStylesheets());
setTitle(i18n("game.crash.title"));
getIcons().add(newImage("/assets/img/icon.png"));
version.set(launchOptions.getVersionName());
memory.set(Optional.ofNullable(launchOptions.getMaxMemory()).map(i -> i + " MB").orElse("-"));
java.set(launchOptions.getJava().getVersion());
}
private void showLogWindow() {
LogWindow logWindow = new LogWindow();
logWindow.logLine("Command: " + new CommandBuilder().addAll(managedProcess.getCommands()).toString(), Log4jLevel.INFO);
for (Map.Entry<String, Log4jLevel> entry : logs)
logWindow.logLine(entry.getKey(), entry.getValue());
logWindow.showNormal();
}
private void exportGameCrashInfo() {
Path logFile = Paths.get("minecraft-exported-crash-info-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".zip").toAbsolutePath();
CompletableFuture.supplyAsync(() ->
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(() -> {
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();
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().open(logFile.toFile());
} catch (IOException | IllegalArgumentException ignored) {
}
}
}, Schedulers.javafx())
.exceptionally(e -> {
LOG.log(Level.WARNING, "Failed to export game crash info", e);
return null;
});
}
private final class View extends VBox {
View() {
HBox titlePane = new HBox();
{
Label title = new Label();
HBox.setHgrow(title, Priority.ALWAYS);
switch (exitType) {
case JVM_ERROR:
title.setText(i18n("launch.failed.cannot_create_jvm"));
break;
case APPLICATION_ERROR:
title.setText(i18n("launch.failed.exited_abnormally"));
break;
}
titlePane.setAlignment(Pos.CENTER);
titlePane.getStyleClass().addAll("jfx-tool-bar-second", "depth-1", "padding-8");
titlePane.getChildren().setAll(title);
}
HBox infoPane = new HBox();
{
TwoLineListItem version = new TwoLineListItem();
version.getStyleClass().setAll("two-line-item-second-large");
version.setTitle(i18n("archive.game_version"));
version.subtitleProperty().bind(GameCrashWindow.this.version);
StackPane versionCard = new StackPane(version);
TwoLineListItem memory = new TwoLineListItem();
memory.getStyleClass().setAll("two-line-item-second-large");
memory.setTitle(i18n("settings.memory"));
memory.subtitleProperty().bind(GameCrashWindow.this.memory);
StackPane memoryCard = new StackPane(memory);
TwoLineListItem java = new TwoLineListItem();
java.getStyleClass().setAll("two-line-item-second-large");
java.setTitle("Java");
java.subtitleProperty().bind(GameCrashWindow.this.java);
StackPane javaCard = new StackPane(java);
TwoLineListItem os = new TwoLineListItem();
os.getStyleClass().setAll("two-line-item-second-large");
os.setTitle(i18n("system.operating_system"));
os.subtitleProperty().bind(GameCrashWindow.this.os);
StackPane osCard = new StackPane(os);
TwoLineListItem arch = new TwoLineListItem();
arch.getStyleClass().setAll("two-line-item-second-large");
arch.setTitle(i18n("system.architecture"));
arch.subtitleProperty().bind(GameCrashWindow.this.arch);
StackPane archCard = new StackPane(arch);
infoPane.setPadding(new Insets(8));
infoPane.getChildren().setAll(versionCard, memoryCard, javaCard, osCard, archCard);
}
VBox gameDirPane = new VBox(8);
{
TwoLineListItem gameDir = new TwoLineListItem();
gameDir.getStyleClass().setAll("two-line-item-second-large");
gameDir.setTitle(i18n("game.directory"));
gameDir.setSubtitle(launchOptions.getGameDir().getAbsolutePath());
TwoLineListItem javaDir = new TwoLineListItem();
javaDir.getStyleClass().setAll("two-line-item-second-large");
javaDir.setTitle(i18n("settings.game.java_directory"));
javaDir.setSubtitle(launchOptions.getJava().getBinary().toAbsolutePath().toString());
TwoLineListItem reason = new TwoLineListItem();
reason.getStyleClass().setAll("two-line-item-second-large");
reason.setTitle(i18n("game.crash.reason"));
reason.setSubtitle(i18n("game.crash.reason.unknown"));
gameDirPane.setPadding(new Insets(8));
VBox.setVgrow(gameDirPane, Priority.ALWAYS);
gameDirPane.getChildren().setAll(gameDir, javaDir, reason);
}
HBox toolBar = new HBox();
{
JFXButton exportGameCrashInfoButton = new JFXButton(i18n("logwindow.export_game_crash_logs"));
exportGameCrashInfoButton.setButtonType(JFXButton.ButtonType.RAISED);
exportGameCrashInfoButton.getStyleClass().add("jfx-button-raised");
exportGameCrashInfoButton.setOnMouseClicked(e -> exportGameCrashInfo());
JFXButton logButton = new JFXButton(i18n("logwindow.title"));
logButton.setButtonType(JFXButton.ButtonType.RAISED);
logButton.getStyleClass().add("jfx-button-raised");
logButton.setOnMouseClicked(e -> showLogWindow());
toolBar.setPadding(new Insets(8));
toolBar.setSpacing(8);
toolBar.getStyleClass().add("jfx-tool-bar");
toolBar.getChildren().setAll(exportGameCrashInfoButton, logButton);
}
getChildren().setAll(titlePane, infoPane, gameDirPane, toolBar);
}
}
}

View File

@ -19,7 +19,6 @@ package org.jackhuang.hmcl.ui;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXScrollPane;
import com.jfoenix.effects.JFXDepthManager;
import javafx.beans.binding.Bindings;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@ -55,7 +54,6 @@ public abstract class ToolbarListPageSkin<T extends ListPageBase<? extends Node>
if (!toolbarButtons.isEmpty()) {
HBox toolbar = new HBox();
toolbar.setAlignment(Pos.CENTER_LEFT);
JFXDepthManager.setDepth(toolbar, 1);
toolbar.setPickOnBounds(false);
toolbar.getChildren().setAll(toolbarButtons);
root.getContent().add(toolbar);

View File

@ -225,6 +225,21 @@
-fx-font-size: 12px;
}
.two-line-item-second-large {
}
.two-line-item-second-large > FlowPane > .title {
-fx-text-fill: rgba(0, 0, 0, 0.5);
-fx-font-weight: normal;
-fx-font-size: 12px;
}
.two-line-item-second-large > HBox > .subtitle {
-fx-text-fill: #292929;
-fx-font-size: 15px;
}
.bubble {
-fx-background-color: rgba(0, 0, 0, 0.5);
-fx-background-radius: 2px;
@ -466,6 +481,12 @@
-fx-spacing: 8;
}
.jfx-tool-bar-second .label {
-fx-text-fill: -fx-base-text-fill;
-fx-font-size: 16;
-fx-font-weight: bold;
}
.jfx-tool-bar-second .jfx-rippler {
-jfx-rippler-fill: WHITE;
}
@ -756,6 +777,10 @@
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.26), 30, 0.3, 0, 10);
}
.padding-8 {
-fx-padding: 8px;
}
.card {
-fx-background-color: rgba(255, 255, 255, 0.8);
-fx-background-radius: 4;

View File

@ -303,20 +303,25 @@ folder.saves=Saves
folder.screenshots=Screenshots
game=Game
game.crash.duplciated_mod=Duplicated mods: %s.
game.crash.file_changed=Game file corrupted.
game.crash.gl_operation_failure=Game crashed due to some mod, shader packs, texture packs.
game.crash.graphics_driver=Please update graphics driver.
game.crash.illegal_access_error=Game crashed because of %1$s.
game.crash.jdk_9=Please use Java 8.
game.crash.jvm_32bit=Please install 64-bit Java VM.
game.crash.mod=Game crashed because of mod %1$s.
game.crash.no_class_def_found_error=Game corrupted.
game.crash.no_such_method_error=Game corrupted.
game.crash.opengl_not_supported=Please update graphics driver.
game.crash.openj9=OpenJ9 JVM is not accepted.
game.crash.out_of_memory=Out of Memory.
game.crash.too_old_java=Please upgrade Java.
game.crash.info=Game Status
game.crash.reason=Crash Analyzer
game.crash.reason.duplciated_mod=Duplicated mods: %s.
game.crash.reason.file_changed=Game file corrupted.
game.crash.reason.gl_operation_failure=Game crashed due to some mod, shader packs, texture packs.
game.crash.reason.graphics_driver=Please update graphics driver.
game.crash.reason.illegal_access_error=Game crashed because of %1$s.
game.crash.reason.jdk_9=Please use Java 8.
game.crash.reason.jvm_32bit=Please install 64-bit Java VM.
game.crash.reason.mod=Game crashed because of mod %1$s.
game.crash.reason.no_class_def_found_error=Game corrupted.
game.crash.reason.no_such_method_error=Game corrupted.
game.crash.reason.opengl_not_supported=Please update graphics driver.
game.crash.reason.openj9=OpenJ9 JVM is not accepted.
game.crash.reason.out_of_memory=Out of Memory.
game.crash.reason.too_old_java=Please upgrade Java.
game.crash.reason.unknown=Unknown. You can look into details by clicking "Logs" button.
game.crash.title=Game crashed
game.directory=Game Directory
game.version=Game version
help=Help
@ -765,6 +770,9 @@ sponsor=Donations
sponsor.bmclapi=Download services are provided by BMCLAPI and MCBBS. Click here for more information.
sponsor.hmcl=Hello Minecraft! Launcher is a free and open source Minecraft launcher which allows users to easily manage multiple, individual Minecraft installations. We use Afdian to continue to pay for hosting and project development. Click here for more information.
system.architecture=Arch
system.operating_system=OS
update=Update
update.accept=Update
update.changelog=Changes

View File

@ -303,20 +303,25 @@ folder.saves=遊戲存檔資料夾
folder.screenshots=截圖資料夾
game=遊戲
game.crash.duplciated_mod=當前遊戲因為 Mod 重複安裝,無法繼續運行。\n%s\n每種 Mod 只能安裝一個,請你刪除多餘的 Mod 再試。
game.crash.file_changed=當前遊戲因為檔案校驗失敗,無法繼續運行。\n如果你手動修改了 Minecraft.jar 檔案,你需要回退修改,或者重新下載遊戲。
game.crash.gl_operation_failure=當前遊戲因為你使用的某些 Mod、光影包、材質包無法繼續運行。\n請先嘗試禁用你所使用的的光影/材質包再試。
game.crash.graphics_driver=當前遊戲因為你的顯示卡驅動存在問題崩潰了。\n請嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。\n如果你的電腦存在獨立顯示卡你需要檢查遊戲是否使用了集成/核心顯示卡,如果是,請嘗試使用獨立顯示卡啟動 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。
game.crash.illegal_access_error=當前遊戲因為某些 Mod 的問題,無法繼續運行。\n如果你認識%1$s你可以更新或刪除對應 Mod 再試。
game.crash.jdk_9=當前遊戲因為 Java 版本過高,無法繼續運行。\n你需要下載安裝 Java 8並在遊戲設置中將 Java 設置為 1.8 的版本。
game.crash.jvm_32bit=如果你的電腦是 64 位系統,請下載安裝並更換 64 位 Java。如果你的電腦室 32 位系統,你或許可以重新安裝 64 位系統,或換一台新電腦。
game.crash.mod=當前遊戲因為 %1$s 的問題,無法繼續運行。\n你可以更新或刪除已經安裝的 %1$s 再試。
game.crash.no_class_def_found_error=當前遊戲因為代碼不完整,無法繼續運行。\n你的遊戲可能缺失了某個 Mod或者某些 Mod 檔案不完整。\n你可能需要重新安裝遊戲和 Mod或請求他人幫助。
game.crash.no_such_method_error=當前遊戲因為代碼不完整,無法繼續運行。\n你的遊戲可能缺失了某個 Mod或者某些 Mod 檔案不完整。\n你可能需要重新安裝遊戲和 Mod或請求他人幫助。
game.crash.opengl_not_supported=當前遊戲因為你的顯示卡驅動存在問題,無法繼續運行。\n原因是 OpenGL 不受支援,你現在是否在遠程桌面或者串流模式下?如果是,請直接使用原電腦啟動遊戲。\n或者嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。如果你的電腦存在獨立顯示卡你需要檢查遊戲是否使用了集成/核心顯示卡,如果是,請嘗試使用獨立顯示卡啟動 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。
game.crash.openj9=當前遊戲無法運行在 OpenJ9 虛擬機上,請你在遊戲設置中更換 Hotspot Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.out_of_memory=當前遊戲因為記憶體不足,無法繼續運行。\n這可能是記憶體分配太小或者 Mod 數量過多導致的。\n你可以在遊戲設置中調大遊戲記憶體分配值以允許遊戲在更大的記憶體下運行。\n如果仍然出現該錯誤你可能需要換一台更好的電腦。
game.crash.too_old_java=當前遊戲因為 Java 虛擬機版本過低,無法繼續運行。\n你需要在遊戲設置中更換更新版本的 Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.info=遊戲訊息
game.crash.reason=崩潰原因
game.crash.reason.duplciated_mod=當前遊戲因為 Mod 重複安裝,無法繼續運行。\n%s\n每種 Mod 只能安裝一個,請你刪除多餘的 Mod 再試。
game.crash.reason.file_changed=當前遊戲因為檔案校驗失敗,無法繼續運行。\n如果你手動修改了 Minecraft.jar 檔案,你需要回退修改,或者重新下載遊戲。
game.crash.reason.gl_operation_failure=當前遊戲因為你使用的某些 Mod、光影包、材質包無法繼續運行。\n請先嘗試禁用你所使用的的光影/材質包再試。
game.crash.reason.graphics_driver=當前遊戲因為你的顯示卡驅動存在問題崩潰了。\n請嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。\n如果你的電腦存在獨立顯示卡你需要檢查遊戲是否使用了集成/核心顯示卡,如果是,請嘗試使用獨立顯示卡啟動 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。
game.crash.reason.illegal_access_error=當前遊戲因為某些 Mod 的問題,無法繼續運行。\n如果你認識%1$s你可以更新或刪除對應 Mod 再試。
game.crash.reason.jdk_9=當前遊戲因為 Java 版本過高,無法繼續運行。\n你需要下載安裝 Java 8並在遊戲設置中將 Java 設置為 1.8 的版本。
game.crash.reason.jvm_32bit=如果你的電腦是 64 位系統,請下載安裝並更換 64 位 Java。如果你的電腦室 32 位系統,你或許可以重新安裝 64 位系統,或換一台新電腦。
game.crash.reason.mod=當前遊戲因為 %1$s 的問題,無法繼續運行。\n你可以更新或刪除已經安裝的 %1$s 再試。
game.crash.reason.no_class_def_found_error=當前遊戲因為代碼不完整,無法繼續運行。\n你的遊戲可能缺失了某個 Mod或者某些 Mod 檔案不完整。\n你可能需要重新安裝遊戲和 Mod或請求他人幫助。
game.crash.reason.no_such_method_error=當前遊戲因為代碼不完整,無法繼續運行。\n你的遊戲可能缺失了某個 Mod或者某些 Mod 檔案不完整。\n你可能需要重新安裝遊戲和 Mod或請求他人幫助。
game.crash.reason.opengl_not_supported=當前遊戲因為你的顯示卡驅動存在問題,無法繼續運行。\n原因是 OpenGL 不受支援,你現在是否在遠程桌面或者串流模式下?如果是,請直接使用原電腦啟動遊戲。\n或者嘗試升級你的顯示卡驅動到最新版本後再嘗試啟動遊戲。如果你的電腦存在獨立顯示卡你需要檢查遊戲是否使用了集成/核心顯示卡,如果是,請嘗試使用獨立顯示卡啟動 HMCL 與遊戲。如果仍有問題,你可能需要考慮換一個新顯示卡或新電腦。
game.crash.reason.openj9=當前遊戲無法運行在 OpenJ9 虛擬機上,請你在遊戲設置中更換 Hotspot Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.reason.out_of_memory=當前遊戲因為記憶體不足,無法繼續運行。\n這可能是記憶體分配太小或者 Mod 數量過多導致的。\n你可以在遊戲設置中調大遊戲記憶體分配值以允許遊戲在更大的記憶體下運行。\n如果仍然出現該錯誤你可能需要換一台更好的電腦。
game.crash.reason.too_old_java=當前遊戲因為 Java 虛擬機版本過低,無法繼續運行。\n你需要在遊戲設置中更換更新版本的 Java 虛擬機,並重新啟動遊戲。如果沒有下載安裝,你可以在網路上自行下載。
game.crash.reason.unknown=原因未知,請點擊日誌按鈕查看詳細訊息。
game.crash.title=遊戲意外退出
game.directory=遊戲路徑
game.version=遊戲版本
help=說明
@ -764,6 +769,9 @@ sponsor=贊助
sponsor.bmclapi=大中華區下載源由 BMCLAPI 和我的世界中文論壇 (MCBBS) 提供高速下載服務
sponsor.hmcl=Hello Minecraft! Launcher 是一個免費、開源的 Minecraft 啟動器,允許玩家方便快捷地安裝、管理、執行遊戲。您的贊助將幫助 Hello Minecraft! Launcher 獲得更好的發展、支援穩定高速的遊戲安裝與檔案下載服務。點選此處查閱更多詳細訊息。
system.architecture=架構
system.operating_system=操作系統
update=啟動器更新
update.accept=更新
update.changelog=更新日誌

View File

@ -303,20 +303,25 @@ folder.saves=存档文件夹
folder.screenshots=截图文件夹
game=游戏
game.crash.duplciated_mod=当前游戏因为 Mod 重复安装,无法继续运行。\n%s\n每种 Mod 只能安装一个,请你删除多余的 Mod 再试。
game.crash.file_changed=当前游戏因为文件校验失败,无法继续运行。\n如果你手动修改了 Minecraft.jar 文件,你需要回退修改,或者重新下载游戏。
game.crash.gl_operation_failure=当前游戏因为你使用的某些 Mod、光影包、材质包无法继续运行。\n请先尝试禁用你所使用的的光影/材质包再试。
game.crash.graphics_driver=当前游戏因为你的显卡驱动存在问题崩溃了。\n请尝试升级你的显卡驱动到最新版本后再尝试启动游戏。\n如果你的电脑存在独立显卡你需要检查游戏是否使用了集成/核心显卡,如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。
game.crash.illegal_access_error=当前游戏因为某些 Mod 的问题,无法继续运行。\n如果你认识%1$s你可以更新或删除对应 Mod 再试。
game.crash.jdk_9=当前游戏因为 Java 版本过高,无法继续运行。\n你需要下载安装 Java 8并在游戏设置中将 Java 设置为 1.8 的版本。
game.crash.jvm_32bit=如果你的电脑是 64 位系统,请下载安装并更换 64 位 Java。如果你的电脑室 32 位系统,你或许可以重新安装 64 位系统,或换一台新电脑。
game.crash.mod=当前游戏因为 %1$s 的问题,无法继续运行。\n你可以更新或删除已经安装的 %1$s 再试。
game.crash.no_class_def_found_error=当前游戏因为代码不完整,无法继续运行。\n你的游戏可能缺失了某个 Mod或者某些 Mod 文件不完整。\n你可能需要重新安装游戏和 Mod或请求他人帮助。
game.crash.no_such_method_error=当前游戏因为代码不完整,无法继续运行。\n你的游戏可能缺失了某个 Mod或者某些 Mod 文件不完整。\n你可能需要重新安装游戏和 Mod或请求他人帮助。
game.crash.opengl_not_supported=当前游戏因为你的显卡驱动存在问题,无法继续运行。\n原因是 OpenGL 不受支持,你现在是否在远程桌面或者串流模式下?如果是,请直接使用原电脑启动游戏。\n或者尝试升级你的显卡驱动到最新版本后再尝试启动游戏。如果你的电脑存在独立显卡你需要检查游戏是否使用了集成/核心显卡,如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。
game.crash.openj9=当前游戏无法运行在 OpenJ9 虚拟机上,请你在游戏设置中更换 Hotspot Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.out_of_memory=当前游戏因为内存不足,无法继续运行。\n这可能是内存分配太小或者 Mod 数量过多导致的。\n你可以在游戏设置中调大游戏内存分配值以允许游戏在更大的内存下运行。\n如果仍然出现该错误你可能需要换一台更好的电脑。
game.crash.too_old_java=当前游戏因为 Java 虚拟机版本过低,无法继续运行。\n你需要在游戏设置中更换更新版本的 Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.info=游戏信息
game.crash.reason=崩溃原因
game.crash.reason.duplciated_mod=当前游戏因为 Mod 重复安装,无法继续运行。\n%s\n每种 Mod 只能安装一个,请你删除多余的 Mod 再试。
game.crash.reason.file_changed=当前游戏因为文件校验失败,无法继续运行。\n如果你手动修改了 Minecraft.jar 文件,你需要回退修改,或者重新下载游戏。
game.crash.reason.gl_operation_failure=当前游戏因为你使用的某些 Mod、光影包、材质包无法继续运行。\n请先尝试禁用你所使用的的光影/材质包再试。
game.crash.reason.graphics_driver=当前游戏因为你的显卡驱动存在问题崩溃了。\n请尝试升级你的显卡驱动到最新版本后再尝试启动游戏。\n如果你的电脑存在独立显卡你需要检查游戏是否使用了集成/核心显卡,如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。
game.crash.reason.illegal_access_error=当前游戏因为某些 Mod 的问题,无法继续运行。\n如果你认识%1$s你可以更新或删除对应 Mod 再试。
game.crash.reason.jdk_9=当前游戏因为 Java 版本过高,无法继续运行。\n你需要下载安装 Java 8并在游戏设置中将 Java 设置为 1.8 的版本。
game.crash.reason.jvm_32bit=如果你的电脑是 64 位系统,请下载安装并更换 64 位 Java。如果你的电脑室 32 位系统,你或许可以重新安装 64 位系统,或换一台新电脑。
game.crash.reason.mod=当前游戏因为 %1$s 的问题,无法继续运行。\n你可以更新或删除已经安装的 %1$s 再试。
game.crash.reason.no_class_def_found_error=当前游戏因为代码不完整,无法继续运行。\n你的游戏可能缺失了某个 Mod或者某些 Mod 文件不完整。\n你可能需要重新安装游戏和 Mod或请求他人帮助。
game.crash.reason.no_such_method_error=当前游戏因为代码不完整,无法继续运行。\n你的游戏可能缺失了某个 Mod或者某些 Mod 文件不完整。\n你可能需要重新安装游戏和 Mod或请求他人帮助。
game.crash.reason.opengl_not_supported=当前游戏因为你的显卡驱动存在问题,无法继续运行。\n原因是 OpenGL 不受支持,你现在是否在远程桌面或者串流模式下?如果是,请直接使用原电脑启动游戏。\n或者尝试升级你的显卡驱动到最新版本后再尝试启动游戏。如果你的电脑存在独立显卡你需要检查游戏是否使用了集成/核心显卡,如果是,请尝试使用独立显卡启动 HMCL 与游戏。如果仍有问题,你可能需要考虑换一个新显卡或新电脑。
game.crash.reason.openj9=当前游戏无法运行在 OpenJ9 虚拟机上,请你在游戏设置中更换 Hotspot Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.reason.out_of_memory=当前游戏因为内存不足,无法继续运行。\n这可能是内存分配太小或者 Mod 数量过多导致的。\n你可以在游戏设置中调大游戏内存分配值以允许游戏在更大的内存下运行。\n如果仍然出现该错误你可能需要换一台更好的电脑。
game.crash.reason.too_old_java=当前游戏因为 Java 虚拟机版本过低,无法继续运行。\n你需要在游戏设置中更换更新版本的 Java 虚拟机,并重新启动游戏。如果没有下载安装,你可以在网上自行下载。
game.crash.reason.unknown=原因未知,请点击日志按钮查看详细信息。
game.crash.title=游戏意外退出
game.directory=游戏路径
game.version=游戏版本
help=帮助
@ -764,6 +769,9 @@ sponsor=赞助
sponsor.bmclapi=国内下载源由 BMCLAPI 和我的世界中文论坛 (MCBBS) 提供高速下载服务。BMCLAPI 是公益服务,请赞助 BMCLAPI 以获得稳定高速的下载服务,点击此处查阅详细信息。
sponsor.hmcl=Hello Minecraft! Launcher 是一个免费、自由、开放源代码的 Minecraft 启动器。您的赞助将帮助 Hello Minecraft! Launcher 获得更好的发展,还可以获得 HMCL 的开发进展。点击此处查阅更多详细信息。
system.architecture=架构
system.operating_system=操作系统
update=启动器更新
update.accept=更新
update.changelog=更新日志