# DNF90 单机模拟器 · 整合启动器 + GM 工具 开发文档 > 本文档用于**换机后快速恢复开发环境**,覆盖环境搭建、项目结构、架构原理、接口清单、打包部署、常见问题等全部关键信息。 > > 最后更新:2026-11-03 --- ## 目录 1. [项目概述](#一项目概述) 2. [开发环境搭建](#二开发环境搭建) 3. [项目结构与关键文件](#三项目结构与关键文件) 4. [技术架构与原理](#四技术架构与原理) 5. [服务端 API 契约](#五服务端-api-契约) 6. [启动器后端 API 清单](#六启动器后端-api-清单) 7. [关键业务逻辑与约定](#七关键业务逻辑与约定) 8. [打包与部署](#八打包与部署) 9. [参考资料位置](#九参考资料位置) 10. [常见问题与坑](#十常见问题与坑) --- ## 一、项目概述 一个**单 EXE** 的 DNF90 单机模拟器启动器,内置完整的 GM 管理工具。 - **技术栈**:Python 3.15 + pywebview 6.x(WebView2 内嵌窗口)+ 纯标准库 HTTP 后端 + 原生 HTML/CSS/JS 前端 - **交付物**:`launcher/dist/DNF90启动器.exe`(单文件,约 14.57MB) - **部署位置**:EXE 始终放在 `Z:\90server\` 根目录(服务端目录内) ### 核心功能 **启动器主界面(4 按钮)**: - ▶ 开始游戏:configure-client → 启动服务端 → 注册账号 → 自动登录进游戏 - ⚙ 打开 GM:切换到内置 GM 管理工具界面 - ■ 关闭服务:安全停止服务端 - ♥ 赞助我们:弹出赞助二维码 - 🔄 一键换装:启动 LoadoutTool/DNFLoadout.exe **内置 GM 工具(功能页)**: - 控制台(服务端/数据库/Native API 状态) - 角色管理(等级/金币/职业转职/无限疲劳/删除角色) - 道具发放(装备/道具两分区 + 武器子类型筛选 + 品级筛选) - 邮件系统 / 背包装备 / 任务管理 / 副本控制 / 钱包点券(含黑钻) - 删档管理 / 连接设置(SQLite / Native 数据源切换) --- ## 二、开发环境搭建 ### 2.1 Python 环境 **本机有两个 Python,务必使用 Python 3.15:** | Python | 路径 | 用途 | |--------|------|------| | **Python 3.15.2** | `C:\Python315-32\python.exe` | **主开发环境(必须用这个)** | | Python 3.13.14 | `python`(PATH 默认) | WorkBuddy 内置,勿用于本项目 | > ⚠️ 所有命令用 `C:\Python315-32\python.exe`,不要用裸 `python`(会指向 3.13)。 ### 2.2 依赖包安装 ```bash # 切到 Python 3.15 C:/Python315-32/python.exe -m pip install pywebview pythonnet clr-loader pyinstaller pillow requests fastapi ``` 关键依赖及版本: | 包 | 版本 | 用途 | |----|------|------| | pywebview | 6.2.1 | 内嵌 WebView2 窗口 | | pythonnet | 3.2.1 | .NET CLR 互操作(pywebview 依赖) | | clr-loader | (latest) | pythonnet 的 CLR 加载器 | | pyinstaller | 6.22.3 | 打包单 EXE | | pillow | 13.0.0 | 二维码裁剪处理 | | requests | 2.34.2 | Native API 客户端(native.py 用) | | fastapi | 0.162.0 | 仅 gmtool 旧版用(launcher 主项目不用) | ### 2.3 pip 国内源(换机后需重新配置) `C:\Users\Administrator\AppData\Roaming\pip\pip.ini`: ```ini [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple extra-index-url = https://mirrors.aliyun.com/pypi/simple/ trusted-host = pypi.tuna.tsinghua.edu.cn ``` ### 2.4 换机后检查清单 - [ ] 安装 Python 3.15(任意位置,更新 `.bat` 和打包命令里的路径) - [ ] 配置 pip 清华源 - [ ] 安装上述依赖包 - [ ] 确认目标电脑有 **WebView2 运行时**(Win10/11 自带;Win7 需手动装) - [ ] 将整个项目目录拷贝到新机(含 `launcher/` 源码和 `90server/` 运行环境) --- ## 三、项目结构与关键文件 ### 3.1 工作区目录(开发源码所在地) ``` C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/ ├── launcher/ # ★ 主项目(启动器 + GM 工具) │ ├── server.py # ★ 整合后端(启动器动作 + GM HTTP 服务,纯标准库) │ ├── native.py # ★ Native API 客户端(封装服务端全部 GM 端点) │ ├── db.py # ★ SQLite 数据访问层(删角色/删档/疲劳) │ ├── index.html # 双视图界面(启动器 + GM 工具) │ ├── style.css # 深色 DNF 风格主题 │ ├── app.js # ★ 前端逻辑(启动器 + GM 路由) │ ├── sponsor.png # 赞助二维码(已裁剪) │ ├── sponsor_full_backup.png# 二维码原图备份 │ ├── sponsor_qr.png # 二维码中间产物 │ ├── DNF90启动器.spec # ★ PyInstaller 打包配置 │ ├── build/ # 打包中间产物(可删) │ └── dist/ # 打包产物 DNF90启动器.exe ├── gmtool/ # 旧版 FastAPI GM 工具(已弃用,仅参考) │ ├── main.py │ ├── gm_client.py │ └── static/ ├── README.md # 项目简介(较简略) ├── 开发文档.md # 本文档 ├── 2026-11-03.md # 当日详细工作日志(历史记录) ├── 启动启动器.bat # 源码方式运行启动器 ├── 启动GM工具.bat # 源码方式运行旧 GM 工具(已弃用) └── .workbuddy/ # WorkBuddy 项目数据(勿删) └── memory/ # 工作记忆(日志) ``` ### 3.2 运行环境(服务端所在,非源码) ``` Z:/90server/ # ★ 可运行模拟器 + 启动器部署位置 ├── DNF90启动器.exe # ★ 打包后的启动器(放这里运行) ├── Server/ # 服务端 │ └── runtime/ │ ├── bin/DNF90Control.exe # 服务端控制器(start/stop/configure-client/launch-client/account) │ ├── config/instance.json # Native API token 配置 │ └── data/dnf90.db # SQLite 数据库(首次启动生成) ├── Client/ # 游戏客户端 └── LoadoutTool/DNFLoadout.exe # 一键换装工具 ``` ### 3.3 服务端源码(Go,仅供参考 API 契约) ``` C:/Users/Administrator/Downloads/90轮回源码/90轮回源码/go-server/ └── internal/ ├── app/dnf90/ │ ├── gm_tool_admin.go # ★ GM 工具 HTTP 路由(GET 查询类) │ └── gm_admin.go # ★ 黑钻等写操作 ├── services/dnfbridge/ │ ├── gm_tool.go # GM 业务逻辑(职业/任务结构定义) │ ├── gm_tool_extended.go # 角色详情、分类逻辑 │ ├── gm_tool_items_extra.go# 道具发放 grant-options │ ├── gm_tool_dungeon.go # 副本难度 │ └── gm_tool_item_customization.go └── modules/dnf/ ├── itemquality/quality.go # 品级定义 └── profession/profile.go # 职业 Option 结构 ``` --- ## 四、技术架构与原理 ### 4.1 整体架构 ``` ┌─────────────────────────────────────────────────┐ │ DNF90启动器.exe(单文件,pywebview WebView2) │ │ │ │ ┌──────────────┐ HTTP(127.0.0.1:19527) │ │ │ 前端 app.js │ ◄──────────────────────────► │ │ │ index.html │ │ │ └──────────────┘ │ │ ▲ │ │ │ api()/post() │ │ ┌───────┴────────────────────────────────────┐ │ │ │ server.py(纯标准库 BaseHTTPRequestHandler)│ │ │ │ ├─ 启动器动作 flow_*() │ │ │ │ ├─ GM HTTP 路由 _api_*() │ │ │ │ ├─ SQLite 直读(DB, db.py) │ │ │ │ └─ Native 客户端(NATIVE, native.py) │ │ │ └───────┬──────────────────┬─────────────────┘ │ └──────────┼──────────────────┼───────────────────┘ │ SQLite 直读 │ HTTP(127.0.0.1:18111, X-Admin-Token) ▼ ▼ Server/runtime/data/dnf90.db DNF90Control.exe(运行中的服务端) ``` ### 4.2 双数据源机制(核心设计) GM 工具支持两种数据源,通过「连接设置」页切换: | 数据源 | 条件 | 特点 | |--------|------|------| | **Native API** | 服务端运行时 | 实时操作,`127.0.0.1:18111` + `X-Admin-Token` | | **SQLite 直读** | 服务端停止时 | 直接读写 `dnf90.db`,可删角色/删档/改疲劳 | - 判断逻辑:`_use_sqlite()` 返回 `True` 时走 SQLite,否则走 Native - **删角色/删档/改疲劳必须停服**(服务端运行时数据库被锁) ### 4.3 路径自动识别(重要) `SERVER_ROOT` 按以下优先级自动定位(`server.py` 模块加载时执行一次): 1. 环境变量 `DNF90_SERVER_ROOT`(手动覆盖) 2. EXE 自身所在目录(若其下存在 `Server/`)—— **正常场景命中** 3. 向上逐级查找含 `Server/` 的目录(最多 4 层) 4. 兜底 EXE 所在目录 `BASE_DIR` 派生路径(全部基于 SERVER_ROOT): ```python CONTROL = SERVER_ROOT + r"\Server\runtime\bin\DNF90Control.exe" CLIENT_DIR = SERVER_ROOT + r"\Client" LOADOUT_EXE = SERVER_ROOT + r"\LoadoutTool\DNFLoadout.exe" INSTANCE_PATH = SERVER_ROOT + r"\Server\runtime\config\instance.json" DB_PATH = SERVER_ROOT + r"\Server\runtime\data\dnf90.db" ``` **关键约定**:启动器 EXE 永远放在 `90server` 根目录,路径解析完全锚定 EXE 自身位置,不依赖任何写死盘符。 ### 4.4 Native API 认证机制 - 服务端 GM API 监听 `127.0.0.1:18111` - 认证头:`X-Admin-Token` - 两套路由:`/dnf/gm/*`(新版)、`/local/dnf-gm/*`(兼容版) - token 通过 `AUTO_GENERATE` 机制生成,存于 `instance.json` - 危险写操作需 `X-Admin-Confirm` + `X-Admin-Idempotency-Key` 头(`_post` 默认 `confirm=True`) --- ## 五、服务端 API 契约 > 服务端是 Go 编写的二进制,源码在 `90轮回源码/go-server/`。以下契约是从源码反推,供 native.py 和 server.py 对接。 ### 5.1 职业转职 ``` GET /dnf/gm/characters/{id}/career → GMCareerState POST /dnf/gm/characters/{id}/career {job, first, awakening} ``` `GMCareerState` 字段:`job`、`first_grow`(分支,0=未转职)、`awakening`、`profession_name`、`options[]`、`skills_reset`、`quest_reset_ids` `options` 层级结构: ``` Option { job, name, branches[] } BranchOption { value, name, awakenings[] } AwakeningOption { value, name } ``` ### 5.2 任务查询 ``` GET /dnf/gm/characters/{id}/quests → {character, active[], completed[]} GET /dnf/gm/quests/search?query=... → GMQuestSummary[] GET /dnf/gm/quests/{id}/detail?quest_id=... → 详情 POST(任务操作 accept/ready/give-up/complete/uncomplete) ``` `GMQuestSummary` 字段:`quest_id`、`name`、`grade`、`type`、`level_min`、`level_max`、`status`、`active`、`completed`、`acceptable` ### 5.3 爆率 / 副本 / 黑钻 ``` # 爆率(游戏玩法设置) GET /dnf/gm/gameplay → GMGameplaySettings POST /dnf/gm/gameplay/hell-drop-rate {percent} POST /dnf/gm/gameplay/epic-potion-test-multiplier {percent} # 副本 GET /dnf/gm/characters/{id}/dungeons → {difficulty_dungeons, difficulty_dungeons_unlocked, hell_areas, hell_permission_quests, hell_permission_quests_cleared} POST /dnf/gm/characters/{id}/dungeons/unlock-difficulties POST /dnf/gm/characters/{id}/dungeons/unlock-hell # 黑钻 GET /local/dnf-gm/character/black-diamond POST /local/dnf-gm/character/black-diamond {character_id, days} ``` `GMGameplaySettings` 字段:`hell_epic_drop_rate_percent`(当前爆率%)、`minimum_percent`、`maximum_percent`(上限 15000%)、`epic_drop_rate_potion_test_multiplier_percent` 黑钻返回:`active`、`expires_at`(时间戳,0=未开启)、`remaining_days`、`fatigue_limit`、`black_diamond_fatigue_limit` ### 5.4 品级(rarity)枚举 **rarity 0~6 共 7 档,权威映射:** | 值 | 品级 | 示例装备 | |----|------|---------| | 0 | 普通 | 粗布衬衫 | | 1 | 高级 | 棉布衬衫 | | 2 | 稀有 | 荣誉者长袍 | | 3 | 神器 | (旧) 雕翎长袍 | | 4 | 史诗 | (旧) 银月少女T恤衫 | | 5 | 传说 | 贤者的智慧之衣 | | 6 | 神话 | 首领萨斯的阴影长袍 | > ⚠️ **注意**:4=史诗、5=传说、6=神话(顺序易记错)。「勇者」不是独立品级档,是异界装备称呼,实际归类于神器(3)。 > 物品搜索的 `rarity` 参数是**精确匹配**(`item.Rarity != rarity` 过滤),范围 -1~6,-1=不限。 ### 5.5 品级机制(装备发放时) - `equipment_quality` 仅接受 `default` / `random` / `top` 三个值 - 品级本质是 `quality_seed` 数值:1=最下级,999999998(TopSeed)=最上级 - **直接进背包路径(grant-options)忽略品级参数**,只有**邮件(mail)路径**品级才真正生效 - 服务端不支持「最下级」,只能最上级(top)或随机(random) ### 5.6 装备分类与武器子类型 - 服务端 `kind` 值:`"equipment"`(装备)、`"stackable"`(道具) - 武器子类型通过 `q=/weapon//` 匹配 PVFPath(如 `equipment/character/swordman/weapon/katana/`) --- ## 六、启动器后端 API 清单 > `server.py` 提供,前端通过 `api()`(GET)和 `post()`(POST)调用。端口 `19527`。 ### 6.1 GET 路由 | 路径 | 说明 | |------|------| | `/api/status` | 启动器状态(含 server_root/client_dir/各文件是否存在/native_available) | | `/api/logs` | 运行日志 | | `/api/gm/health` | GM 健康检查 | | `/api/accounts-config` | 账号配置 | | `/api/accounts` | 账号列表 | | `/api/characters` | 角色列表(支持 ?account= 筛选) | | `/api/character` | 角色详情 | | `/api/character/inventory` | 背包 | | `/api/character/equipment` | 装备 | | `/api/character/mailbox` | 邮箱 | | `/api/character/fatigue` | 疲劳(mode=query) | | `/api/character/career` | 职业信息(转职查询) | | `/api/character/dungeons` | 副本状态 | | `/api/character/black-diamond` | 黑钻状态 | | `/api/gameplay` | 爆率设置查询 | | `/api/quests` | 任务概览 | | `/api/quests/search` | 任务搜索 | | `/api/quests/detail` | 任务详情 | | `/api/wipe/preview` | 删档预览 | | `/api/items/categories` | 道具分类 | | `/api/item/search` | 道具搜索 | ### 6.2 POST 路由 | 路径 | 说明 | |------|------| | `/api/action` | 启动器动作(start/stop/gm/loadout) | | `/api/accounts-config` | 账号配置写操作 | | `/api/source` | 切换数据源(SQLite/Native) | | `/api/character/save` | 保存角色 | | `/api/character/stat` | 改属性 | | `/api/character/fatigue` | 改疲劳 | | `/api/character/gold` | 改金币 | | `/api/character/level` | 改等级 | | `/api/character/skill-points` | 改技能点 | | `/api/character/career` | 应用转职 | | `/api/dungeon/unlock` | 解锁副本难度 | | `/api/black-diamond/activate` | 开启黑钻 | | `/api/gameplay/hell-drop-rate` | 设置爆率 | | `/api/gameplay/epic-potion-multiplier` | 设置药剂倍率 | | `/api/quests/action` | 任务操作 | | `/api/character/grant` | 发放道具 | | `/api/character/delete` | 删除角色 | | `/api/account/delete` | 删除账号 | | `/api/item/search` | 道具搜索(POST body) | | `/api/item/grant` | 发放道具 | | `/api/item/grant-options` | 发放道具(高级选项) | | `/api/item/mail` | 邮件发放道具 | | `/api/mail/send` | 发送邮件 | | `/api/mailbox/clear` | 清空邮箱 | | `/api/inventory/clear` | 清空背包 | | `/api/inventory/delete` | 删除背包物品 | | `/api/wallet/query` | 钱包查询 | | `/api/cera` | 点券充值 | ### 6.3 native.py 方法清单(服务端 GM 端点封装) `native.py` 是服务端 GM API 的完整 Python 客户端封装,方法列表: - **账号**:`list_accounts` / `get_account` / `set_account_value` - **角色**:`list_characters` / `get_character` / `get_character_detail` - **物品/背包**:`get_inventory` / `get_equipment` / `get_mailbox` / `get_item_detail` / `get_item_mail_options` / `get_item_categories` / `search_items` / `search_avatar_sets` - **道具发放**:`grant_item` / `grant_item_options` / `grant_item_with_emblems` / `send_item_mail` - **删除**:`delete_item` / `delete_inventory_item` / `clear_inventory` / `unequip_equipment` / `delete_equipment` - **属性修改**:`set_gold` / `set_level` / `set_skill_bonus` / `set_career` / `get_career` / `set_cera` / `adjust_revive_coin` - **钱包**:`query_wallet` / `update_wallet` / `set_account_cube` / `get_account_cubes` - **邮件**:`send_system_mail` / `clear_mailbox` / `delete_mailbox_mails` - **任务**:`get_quest_overview` / `search_quests` / `get_quest_detail` / `accept_quest` / `mark_quest_ready` / `give_up_quest` / `complete_quest` / `uncomplete_quest` / `complete_quest_batch` - **副本**:`get_dungeons` / `unlock_dungeon_difficulties` / `unlock_hell_challenges` - **黑钻**:`get_black_diamond` / `activate_black_diamond` - **爆率**:`get_gameplay_settings` / `set_hell_drop_rate` / `set_epic_potion_multiplier` - **宠物**:`update_pet` --- ## 七、关键业务逻辑与约定 ### 7.1 疲劳值机制 - 角色 `stats` 里的字段:`fatigue`(当前疲劳)、`fatigue_limit`(上限,默认156/黑钻188)、`fatigue_display_update`(已用) - 每天 6 点重置回上限 - **无限疲劳** = 把 `fatigue` 和 `fatigue_limit` 都设为超大值(999999) - 服务端**无独立疲劳查询 GM 接口**,从 `get_character_detail()` 的 `stats` 里读 ### 7.2 账号配置 - `accounts.json` 存 EXE 同目录(`BASE_DIR`) - `load_accounts` / `save_accounts` / `get_default_account` - 默认账号 `dnfplayer` 不可删除 ### 7.3 窗口与 UI 约定 - **GM 窗口打开直接最大化**,但**不用 `maximize()`**(会遮挡任务栏) - 用 `_get_work_area()`(`ctypes` 调 `SystemParametersInfoW(SPI_GETWORKAREA=0x0030)`)获取扣除任务栏的工作区,再 `move()` + `resize()` - 主窗口和 GM 窗口都屏幕居中(`webview.screens[0].width/height` 计算 x/y) - 深色 DNF 风格 + 紫青渐变 + 毛玻璃质感 ### 7.4 危险操作约定 - 删除角色/删档/改疲劳:**需先停服**(SQLite 直读模式) - 危险操作二次确认:输入确认词(如 `DELETE`、`转职`) ### 7.5 进程回收 - 关闭后需 `os._exit(0)` 强制退出 + `_kill_webview2_children()`(清理 WebView2 子进程) - 打包前需先 `taskkill /F /IM "DNF90启动器.exe"`(否则 dist exe 被锁定) --- ## 八、打包与部署 ### 8.1 打包命令 用 spec 文件打包(推荐,配置已固化): ```bash cd "C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/launcher" # 先杀掉残留进程(避免文件锁定) taskkill /F /IM "DNF90启动器.exe" # 打包 C:/Python315-32/python.exe -m PyInstaller --clean --noconfirm "DNF90启动器.spec" ``` 产物:`launcher/dist/DNF90启动器.exe` ### 8.2 拷贝到运行目录 ```bash cp -f "C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/launcher/dist/DNF90启动器.exe" "Z:/90server/DNF90启动器.exe" ``` ### 8.3 spec 文件要点 `DNF90启动器.spec` 关键配置: - `datas`:打包 `index.html`、`style.css`、`app.js`、`sponsor.png`、`db.py`、`native.py` - `hiddenimports`:`clr_loader`、`pythonnet` - `collect_all('webview')`:pywebview 全部资源 - `console=False`:windowed 模式(无控制台) - `upx=True`:UPX 压缩 - `name='DNF90启动器'` > 如果不用 spec,等价命令行(注意 Windows 分隔符是 `;`)见 `README.md`。 ### 8.4 部署要求 - EXE 放在 `90server` 根目录 - 目标电脑需 WebView2 运行时(Win10/11 自带) - 首次运行请求管理员权限(UAC,启动服务端需要) - 无需安装 Python 或其他依赖(单文件已全打包) ### 8.5 验证方法 打包后在同批命令内验证(后台进程在命令结束时会被回收): ```bash cd "Z:/90server" && ./DNF90启动器.exe > /dev/null 2>&1 & sleep 8 curl -s --noproxy "*" "http://127.0.0.1:19527/api/status" ``` 预期返回:`server_root=Z:\90server`、`db_exists=true`、`native_available=true`、`control_exists=true`、`server_dir_exists=true`、`client_dir_exists=true`。 --- ## 九、参考资料位置 | 资料 | 位置 | |------|------| | 服务端源码(Go) | `C:/Users/Administrator/Downloads/90轮回源码/90轮回源码/go-server/` | | 旧 GM 工具源码备份 | WorkBuddy 资料库节点 `sfEHKi5MJIh0D9lSykGVoT`(DNF90工具与资料备份 web 页) | | 旧 GM 工具(运行版) | `Z:/90server/gm_tool/`(已打包 DNF90GM工具.exe) | | 可运行模拟器 | `Z:/90server/` | | 当日工作日志 | `C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/2026-11-03.md` | ### 读取资料库参考资料的方法 ```bash # 查询节点信息 python3 "C:/Users/Administrator/AppData/Local/Programs/WorkBuddy/resources/app.asar.unpacked/resources/plugins/workbuddy-builtin/skills/library/space_api.py" space.workspace.node-info --node-id sfEHKi5MJIh0D9lSykGVoT # 下载 artifacts python3 ".../library/page/download_page_artifacts.py" --node-id "sfEHKi5MJIh0D9lSykGVoT" --out-dir "/tmp/gmref" --path "..." ``` --- ## 十、常见问题与坑 ### 10.1 打包相关 | 问题 | 解决 | |------|------| | 打包报 OSError safe-delete 失败 | dist 的 exe 被占用,先 `taskkill /F /IM "DNF90启动器.exe"` | | `--add-data` 分隔符 | Windows 用 `;`(不是 `:`) | | 打包后窗口变浏览器 | pywebview `transparent=True` 在 Windows 不支持,会导致降级 | ### 10.2 pywebview 相关 | 问题 | 解决 | |------|------| | 无边框窗口 maximize 遮挡任务栏 | 用 `_get_work_area()` 获取工作区再 resize,不要用 `maximize()` | | 关闭后 WebView2 子进程残留 | `os._exit(0)` + `_kill_webview2_children()` | | `create_window()` 报错 | 必须在 `webview.start()` 之前调用 | ### 10.3 后端参数解析 **重要教训**:`_api_character_fatigue` 曾有个 bug——用 `if "id" in data_or_qs` 判断,导致 GET 请求的 `parse_qs` 结果(值是 list)被当成标量,`char_id` 变成 `['1']` 列表,报「角色 ['1'] 不存在」。 **正确写法**:GET 请求统一用 `qs.get("id", [""])[0]` 取第一个值;POST body 才直接 `data.get("id")`。 ### 10.4 数据源相关 | 问题 | 解决 | |------|------| | 删角色/删档报数据库锁定 | 需先停服(点「关闭服务」) | | 疲劳值读不出 | 服务端无独立疲劳接口,用 `get_character_detail()` 的 `stats.fatigue` | | 道具搜索 404 | 前端用 `post('/api/item/search')` 但后端原来只有 GET 路由,需补 POST 路由 | ### 10.5 品级相关 - rarity 精确匹配(`-1` = 不限),枚举 0~6:普通/高级/稀有/神器/史诗/传说/神话 - 品级 `equipment_quality` 只接受 default/random/top - 品级只有邮件路径生效,直接进背包路径忽略品级 ### 10.6 测试相关 - **后台进程在命令结束时会被回收**(非交互模式),验证必须把启动和测试放同一批命令内 - 服务端 `DNF90Server.exe` 是常驻进程,测试时**不要**误杀 - 默认测试角色:`character_id=1`,名「测试」,职业神枪手,1级 --- ## 附:快速上手速查 ```bash # 1. 源码方式运行启动器(开发调试) cd "C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/launcher" C:/Python315-32/python.exe server.py # 2. 校验语法 C:/Python315-32/python.exe -c "import ast; ast.parse(open('server.py',encoding='utf-8').read())" node --check app.js # 3. 打包 + 拷贝(换机后重复此流程) taskkill /F /IM "DNF90启动器.exe" cd "C:/Users/Administrator/WorkBuddy/DNF启动器和GM管理工具/launcher" C:/Python315-32/python.exe -m PyInstaller --clean --noconfirm "DNF90启动器.spec" cp -f dist/DNF90启动器.exe "Z:/90server/DNF90启动器.exe" # 4. 用默认测试角色验证(同批命令内) cd "Z:/90server" && ./DNF90启动器.exe > /dev/null 2>&1 & sleep 8 && curl -s --noproxy "*" "http://127.0.0.1:19527/api/status" ```