Supports uploading logs to the server.
支持上传日志到服务器。
This commit is contained in:
commit
f1b696ad5e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ export_presets.cfg
|
|||
.vs/
|
||||
*.translation
|
||||
*.user
|
||||
AppConfig.yaml
|
28
README.md
28
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.
|
||||
|
|
28
README_JA.md
28
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ファイルを編集することができます。新しい翻訳を加えたり修正したりしています
|
||||
|
|
28
README_ZH.md
28
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文件。来修改和添加新的翻译。
|
||||
|
|
|
@ -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}個の戦利品データが返されます。
|
||||
|
@ -76,3 +76,7 @@ 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.",でも、拾得物が拾い上げられたら、ラベルは表示されません。
|
||||
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}です。
|
|
82
scripts/AppConfig.cs
Normal file
82
scripts/AppConfig.cs
Normal file
|
@ -0,0 +1,82 @@
|
|||
using ColdMint.scripts.debug;
|
||||
using ColdMint.scripts.openObserve;
|
||||
using ColdMint.scripts.serialization;
|
||||
using Godot;
|
||||
|
||||
namespace ColdMint.scripts;
|
||||
|
||||
public class AppConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Load configuration from file</para>
|
||||
/// <para>从文件加载配置</para>
|
||||
/// </summary>
|
||||
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<AppConfigData>(yamlData);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>ApplyAppConfig</para>
|
||||
/// <para>应用配置</para>
|
||||
/// </summary>
|
||||
/// <param name="appConfigData"></param>
|
||||
public static void ApplyAppConfig(AppConfigData appConfigData)
|
||||
{
|
||||
if (appConfigData.OpenObserve != null)
|
||||
{
|
||||
LogCollector.UpdateHttpClient(appConfigData.OpenObserve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AppConfigData
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>OpenObserve configuration information</para>
|
||||
/// <para>OpenObserve的配置信息</para>
|
||||
/// </summary>
|
||||
public OpenObserve? OpenObserve { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>OpenObserve Configuration information</para>
|
||||
/// <para>OpenObserve配置信息</para>
|
||||
/// </summary>
|
||||
public class OpenObserve
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>server address</para>
|
||||
/// <para>服务器地址</para>
|
||||
/// </summary>
|
||||
public string? Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Access Token</para>
|
||||
/// <para>访问密匙</para>
|
||||
/// </summary>
|
||||
public string? AccessToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Organization ID</para>
|
||||
/// <para>组织ID</para>
|
||||
/// </summary>
|
||||
public string? OrgId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Stream Name</para>
|
||||
/// <para>流名称</para>
|
||||
/// </summary>
|
||||
public string? StreamName { get; set; }
|
||||
}
|
|
@ -85,6 +85,12 @@ public static class Config
|
|||
public const string Aborigines = "Aborigines";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Path of the App configuration file</para>
|
||||
/// <para>App配置文件路径</para>
|
||||
/// </summary>
|
||||
public const string AppConfigPath = "res://AppConfig.yaml";
|
||||
|
||||
/// <summary>
|
||||
/// <para>The percentage of speed reduced after a thrown item hits an enemy</para>
|
||||
/// <para>抛出的物品击中敌人后减少的速度百分比</para>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<PackedScene>("res://prefab/ui/FloatLabel.tscn");
|
||||
//Initializes the float label.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ColdMint.scripts.openObserve;
|
||||
using ColdMint.scripts.utils;
|
||||
using Godot;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -53,7 +54,13 @@ public static class LogCat
|
|||
/// <para>BubbleMarker</para>
|
||||
/// <para>气泡标记</para>
|
||||
/// </summary>
|
||||
public static string BubbleMarker = "BubbleMarker";
|
||||
public const string BubbleMarker = "BubbleMarker";
|
||||
|
||||
/// <summary>
|
||||
/// <para>LogCollector</para>
|
||||
/// <para>日志收集器</para>
|
||||
/// </summary>
|
||||
public const string LogCollector = "LogCollector";
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,6 +104,12 @@ public static class LogCat
|
|||
set => _minLogLevel = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Whether to upload logs that need to be formatted by default</para>
|
||||
/// <para>是否默认上传需要格式化的日志</para>
|
||||
/// </summary>
|
||||
public static bool UploadFormat { get; set; } = true;
|
||||
|
||||
private static readonly StringBuilder StringBuilder = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
|
@ -216,7 +229,14 @@ public static class LogCat
|
|||
/// </param>
|
||||
/// <param name="label">
|
||||
/// </param>
|
||||
public static void Log(string message, string label = LogLabel.Default)
|
||||
/// <param name="upload">
|
||||
/// </param>
|
||||
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))
|
||||
{
|
||||
|
@ -228,7 +248,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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -242,80 +273,34 @@ public static class LogCat
|
|||
/// <para>这个消息支持本地化输出,假设已存在翻译key,Hello = 你好,传入Hello则会输出你好。</para>
|
||||
/// </param>
|
||||
/// <param name="label"></param>
|
||||
public static void LogError(string message, string label = LogLabel.Default)
|
||||
/// <param name="upload"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -333,6 +318,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);
|
||||
}
|
||||
}
|
|
@ -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<ItemTypeInfo> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,12 @@ public partial class MainMenuLoader : UiLoaderTemplate
|
|||
|
||||
public override void InitializeData()
|
||||
{
|
||||
LogCat.Init();
|
||||
AppConfigData? appConfigData = AppConfig.LoadFromFile();
|
||||
if (appConfigData != null)
|
||||
{
|
||||
AppConfig.ApplyAppConfig(appConfigData);
|
||||
}
|
||||
|
||||
if (Config.IsDebug())
|
||||
{
|
||||
//Set the minimum log level to Info in debug mode.(Print all logs)
|
||||
|
|
|
@ -25,7 +25,7 @@ public readonly struct LootList(string id, IList<LootGroup> groups)
|
|||
{
|
||||
if (Groups is [])
|
||||
{
|
||||
LogCat.LogWithFormat("loot_list_has_no_entries", LogCat.LogLabel.Default, Id);
|
||||
LogCat.LogWithFormat("loot_list_has_no_entries", LogCat.LogLabel.Default, LogCat.UploadFormat, Id);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -41,10 +41,10 @@ public readonly struct LootList(string id, IList<LootGroup> groups)
|
|||
//我们为每个战利品条目生成一个战利品数据。
|
||||
var datum = group.GenerateLootData();
|
||||
lootDataList.Add(datum);
|
||||
LogCat.LogWithFormat("loot_data_add", LogCat.LogLabel.Default, datum);
|
||||
LogCat.LogWithFormat("loot_data_add", LogCat.LogLabel.Default, LogCat.UploadFormat,datum);
|
||||
}
|
||||
|
||||
LogCat.LogWithFormat("loot_data_quantity", LogCat.LogLabel.Default, lootDataList.Count);
|
||||
LogCat.LogWithFormat("loot_data_quantity", LogCat.LogLabel.Default, LogCat.UploadFormat,lootDataList.Count);
|
||||
return lootDataList.ToArray();
|
||||
}
|
||||
}
|
|
@ -241,7 +241,7 @@ public static class MapGenerator
|
|||
//If the room injection processor cannot be found, a print error occurs.
|
||||
//如果找不到房间注入处理器,那么打印错误。
|
||||
LogCat.LogErrorWithFormat("room_injection_processor_does_not_exist",
|
||||
LogCat.LogLabel.Default, injectionProcessorData.Id);
|
||||
LogCat.LogLabel.Default, LogCat.UploadFormat,injectionProcessorData.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ public static class MapGenerator
|
|||
if (roomPlacementData == null)
|
||||
{
|
||||
LogCat.LogWithFormat("failed_to_calculate_the_room_location", LogCat.LogLabel.Default,
|
||||
roomNodeData.Id);
|
||||
LogCat.UploadFormat,roomNodeData.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -324,18 +324,18 @@ public static class MapGenerator
|
|||
|
||||
if (dictionary.ContainsKey(roomNodeDataId))
|
||||
{
|
||||
LogCat.LogWithFormat("place_existing_rooms", LogCat.LogLabel.Default, roomNodeDataId);
|
||||
LogCat.LogWithFormat("place_existing_rooms", LogCat.LogLabel.Default, LogCat.UploadFormat,roomNodeDataId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!await _roomPlacementStrategy.PlaceRoom(_mapRoot, roomPlacementData))
|
||||
{
|
||||
LogCat.LogWarningWithFormat("room_placement_failed", LogCat.LogLabel.Default, roomNodeDataId);
|
||||
LogCat.LogWarningWithFormat("room_placement_failed", LogCat.UploadFormat,LogCat.LogLabel.Default, roomNodeDataId);
|
||||
return false;
|
||||
}
|
||||
|
||||
dictionary.Add(roomNodeDataId, roomPlacementData.Room);
|
||||
LogCat.LogWithFormat("room_placement_information", LogCat.LogLabel.Default, roomNodeDataId,
|
||||
LogCat.LogWithFormat("room_placement_information", LogCat.LogLabel.Default, LogCat.UploadFormat,roomNodeDataId,
|
||||
roomPlacementData.Position.ToString());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class Room
|
|||
{
|
||||
if (_rootNode != null)
|
||||
{
|
||||
LogCat.LogWithFormat("enter_the_room_debug", LogCat.LogLabel.Default, node.Name, _rootNode.Name);
|
||||
LogCat.LogWithFormat("enter_the_room_debug", LogCat.LogLabel.Default, LogCat.UploadFormat,node.Name, _rootNode.Name);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(EnterRoomEventHandlerId))
|
||||
|
@ -57,7 +57,7 @@ public class Room
|
|||
{
|
||||
if (_rootNode != null)
|
||||
{
|
||||
LogCat.LogWithFormat("exit_the_room_debug", LogCat.LogLabel.Default, node.Name, _rootNode.Name);
|
||||
LogCat.LogWithFormat("exit_the_room_debug", LogCat.LogLabel.Default, LogCat.UploadFormat,node.Name, _rootNode.Name);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ExitRoomEventHandlerId))
|
||||
|
|
139
scripts/openObserve/LogCollector.cs
Normal file
139
scripts/openObserve/LogCollector.cs
Normal file
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using ColdMint.scripts.debug;
|
||||
using HttpClient = System.Net.Http.HttpClient;
|
||||
|
||||
namespace ColdMint.scripts.openObserve;
|
||||
|
||||
/// <summary>
|
||||
/// <para>LogCollector</para>
|
||||
/// <para>日志收集器</para>
|
||||
/// </summary>
|
||||
public static class LogCollector
|
||||
{
|
||||
private static readonly List<LogData> LogDataList = [];
|
||||
|
||||
/// <summary>
|
||||
/// <para>Automatic upload threshold</para>
|
||||
/// <para>自动上传的阈值</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
///<para>An attempt is made to upload logs when messages reach this number.</para>
|
||||
///<para>当消息到达此数量后将尝试上传日志。</para>
|
||||
/// </remarks>
|
||||
public static int UploadThreshold { get; set; } = 300;
|
||||
|
||||
private static bool _lockList = false;
|
||||
|
||||
/// <summary>
|
||||
/// <para>httpClient</para>
|
||||
/// <para>Http客户</para>
|
||||
/// </summary>
|
||||
private static HttpClient? _httpClient;
|
||||
|
||||
private static string? _orgId;
|
||||
private static string? _streamName;
|
||||
|
||||
/// <summary>
|
||||
/// <para>CanUploadLog</para>
|
||||
/// <para>是否能上传日志</para>
|
||||
/// </summary>
|
||||
public static bool CanUploadLog => _httpClient != null;
|
||||
|
||||
/// <summary>
|
||||
/// <para>UpdateHttpClient</para>
|
||||
/// <para>更新Http客户端</para>
|
||||
/// </summary>
|
||||
/// <param name="openObserve"></param>
|
||||
public static void UpdateHttpClient(OpenObserve openObserve)
|
||||
{
|
||||
if (openObserve.Address == null || openObserve.AccessToken == null || openObserve.OrgId == null ||
|
||||
openObserve.StreamName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var httpClient = new HttpClient();
|
||||
httpClient.BaseAddress = new Uri(openObserve.Address);
|
||||
//Add a Cookie to the request header
|
||||
//添加Cookie到请求头
|
||||
var cookie = new Cookie("auth_tokens",
|
||||
"{\"access_token\":\"Basic " + openObserve.AccessToken + "\",\"refresh_token\":\"\"}");
|
||||
httpClient.DefaultRequestHeaders.Add("Cookie", cookie.ToString());
|
||||
_httpClient = httpClient;
|
||||
_orgId = openObserve.OrgId;
|
||||
_streamName = openObserve.StreamName;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Push log</para>
|
||||
/// <para>推送日志</para>
|
||||
/// </summary>
|
||||
/// <param name="logRequestBean"></param>
|
||||
private static async Task PostLog(List<LogData> logRequestBean)
|
||||
{
|
||||
if (_httpClient == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_lockList = true;
|
||||
LogCat.LogWithFormat("start_uploading", label: LogCat.LogLabel.LogCollector, false, logRequestBean.Count);
|
||||
var httpResponseMessage =
|
||||
await _httpClient.PostAsJsonAsync("/api/" + _orgId + "/" + _streamName + "/_json", logRequestBean);
|
||||
_lockList = false;
|
||||
if (httpResponseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
LogDataList.RemoveRange(0, logRequestBean.Count);
|
||||
LogCat.LogWithFormat("upload_successful", label: LogCat.LogLabel.LogCollector, false,
|
||||
logRequestBean.Count, LogDataList.Count);
|
||||
if (LogDataList.Count > UploadThreshold)
|
||||
{
|
||||
//After the upload succeeds, if the threshold is still met, continue uploading.
|
||||
//上传成功后,如果依然满足阈值,那么继续上传。
|
||||
PostLog(LogDataList.GetRange(0, UploadThreshold));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogCat.LogWithFormat("upload_failed", label: LogCat.LogLabel.LogCollector, false,
|
||||
httpResponseMessage.StatusCode.ToString(), LogDataList.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Push(LogData logData)
|
||||
{
|
||||
LogDataList.Add(logData);
|
||||
LogCat.LogWithFormat("upload_status", LogCat.LogLabel.LogCollector, false, LogDataList.Count, UploadThreshold);
|
||||
if (!_lockList && LogDataList.Count > UploadThreshold)
|
||||
{
|
||||
//执行上传
|
||||
PostLog(LogDataList.GetRange(0, UploadThreshold));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LogData
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>The AppId of this application</para>
|
||||
/// <para>此应用的AppId</para>
|
||||
/// </summary>
|
||||
public string? AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>message</para>
|
||||
/// <para>消息</para>
|
||||
/// </summary>
|
||||
public string? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>level</para>
|
||||
/// <para>错误等级</para>
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
}
|
|
@ -33,7 +33,7 @@ public class StateContext
|
|||
return;
|
||||
}
|
||||
|
||||
LogCat.LogWithFormat("state_change", label: LogCat.LogLabel.StateContext, _currentState, value);
|
||||
LogCat.LogWithFormat("state_change", label: LogCat.LogLabel.StateContext, LogCat.UploadFormat,_currentState, value);
|
||||
OnStateChange?.Invoke(_currentState, value);
|
||||
_previousState = _currentState;
|
||||
_currentState = value;
|
||||
|
|
|
@ -69,7 +69,7 @@ public abstract class StateMachineTemplate : IStateMachine
|
|||
else
|
||||
{
|
||||
LogCat.LogErrorWithFormat("state_processor_not_found", label: LogCat.LogLabel.StateMachineTemplate,
|
||||
newState);
|
||||
LogCat.UploadFormat,newState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ public class PatrolStateProcessor : StateProcessorTemplate
|
|||
|
||||
_originPosition = aiCharacter.GlobalPosition;
|
||||
LogCat.LogWithFormat("patrol_origin_position", LogCat.LogLabel.PatrolStateProcessor,
|
||||
_originPosition);
|
||||
LogCat.UploadFormat,_originPosition);
|
||||
}
|
||||
|
||||
var point = _originPosition + Points[_index];
|
||||
|
@ -87,7 +87,7 @@ public class PatrolStateProcessor : StateProcessorTemplate
|
|||
{
|
||||
//No need to actually come to the patrol point, we just need a distance to get close.
|
||||
//无需真正的来到巡逻点,我们只需要一个距离接近了就可以了。
|
||||
LogCat.LogWithFormat("patrol_arrival_point", LogCat.LogLabel.PatrolStateProcessor, point);
|
||||
LogCat.LogWithFormat("patrol_arrival_point", LogCat.LogLabel.PatrolStateProcessor, LogCat.UploadFormat,point);
|
||||
_index++;
|
||||
if (_index >= Points.Length)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ public class PatrolStateProcessor : StateProcessorTemplate
|
|||
}
|
||||
else
|
||||
{
|
||||
LogCat.LogWithFormat("patrol_to_next_point", label: LogCat.LogLabel.PatrolStateProcessor, point,
|
||||
LogCat.LogWithFormat("patrol_to_next_point", label: LogCat.LogLabel.PatrolStateProcessor, LogCat.UploadFormat,point,
|
||||
aiCharacter.GlobalPosition, Points[_index],
|
||||
distance);
|
||||
aiCharacter.SetTargetPosition(point.Value);
|
||||
|
|
|
@ -279,7 +279,8 @@ public static class NodeUtils
|
|||
if (node is T result) return result;
|
||||
// If the transformation fails, release the created node
|
||||
//如果转型失败,释放所创建的节点
|
||||
LogCat.LogWarningWithFormat("warning_node_cannot_cast_to", LogCat.LogLabel.Default, node, nameof(T));
|
||||
LogCat.LogWarningWithFormat("warning_node_cannot_cast_to", LogCat.UploadFormat, LogCat.LogLabel.Default, node,
|
||||
nameof(T));
|
||||
node.QueueFree();
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public static class TimeUtils
|
|||
var compNum1 = DateTime.Compare(dateTime, dtStartTime);
|
||||
var compNum2 = DateTime.Compare(dateTime, dtEndTime);
|
||||
var result = compNum1 >= 0 && compNum2 <= 0;
|
||||
LogCat.LogWithFormat("time_range_debug", LogCat.LogLabel.Default, dateTime, dtStartTime, dtEndTime,
|
||||
LogCat.LogWithFormat("time_range_debug", LogCat.LogLabel.Default, LogCat.UploadFormat,dateTime, dtStartTime, dtEndTime,
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user