From 0b5e2c3217997bd76f5ba578593fc0dbb8cb0244 Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Mon, 15 Jul 2024 20:37:30 +0800 Subject: [PATCH] =?UTF-8?q?Upload=20logs=20to=20the=20server.=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=B8=8A=E4=BC=A0=E6=97=A5=E5=BF=97=E5=88=B0=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + README.md | 28 ++ README_JA.md | 28 ++ README_ZH.md | 28 ++ locals/Log.csv | 8 +- scripts/AppConfig.cs | 82 ++++++ scripts/Config.cs | 6 + scripts/bubble/BubbleMarker.cs | 4 +- scripts/camp/CampManager.cs | 2 +- scripts/character/CharacterTemplate.cs | 4 +- scripts/character/Player.cs | 2 +- scripts/debug/LogCat.cs | 120 ++++---- scripts/inventory/ItemTypeRegister.cs | 14 +- scripts/loader/uiLoader/MainMenuLoader.cs | 268 +++++++++--------- scripts/loot/LootList.cs | 6 +- scripts/map/MapGenerator.cs | 10 +- scripts/map/room/Room.cs | 4 +- scripts/openObserve/LogCollector.cs | 139 +++++++++ scripts/stateMachine/IStateContext.cs | 2 +- scripts/stateMachine/StateMachineTemplate.cs | 2 +- .../StateProcessor/PatrolStateProcessor.cs | 6 +- scripts/utils/NodeUtils.cs | 3 +- scripts/utils/TimeUtils.cs | 2 +- 23 files changed, 540 insertions(+), 229 deletions(-) create mode 100644 scripts/AppConfig.cs create mode 100644 scripts/openObserve/LogCollector.cs diff --git a/.gitignore b/.gitignore index 1ebcbdd..dbf6167 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ export_presets.cfg .vs/ *.translation *.user +AppConfig.yaml \ No newline at end of file diff --git a/README.md b/README.md index 60c9eb4..845c392 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,34 @@ You need to fill in the Export Presets > Resources > Filter to export non-resour data/* ``` +## Configuring Openobserve + +> This is optional, and the game will work even if you do not configure Openobserve. + +openobserve is used to continuously collect logs and alarm information after a game has been released. + +#### Set up the openobserve server + +see:[openobserve](https://github.com/openobserve/openobserve) + +#### Write configuration + +After you have set up an openobserve server, follow the following steps to configure the file: + +1. Create a configuration file named **AppConfig.yaml** in the root directory of your project. + +2. Fill in the information for the remote server. + + ```yaml + open_observe: + address: [address] + access_token: [token] + org_id: [org_id] + stream_name: [stream_name] + ``` + + address Indicates the address of the server in the format of http(s)://www.example.com. (Support http and https) + ## Participate in translation The project is prepared for localization at the beginning of writing. You can edit the csv file in the locals directory. To modify and add new translations. diff --git a/README_JA.md b/README_JA.md index 3ba5955..0608bf5 100644 --- a/README_JA.md +++ b/README_JA.md @@ -50,6 +50,34 @@ git clone https://github.com/Cold-Mint/Traveller.git data/* ``` +## はいちOpenobserve + +> これはオプションなので、Openobserveを設定しなくてもゲームは正常に動作します。 + +openobserveは、リリース後にログやアラームを継続的に収集するために使用されます。 + +#### 搭建openobserve衣服务器 + +読み過ごす:[openobserve](https://github.com/openobserve/openobserve) + +#### 構成を書きます + +openobserveのサーバーを構築したら、次のようにファイルを設定します。 + +1. プロジェクトのルートディレクトリに**AppConfig.yaml **というプロファイルを作成します。 + +2. リモートサーバーの情報を入力します。 + + ```yaml + open_observe: + address: [address] + access_token: [token] + org_id: [org_id] + stream_name: [stream_name] + ``` + + address サーバーのアドレス、フォーマットはこうなります http(s)://www.example.com。(支持http和https) + ## 翻訳に携わります このプロジェクトは、当初からローカライズの準備ができていました。localsディレクトリのcsvファイルを編集することができます。新しい翻訳を加えたり修正したりしています diff --git a/README_ZH.md b/README_ZH.md index 83a0c80..5cef5e2 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -52,6 +52,34 @@ git clone https://github.com/Cold-Mint/Traveller.git data/* ``` +## 配置Openobserve + +> 这是可选的操作,即使您不配置Openobserve,游戏也能正常运行。 + +openobserve用于在游戏发布后,持续收集日志和报警信息。 + +#### 搭建openobserve服务器 + +请见:[openobserve](https://github.com/openobserve/openobserve) + +#### 编写配置 + +在您搭建完毕openobserve的服务器后,按如下步骤配置文件: + +1. 在项目的根目录创建名为**AppConfig.yaml**的配置文件。 + +2. 填入远程服务器的信息。 + + ```yaml + open_observe: + address: [address] + access_token: [token] + org_id: [org_id] + stream_name: [stream_name] + ``` + + address 服务器的地址,格式为 http(s)://www.example.com。(支持http和https) + ## 参与翻译 此项目在编写之初就为本地化做好了准备。您可以编辑locals目录下的csv文件。来修改和添加新的翻译。 diff --git a/locals/Log.csv b/locals/Log.csv index 7186f21..f23d688 100644 --- a/locals/Log.csv +++ b/locals/Log.csv @@ -23,7 +23,7 @@ log_player_packed_scene_not_exist,玩家预制场景不存在。,Player packed s log_exit_the_room_debug,节点{0}退出房间{1}。,"Node {0} exits room {1}.",ノード{0}が部屋{1}を退出します。 log_enter_the_room_debug,节点{0}进入房间{1}。,"Node {0} enters room {1}.",ノード{0}が部屋{1}に入ります。 log_death_info,生物{0}被{1}击败。,"Creature {0} was defeated by {1}.",生物{0}が{1}によって打ち負かされました。 - +log_appConfig_not_exist,您可以在项目根目录创建名为AppConfig.yaml的文件,并在其中配置OpenObserve的数据,以便在游戏发布后持续收集日志和运行数据。,You can create a file named AppConfig.yaml in the project root directory and configure OpenObserve data in it to collect log and run data continuously after the game has been released.,プロジェクトのルートディレクトリにappconfig.yamlというファイルを作成し、そこにOpenObserveのデータを配置して、リリース後も継続的にログや実行データを収集することができます。 log_loot_list_has_no_entries,ID为{0}的战利品表,没有指定条目。,"Loot list with ID {0}, no entry specified.",ID{0}の戦利品テーブルは、エントリ指定されていません。 log_not_within_the_loot_spawn_range,给定的数值{0}没有在战利品{1}的生成范围{2}内。,The given value {0} is not within the spawn range {2} of loot {1}.,与えられた数値{0}は戦利品{1}の生成範囲{2}内にありません。 log_loot_data_quantity,有{0}个战利品数据被返回。,{0} loot data was returned.,{0}個の戦利品データが返されます。 @@ -75,4 +75,8 @@ log_owner_is_not_AiCharacter,所有者不是AiCharacter。,Owner is not AiCharac log_weaponContainer_is_null,武器容器为空。,Weapon container is null.,武器コンテナが空です。 log_find_nearest_item,查找最近的物品。,Find the nearest item.,最も近いアイテムを見つけます。 log_float_label_instantiate_failed,浮动标签实例化失败。,Float label instantiation failed.,フロートラベルのインスタンス化に失敗しました。 -log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。 \ No newline at end of file +log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。 +log_start_uploading,开始上传{0}条日志。,Start uploading {0} logs.,{0}個のログをアップロードを開始します。 +log_upload_successful,上传成功,已上传{0}条日志,剩余{1}条日志待上传。,"Upload successful, {0} logs uploaded, {1} logs remaining.",アップロードが成功しました、{0}個のログがアップロードされ、{1}個のログが残っています。 +log_upload_failed,上传失败,错误代码:{0},剩余{1}条日志待上传。,"Upload failed, error code: {0}, {1} logs remaining.",アップロードに失敗しました、エラーコード:{0}、{1}個のログが残っています。 +log_upload_status,已记录{0}条日志,上传阈值为{1}。,"{0} logs recorded, upload threshold is {1}.",{0}個のログが記録され、アップロード閾値は{1}です。 \ No newline at end of file diff --git a/scripts/AppConfig.cs b/scripts/AppConfig.cs new file mode 100644 index 0000000..9b19987 --- /dev/null +++ b/scripts/AppConfig.cs @@ -0,0 +1,82 @@ +using ColdMint.scripts.debug; +using ColdMint.scripts.openObserve; +using ColdMint.scripts.serialization; +using Godot; + +namespace ColdMint.scripts; + +public class AppConfig +{ + /// + /// Load configuration from file + /// 从文件加载配置 + /// + public static AppConfigData? LoadFromFile() + { + var appConfigExists = FileAccess.FileExists(Config.AppConfigPath); + if (!appConfigExists) + { + LogCat.LogWarning("appConfig_not_exist"); + return null; + } + + var appConfigFileAccess = FileAccess.Open(Config.AppConfigPath, FileAccess.ModeFlags.Read); + var yamlData = appConfigFileAccess.GetAsText(); + appConfigFileAccess.Close(); + return YamlSerialization.Deserialize(yamlData); + } + + + /// + /// ApplyAppConfig + /// 应用配置 + /// + /// + public static void ApplyAppConfig(AppConfigData appConfigData) + { + if (appConfigData.OpenObserve != null) + { + LogCollector.UpdateHttpClient(appConfigData.OpenObserve); + } + } +} + +public class AppConfigData +{ + /// + /// OpenObserve configuration information + /// OpenObserve的配置信息 + /// + public OpenObserve? OpenObserve { get; set; } +} + +/// +/// OpenObserve Configuration information +/// OpenObserve配置信息 +/// +public class OpenObserve +{ + /// + /// server address + /// 服务器地址 + /// + public string? Address { get; set; } + + /// + /// Access Token + /// 访问密匙 + /// + public string? AccessToken { get; set; } + + /// + /// Organization ID + /// 组织ID + /// + public string? OrgId { get; set; } + + /// + /// Stream Name + /// 流名称 + /// + public string? StreamName { get; set; } +} \ No newline at end of file diff --git a/scripts/Config.cs b/scripts/Config.cs index fa14572..d626cbb 100644 --- a/scripts/Config.cs +++ b/scripts/Config.cs @@ -85,6 +85,12 @@ public static class Config public const string Aborigines = "Aborigines"; } + /// + /// Path of the App configuration file + /// App配置文件路径 + /// + public const string AppConfigPath = "res://AppConfig.yaml"; + /// /// The percentage of speed reduced after a thrown item hits an enemy /// 抛出的物品击中敌人后减少的速度百分比 diff --git a/scripts/bubble/BubbleMarker.cs b/scripts/bubble/BubbleMarker.cs index 263f72b..959e2c6 100644 --- a/scripts/bubble/BubbleMarker.cs +++ b/scripts/bubble/BubbleMarker.cs @@ -45,7 +45,7 @@ public partial class BubbleMarker : Marker2D { if (!_bubbleDictionary.TryGetValue(id, out var value)) { - LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, id); + LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, LogCat.UploadFormat,id); return; } @@ -60,7 +60,7 @@ public partial class BubbleMarker : Marker2D { if (!_bubbleDictionary.TryGetValue(id, out var value)) { - LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, id); + LogCat.LogErrorWithFormat("bubble_not_found", LogCat.LogLabel.BubbleMarker, LogCat.UploadFormat,id); return; } diff --git a/scripts/camp/CampManager.cs b/scripts/camp/CampManager.cs index c944ec8..3ee99c3 100644 --- a/scripts/camp/CampManager.cs +++ b/scripts/camp/CampManager.cs @@ -40,7 +40,7 @@ public static class CampManager if (camp.Id != Config.CampId.Default) return false; _defaultCamp = camp; AddCamp(camp); - LogCat.LogWithFormat("set_default_camp", label: LogCat.LogLabel.CampManager, camp.Id); + LogCat.LogWithFormat("set_default_camp", label: LogCat.LogLabel.CampManager, LogCat.UploadFormat, camp.Id); return true; } diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index 0a540dd..baf6e6f 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -585,12 +585,12 @@ public partial class CharacterTemplate : CharacterBody2D if (damageTemplate.Attacker is CharacterTemplate characterTemplate && !string.IsNullOrEmpty(characterTemplate.CharacterName)) { - LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, CharacterName, + LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, LogCat.UploadFormat,CharacterName, characterTemplate.CharacterName); } else { - LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, CharacterName, + LogCat.LogWithFormat("death_info", LogCat.LogLabel.Default, LogCat.UploadFormat,CharacterName, damageTemplate.Attacker.Name); } } diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs index 380ee9e..384161b 100644 --- a/scripts/character/Player.cs +++ b/scripts/character/Player.cs @@ -48,7 +48,7 @@ public partial class Player : CharacterTemplate { base._Ready(); CharacterName = TranslationServerUtils.Translate("default_player_name"); - LogCat.LogWithFormat("player_spawn_debug", LogCat.LogLabel.Default, ReadOnlyCharacterName, + LogCat.LogWithFormat("player_spawn_debug", LogCat.LogLabel.Default, LogCat.UploadFormat,ReadOnlyCharacterName, GlobalPosition); var floatLabelPackedScene = GD.Load("res://prefab/ui/FloatLabel.tscn"); //Initializes the float label. diff --git a/scripts/debug/LogCat.cs b/scripts/debug/LogCat.cs index b59e859..4cb198c 100644 --- a/scripts/debug/LogCat.cs +++ b/scripts/debug/LogCat.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using ColdMint.scripts.openObserve; using ColdMint.scripts.utils; using Godot; @@ -27,19 +28,19 @@ public static class LogCat /// 阵营管理器 /// public const string CampManager = "CampManager"; - + /// /// State context /// 状态上下文 /// public const string StateContext = "StateContext"; - + /// /// StateMachineTemplate /// 状态机模板 /// public const string StateMachineTemplate = "StateMachineTemplate"; - + /// /// Pursuit enemy processor /// 追击敌人处理器 @@ -50,7 +51,13 @@ public static class LogCat /// BubbleMarker /// 气泡标记 /// - public static string BubbleMarker = "BubbleMarker"; + public const string BubbleMarker = "BubbleMarker"; + + /// + /// LogCollector + /// 日志收集器 + /// + public const string LogCollector = "LogCollector"; } @@ -94,6 +101,12 @@ public static class LogCat 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(); /// @@ -194,7 +207,14 @@ public static class LogCat /// /// /// - public static void Log(string message, string label = LogLabel.Default) + /// + /// + 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)) { @@ -206,7 +226,18 @@ public static class LogCat return; } - GD.Print(HandleMessage(InfoLogLevel, message, label)); + if (LogCollector.CanUploadLog && upload) + { + var logData = new LogData + { + Level = level, + Message = concreteLog, + AppId = "none" + }; + LogCollector.Push(logData); + } + + GD.Print(concreteLog); } /// @@ -220,80 +251,34 @@ public static class LogCat /// 这个消息支持本地化输出,假设已存在翻译key,Hello = 你好,传入Hello则会输出你好。 /// /// - public static void LogError(string message, string label = LogLabel.Default) + /// + public static void LogError(string message, string label = LogLabel.Default, bool upload = true) { - if (!IsEnabledLogLabel(label)) - { - return; - } - - if (_minLogLevel > ErrorLogLevel) - { - return; - } - - GD.PrintErr(HandleMessage(ErrorLogLevel, message, label)); + PrintLog(ErrorLogLevel, HandleMessage(ErrorLogLevel, message, label).ToString(), label, upload); } - public static void LogWarning(string message, string label = LogLabel.Default) + public static void LogWarning(string message, string label = LogLabel.Default, bool upload = true) { - if (!IsEnabledLogLabel(label)) - { - return; - } - - if (_minLogLevel > WarningLogLevel) - { - return; - } - - GD.Print(HandleMessage(WarningLogLevel, message, label)); + PrintLog(WarningLogLevel, HandleMessage(WarningLogLevel, message, label).ToString(), label, upload); } - public static void LogErrorWithFormat(string message, string label, params object?[] args) + public static void LogErrorWithFormat(string message, string label, bool upload, params object?[] args) { - if (!IsEnabledLogLabel(label)) - { - return; - } - - if (_minLogLevel > ErrorLogLevel) - { - return; - } - - GD.PrintErr(string.Format(HandleMessage(ErrorLogLevel, message, label).ToString(), args)); + PrintLog(WarningLogLevel, string.Format(HandleMessage(ErrorLogLevel, message, label).ToString(), args), label, + upload); } - public static void LogWithFormat(string message, string label, params object?[] args) + public static void LogWithFormat(string message, string label, bool upload, params object?[] args) { - if (!IsEnabledLogLabel(label)) - { - return; - } - - if (_minLogLevel > InfoLogLevel) - { - return; - } - - GD.Print(string.Format(HandleMessage(InfoLogLevel, message, label).ToString(), args)); + PrintLog(InfoLogLevel, string.Format(HandleMessage(InfoLogLevel, message, label).ToString(), args), label, + upload); } - public static void LogWarningWithFormat(string message, string label, params object?[] args) + public static void LogWarningWithFormat(string message, bool upload, string label, params object?[] args) { - if (!IsEnabledLogLabel(label)) - { - return; - } - - if (_minLogLevel > InfoLogLevel) - { - return; - } - - GD.Print(string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args)); + PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label, + upload); } /// @@ -311,6 +296,7 @@ public static class LogCat //Log an exception here or send it to the server. //请在这里记录异常或将异常发送至服务器。 - GD.PrintErr(HandleMessage(ErrorLogLevel, e.Message, label).Append('\n').Append(e.StackTrace)); + PrintLog(ErrorLogLevel, + HandleMessage(ErrorLogLevel, e.Message, label).Append('\n').Append(e.StackTrace).ToString(), label, true); } } \ No newline at end of file diff --git a/scripts/inventory/ItemTypeRegister.cs b/scripts/inventory/ItemTypeRegister.cs index 3a55fd4..7ab2fed 100644 --- a/scripts/inventory/ItemTypeRegister.cs +++ b/scripts/inventory/ItemTypeRegister.cs @@ -36,7 +36,7 @@ public static class ItemTypeRegister var error = DirAccess.GetOpenError(); if (error is not Error.Ok) { - LogCat.LogError("error_when_open_item_regs_dir",error.ToString()); + LogCat.LogError("error_when_open_item_regs_dir", error.ToString()); } //找到文件 @@ -44,16 +44,16 @@ public static class ItemTypeRegister var files = itemRegsDir.GetFiles(); if (files == null) { - LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, 0); + LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, LogCat.UploadFormat, 0); return; } - LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, files.Length); + LogCat.LogWithFormat("found_files", LogCat.LogLabel.Default, LogCat.UploadFormat, files.Length); //将文件解析为项目类型信息 //parse files to item type infos IEnumerable typeInfos = files.SelectMany(file => ParseFile($"{itemRegsDirPath}/{file}")).ToList(); - LogCat.LogWithFormat("found_item_types", LogCat.LogLabel.Default, typeInfos.Count()); + LogCat.LogWithFormat("found_item_types", LogCat.LogLabel.Default, LogCat.UploadFormat, typeInfos.Count()); //遍历类型信息并注册它们。 //traverse type infos and register them. @@ -120,7 +120,8 @@ public static class ItemTypeRegister }, icon, typeInfo.MaxStackValue); var succeed = ItemTypeManager.Register(itemType); - LogCat.LogWithFormat("register_item", label: LogCat.LogLabel.Default, itemType.Id, succeed); + LogCat.LogWithFormat("register_item", label: LogCat.LogLabel.Default, LogCat.UploadFormat, itemType.Id, + succeed); } //Use for yaml deserialization @@ -151,7 +152,8 @@ public static class ItemTypeRegister var ss = s.Split(','); if (ss.Length != 2) { - LogCat.LogErrorWithFormat("wrong_custom_arg", LogCat.LogLabel.Default, "Vector2", s); + LogCat.LogErrorWithFormat("wrong_custom_arg", LogCat.LogLabel.Default, LogCat.UploadFormat, "Vector2", + s); return Vector2.Zero; } diff --git a/scripts/loader/uiLoader/MainMenuLoader.cs b/scripts/loader/uiLoader/MainMenuLoader.cs index 5c19867..b4fe177 100644 --- a/scripts/loader/uiLoader/MainMenuLoader.cs +++ b/scripts/loader/uiLoader/MainMenuLoader.cs @@ -20,148 +20,154 @@ namespace ColdMint.scripts.loader.uiLoader; /// public partial class MainMenuLoader : UiLoaderTemplate { - private Button? _startGameButton; - private Label? _copyrightLabel; - private StringBuilder? _copyrightBuilder; - private PackedScene? _gameScene; - private PackedScene? _contributor; - private PackedScene? _levelGraphEditor; - private Label? _sloganLabel; - private Label? _versionLabel; - private Button? _levelGraphEditorButton; - private LinkButton? _contributorButton; + private Button? _startGameButton; + private Label? _copyrightLabel; + private StringBuilder? _copyrightBuilder; + private PackedScene? _gameScene; + private PackedScene? _contributor; + private PackedScene? _levelGraphEditor; + private Label? _sloganLabel; + private Label? _versionLabel; + private Button? _levelGraphEditorButton; + private LinkButton? _contributorButton; - public override void InitializeData() - { - if (Config.IsDebug()) - { - //Set the minimum log level to Info in debug mode.(Print all logs) - //在调试模式下将最小日志等级设置为Info。(打印全部日志) - LogCat.MinLogLevel = LogCat.InfoLogLevel; - } - else - { - //Disable all logs in the release version. - //在发行版禁用所有日志。 - LogCat.MinLogLevel = LogCat.DisableAllLogLevel; - } + public override void InitializeData() + { + AppConfigData? appConfigData = AppConfig.LoadFromFile(); + if (appConfigData != null) + { + AppConfig.ApplyAppConfig(appConfigData); + } - ContributorDataManager.RegisterAllContributorData(); - DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler()); - MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor()); - MapGenerator.RegisterRoomInjectionProcessor(new TimeIntervalRoomInjectorProcessor()); - //Register the corresponding encoding provider to solve the problem of garbled Chinese path of the compressed package - //注册对应的编码提供程序,解决压缩包中文路径乱码问题 - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - //创建游戏数据文件夹 - var dataPath = Config.GetGameDataDirectory(); - if (!Directory.Exists(dataPath)) - { - Directory.CreateDirectory(dataPath); - } + if (Config.IsDebug()) + { + //Set the minimum log level to Info in debug mode.(Print all logs) + //在调试模式下将最小日志等级设置为Info。(打印全部日志) + LogCat.MinLogLevel = LogCat.InfoLogLevel; + } + else + { + //Disable all logs in the release version. + //在发行版禁用所有日志。 + LogCat.MinLogLevel = LogCat.DisableAllLogLevel; + } + + ContributorDataManager.RegisterAllContributorData(); + DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler()); + MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor()); + MapGenerator.RegisterRoomInjectionProcessor(new TimeIntervalRoomInjectorProcessor()); + //Register the corresponding encoding provider to solve the problem of garbled Chinese path of the compressed package + //注册对应的编码提供程序,解决压缩包中文路径乱码问题 + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + //创建游戏数据文件夹 + var dataPath = Config.GetGameDataDirectory(); + if (!Directory.Exists(dataPath)) + { + Directory.CreateDirectory(dataPath); + } - //Registered camp - //注册阵营 - var defaultCamp = new Camp(Config.CampId.Default) - { - FriendInjury = true - }; - CampManager.SetDefaultCamp(defaultCamp); - var mazoku = new Camp(Config.CampId.Mazoku); - CampManager.AddCamp(mazoku); - var aborigines = new Camp(Config.CampId.Aborigines); - CampManager.AddCamp(aborigines); - _gameScene = GD.Load("res://scenes/game.tscn"); - _contributor = GD.Load("res://scenes/contributor.tscn"); - _levelGraphEditor = GD.Load("res://scenes/levelGraphEditor.tscn"); + //Registered camp + //注册阵营 + var defaultCamp = new Camp(Config.CampId.Default) + { + FriendInjury = true + }; + CampManager.SetDefaultCamp(defaultCamp); + var mazoku = new Camp(Config.CampId.Mazoku); + CampManager.AddCamp(mazoku); + var aborigines = new Camp(Config.CampId.Aborigines); + CampManager.AddCamp(aborigines); + _gameScene = GD.Load("res://scenes/game.tscn"); + _contributor = GD.Load("res://scenes/contributor.tscn"); + _levelGraphEditor = GD.Load("res://scenes/levelGraphEditor.tscn"); - //Register ItemTypes from file - //从文件注册物品类型 - ItemTypeRegister.RegisterFromFile(); - //Hardcoded ItemTypes Register - //硬编码注册物品类型 - ItemTypeRegister.StaticRegister(); + //Register ItemTypes from file + //从文件注册物品类型 + ItemTypeRegister.RegisterFromFile(); + //Hardcoded ItemTypes Register + //硬编码注册物品类型 + ItemTypeRegister.StaticRegister(); - //静态注册掉落表 - LootRegister.StaticRegister(); - } + //静态注册掉落表 + LootRegister.StaticRegister(); + } - public override void InitializeUi() - { - _contributorButton = GetNode("VBoxContainer2/ContributorButton"); - _startGameButton = GetNode