117 lines
5.4 KiB
Markdown
117 lines
5.4 KiB
Markdown
## ADDED Requirements
|
||
|
||
### Requirement: Protobuf 协议定义文件
|
||
|
||
所有客户端-服务端 Hero/Bag/Equipment 消息 MUST 在新的 proto 文件中定义,存放路径 `Packages/cn.etetet.<新业务包>/Proto/<Module>Outer_C_<startId>.proto`。MUST 遵循 ET 框架已有命名规则:消息名 `C2G_xxx` 表示客户端→Gate,`G2C_xxx` 表示 Gate→客户端,`xxx_yyy` 表示推送消息(无 RpcId)。
|
||
|
||
#### Scenario: 协议文件结构
|
||
- **WHEN** 创建 `HeroOuter_C_3000.proto` 文件
|
||
- **THEN** 文件头部 MUST 声明 `syntax = "proto3"` 和 `package ET`
|
||
- **AND** 注释每个消息的 `ResponseType` 用于 ET Proto2CS 工具识别
|
||
- **AND** 该文件起始消息 ID = 3000,每个 message 顺序 +1
|
||
|
||
### Requirement: 数据传输对象 (DTO)
|
||
|
||
协议层 MUST 定义以下核心 DTO 结构供 RPC 和推送使用:
|
||
|
||
- `HeroInfo`: heroId (int64), configId (int32), level, exp, star, starExp, talentIndex, skills (repeated SkillInfo), talentTrees (repeated TalentTreeInfo), equipSlots (repeated EquipSlot)
|
||
- `SkillInfo`: skillId (int32), skillLevel (int32)
|
||
- `TalentTreeInfo`: pageIndex (int32), name (string), nodes (repeated TalentNodeInfo)
|
||
- `TalentNodeInfo`: nodeId (int32), level (int32)
|
||
- `EquipSlot`: subType (int32), itemIndex (int64, 0 表示空)
|
||
- `ItemInfo`: itemIndex (int64), itemId (int32), count (int64), itemType (int32), heroId (int64)
|
||
|
||
#### Scenario: 序列化 HeroInfo
|
||
- **WHEN** 服务端构造 HeroInfo 并通过 `MessageHelper.SendToClient` 发送
|
||
- **THEN** ET 框架自动使用 MemoryPack 序列化
|
||
- **AND** 客户端反序列化得到等价 HeroInfo 实例
|
||
|
||
### Requirement: 客户端→服务端 RPC 消息
|
||
|
||
协议层 MUST 包含以下 12 个 Hero/Equipment 业务 RPC(每个有 `ResponseType` 声明):
|
||
|
||
| RPC 名 | 说明 |
|
||
|---|---|
|
||
| C2G_SummonHero | 召唤英雄 |
|
||
| C2G_HeroAddExp | 加经验升级 |
|
||
| C2G_HeroStarUp | 升星 |
|
||
| C2G_HeroSkillUp | 技能升级 |
|
||
| C2G_HeroAwake | 觉醒 |
|
||
| C2G_TalentUp | 学天赋 |
|
||
| C2G_ChangeTalentIndex | 切换天赋页 |
|
||
| C2G_ResetTalent | 重置天赋页 |
|
||
| C2G_ModifyTalentName | 修改天赋页名 |
|
||
| C2G_HeroWearEquip | 穿装备 |
|
||
| C2G_TakeOffEquip | 卸装备 |
|
||
| C2G_ExchangeHeroItem | 雕像兑换碎片 |
|
||
|
||
Bag/Equipment 业务额外 RPC:
|
||
|
||
| RPC 名 | 说明 |
|
||
|---|---|
|
||
| C2G_UseItem | 使用道具 |
|
||
| C2G_MakeEquipment | 锻造装备 |
|
||
| C2G_ResolveEquipment | 分解装备 |
|
||
| C2G_MixMaterial | 合成材料 |
|
||
|
||
#### Scenario: 每个 RPC 都有错误码字段
|
||
- **WHEN** 定义任一 `G2C_xxx` Response
|
||
- **THEN** MUST 包含 `int32 Error` 和 `string Message` 字段
|
||
- **AND** Error 0 = 成功,非 0 = 失败码
|
||
|
||
### Requirement: 服务端→客户端推送消息
|
||
|
||
协议层 MUST 包含以下推送消息(无 RpcId、不需要回应):
|
||
- `Hero_HeroInfo { HeroInfo hero }` - 单个英雄数据变化
|
||
- `Hero_HeroInfoList { repeated HeroInfo heroes }` - 全量英雄列表(登录后)
|
||
- `Item_ItemInfo { ItemInfo item }` - 单个道具数量变化
|
||
- `Item_ItemInfoList { repeated ItemInfo items }` - 全量道具列表(登录后)
|
||
- `Item_RemoveItem { int64 itemIndex }` - 道具被完全移除
|
||
|
||
#### Scenario: 登录后全量同步
|
||
- **WHEN** 玩家通过 `C2G_LoginGate` 登录到 Gate 成功
|
||
- **THEN** 服务端 MUST 在 200ms 内推送 `Hero_HeroInfoList` 和 `Item_ItemInfoList`
|
||
- **AND** 客户端按顺序更新两个 Component 缓存
|
||
|
||
#### Scenario: 业务操作后增量推送
|
||
- **WHEN** 服务端处理任意 Hero/Bag 业务请求成功后
|
||
- **THEN** MUST 在响应中或之后立刻推送相关 `Hero_HeroInfo` / `Item_ItemInfo`
|
||
- **AND** 推送的数据是该操作影响的完整快照(不是 delta diff)
|
||
|
||
### Requirement: 错误码统一定义
|
||
|
||
所有 Hero/Bag/Equipment 错误码 MUST 在 `Packages/cn.etetet.login/Scripts/Model/Share/ErrorCode.cs` 或新增 `HeroBagErrorCode.cs` 中集中定义为 `public const int xxx`。命名规则:`ERR_<Module>_<Reason>`。
|
||
|
||
#### Scenario: 错误码示例
|
||
- **WHEN** 服务端拒绝因碎片不足的招募请求
|
||
- **THEN** 返回 `error = ERR_HERO_ITEM_NOT_ENOUGH`
|
||
- **AND** 客户端按错误码查表显示本地化文案
|
||
|
||
### Requirement: 消息 ID 分配
|
||
|
||
新协议 MUST 占用尚未使用的消息 ID 段(避开 1000 Login / 1100 Router / 11001 StateSync 等已用段)。建议使用 3000-3999 段。
|
||
|
||
#### Scenario: ID 段不冲突
|
||
- **WHEN** 通过 `ET/Proto/Proto2CS` 工具生成代码
|
||
- **THEN** 工具 MUST 检查 ID 不与现有 proto 冲突
|
||
- **AND** 若冲突则编译失败并提示
|
||
|
||
### Requirement: 协议代码生成
|
||
|
||
新增 proto 文件后 MUST 通过 ET 工具菜单 `ET/Proto/Proto2CS` 生成 C# 代码到 `Packages/cn.etetet.proto/CodeMode/Model/{Client|Server|ClientServer}/<Module>Outer_C_<startId>.cs`。生成的代码 MUST 自动注册到 ET 的 MessageDispatcher。
|
||
|
||
#### Scenario: 重新生成不破坏现有代码
|
||
- **WHEN** 修改 proto 文件后再次运行 Proto2CS
|
||
- **THEN** 工具 MUST 完全覆盖旧的生成 .cs 文件
|
||
- **AND** 不影响业务 Handler 代码(Handler 是手写的)
|
||
|
||
### Requirement: Handler 注册
|
||
|
||
所有 RPC 消息 MUST 有对应的服务端 Handler 类,命名规则 `C2G_<Name>Handler`,挂 `[MessageHandler(SceneType.Gate)]` 特性。Handler 类 MUST 实现 `MessageSessionHandler<C2G_xxx, G2C_xxx>` 模板。
|
||
|
||
#### Scenario: 消息路由
|
||
- **WHEN** 客户端发送 `C2G_SummonHero`
|
||
- **THEN** Gate Scene 的 MessageDispatcher 路由到 `C2G_SummonHeroHandler.Run()`
|
||
- **AND** Handler 通过 `session.GetComponent<SessionPlayerComponent>().Player` 获取玩家
|
||
- **AND** 修改业务后返回 Response
|