using System; using System.Collections.Generic; using System.Text; using ColdMint.scripts.openObserve; using ColdMint.scripts.utils; using Godot; namespace ColdMint.scripts.debug; public static class LogCat { public static class LogLabel { /// /// Default log label /// 默认的日志标签 /// public const string Default = "Default"; /// /// LookForWeaponProcessor /// 查找武器处理器 /// public const string LookForWeaponProcessor = "LookForWeaponProcessor"; /// /// PatrolStateProcessor /// 巡逻状态处理器 /// public const string PatrolStateProcessor = "PatrolStateProcessor"; /// /// CampManager /// 阵营管理器 /// public const string CampManager = "CampManager"; /// /// State context /// 状态上下文 /// public const string StateContext = "StateContext"; /// /// StateMachineTemplate /// 状态机模板 /// public const string StateMachineTemplate = "StateMachineTemplate"; /// /// Pursuit enemy processor /// 追击敌人处理器 /// public const string ChaseStateProcessor = "ChaseStateProcessor"; /// /// BubbleMarker /// 气泡标记 /// public const string BubbleMarker = "BubbleMarker"; /// /// LogCollector /// 日志收集器 /// public const string LogCollector = "LogCollector"; /// /// Mod Loader /// 模组加载器 /// public const string ModLoader = "ModLoader"; } /// /// Information log level /// 信息日志等级 /// public const int InfoLogLevel = 0; /// /// Warning level /// 警告等级 /// public const int WarningLogLevel = 1; /// /// Error log level /// 错误日志等级 /// public const int ErrorLogLevel = 2; /// ///Disable all logs ///禁用所有日志 /// public const int DisableAllLogLevel = int.MaxValue; private static int _minLogLevel = InfoLogLevel; /// /// Set the minimum log level /// 设置最小日志等级 /// /// ///Set a value for it so that LogCat only prints logs with a level higher than the set value. ///为其设置一个值,使LogCat仅打印等级高于设定值的日志。 /// public static int MinLogLevel { get => _minLogLevel; set => _minLogLevel = value; } /// /// Whether to upload logs that need to be formatted by default /// 是否默认上传需要格式化的日志 /// public static bool UploadFormat { get; set; } = true; private static readonly StringBuilder StringBuilder = new StringBuilder(); /// /// Disabled log label /// 禁用的日志标签 /// private static HashSet DisabledLogLabels { get; } = []; /// /// Disable log Label /// 禁用某个日志标签 /// /// ///label ///标签名称 /// /// ///Returns whether the function is disabled successfully ///返回是否禁用成功 /// public static bool DisableLogLabel(string label) { return DisabledLogLabels.Add(label); } /// /// Whether a label is enabled /// 某个标签是否处于启用状态 /// /// ///label ///标签名称 /// /// ///Whether enabled ///是否处于启用 /// public static bool IsEnabledLogLabel(string label) { return !DisabledLogLabels.Contains(label); } /// /// EnableLogLabel /// 启用某个日志标签 /// /// ///label /// 标签名称 /// /// ///Returns whether the function is enabled successfully ///返回是否启用成功 /// public static bool EnableLogLabel(string label) { return DisabledLogLabels.Remove(label); } private static StringBuilder HandleMessage(int level, string message, string label) { StringBuilder.Clear(); switch (level) { case InfoLogLevel: StringBuilder.Append("INFO"); break; case WarningLogLevel: StringBuilder.Append("WARNING"); break; case ErrorLogLevel: StringBuilder.Append("ERROR"); break; default: StringBuilder.Append("INFO"); break; } StringBuilder.Append(DateTime.Now.ToString(" (K)yyyy-MM-d hh:mm:ss.fff ")); StringBuilder.Append(label); StringBuilder.Append(" :"); var key = $"log_{message}"; var translationResult = TranslationServerUtils.Translate(key); StringBuilder.Append(translationResult == key ? message : translationResult); return StringBuilder; } /// /// Print log /// 打印日志 /// /// ///message ///消息 /// This message supports localized output, assuming there is already a translation key, Hello = 你好, passing hello will output 你好. /// 这个消息支持本地化输出,假设已存在翻译key,Hello = 你好,传入Hello则会输出你好。 /// /// /// /// /// public static void Log(string message, string label = LogLabel.Default, bool upload = true) { PrintLog(InfoLogLevel, HandleMessage(InfoLogLevel, message, label).ToString(), label, upload); } private static void PrintLog(int level, string concreteLog, string label, bool upload) { if (!IsEnabledLogLabel(label)) { return; } if (_minLogLevel > InfoLogLevel) { return; } //If you need to upload logs, you can upload logs. //如果需要上传日志,并且能够上传日志。 if (LogCollector.CanUploadLog && upload) { var logData = new LogData { Level = level, Message = concreteLog }; #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed LogCollector.Push(logData); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } switch (level) { case WarningLogLevel: GD.Print(concreteLog); break; case ErrorLogLevel: GD.PrintErr(concreteLog); break; default: GD.Print(concreteLog); break; } } /// /// Print error log /// 打印错误日志 /// /// ///message ///消息 /// This message supports localized output, assuming there is already a translation key, Hello = 你好, passing hello will output 你好. /// 这个消息支持本地化输出,假设已存在翻译key,Hello = 你好,传入Hello则会输出你好。 /// /// /// public static void LogError(string message, string label = LogLabel.Default, bool upload = true) { PrintLog(ErrorLogLevel, HandleMessage(ErrorLogLevel, message, label).ToString(), label, upload); } public static void LogWarning(string message, string label = LogLabel.Default, bool upload = true) { PrintLog(WarningLogLevel, HandleMessage(WarningLogLevel, message, label).ToString(), label, upload); } public static void LogErrorWithFormat(string message, string label, bool upload, params object?[] args) { PrintLog(ErrorLogLevel, string.Format(HandleMessage(ErrorLogLevel, message, label).ToString(), args), label, upload); } public static void LogWithFormat(string message, string label, bool upload, params object?[] args) { PrintLog(InfoLogLevel, string.Format(HandleMessage(InfoLogLevel, message, label).ToString(), args), label, upload); } public static void LogWarningWithFormat(string message, string label, bool upload, params object?[] args) { PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label, upload); } /// /// This method is called when an exception is caught /// 当捕获异常后调用此方法 /// /// /// public static void WhenCaughtException(Exception e, string label = LogLabel.Default) { if (!IsEnabledLogLabel(label)) { return; } //Log an exception here or send it to the server. //请在这里记录异常或将异常发送至服务器。 PrintLog(ErrorLogLevel, HandleMessage(ErrorLogLevel, e.Message, label).Append('\n').Append(e.StackTrace).ToString(), label, true); } }