Files
90CNServer/docs/服务端开发文档.md
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

148 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DNF90 服务端开发文档
> 覆盖服务端(Go)的架构、GM 接口契约、编译部署、以及本次新增的拍卖行 / 背包管理改动。
>
> 最后更新:2026-11-03
---
## 一、架构概览
服务端是 Go 单模块(`module longheng.io/server`),采用分层结构:
```
server/
├── cmd/
│ ├── server/dnf90/ 产品入口(主服务进程,产出 DNF90Server.exe)
│ ├── server/control/ 部署控制器(DNF90Control.exe,start/stop/configure)
│ ├── server/doctor/ 部署预检(DNF90Doctor.exe)
│ ├── companionpvf/ PVF 伴随进程
│ └── devtools/ scratch/ 开发调试工具(非产品)
├── internal/
│ ├── app/dnf90/ 单一组合根(路由注册、依赖装配)
│ ├── services/dnfbridge/ 客户端传输 + GM bridge 层(本次改动重点)
│ ├── modules/dnf/ DNF 领域模块(auction、dungeon、character 等)
│ ├── platform/ 框架层(含 platform/pvf PVF 解析)
│ ├── services/logic/dnf/ MySQL 仓储装配
│ └── ...
└── pkg/ 对外包
```
关键入口:
- 主服务:`cmd/server/dnf90/main.go`
- GM 路由:`internal/app/dnf90/gm_tool_compat.go`(兼容层,`/local/dnf-gm/*`)
- GM bridge:`internal/services/dnfbridge/gm_*.go`
---
## 二、编译与部署
### 环境要求
- **Go ≥ 1.26**(`go.mod` 声明 `go 1.26.5`)
- 依赖走国内镜像(加速):`GOPROXY=https://goproxy.cn,direct`、`GOSUMDB=sum.golang.google.cn`
### 编译命令
```bash
cd server
# 主服务端
go build -buildvcs=false -trimpath -o DNF90Server.exe ./cmd/server/dnf90
# 部署控制器
go build -buildvcs=false -trimpath -o DNF90Control.exe ./cmd/server/control
# 部署预检
go build -buildvcs=false -trimpath -o DNF90Doctor.exe ./cmd/server/doctor
```
编译产物部署到 `90server/Server/runtime/bin/`。
> 若 `go build` 报 "package unsafe is not in std",说明本地 Go SDK 的 src 不完整,
> 需改用完整 toolchain(见 `docs/开发文档.md` 的「Go 环境问题」章节)。
---
## 三、GM 接口契约(`/local/dnf-gm/*`)
GM 接口由 `internal/app/dnf90/gm_tool_compat.go` 注册,bridge 层实现在 `internal/services/dnfbridge/`。
### 认证
所有接口走 admin HTTP 端口(默认 `127.0.0.1:18111`),请求头带 `X-Admin-Token`(token 来自 `instance.json` 的 `adminToken`)。
### 返回结构
统一约定:`{"ok": true, "data": <结果>}`;错误时 `{"error": "<msg>"}`。
### 拍卖行接口(本次新增)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/local/dnf-gm/auction/listings` | 列出所有挂单,返回 `{listings, escrow_gold}` |
| POST | `/local/dnf-gm/auction/list` | 上架(支持自动补足) |
| POST | `/local/dnf-gm/auction/cancel` | 下架 |
上架请求体(`GMAuctionListRequest`):
```json
{
"seller_id": "角色ID",
"item_id": 10001,
"count": 1,
"unit_price": 10000,
"start_price": -1, // 每件起拍价,-1=不设竞拍
"buyout_price": -1, // 每件一口价,-1=不设一口价
"duration_hours": 24, // 24 或 48
"grant_if_missing": true // 背包不足时自动凭空发放差额再上架
}
```
### 背包管理接口(本次新增)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/local/dnf-gm/inventory/list?character_id=xxx` | 列角色背包 + 穿戴装备,每行 `{collection, entry_key, item_id, count, bind, item_name}` |
| POST | `/local/dnf-gm/item/delete` | 删除指定背包行(`entry_key` + `collection`,支持 slots/wear) |
---
## 四、本次关键改动说明
### 1. GM 拍卖行(线上上架通道)
- **新增** `internal/services/dnfbridge/gm_auction.go`:
- `GMAuctionListings` / `GMAuctionList` / `GMAuctionCancel` 三个方法。
- 直接调用 `dnfauction.Owner` 的纯数据层 `Register`/`Cancel`/`LoadListing`,**不依赖玩家 session**。
- **新增** `GMInventoryList` 方法(列背包全部道具 + 穿戴装备)。
### 2. 上架免押金
`gm_auction.go` 的 `GMAuctionList` 中,`Register` 的 `Deposit` 设为 `0`(原为 `dnfauction.ListingDepositGold = 10000`)。
服务端 `owner.go` 里是 `if cmd.Deposit > 0` 才扣款,因此 `Deposit=0` 直接跳过押金逻辑。
### 3. 自动补足上架(发放式)
`GMAuctionList` 支持 `grant_if_missing`:卖家背包物品不足时,先调 `GMGrantItem`(`dnfdungeon.Owner.GrantPickupItem`)凭空发放差额到背包,再 `Register` 上架。实现「像发放道具那样直接上架」。
### 4. 路由层
`gm_tool_compat.go` 新增常量与路由:
- `gmAuctionListingsPath` / `gmAuctionListPath` / `gmAuctionCancelPath`
- `gmInventoryListPath`
---
## 五、GM bridge 层约定
- GM 方法都在 `internal/services/dnfbridge/` 包,方法签名形如 `func (s *Service) GMXxx(ctx, req) (resp, error)`。
- 数据访问用 `s.repositoryGroup()`(返回 `dnfrepo.Group`,含 `Inventory`、`Equipment`、`Character` 等仓储)。
- 物品名解析用 `s.currentPVFItemCatalog()`(`dnfpvf` 目录),`ResolveItem(itemID)` 得到 `definition.Name`。
---
## 六、常见坑
1. **`go 1.26.5` 版本声明**:装 ≥1.26 即可,`GOTOOLCHAIN=auto` 会自动下载所需 toolchain。
2. **GM 接口路由**:`gm_tool_compat.go` 里 `gmToolPost` 包装 POST 接口,GET 接口用 `HandleFunc` + `writeGMJSON`。
3. **服务端 `Register` 的校验**:`buyout_price` 必须等于 `unit_price`(或"不设一口价"),`start_price` 在 `[0, unit_price]` 或"不设竞拍",时长只能是 24/48。
4. **对外发布**:不要附带本机测试用的深渊掉落修改;远程换装工具不要公开 Admin 端口。