From 98213cff67a9d8356ffc70681cc8a10b2fe07053 Mon Sep 17 00:00:00 2001 From: WYH2004 <32890512+WYH2004-MC@users.noreply.github.com> Date: Fri, 25 Oct 2024 20:20:26 +0800 Subject: [PATCH] [+] ShowErrorLog (#74) * [+] ShowErrorLog * [O] Fixed spelling errors in method names --- AquaMai/AquaMai.toml | 4 ++ AquaMai/AquaMai.zh.toml | 2 + AquaMai/Config.cs | 1 + AquaMai/Utils/ShowErrorLog.cs | 96 +++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 AquaMai/Utils/ShowErrorLog.cs diff --git a/AquaMai/AquaMai.toml b/AquaMai/AquaMai.toml index dd0529c3..52e1addb 100644 --- a/AquaMai/AquaMai.toml +++ b/AquaMai/AquaMai.toml @@ -100,6 +100,10 @@ JudgeAdjustB=0.0 TouchDelay=0 # Show detail of selected song in music selection screen SelectionDetail=true +# Show Network error detail in the game +ShowNetErrorDetail=true +# Show error log in the game +ShowErrorLog=false # Display framerate FrameRateDisplay=false # Practice mode, activated by pressing Test in the game diff --git a/AquaMai/AquaMai.zh.toml b/AquaMai/AquaMai.zh.toml index d5a66711..1f6dd10f 100644 --- a/AquaMai/AquaMai.zh.toml +++ b/AquaMai/AquaMai.zh.toml @@ -120,6 +120,8 @@ TouchDelay=0 SelectionDetail=true # 出现灰网时显示原因 ShowNetErrorDetail=true +# 在游戏中显示错误日志窗口而不是关闭游戏进程 +ShowErrorLog=false # 显示帧率 FrameRateDisplay=false # 练习模式,在游戏中按 Test 打开 diff --git a/AquaMai/Config.cs b/AquaMai/Config.cs index d052d428..8dd33dd1 100644 --- a/AquaMai/Config.cs +++ b/AquaMai/Config.cs @@ -74,6 +74,7 @@ namespace AquaMai public bool PractiseMode { get; set; } public bool SelectionDetail { get; set; } public bool ShowNetErrorDetail { get; set; } + public bool ShowErrorLog { get; set; } public bool FrameRateDisplay { get; set; } public int TouchPanelBaudRate { get; set; } } diff --git a/AquaMai/Utils/ShowErrorLog.cs b/AquaMai/Utils/ShowErrorLog.cs new file mode 100644 index 00000000..b0e5fe6d --- /dev/null +++ b/AquaMai/Utils/ShowErrorLog.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading; +using AquaMai.Helpers; +using HarmonyLib; +using Main; +using MelonLoader; +using UnityEngine; + +namespace AquaMai.Utils; + +public class ShowErrorLog +{ + private static Ui _errorUi; + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameMain), "ExceptionHandler")] + private static void ExceptionHandler(GameMain __instance, Exception e) + { + if (_errorUi == null) + { + _errorUi = new GameObject("ErrorUI").AddComponent(); + _errorUi.gameObject.SetActive(true); + } + string logFile = $"{MAI2System.Path.ErrorLogPath}{DateTime.Now:yyyyMMddHHmmss}.log"; + MelonLogger.Msg("Error Log:"); + if (File.Exists(logFile)) + { + MelonLogger.Error(File.ReadAllText(logFile)); + _errorUi.SetErrorLog(File.ReadAllText(logFile)); + } + else + { + MelonLogger.Error(e); + _errorUi.SetErrorLog(e.ToString()); + } + + Application.quitting += ApplicationOnQuitting; + _errorUi.StartCoroutine(_errorUi.Show()); + } + + private static void ApplicationOnQuitting() + { + Thread.Sleep(Timeout.Infinite); + } + + private class Ui : MonoBehaviour + { + private string _errorLog = ""; + + public void SetErrorLog(string text) + { + _errorLog = "Error Log:\n" + text; + } + + public void OnGUI() + { + var labelStyle = new GUIStyle(GUI.skin.label) + { + fontSize = GuiSizes.FontSize, + alignment = TextAnchor.MiddleLeft, + normal = new GUIStyleState(){textColor = Color.black} + }; + + var boxStyle = new GUIStyle(GUI.skin.box) + { + normal = new GUIStyleState() { background = Texture2D.whiteTexture } + }; + + int logLineCount = Regex.Matches(_errorLog, "\n").Count + 1; + float offset = GuiSizes.PlayerCenter * 0.12f; + var x = GuiSizes.PlayerCenter / 2f + offset / 2f; + var y = Screen.height / 1.8f; + var width = GuiSizes.PlayerCenter - offset; + var height = GuiSizes.LabelHeight * logLineCount + GuiSizes.Margin * 2; + + GUI.Box(new Rect(x, y, width, height), "", boxStyle); + GUI.Label(new Rect(x, y, width, height), _errorLog, labelStyle); + if (!AquaMai.AppConfig.UX.SinglePlayer) + { + GUI.Box(new Rect(x + GuiSizes.PlayerWidth, y, width, height), "", boxStyle); + GUI.Label(new Rect(x + GuiSizes.PlayerWidth, y, width, height), _errorLog, labelStyle); + } + } + + public IEnumerator Show() + { + while (true) + { + yield return null; // 让 Unity 处理一帧 + } + } + } +} \ No newline at end of file