1
This commit is contained in:
@@ -23,6 +23,10 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
[Tooltip("是否使用后端下发的 BotConfig。false=用 Inspector 本地配置(默认,方便测试);true=用后端 GameConfig 返回的 botConfig 覆盖本地")]
|
||||
public bool useRemoteBotConfig = false;
|
||||
|
||||
[Header("日志文件")]
|
||||
[Tooltip("运行时开关:是否实际生成日志文件。需要同时启用 ENABLE_LOG_FILE 预编译指令才生效。\ntrue=生成日志文件;false=不生成(运行时关闭)")]
|
||||
public bool enableLogFile = true;
|
||||
|
||||
public GameConfig gameConfig;
|
||||
public ActivityConfig activityConfig;
|
||||
public Dictionary<string, FishTypeConfig> dic_fishTypeConfigs = new Dictionary<string, FishTypeConfig>();
|
||||
@@ -209,8 +213,12 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
// ⭐ 防止手机屏幕自动黑屏休眠
|
||||
Screen.sleepTimeout = SleepTimeout.NeverSleep;
|
||||
|
||||
#if ENABLE_LOG_FILE
|
||||
// ⭐ 启动日志文件自动保存:把所有 Debug.Log/Warning/Error 写入 persistentDataPath/Logs/
|
||||
InitLogFileWriter();
|
||||
// 需要在 Player Settings → Scripting Define Symbols 中添加 ENABLE_LOG_FILE 才会编译
|
||||
// 运行时可通过 Inspector 的 enableLogFile 勾选框关闭
|
||||
if (enableLogFile) InitLogFileWriter();
|
||||
#endif
|
||||
|
||||
AudioResourcesData audioResourcesData = new AudioResourcesData();
|
||||
InItLoad();
|
||||
@@ -244,8 +252,15 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
|
||||
}
|
||||
|
||||
// ⭐ 日志文件写入器:把 Application.logMessageReceived 的日志实时写入文件
|
||||
#if ENABLE_LOG_FILE
|
||||
// ============================ 日志文件系统 ============================
|
||||
// 启用方法: Player Settings → Other Settings → Scripting Define Symbols 添加 ENABLE_LOG_FILE
|
||||
// 关闭方法: 删除该符号,或 Inspector 中 enableLogFile 取消勾选
|
||||
// 说明: LogGoldFlow 用 [Conditional] 标记,未定义 ENABLE_LOG_FILE 时所有调用点会被编译器自动移除,零开销
|
||||
|
||||
private StreamWriter _logFileWriter;
|
||||
private StreamWriter _goldFlowWriter;
|
||||
|
||||
private void InitLogFileWriter()
|
||||
{
|
||||
try
|
||||
@@ -257,7 +272,6 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
Application.logMessageReceived += OnLogMessageReceived;
|
||||
Debug.Log($"[GameManager] 日志文件已创建: {logPath}");
|
||||
|
||||
// 同时初始化金币流水日志文件
|
||||
InitGoldFlowWriter(logDir);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -266,17 +280,23 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
}
|
||||
}
|
||||
|
||||
// ⭐ 金币流水日志写入器:单独写入"金币流水"文件,格式对齐后端日志
|
||||
private StreamWriter _goldFlowWriter;
|
||||
private void InitGoldFlowWriter(string logDir)
|
||||
{
|
||||
try
|
||||
{
|
||||
string goldLogPath = Path.Combine(logDir, "金币流水_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".log");
|
||||
_goldFlowWriter = new StreamWriter(goldLogPath, true) { AutoFlush = true };
|
||||
|
||||
// ===== 文件头:只记录当前玩家自己(进游戏前可能 user 还没拉到,做 null 保护) =====
|
||||
string userName = user?.BaseInfo?.userName ?? "未登录";
|
||||
string userId = user?.id ?? "未登录";
|
||||
_goldFlowWriter.WriteLine($"# 金币流水日志 - 启动于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||
_goldFlowWriter.WriteLine($"# 格式: 时间|service=client|INFO|GoldFlow|[金币流水] 玩家=名称(ID) 事件=xxx {描述}");
|
||||
_goldFlowWriter.WriteLine($"# 当前玩家: {userName}({userId})");
|
||||
_goldFlowWriter.WriteLine($"# 说明: 只记录当前玩家自己的金币变动,不记录其他玩家");
|
||||
_goldFlowWriter.WriteLine($"# 格式: 时间|service=client|INFO|GoldFlow|[分类] 玩家=名称(ID) 事件=target 描述");
|
||||
_goldFlowWriter.WriteLine($"# 分类: 收到加钱/已加钱/收到扣钱/已扣钱/金币流水(通用)");
|
||||
_goldFlowWriter.WriteLine(new string('-', 80));
|
||||
|
||||
Debug.Log($"[GameManager] 金币流水日志文件已创建: {goldLogPath}");
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -285,24 +305,6 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录金币流水(供全项目调用)
|
||||
/// 用法: GameManager.LogGoldFlow("KillFish", $"击中鱼原有金币={oldGold} 增加金币=+{addGold} 剩余金币={newGold} 房间={roomId}");
|
||||
/// </summary>
|
||||
public static void LogGoldFlow(string eventName, string description)
|
||||
{
|
||||
var inst = Instance;
|
||||
if (inst == null || inst._goldFlowWriter == null) return;
|
||||
try
|
||||
{
|
||||
string userName = inst.user?.BaseInfo?.userName ?? "未知";
|
||||
string userId = inst.user?.id ?? "未知";
|
||||
string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
inst._goldFlowWriter.WriteLine($"{timeStr}|service=client|INFO|GoldFlow|[金币流水] 玩家={userName}({userId}) 事件={eventName} {description}");
|
||||
}
|
||||
catch { /* 写日志失败不影响游戏运行 */ }
|
||||
}
|
||||
|
||||
private void OnLogMessageReceived(string condition, string stackTrace, LogType type)
|
||||
{
|
||||
if (_logFileWriter == null) return;
|
||||
@@ -323,7 +325,7 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
_logFileWriter.WriteLine($" Stack: {stackTrace}");
|
||||
}
|
||||
}
|
||||
catch { /* 写日志失败不影响游戏运行 */ }
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -340,6 +342,82 @@ public class GameManager : MonoSingleton<GameManager>
|
||||
_goldFlowWriter = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ============================ 金币流水日志(与后端逐条对比) ============================
|
||||
// 拆成4类,方便和后端日志逐行对比:
|
||||
// - 收到扣钱信息(推送): 后端发来扣钱通知,客户端尚未执行
|
||||
// - 已扣钱(本地执行): 客户端本地已扣完金币
|
||||
// - 收到加钱信息(推送): 后端发来加钱通知,客户端尚未执行
|
||||
// - 已加钱(本地执行): 客户端本地已加完金币
|
||||
//
|
||||
// 控制方式:
|
||||
// 1. 编译时: 未定义 ENABLE_LOG_FILE 符号时,所有调用被编译器自动移除([Conditional]特性),零开销
|
||||
// 2. 运行时: 即使编译了,Inspector 中 enableLogFile=false 也不会写入文件
|
||||
//
|
||||
// 通用记录(无关扣/加,如退出房间)继续用 LogGoldFlow
|
||||
|
||||
/// <summary>记录"收到扣钱信息"(后端推送,尚未执行)。如:后端推送 SyncPlayerGold 差值为负</summary>
|
||||
[System.Diagnostics.Conditional("ENABLE_LOG_FILE")]
|
||||
public static void LogGoldFlowReceiveCost(string eventName, string description)
|
||||
{
|
||||
#if ENABLE_LOG_FILE
|
||||
WriteGoldFlow("收到扣钱", eventName, description);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>记录"已扣钱"(本地已执行扣金币)。如:开火 ConsumeGold 扣完</summary>
|
||||
[System.Diagnostics.Conditional("ENABLE_LOG_FILE")]
|
||||
public static void LogGoldFlowAppliedCost(string eventName, string description)
|
||||
{
|
||||
#if ENABLE_LOG_FILE
|
||||
WriteGoldFlow("已扣钱", eventName, description);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>记录"收到加钱信息"(后端推送,尚未执行)。如:RoomJoinNotice/RoomInfo 推送金币</summary>
|
||||
[System.Diagnostics.Conditional("ENABLE_LOG_FILE")]
|
||||
public static void LogGoldFlowReceiveGain(string eventName, string description)
|
||||
{
|
||||
#if ENABLE_LOG_FILE
|
||||
WriteGoldFlow("收到加钱", eventName, description);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>记录"已加钱"(本地已执行加金币)。如:杀鱼 KillFish 加完、进房 JoinGame 设置初始金币</summary>
|
||||
[System.Diagnostics.Conditional("ENABLE_LOG_FILE")]
|
||||
public static void LogGoldFlowAppliedGain(string eventName, string description)
|
||||
{
|
||||
#if ENABLE_LOG_FILE
|
||||
WriteGoldFlow("已加钱", eventName, description);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>通用金币流水记录(无关扣/加,如退出房间)。需要明确分类时请用上面4个方法</summary>
|
||||
[System.Diagnostics.Conditional("ENABLE_LOG_FILE")]
|
||||
public static void LogGoldFlow(string eventName, string description)
|
||||
{
|
||||
#if ENABLE_LOG_FILE
|
||||
WriteGoldFlow("金币流水", eventName, description);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLE_LOG_FILE
|
||||
/// <summary>金币流水核心写入(私有)。所有公开 LogGoldFlow* 方法最终都走这里</summary>
|
||||
private static void WriteGoldFlow(string category, string eventName, string description)
|
||||
{
|
||||
var inst = Instance;
|
||||
if (inst == null || !inst.enableLogFile || inst._goldFlowWriter == null) return;
|
||||
try
|
||||
{
|
||||
string userName = inst.user?.BaseInfo?.userName ?? "未知";
|
||||
string userId = inst.user?.id ?? "未知";
|
||||
string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
inst._goldFlowWriter.WriteLine($"{timeStr}|service=client|INFO|GoldFlow|[{category}] 玩家={userName}({userId}) 事件={eventName} {description}");
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endif
|
||||
|
||||
public async Task InItLoad()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user