|
|
@@ -0,0 +1,447 @@
|
|
|
+# 服务器起服 & 客户端连接异常排查
|
|
|
+
|
|
|
+> 整理自 Cursor Agent 对话(2026-06-11)
|
|
|
+> 服务端项目:`D:\WorkSpace\project\chuanzhanServer`
|
|
|
+> Unity 客户端:`D:\WorkSpace\jyyz_game\client`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 目录
|
|
|
+
|
|
|
+1. [架构与端口规划](#1-架构与端口规划)
|
|
|
+2. [本地起服完整流程](#2-本地起服完整流程)
|
|
|
+3. [起服异常:AccountServer 拉取静态配置失败](#3-起服异常accountserver-拉取静态配置失败)
|
|
|
+4. [Unity 客户端连接服务器流程](#4-unity-客户端连接服务器流程)
|
|
|
+5. [`address=` 日志在哪里打印](#5-address-日志在哪里打印)
|
|
|
+6. [为什么本地 `serverlist.json` 没生效](#6-为什么本地-serverlistjson-没生效)
|
|
|
+7. [验证清单](#7-验证清单)
|
|
|
+8. [常见误区](#8-常见误区)
|
|
|
+9. [关键文件索引](#9-关键文件索引)
|
|
|
+10. [总结](#10-总结)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 架构与端口规划
|
|
|
+
|
|
|
+### 1.1 两类地址(极易混淆)
|
|
|
+
|
|
|
+配置和日志里的 `127.0.0.1` 分两类:
|
|
|
+
|
|
|
+| 类型 | 说明 | 谁提供 |
|
|
|
+|------|------|--------|
|
|
|
+| **静态配置 URL** | `serverlist.json`、停服配置等 | 需独立 HTTP 静态服务(80 / 8000) |
|
|
|
+| **游戏服自身服务** | 账号、支付、Connector TCP 等 | `OpenCards.Server.Main` 进程 |
|
|
|
+
|
|
|
+### 1.2 端口对照表
|
|
|
+
|
|
|
+| 服务 | 端口 | 协议 | 说明 |
|
|
|
+|------|------|------|------|
|
|
|
+| 静态配置(无端口) | 80 | HTTP | 停服/更新/版本记录 JSON |
|
|
|
+| 区服列表 | 8000 | HTTP | `serverlist.json` |
|
|
|
+| AccountServer | 18081 | HTTP | 登录、账号 API |
|
|
|
+| PayServer | 18082 | HTTP | 支付 |
|
|
|
+| AdminService | 18088 | HTTP | GM 后台 |
|
|
|
+| **Connector(客户端游戏连接)** | **19821** | **TCP** | `local` 单节点默认 |
|
|
|
+| Connector 2 区 | 19822 | TCP | `local2` 多节点 2 区 |
|
|
|
+| Redis | 6379 | TCP | 依赖服务 |
|
|
|
+| MySQL | 3306 | TCP | Pay 等模块依赖 |
|
|
|
+
|
|
|
+> **注意**:`18081` 是 HTTP 账号接口,`19821` 才是 Unity 客户端建立游戏长连接的 TCP 端口。`serverlist.json` 里的 `address` 必须写 Connector 地址(如 `127.0.0.1:19821`),不能写 `18081`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 本地起服完整流程
|
|
|
+
|
|
|
+建议每次本地调试按以下顺序操作:
|
|
|
+
|
|
|
+### 第一步:启动依赖
|
|
|
+
|
|
|
+- Redis(`6379`)
|
|
|
+- MySQL(若启用 Pay 等模块)
|
|
|
+
|
|
|
+### 第二步:启动静态配置 HTTP 服务
|
|
|
+
|
|
|
+```powershell
|
|
|
+# 以管理员身份运行(80 端口可能需要管理员权限)
|
|
|
+powershell -ExecutionPolicy Bypass -File D:\WorkSpace\project\chuanzhanServer\scripts\start_local_static.ps1
|
|
|
+```
|
|
|
+
|
|
|
+或手动启动:
|
|
|
+
|
|
|
+```powershell
|
|
|
+python -m http.server 80 --directory D:\WorkSpace\project\chuanzhanServer\local_static\port80
|
|
|
+python -m http.server 8000 --directory D:\WorkSpace\project\chuanzhanServer\local_static\port8000
|
|
|
+```
|
|
|
+
|
|
|
+### 第三步:以管理员身份启动游戏服
|
|
|
+
|
|
|
+```powershell
|
|
|
+cd server\src\_output.server\net5.0
|
|
|
+OpenCards.Server.Main.exe local
|
|
|
+```
|
|
|
+
|
|
|
+Windows 下 HTTP 监听 `http://+:18081` 等需 URL ACL,可手动注册:
|
|
|
+
|
|
|
+```powershell
|
|
|
+netsh http add urlacl url=http://+:18081/account/ user=Everyone
|
|
|
+netsh http add urlacl url=http://+:18082/pay/ user=Everyone
|
|
|
+netsh http add urlacl url=http://+:18088/api/ user=Everyone
|
|
|
+netsh http add urlacl url=http://+:18089/chat/ user=Everyone
|
|
|
+```
|
|
|
+
|
|
|
+### 第四步:验证端口
|
|
|
+
|
|
|
+```powershell
|
|
|
+netstat -ano | findstr "LISTENING" | findstr ":80 :8000 :18081 :18082 :18088 :19821"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 起服异常:AccountServer 拉取静态配置失败
|
|
|
+
|
|
|
+### 3.1 现象
|
|
|
+
|
|
|
+```
|
|
|
+ERROR AccountServer - 由于目标计算机积极拒绝,无法连接。 (127.0.0.1:80),url:
|
|
|
+ http://127.0.0.1/cjw_60000_stop_server.json
|
|
|
+
|
|
|
+System.Net.Http.HttpRequestException : 由于目标计算机积极拒绝,无法连接。 (127.0.0.1:80)
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 原因
|
|
|
+
|
|
|
+**不是游戏服没起来**,而是 AccountServer 启动后会 **主动 HTTP 拉取外部静态 JSON**,本机 80 / 8000 没有 HTTP 服务时会报「积极拒绝连接」。
|
|
|
+
|
|
|
+`_launch_server_local.xml` 相关配置:
|
|
|
+
|
|
|
+```xml
|
|
|
+<StopServerDataURL>http://127.0.0.1/cjw_60000_stop_server.json</StopServerDataURL>
|
|
|
+<ServerListUrl>http://127.0.0.1:8000/serverlist.json</ServerListUrl>
|
|
|
+<UpdateServerConfig>http://127.0.0.1/update_server_config.json</UpdateServerConfig>
|
|
|
+<!-- 以及 android/ios 版本记录配置 -->
|
|
|
+```
|
|
|
+
|
|
|
+| URL | 需要的本地服务 |
|
|
|
+|-----|----------------|
|
|
|
+| `http://127.0.0.1:8000/serverlist.json` | 8000 端口静态文件服务 |
|
|
|
+| `http://127.0.0.1/xxx.json`(无端口 = 80) | 80 端口静态文件服务 |
|
|
|
+
|
|
|
+### 3.3 本地静态配置目录
|
|
|
+
|
|
|
+项目已准备:
|
|
|
+
|
|
|
+| 端口 | 目录 | 说明 |
|
|
|
+|------|------|------|
|
|
|
+| 80 | `local_static/port80/` | 停服、更新、版本记录等 JSON |
|
|
|
+| 8000 | `local_static/port8000/` | 区服列表 `serverlist.json` |
|
|
|
+
|
|
|
+启动脚本:`scripts/start_local_static.ps1`
|
|
|
+
|
|
|
+### 3.4 备选:改用 OSS 远程地址
|
|
|
+
|
|
|
+不想搭本地静态服时,参考 `_launch_server_dev.xml` 将 URL 改为 OSS:
|
|
|
+
|
|
|
+```xml
|
|
|
+<StopServerDataURL>https://zqtfcn.oss-cn-shanghai.aliyuncs.com/apollo/cjw_60000_stop_server.json</StopServerDataURL>
|
|
|
+<ServerListUrl>https://zqtfcn.oss-cn-shanghai.aliyuncs.com/apollo/serverlist.json</ServerListUrl>
|
|
|
+```
|
|
|
+
|
|
|
+使用远程列表时,`address` 仍需改成本机 Connector 地址。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. Unity 客户端连接服务器流程
|
|
|
+
|
|
|
+整体链路如下:
|
|
|
+
|
|
|
+```
|
|
|
+┌─────────────────────────────────────────────────────────────────┐
|
|
|
+│ Unity 客户端 │
|
|
|
+├─────────────────────────────────────────────────────────────────┤
|
|
|
+│ 热更/版本检查 → LoginMgr.login_url(账号服 HTTP 地址) │
|
|
|
+│ ↓ │
|
|
|
+│ 获取区服列表(见下方两条链路) │
|
|
|
+│ ↓ │
|
|
|
+│ 账号登录 → s2c_gateUrl(SDK 模式)或 serverlist.address(DEBUG)│
|
|
|
+│ ↓ │
|
|
|
+│ loginCtrl.EnterServer → LoginMgr.EnterServerRequest(address) │
|
|
|
+│ ↓ │
|
|
|
+│ connector.Connect(address) → Connector TCP(19821/19822) │
|
|
|
+└─────────────────────────────────────────────────────────────────┘
|
|
|
+```
|
|
|
+
|
|
|
+### 4.1 区服列表的两条独立链路
|
|
|
+
|
|
|
+| 链路 | 触发方 | 数据来源 | 影响范围 |
|
|
|
+|------|--------|----------|----------|
|
|
|
+| **链路 A:DEBUG 登录** | `LoginMgr.GetServerUrl()` | Unity C# 硬编码/配置的 URL | `loginCtrl.serverlist_data` → `address` |
|
|
|
+| **链路 B:账号服** | AccountServer 启动拉取 | `_launch_server.xml` 的 `ServerListUrl` | 登录返回 `s2c_gateUrl` |
|
|
|
+
|
|
|
+**只改仓库里的 JSON 文件,不等于 Unity 一定会用到**——必须让对应链路的 URL 指向你的 JSON,且静态 HTTP 服务在运行。
|
|
|
+
|
|
|
+### 4.2 DEBUG 模式 vs SDK 模式
|
|
|
+
|
|
|
+| 模式 | 判定 | address 来源 |
|
|
|
+|------|------|-------------|
|
|
|
+| **DEBUG** | `loginCtrl.LOGINDEBUG = true`(`PLAT_ID == NORAML` 时默认 true) | `LoginMgr.GetServerUrl()` → `serverlist_data[].address` |
|
|
|
+| **SDK** | 走第三方/平台登录 | 账号登录响应 `s2c_gateUrl` ← AccountServer 从 serverlist 读出 |
|
|
|
+
|
|
|
+SDK 模式下账号服赋值逻辑:
|
|
|
+
|
|
|
+```csharp
|
|
|
+// AccountServer.HandleLogin.cs
|
|
|
+rsp.s2c_gateUrl = serverInfo.address;
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. `address=` 日志在哪里打印
|
|
|
+
|
|
|
+连接地址会在 **Lua 和 C# 两层** 打印。
|
|
|
+
|
|
|
+### 5.1 Lua 层
|
|
|
+
|
|
|
+文件:`server/src/data/ClientScript/gameControl/login/loginCtrl.lua`
|
|
|
+
|
|
|
+```lua
|
|
|
+function loginCtrl.EnterServer(uuid, token, serverID, address)
|
|
|
+ if not address then
|
|
|
+ -- 从 serverlist_data 按 serverid 查找
|
|
|
+ for i = 1, #loginCtrl.serverlist_data do
|
|
|
+ local v = loginCtrl.serverlist_data[i]
|
|
|
+ if v.serverid == tonumber(serverID) then
|
|
|
+ address = v.address
|
|
|
+ break
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
+ print("address=" .. address) -- ← 此处打印
|
|
|
+ LoginMgr.EnterServerRequest(address, uuid, token, ...)
|
|
|
+end
|
|
|
+```
|
|
|
+
|
|
|
+调用入口(DEBUG 模式):
|
|
|
+
|
|
|
+- `loginView.lua` → `InitCompInDEBUG()` → 选服后 `loginCtrl.EnterServer(...)`
|
|
|
+
|
|
|
+### 5.2 C# 层(Unity)
|
|
|
+
|
|
|
+文件:`jyyz_game/client/Assets/Scripts/Common/LoginMgr.cs`
|
|
|
+
|
|
|
+```csharp
|
|
|
+public static void EnterServerRequest(string address, string account, string token, int sessionId, LuaFunction callBack)
|
|
|
+{
|
|
|
+ Debug.Log("EnterServerRequest=address=" + address); // ← Unity 控制台也会打印
|
|
|
+ connector.Connect(address, 15000, new ClientEnterServerRequest() { ... });
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+若看到 `address=127.0.0.1:19822`,说明客户端拿到的区服列表里该服的 `address` 字段就是 `127.0.0.1:19822`。
|
|
|
+
|
|
|
+### 5.3 关于 `19822` 端口
|
|
|
+
|
|
|
+- `local` 单节点:Connector 默认 **19821**(`_launch_server_local.xml`)
|
|
|
+- `local2` 多节点:2 区 Connector 为 **19822**(`_launch_server_local2.xml`)
|
|
|
+
|
|
|
+若选了 `serverid=2` 或 serverlist 中 2 区写了 `19822`,日志就会显示该地址。需与当前实际起服配置和监听端口一致。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 为什么本地 `serverlist.json` 没生效
|
|
|
+
|
|
|
+### 6.1 链路 A:Unity DEBUG 模式(最常见)
|
|
|
+
|
|
|
+`LoginMgr.GetServerUrl` 从 **Unity 工程 C# 里配置的 URL** 下载列表,**不会自动读** 服务端仓库里的文件。
|
|
|
+
|
|
|
+当前客户端实现(`LoginMgr.cs`):
|
|
|
+
|
|
|
+```csharp
|
|
|
+public static void GetServerUrl(bool isDebug, LuaFunction callBack)
|
|
|
+{
|
|
|
+ // string url = DataPathHelper.server_list; // 已注释
|
|
|
+ string url = "http://192.168.0.85/serverlist.json"; // ← 硬编码 URL
|
|
|
+ string returnText = wc.DownloadString(url);
|
|
|
+ // 包装为 {"servers": [...]} 后回调 Lua
|
|
|
+ callBack.call(serverData);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**要让本地 serverlist 生效,需修改此处 URL**,例如:
|
|
|
+
|
|
|
+```csharp
|
|
|
+string url = "http://127.0.0.1:8000/serverlist.json";
|
|
|
+// 或本机 80 端口:http://127.0.0.1/serverlist.json
|
|
|
+```
|
|
|
+
|
|
|
+并确保对应端口的静态 HTTP 服务已启动。
|
|
|
+
|
|
|
+### 6.2 链路 B:账号服(影响 `s2c_gateUrl`)
|
|
|
+
|
|
|
+账号服从 `_launch_server.xml` 的 `ServerListUrl` 拉取:
|
|
|
+
|
|
|
+```xml
|
|
|
+<!-- _launch_server_local.xml -->
|
|
|
+<ServerListUrl>http://127.0.0.1:8000/serverlist.json</ServerListUrl>
|
|
|
+```
|
|
|
+
|
|
|
+生效条件:
|
|
|
+
|
|
|
+1. **8000 端口静态 HTTP 在运行**
|
|
|
+2. **游戏服已重启**(AccountServer 启动时拉取并缓存)
|
|
|
+3. **`address` 字段正确**(Connector TCP 端口,非 HTTP 端口)
|
|
|
+
|
|
|
+可通过账号服接口验证缓存内容:
|
|
|
+
|
|
|
+```
|
|
|
+http://127.0.0.1:18081/account/getserverlist
|
|
|
+```
|
|
|
+
|
|
|
+AccountServer 日志中也可看到:
|
|
|
+
|
|
|
+```
|
|
|
+GetServerList 服务器列表地址 : http://127.0.0.1:8000/serverlist.json
|
|
|
+GetServerList content : 1,true,127.0.0.1:19821,...
|
|
|
+```
|
|
|
+
|
|
|
+### 6.3 `serverlist.json` 正确写法
|
|
|
+
|
|
|
+```json
|
|
|
+[
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "index": 0,
|
|
|
+ "name": "本地1区",
|
|
|
+ "address": "127.0.0.1:19821",
|
|
|
+ "state": 1,
|
|
|
+ "is_open": true,
|
|
|
+ "capacity": 2000,
|
|
|
+ "serverid": 1,
|
|
|
+ "groupid": 1,
|
|
|
+ "note": "local"
|
|
|
+ }
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+字段注意:
|
|
|
+
|
|
|
+| 字段 | 要求 |
|
|
|
+|------|------|
|
|
|
+| `address` | `IP:端口`,**不要** `http://`,**不要** 尾部 `/` |
|
|
|
+| `address` 端口 | 必须是 Connector(19821),**不是** 18081 |
|
|
|
+| `id` | 账号服用 `id` 做 map key,需与登录时 `serverid` 对应 |
|
|
|
+| `is_open` | `true` 才会进入有效区服列表 |
|
|
|
+
|
|
|
+### 6.4 错误示例
|
|
|
+
|
|
|
+```json
|
|
|
+"address": "192.168.0.85:18081/"
|
|
|
+```
|
|
|
+
|
|
|
+问题:
|
|
|
+
|
|
|
+- `18081` 是账号 HTTP 接口,不是游戏 TCP 入口
|
|
|
+- 尾部 `/` 可能导致地址解析异常
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 验证清单
|
|
|
+
|
|
|
+### 7.1 端口监听
|
|
|
+
|
|
|
+```powershell
|
|
|
+netstat -ano | findstr "LISTENING" | findstr ":80 :8000 :18081 :18082 :18088 :19821 :19822"
|
|
|
+```
|
|
|
+
|
|
|
+| 端口 | 期望 |
|
|
|
+|------|------|
|
|
|
+| 80 | LISTENING(静态配置) |
|
|
|
+| 8000 | LISTENING(serverlist) |
|
|
|
+| 18081 | LISTENING(AccountServer) |
|
|
|
+| 19821 | LISTENING(Connector,local 模式) |
|
|
|
+| 19822 | LISTENING(仅 local2 的 2 区) |
|
|
|
+
|
|
|
+### 7.2 静态配置可访问
|
|
|
+
|
|
|
+```powershell
|
|
|
+Invoke-WebRequest -Uri "http://127.0.0.1/cjw_60000_stop_server.json" -UseBasicParsing
|
|
|
+Invoke-WebRequest -Uri "http://127.0.0.1:8000/serverlist.json" -UseBasicParsing
|
|
|
+```
|
|
|
+
|
|
|
+### 7.3 账号服区服列表
|
|
|
+
|
|
|
+```powershell
|
|
|
+Invoke-WebRequest -Uri "http://127.0.0.1:18081/account/getserverlist" -UseBasicParsing
|
|
|
+```
|
|
|
+
|
|
|
+确认返回 JSON 中 `address` 为 `127.0.0.1:19821`(或你期望的 Connector 地址)。
|
|
|
+
|
|
|
+### 7.4 客户端实际连接地址
|
|
|
+
|
|
|
+Unity 控制台搜索:
|
|
|
+
|
|
|
+- Lua:`address=`
|
|
|
+- C#:`EnterServerRequest=address=`
|
|
|
+
|
|
|
+两者应一致,且与 `netstat` 中 Connector 监听端口匹配。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 常见误区
|
|
|
+
|
|
|
+| 误区 | 说明 |
|
|
|
+|------|------|
|
|
|
+| 只改仓库 JSON,不改 Unity `LoginMgr.cs` | DEBUG 模式走 `GetServerUrl` 硬编码 URL,不读本地文件 |
|
|
|
+| `address` 写成 `18081` | 那是 HTTP 账号接口,客户端 TCP 应连 19821 |
|
|
|
+| 只改 JSON 不重启游戏服 | AccountServer 启动时拉取一次 serverlist 并缓存 |
|
|
|
+| 8000 静态服未启动 | `ServerListUrl` 指向 8000 但无进程监听 → 拉取失败 |
|
|
|
+| 起服配置与 serverlist 端口不一致 | `local` 用 19821,`local2` 二区用 19822,需对应 |
|
|
|
+| 混淆 80 报错与客户端连不上 | 80 是 AccountServer 拉停服配置;客户端连的是 Connector TCP |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 关键文件索引
|
|
|
+
|
|
|
+### 服务端
|
|
|
+
|
|
|
+| 主题 | 路径 |
|
|
|
+|------|------|
|
|
|
+| 本地起服配置 | `server/src/server/OpenCards.Server.Main/_launch_server_local.xml` |
|
|
|
+| 多节点本地配置(含 19822) | `server/src/server/OpenCards.Server.Main/_launch_server_local2.xml` |
|
|
|
+| OSS 配置参考 | `server/src/server/OpenCards.Server.Main/_launch_server_dev.xml` |
|
|
|
+| AccountServer 拉取 serverlist | `server/src/server/OpenCards.Server.Account/Modules/AccountServer.HanldeServerListData.cs` |
|
|
|
+| 登录返回 gateUrl | `server/src/server/OpenCards.Server.Account/Modules/AccountServer.HandleLogin.cs` |
|
|
|
+| 本地静态配置(80) | `local_static/port80/` |
|
|
|
+| 本地静态配置(8000) | `local_static/port8000/` |
|
|
|
+| 静态服启动脚本 | `scripts/start_local_static.ps1` |
|
|
|
+| 配置样例 | `apollo_60000/` |
|
|
|
+
|
|
|
+### 客户端 Lua
|
|
|
+
|
|
|
+| 主题 | 路径 |
|
|
|
+|------|------|
|
|
|
+| 打印 `address=` | `server/src/data/ClientScript/gameControl/login/loginCtrl.lua` |
|
|
|
+| DEBUG 选服登录 | `server/src/data/ClientScript/gameView/login/loginView.lua` |
|
|
|
+| 热更设置 login_url | `server/src/data/ClientScript/HotUpdate/HotUpdateCtrl.lua` |
|
|
|
+
|
|
|
+### Unity C#
|
|
|
+
|
|
|
+| 主题 | 路径 |
|
|
|
+|------|------|
|
|
|
+| 拉取 serverlist(DEBUG) | `jyyz_game/client/Assets/Scripts/Common/LoginMgr.cs` → `GetServerUrl` |
|
|
|
+| TCP 连接 Connector | `jyyz_game/client/Assets/Scripts/Common/LoginMgr.cs` → `EnterServerRequest` |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 10. 总结
|
|
|
+
|
|
|
+| 问题 | 结论 |
|
|
|
+|------|------|
|
|
|
+| 起服报 `127.0.0.1:80` 拒绝 | 需独立静态 HTTP(80/8000),游戏服不提供这些 JSON |
|
|
|
+| `address=` 在哪打印 | Lua `loginCtrl.EnterServer` + C# `LoginMgr.EnterServerRequest` |
|
|
|
+| 本地 serverlist 不生效 | DEBUG 改 `LoginMgr.GetServerUrl` URL;SDK 改 `ServerListUrl` + 启静态服 + 重启游戏服 |
|
|
|
+| 客户端应连哪个端口 | Connector TCP:**19821**(local)或 **19822**(local2 二区),不是 18081 |
|
|
|
+| 推荐本地联调顺序 | 静态服(80/8000) → 游戏服 → 改 Unity URL → 验证 getserverlist → 看 `address=` 日志 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+*文档由 Cursor 对话自动整理生成*
|