jeson_fxd пре 2 недеља
родитељ
комит
8c3a8a1975
1 измењених фајлова са 284 додато и 0 уклоњено
  1. 284 0
      docs/文档/OpenCards.Server.Main启动问题排查记录.md

+ 284 - 0
docs/文档/OpenCards.Server.Main启动问题排查记录.md

@@ -0,0 +1,284 @@
+# OpenCards.Server.Main 启动问题排查记录
+
+> 整理自 Cursor Agent 对话(2026-06-10)  
+> 项目路径:`D:\WorkSpace\project\chuanzhanServer`
+
+---
+
+## 目录
+
+1. [Quartz 启动报错:System.Configuration.ConfigurationManager 找不到](#1-quartz-启动报错systemconfigurationconfigurationmanager-找不到)
+2. [LuaTemplateLoader 初始化 NullReferenceException](#2-luatemplateloader-初始化-nullreferenceexception)
+3. [TableManager.LoadTemplates 报错且 _IdMap 为 null](#3-tablemanagerloadtemplates-报错且-_idmap-为-null)
+4. [activity_task.lua 存在但仍报错的误解](#4-activity_tasklua-存在但仍报错的误解)
+5. [推荐启动配置清单](#5-推荐启动配置清单)
+
+---
+
+## 1. Quartz 启动报错:System.Configuration.ConfigurationManager 找不到
+
+### 现象
+
+启动 `OpenCards.Server.Main` 时出现类似日志:
+
+```
+2026-06-10 10:14:45,047 INFO  CenterService@NODE_NAME - Service Starting...
+2026-06-10 10:14:45,107 ERROR Quartz - One or more errors occurred. (Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. 系统找不到指定的文件。)
+System.AggregateException : One or more errors occurred. (Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. 系统找不到指定的文件。)
+```
+
+### 结论
+
+**不是** `_launch_server_*.xml` 等路径配置文件的问题,而是 **.NET 依赖 DLL 版本不匹配**。
+
+### 原因分析
+
+调用链:
+
+1. `CenterService` 启动时调用 `Provider.CreateCornJobAsync()` 注册定时任务
+2. `DeepFrozen.RPC.dll` 内部使用 **Quartz** 调度器
+3. `Quartz.dll`(3.3.2.0)编译时依赖 `System.Configuration.ConfigurationManager` **版本 4.0.3.0**
+
+| 组件 | 需要的版本 | 输出目录原有版本 |
+|------|-----------|----------------|
+| Quartz.dll | ConfigurationManager **4.0.3.0** | **4.0.1.0** |
+
+`OpenCards.Server.DotNetCore` 项目已引用该 NuGet 包,但 `OpenCards.Server.Main` 未引用,构建时不会把正确版本复制到 `_output.server`。
+
+### 修复方案
+
+在 `OpenCards.Server.Main.csproj` 中添加:
+
+```xml
+<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
+```
+
+重新 `dotnet build` 后,输出目录中 DLL 版本变为 **4.0.3.0**,与 Quartz 要求一致。
+
+### 操作步骤
+
+```powershell
+cd D:\WorkSpace\project\chuanzhanServer\server\src\server\OpenCards.Server.Main
+dotnet build -c Debug
+cd ..\..\_output.server
+.\OpenCards.Server.Main.exe local
+```
+
+---
+
+## 2. LuaTemplateLoader 初始化 NullReferenceException
+
+### 现象
+
+`Program.cs` 第 129 行:
+
+```csharp
+new DeepCore.Lua.LuaTemplateLoader(true, ad);
+```
+
+调试时报 `System.NullReferenceException`,堆栈类似:
+
+```
+Error initializing UnityScriptLoader : System.NullReferenceException
+   at MoonSharp.Interpreter.Compatibility.Frameworks.FrameworkClrBase.GetProperty(Type type, String name)
+   at MoonSharp.Interpreter.Loaders.UnityAssetsScriptLoader.LoadResourcesWithReflection(String assetsPath)
+```
+
+已知运行时 `ad` 的实例为 `{DeepCore.Template.MoonSharp.MoonSharpLuaAdapter}`。
+
+### 结论
+
+**不是 `ad` 为空**,而是构造函数第一个参数 `true` 触发了 Unity 专用脚本加载器初始化。
+
+### 原因分析
+
+- 构造函数签名:`LuaTemplateLoader(Boolean instance, ILuaAdapter adapter)`
+- `instance = true`:按 **Unity 客户端** 模式初始化
+- 内部创建 `UnityAssetsScriptLoader`,调用 `LoadResourcesWithReflection()`
+- 该方法通过反射加载 `UnityEngine.Resources`、`UnityEngine.TextAsset`
+- 服务端 .NET 控制台环境**没有** `UnityEngine.dll`,`Type.GetType(...)` 返回 null
+- `FrameworkClrBase.GetProperty(null, "name")` → NullReferenceException
+
+该异常在 MoonSharp 内部被 `catch` 并打印日志,**一般不会向外抛出**,程序可继续运行。若 Visual Studio 开启「引发时中断」,调试器会在 `Program.cs` 该行停下。
+
+### 重要:true 与 false 的区别
+
+| 参数 | `LuaTemplateLoader.Instance` | 对 TableManager 的影响 |
+|------|------------------------------|------------------------|
+| `true` | **有值** | `LoadTemplates` 正常工作 |
+| `false` | **null** | `LoadTemplates` 必然 NRE |
+
+**不能**为避免 Unity 日志而将 `true` 改为 `false`,否则所有配置表加载失败(见第 3 节)。
+
+### 处理建议
+
+- 服务端保持 `new DeepCore.Lua.LuaTemplateLoader(true, ad);`
+- 忽略控制台中的 `Error initializing UnityScriptLoader` 日志
+- 或在 VS 中关闭对该异常的「引发时中断」
+
+---
+
+## 3. TableManager.LoadTemplates 报错且 _IdMap 为 null
+
+### 现象
+
+`TableManager.cs` 中:
+
+```csharp
+_IdMap = loader.LoadTemplates<int, Table_ActivityTask>(nameof(Table_ActivityTask.Id), "activity_task");
+```
+
+该行报错,且 `_IdMap` 值为 `null`。
+
+### 根因
+
+若 `Program.cs` 使用了 `new LuaTemplateLoader(false, ad)`:
+
+1. `LuaTemplateLoader.Instance` 不会被赋值(保持 null)
+2. `loader.LoadTemplates(...)` 内部依赖该静态单例
+3. 在 `DeepCore.TemplateLoader.XLSLoader.LoadTemplates` 处抛出 `NullReferenceException`
+4. `_IdMap` 赋值失败,保持 null
+
+### 修复方案
+
+恢复 `Program.cs` 中的正确写法:
+
+```csharp
+DeepCore.GameEvent.Lua.LuaEventManager.DefaultAdapter = new DeepCore.Template.MoonSharp.MoonSharpLuaAdapter();
+var ad = DeepCore.GameEvent.Lua.LuaEventManager.DefaultAdapter;
+if (ad != null)
+{
+    // 必须传 true,否则 LuaTemplateLoader.Instance 不会被赋值,TableManager.LoadTemplates 会 NRE。
+    // true 时 MoonSharp 会尝试初始化 Unity 脚本加载器并打印 Error initializing UnityScriptLoader,可忽略。
+    new DeepCore.Lua.LuaTemplateLoader(true, ad);
+    CardsServerTemplateManager.TemplateDataRootPath =
+        CardsServerTemplateManager.ResolveServerDataRoot();
+    new DeepCore.Lua.LuaDataCenter(ad,
+        Path.Combine(CardsServerTemplateManager.TemplateDataRootPath, "templates_lua"));
+}
+CardsServerTemplateManager.Instance.Init();
+```
+
+### 初始化顺序(不可打乱)
+
+1. `MoonSharpLuaAdapter` → `LuaEventManager.DefaultAdapter`
+2. `new LuaTemplateLoader(true, ad)`
+3. `new LuaDataCenter(ad, templates_lua 路径)`
+4. `CardsServerTemplateManager.Instance.Init()` → 内部 `TableManager.LoadAllConfig`
+
+### 验证
+
+```csharp
+Table_ActivityTaskManager.IdMap.Count  // 正常应为 3
+Table_ActivityTaskManager.GetById(1)   // 应有数据
+```
+
+---
+
+## 4. activity_task.lua 存在但仍报错的误解
+
+### 用户疑问
+
+`ClientScript\Data\activity_new.xlsx\activity_task.lua` 文件存在,为何仍报错?是否所有 `.lua` 都没加载?
+
+### 关键说明
+
+#### 服务端不读 ClientScript 目录
+
+服务端模板根目录解析为:
+
+```
+server/src/data/ServerData/
+```
+
+`TableManager` 实际读取:
+
+```
+data/ServerData/templates_lua/activity_new.xlsx/activity_task.lua
+```
+
+**不会**读取 `data/ClientScript/Data/activity_new.xlsx/activity_task.lua`。  
+`ClientScript` 供 Unity 客户端使用;`ServerData/templates_lua` 供服务端使用,两套目录并行维护。
+
+#### activity_task.lua 可以正常加载
+
+在 `LuaTemplateLoader(true, ad)` 条件下,日志可见:
+
+```
+WARN LuaTemplateLoader - Field not found ... Table_ActivityTask.StageName : Sheet=activity_task
+WARN LuaTemplateLoader - Field not found ... Table_ActivityTask.Desc : Sheet=activity_task
+```
+
+说明 Lua 已解析,只是 `StageName`、`Desc` 在服务端 C# 类中未定义(客户端展示字段),属于正常 WARN。
+
+服务端 `Table_ActivityTask` 仅包含:
+
+```csharp
+public int Id;
+public int Type;
+public int Target;
+public int DropGroupId;
+```
+
+#### 并非所有 lua 未加载
+
+启动日志中有大量:
+
+```
+TemplateDataCenter - Reload : CacheData : File=templates_lua/activity_new.xlsx
+```
+
+表示对应 xlsx 目录下的 lua 已成功缓存。真正的加载失败会由 `LogicUtils.LogError` 记录并 `throw`。
+
+### 日志类型对照
+
+| 日志 | 含义 |
+|------|------|
+| `Error initializing UnityScriptLoader` | Unity 加载器初始化失败,不影响磁盘读 Lua |
+| `Field not found ... StageName/Desc` | Lua 已加载,客户端字段被忽略 |
+| `TemplateDataCenter - Reload` | 表加载成功 |
+| `LogicUtils.LogError` + 异常堆栈 | 真正的表加载失败 |
+
+---
+
+## 5. 推荐启动配置清单
+
+### 已修复项
+
+- [x] `OpenCards.Server.Main.csproj` 添加 `System.Configuration.ConfigurationManager` 4.7.0
+- [x] `Program.cs` 使用 `LuaTemplateLoader(true, ad)` 而非 `false`
+
+### 启动前检查
+
+1. 工作目录为 `_output.server`(或确保 `ResolveServerDataRoot` 能找到 `map/map_events.json`)
+2. Redis 已启动(配置见 `_launch_server_local.xml`)
+3. 模板数据存在于 `server/src/data/ServerData/templates_lua/`
+
+### 可忽略的启动日志
+
+- `Error initializing UnityScriptLoader : NullReferenceException`
+- `Field not found in C# class ... StageName / Desc / Name` 等客户端字段警告
+
+### 需要关注的错误
+
+- `System.Configuration.ConfigurationManager` 程序集找不到(需重新 build)
+- `TableManager` 中 `LoadTemplates` 的 NRE(检查是否误用 `LuaTemplateLoader(false, ad)`)
+- `Cannot find ServerData directory`(工作目录或数据路径错误)
+
+---
+
+## 附录:相关文件路径
+
+| 文件 | 说明 |
+|------|------|
+| `server/src/server/OpenCards.Server.Main/Program.cs` | 主程序入口,Lua 初始化 |
+| `server/src/server/OpenCards.Server.Main/OpenCards.Server.Main.csproj` | Main 项目,Quartz 依赖修复 |
+| `server/src/server/OpenCards.Server.Core/TableManager.cs` | 配置表加载 |
+| `server/src/server/OpenCards.Server.Core/Table/Table_ActivityTask.cs` | activity_task 表定义 |
+| `server/src/data/ServerData/templates_lua/activity_new.xlsx/activity_task.lua` | 服务端实际读取的 lua |
+| `server/src/data/ClientScript/Data/activity_new.xlsx/activity_task.lua` | 客户端 lua(服务端不读) |
+| `server/src/_output.server/` | 编译输出与运行目录 |
+
+---
+
+*文档生成时间:2026-06-10*