|
|
@@ -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*
|