PRD-018 面对面交易
文档编号:PRD-018
版本:v1.0
状态:已通过
适用端:服务端 / 客户端
关联模块:ScenesServer/Trade.cpp、RecordServer、ItemManager
1. 背景与目标
面对面交易用于玩家间即时交换物品/货币。当前存在锁定后可换物品、交易双方距离过远仍成交、断线导致物品丢失等问题。本 PRD 统一交易申请、放置、锁定、确认、成交与取消。
2. 核心规则
2.1 交易条件
- 双方等级 ≥ 10,均未处于交易、副本结算、死亡状态。
- 距离 ≤ 5 格,同一地图。
- 交易物品必须非绑定、可交易、未锁定。
- 单次最多 6 格物品 + 货币。
2.2 流程
申请 → 对方同意 → 双方放置 → 双方锁定 → 双方确认 → 服务端校验 → 成交
- 放置/修改物品后自动取消锁定。
- 锁定后不能修改,需先取消锁定。
- 双方确认后进入 3 秒倒计时,期间可取消。
- 成交后物品/货币原子交换,写日志。
2.3 取消
- 任一方取消、超时、死亡、离开地图、掉线,交易取消。
- 取消后物品/货币原路退回,不进入背包临时格。
- 交易冷却 3 秒,防止刷请求。
3. 服务端设计
3.1 数据结构
struct TradeSession {
uint64_t session_id;
uint64_t role_a, role_b;
std::vector<TradeItem> items_a, items_b;
uint64_t gold_a, gold_b;
bool locked_a, locked_b;
bool confirmed_a, confirmed_b;
uint32_t deadline_ms;
};
3.2 协议
| 方向 | 协议 | 说明 |
|---|---|---|
| C→S | CS_TradeRequest | 发起交易 |
| C→S | CS_TradeAddItem | 放置物品 |
| C→S | CS_TradeSetGold | 设置货币 |
| C→S | CS_TradeLock | 锁定 |
| C→S | CS_TradeConfirm | 确认 |
| C→S | CS_TradeCancel | 取消 |
| S→C | SC_TradeState | 双方物品/锁定状态 |
| S→C | SC_TradeResult | 成交/取消原因 |
3.3 成交校验
- 再次校验双方在线、距离、物品仍属于本人、货币充足。
- 校验物品未被装备/强化/上架拍卖。
- 原子交换:A 的物品给 B,B 的给 A;失败全部回滚。
- 成交后物品绑定规则按
bind_type处理。
3.4 防骗与风控
- 锁定后界面禁止拖拽,任何修改需重新锁定。
- 确认弹窗显示双方物品/货币汇总,二次确认。
- 记录交易双方、物品 UID、货币、IP、时间。
- 高频交易/异常价格触发风控。
4. 客户端设计
- 交易窗口双栏,显示对方物品、货币、锁定/确认状态。
- 放置物品时从背包拖拽,显示数量选择。
- 锁定后格子加锁图标,修改按钮置灰。
- 确认后显示 3 秒倒计时,可取消。
- 成交后播放交易成功提示,刷新背包。
5. 配置
Trade.xml:max_items、max_distance、min_level、confirm_seconds、cooldown、max_gold。
6. 边界与异常
| 场景 | 处理 |
|---|---|
| 对方下线 | 立即取消,物品退回 |
| 交易中死亡 | 取消 |
| 物品被强化/出售 | 成交校验失败,取消 |
| 背包满 | 成交前校验双方空格,不足则拒绝 |
| 双方同时确认 | 服务端串行处理,只成交一次 |
| 重复确认包 | 幂等 |
7. 验收标准
- 申请/放置/锁定/确认/成交/取消全流程正确。
- 锁定后无法修改,修改必须重新锁定。
- 距离、地图、等级、绑定校验完整。
- 断线/死亡/超时不丢物品、不刷货币。
- 交易日志可按角色/物品追溯。