ygopro-msg-encode 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +4 -0
- package/.eslintrc.js +25 -0
- package/.prettierrc +4 -0
- package/AGENTS.md +12 -0
- package/CHANGES.md +270 -0
- package/CTOS_STOC_IMPLEMENTATION.md +279 -0
- package/FINAL_SUMMARY.md +357 -0
- package/FULL_PAYLOAD_SUMMARY.md +491 -0
- package/FULL_PAYLOAD_UPDATE.md +598 -0
- package/IMPLEMENTATION_SUMMARY.md +294 -0
- package/LICENSE +22 -0
- package/MSG_IMPLEMENTATION_SUMMARY.md +358 -0
- package/OPPONENT_VIEW_SUMMARY.md +387 -0
- package/PROJECT_COMPLETE.md +565 -0
- package/QUICK_REFERENCE.md +352 -0
- package/README.md +494 -0
- package/REAL_IP_STRING_UPDATE.md +289 -0
- package/TESTS_MIGRATION.md +342 -0
- package/VARIABLE_LENGTH_STRINGS.md +224 -0
- package/VARIABLE_LENGTH_UPDATE.md +229 -0
- package/dist/index.cjs +5131 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +5185 -0
- package/dist/index.mjs.map +7 -0
- package/dist/src/binary/binary-meta.d.ts +18 -0
- package/dist/src/binary/fill-binary-fields.d.ts +2 -0
- package/dist/src/metadata.d.ts +10 -0
- package/dist/src/proto-base/payload-base.d.ts +8 -0
- package/dist/src/proto-base/registry-base.d.ts +13 -0
- package/dist/src/protos/common/host-info.d.ts +12 -0
- package/dist/src/protos/common/index.d.ts +1 -0
- package/dist/src/protos/ctos/base.d.ts +17 -0
- package/dist/src/protos/ctos/index.d.ts +3 -0
- package/dist/src/protos/ctos/proto/chat.d.ts +9 -0
- package/dist/src/protos/ctos/proto/create-game.d.ts +8 -0
- package/dist/src/protos/ctos/proto/external-address.d.ts +12 -0
- package/dist/src/protos/ctos/proto/hand-result.d.ts +5 -0
- package/dist/src/protos/ctos/proto/hs-notready.d.ts +4 -0
- package/dist/src/protos/ctos/proto/hs-ready.d.ts +4 -0
- package/dist/src/protos/ctos/proto/hs-start.d.ts +4 -0
- package/dist/src/protos/ctos/proto/hs-toduelist.d.ts +4 -0
- package/dist/src/protos/ctos/proto/hs-toobserver.d.ts +4 -0
- package/dist/src/protos/ctos/proto/index.d.ts +19 -0
- package/dist/src/protos/ctos/proto/join-game.d.ts +7 -0
- package/dist/src/protos/ctos/proto/kick.d.ts +5 -0
- package/dist/src/protos/ctos/proto/leave-game.d.ts +4 -0
- package/dist/src/protos/ctos/proto/player-info.d.ts +5 -0
- package/dist/src/protos/ctos/proto/request-field.d.ts +4 -0
- package/dist/src/protos/ctos/proto/response.d.ts +7 -0
- package/dist/src/protos/ctos/proto/surrender.d.ts +4 -0
- package/dist/src/protos/ctos/proto/time-confirm.d.ts +4 -0
- package/dist/src/protos/ctos/proto/tp-result.d.ts +5 -0
- package/dist/src/protos/ctos/proto/update-deck.d.ts +11 -0
- package/dist/src/protos/ctos/registry.d.ts +3 -0
- package/dist/src/protos/msg/base.d.ts +9 -0
- package/dist/src/protos/msg/index.d.ts +3 -0
- package/dist/src/protos/msg/proto/add-counter.d.ts +9 -0
- package/dist/src/protos/msg/proto/announce-attrib.d.ts +7 -0
- package/dist/src/protos/msg/proto/announce-card.d.ts +7 -0
- package/dist/src/protos/msg/proto/announce-number.d.ts +7 -0
- package/dist/src/protos/msg/proto/announce-race.d.ts +7 -0
- package/dist/src/protos/msg/proto/attack-disabled.d.ts +4 -0
- package/dist/src/protos/msg/proto/attack.d.ts +12 -0
- package/dist/src/protos/msg/proto/battle.d.ts +18 -0
- package/dist/src/protos/msg/proto/become-target.d.ts +6 -0
- package/dist/src/protos/msg/proto/cancel-target.d.ts +11 -0
- package/dist/src/protos/msg/proto/card-hint.d.ts +10 -0
- package/dist/src/protos/msg/proto/card-query.d.ts +38 -0
- package/dist/src/protos/msg/proto/card-target.d.ts +11 -0
- package/dist/src/protos/msg/proto/chain-disabled.d.ts +5 -0
- package/dist/src/protos/msg/proto/chain-end.d.ts +4 -0
- package/dist/src/protos/msg/proto/chain-negated.d.ts +5 -0
- package/dist/src/protos/msg/proto/chain-solved.d.ts +5 -0
- package/dist/src/protos/msg/proto/chain-solving.d.ts +5 -0
- package/dist/src/protos/msg/proto/chained.d.ts +5 -0
- package/dist/src/protos/msg/proto/chaining.d.ts +12 -0
- package/dist/src/protos/msg/proto/confirm-cards.d.ts +16 -0
- package/dist/src/protos/msg/proto/confirm-decktop.d.ts +14 -0
- package/dist/src/protos/msg/proto/confirm-extratop.d.ts +14 -0
- package/dist/src/protos/msg/proto/damage-step-end.d.ts +4 -0
- package/dist/src/protos/msg/proto/damage-step-start.d.ts +4 -0
- package/dist/src/protos/msg/proto/damage.d.ts +6 -0
- package/dist/src/protos/msg/proto/deck-top.d.ts +8 -0
- package/dist/src/protos/msg/proto/draw.d.ts +8 -0
- package/dist/src/protos/msg/proto/equip.d.ts +12 -0
- package/dist/src/protos/msg/proto/field-disabled.d.ts +5 -0
- package/dist/src/protos/msg/proto/flipsummoned.d.ts +4 -0
- package/dist/src/protos/msg/proto/flipsummoning.d.ts +9 -0
- package/dist/src/protos/msg/proto/hand-res.d.ts +5 -0
- package/dist/src/protos/msg/proto/hint.d.ts +7 -0
- package/dist/src/protos/msg/proto/index.d.ts +85 -0
- package/dist/src/protos/msg/proto/lpupdate.d.ts +6 -0
- package/dist/src/protos/msg/proto/match-kill.d.ts +5 -0
- package/dist/src/protos/msg/proto/missed-effect.d.ts +7 -0
- package/dist/src/protos/msg/proto/move.d.ts +14 -0
- package/dist/src/protos/msg/proto/new-phase.d.ts +5 -0
- package/dist/src/protos/msg/proto/new-turn.d.ts +5 -0
- package/dist/src/protos/msg/proto/pay-lpcost.d.ts +6 -0
- package/dist/src/protos/msg/proto/player-hint.d.ts +7 -0
- package/dist/src/protos/msg/proto/pos-change.d.ts +12 -0
- package/dist/src/protos/msg/proto/random-selected.d.ts +7 -0
- package/dist/src/protos/msg/proto/recover.d.ts +6 -0
- package/dist/src/protos/msg/proto/reload-field.d.ts +36 -0
- package/dist/src/protos/msg/proto/remove-counter.d.ts +9 -0
- package/dist/src/protos/msg/proto/reset-time.d.ts +6 -0
- package/dist/src/protos/msg/proto/retry.d.ts +4 -0
- package/dist/src/protos/msg/proto/reverse-deck.d.ts +4 -0
- package/dist/src/protos/msg/proto/rock-paper-scissors.d.ts +5 -0
- package/dist/src/protos/msg/proto/select-battlecmd.d.ts +25 -0
- package/dist/src/protos/msg/proto/select-card.d.ts +17 -0
- package/dist/src/protos/msg/proto/select-chain.d.ts +19 -0
- package/dist/src/protos/msg/proto/select-counter.d.ts +17 -0
- package/dist/src/protos/msg/proto/select-disfield.d.ts +7 -0
- package/dist/src/protos/msg/proto/select-effectyn.d.ts +11 -0
- package/dist/src/protos/msg/proto/select-idlecmd.d.ts +37 -0
- package/dist/src/protos/msg/proto/select-option.d.ts +7 -0
- package/dist/src/protos/msg/proto/select-place.d.ts +7 -0
- package/dist/src/protos/msg/proto/select-position.d.ts +7 -0
- package/dist/src/protos/msg/proto/select-sum.d.ts +20 -0
- package/dist/src/protos/msg/proto/select-tribute.d.ts +18 -0
- package/dist/src/protos/msg/proto/select-unselect-card.d.ts +20 -0
- package/dist/src/protos/msg/proto/select-yesno.d.ts +6 -0
- package/dist/src/protos/msg/proto/set.d.ts +5 -0
- package/dist/src/protos/msg/proto/shuffle-deck.d.ts +5 -0
- package/dist/src/protos/msg/proto/shuffle-extra.d.ts +8 -0
- package/dist/src/protos/msg/proto/shuffle-hand.d.ts +8 -0
- package/dist/src/protos/msg/proto/shuffle-set-card.d.ts +17 -0
- package/dist/src/protos/msg/proto/sort-card.d.ts +13 -0
- package/dist/src/protos/msg/proto/spsummoned.d.ts +4 -0
- package/dist/src/protos/msg/proto/spsummoning.d.ts +9 -0
- package/dist/src/protos/msg/proto/start.d.ts +14 -0
- package/dist/src/protos/msg/proto/summoned.d.ts +4 -0
- package/dist/src/protos/msg/proto/summoning.d.ts +9 -0
- package/dist/src/protos/msg/proto/swap-grave-deck.d.ts +5 -0
- package/dist/src/protos/msg/proto/swap.d.ts +12 -0
- package/dist/src/protos/msg/proto/tag-swap.d.ts +14 -0
- package/dist/src/protos/msg/proto/toss-coin.d.ts +7 -0
- package/dist/src/protos/msg/proto/toss-dice.d.ts +7 -0
- package/dist/src/protos/msg/proto/update-card.d.ts +14 -0
- package/dist/src/protos/msg/proto/update-data.d.ts +12 -0
- package/dist/src/protos/msg/proto/waiting.d.ts +4 -0
- package/dist/src/protos/msg/proto/win.d.ts +6 -0
- package/dist/src/protos/msg/registry.d.ts +3 -0
- package/dist/src/protos/stoc/base.d.ts +17 -0
- package/dist/src/protos/stoc/index.d.ts +3 -0
- package/dist/src/protos/stoc/proto/change-side.d.ts +4 -0
- package/dist/src/protos/stoc/proto/chat.d.ts +10 -0
- package/dist/src/protos/stoc/proto/create-game.d.ts +5 -0
- package/dist/src/protos/stoc/proto/deck-count.d.ts +5 -0
- package/dist/src/protos/stoc/proto/duel-end.d.ts +4 -0
- package/dist/src/protos/stoc/proto/duel-start.d.ts +4 -0
- package/dist/src/protos/stoc/proto/error-msg.d.ts +6 -0
- package/dist/src/protos/stoc/proto/field-finish.d.ts +4 -0
- package/dist/src/protos/stoc/proto/game-msg.d.ts +9 -0
- package/dist/src/protos/stoc/proto/hand-result.d.ts +6 -0
- package/dist/src/protos/stoc/proto/hs-player-change.d.ts +5 -0
- package/dist/src/protos/stoc/proto/hs-player-enter.d.ts +6 -0
- package/dist/src/protos/stoc/proto/hs-watch-change.d.ts +5 -0
- package/dist/src/protos/stoc/proto/index.d.ts +24 -0
- package/dist/src/protos/stoc/proto/join-game.d.ts +6 -0
- package/dist/src/protos/stoc/proto/leave-game.d.ts +5 -0
- package/dist/src/protos/stoc/proto/replay.d.ts +11 -0
- package/dist/src/protos/stoc/proto/select-hand.d.ts +4 -0
- package/dist/src/protos/stoc/proto/select-tp.d.ts +4 -0
- package/dist/src/protos/stoc/proto/srvpro-roomlist.d.ts +18 -0
- package/dist/src/protos/stoc/proto/teammate-surrender.d.ts +4 -0
- package/dist/src/protos/stoc/proto/time-limit.d.ts +6 -0
- package/dist/src/protos/stoc/proto/tp-result.d.ts +4 -0
- package/dist/src/protos/stoc/proto/type-change.d.ts +5 -0
- package/dist/src/protos/stoc/proto/waiting-side.d.ts +4 -0
- package/dist/src/protos/stoc/registry.d.ts +3 -0
- package/dist/src/vendor/ocgcore-constants.d.ts +360 -0
- package/dist/src/vendor/script-constants.d.ts +836 -0
- package/index.ts +6 -0
- package/package.json +74 -0
- package/scripts/gen-constants.js +156 -0
- package/tsconfig.json +20 -0
package/FINAL_SUMMARY.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# CTOS/STOC 协议实现 - 最终总结
|
|
2
|
+
|
|
3
|
+
## ✅ 完成状态
|
|
4
|
+
|
|
5
|
+
**所有 CTOS 和 STOC 协议已完整实现,构建测试通过!**
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📊 实现统计
|
|
10
|
+
|
|
11
|
+
### 协议数量
|
|
12
|
+
- **CTOS 协议**: 19 个 ✅
|
|
13
|
+
- **STOC 协议**: 24 个 ✅
|
|
14
|
+
- **总计**: 43 个协议
|
|
15
|
+
|
|
16
|
+
### 文件统计
|
|
17
|
+
- 新建文件: 50+ 个
|
|
18
|
+
- 代码行数: 约 1600+ 行
|
|
19
|
+
- 构建产物大小: 144.4kb (ESM) / 154.6kb (CJS)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📁 完整的文件结构
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
src/protos/
|
|
27
|
+
├── common/
|
|
28
|
+
│ ├── host-info.ts ✅ HostInfo 公共结构
|
|
29
|
+
│ └── index.ts
|
|
30
|
+
├── ctos/ ✅ 19 个 CTOS 协议
|
|
31
|
+
│ ├── base.ts
|
|
32
|
+
│ ├── registry.ts
|
|
33
|
+
│ ├── index.ts
|
|
34
|
+
│ └── proto/
|
|
35
|
+
│ ├── response.ts (0x01) 响应数据
|
|
36
|
+
│ ├── update-deck.ts (0x02) 更新卡组 [特殊封装]
|
|
37
|
+
│ ├── hand-result.ts (0x03) 猜拳结果
|
|
38
|
+
│ ├── tp-result.ts (0x04) 先后手结果
|
|
39
|
+
│ ├── player-info.ts (0x10) 玩家信息
|
|
40
|
+
│ ├── create-game.ts (0x11) 创建房间
|
|
41
|
+
│ ├── join-game.ts (0x12) 加入房间
|
|
42
|
+
│ ├── leave-game.ts (0x13) 离开房间
|
|
43
|
+
│ ├── surrender.ts (0x14) 认输
|
|
44
|
+
│ ├── time-confirm.ts (0x15) 时间确认
|
|
45
|
+
│ ├── chat.ts (0x16) 聊天
|
|
46
|
+
│ ├── external-address.ts(0x17) 外部地址
|
|
47
|
+
│ ├── hs-toduelist.ts (0x20) 切换到决斗者
|
|
48
|
+
│ ├── hs-toobserver.ts (0x21) 切换到观战者
|
|
49
|
+
│ ├── hs-ready.ts (0x22) 准备
|
|
50
|
+
│ ├── hs-notready.ts (0x23) 取消准备
|
|
51
|
+
│ ├── kick.ts (0x24) 踢人
|
|
52
|
+
│ ├── hs-start.ts (0x25) 开始决斗
|
|
53
|
+
│ ├── request-field.ts (0x30) 请求场地
|
|
54
|
+
│ └── index.ts
|
|
55
|
+
└── stoc/ ✅ 24 个 STOC 协议
|
|
56
|
+
├── base.ts
|
|
57
|
+
├── registry.ts
|
|
58
|
+
├── index.ts
|
|
59
|
+
└── proto/
|
|
60
|
+
├── game-msg.ts (0x01) 游戏消息 [特殊封装]
|
|
61
|
+
├── error-msg.ts (0x02) 错误消息
|
|
62
|
+
├── select-hand.ts (0x03) 选择猜拳
|
|
63
|
+
├── select-tp.ts (0x04) 选择先后手
|
|
64
|
+
├── hand-result.ts (0x05) 猜拳结果
|
|
65
|
+
├── tp-result.ts (0x06) 先后手结果
|
|
66
|
+
├── change-side.ts (0x07) 换边
|
|
67
|
+
├── waiting-side.ts (0x08) 等待换边
|
|
68
|
+
├── deck-count.ts (0x09) 卡组数量
|
|
69
|
+
├── create-game.ts (0x11) 创建房间
|
|
70
|
+
├── join-game.ts (0x12) 加入房间
|
|
71
|
+
├── type-change.ts (0x13) 类型变更
|
|
72
|
+
├── leave-game.ts (0x14) 离开房间
|
|
73
|
+
├── duel-start.ts (0x15) 决斗开始
|
|
74
|
+
├── duel-end.ts (0x16) 决斗结束
|
|
75
|
+
├── replay.ts (0x17) 录像 [特殊封装]
|
|
76
|
+
├── time-limit.ts (0x18) 时间限制
|
|
77
|
+
├── chat.ts (0x19) 聊天
|
|
78
|
+
├── hs-player-enter.ts (0x20) 玩家进入
|
|
79
|
+
├── hs-player-change.ts(0x21) 玩家状态变更
|
|
80
|
+
├── hs-watch-change.ts (0x22) 观战者变更
|
|
81
|
+
├── teammate-surrender.ts(0x23) 队友认输
|
|
82
|
+
├── field-finish.ts (0x30) 场地同步完成
|
|
83
|
+
├── srvpro-roomlist.ts (0x31) SRVPro房间列表 [特殊]
|
|
84
|
+
└── index.ts
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 🔑 关键实现点
|
|
90
|
+
|
|
91
|
+
### 1. 协议格式正确处理
|
|
92
|
+
```
|
|
93
|
+
[length 2 bytes][identifier 1 byte][body]
|
|
94
|
+
```
|
|
95
|
+
- ✅ Base 类只处理 body 部分
|
|
96
|
+
- ✅ Registry 配置 `identifierOffset: 2`, `dataOffset: 3`
|
|
97
|
+
|
|
98
|
+
### 2. Struct Padding 正确处理
|
|
99
|
+
- ✅ HostInfo: 20 字节(含 3 字节 padding)
|
|
100
|
+
- ✅ CTOS_JoinGame: 48 字节(含 2 字节 padding)
|
|
101
|
+
- ✅ STOC_ErrorMsg: 8 字节(含 3 字节 padding)
|
|
102
|
+
- ✅ STOC_TimeLimit: 4 字节(含 1 字节 padding)
|
|
103
|
+
- ✅ STOC_HS_PlayerEnter: 41 字节(workaround)
|
|
104
|
+
|
|
105
|
+
### 3. 特殊协议封装
|
|
106
|
+
|
|
107
|
+
#### ✅ CTOS_UPDATE_DECK (0x02)
|
|
108
|
+
```typescript
|
|
109
|
+
- 使用: ygopro-deck-encode
|
|
110
|
+
- 成员: deck: YGOProDeck
|
|
111
|
+
- fromPartial: 使用 constructor
|
|
112
|
+
- copy: 深拷贝
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### ✅ STOC_REPLAY (0x17)
|
|
116
|
+
```typescript
|
|
117
|
+
- 使用: ygopro-yrp-encode
|
|
118
|
+
- 成员: replay: YGOProYrp
|
|
119
|
+
- fromPartial: 使用 constructor
|
|
120
|
+
- copy: 深拷贝
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### ✅ STOC_GAME_MSG (0x01)
|
|
124
|
+
```typescript
|
|
125
|
+
- 使用: YGOProMessages registry
|
|
126
|
+
- 成员: msg: YGOProMsgBase | undefined
|
|
127
|
+
- fromPartial: 使用 copy()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### ✅ STOC_SRVPRO_ROOMLIST (0x31)
|
|
131
|
+
```typescript
|
|
132
|
+
- SRVPro 服务器特定协议
|
|
133
|
+
- 结构: count + SrvproRoomInfo[]
|
|
134
|
+
- 每个房间: 333 字节
|
|
135
|
+
- 包含: 房间名、状态、玩家信息、LP 等
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 4. 数组字段处理
|
|
139
|
+
- ✅ 固定长度: `@BinaryField('u16', offset, length)`
|
|
140
|
+
- ✅ UTF-16 字符串: `@BinaryField('utf16', offset, length)`
|
|
141
|
+
- ✅ UTF-8 字符串: `@BinaryField('utf8', offset, length)`
|
|
142
|
+
- ❌ 不使用: `'u16[]'`, `'u8[]'` 等写法
|
|
143
|
+
|
|
144
|
+
### 5. 可变长度字符串协议 ⭐ NEW
|
|
145
|
+
三个协议使用自定义实现以支持可变长度字符串:
|
|
146
|
+
- ✅ **CTOS_CHAT** (0x16): 可变长度聊天消息
|
|
147
|
+
- ✅ **STOC_CHAT** (0x19): 可变长度聊天消息 + player_type
|
|
148
|
+
- ✅ **CTOS_EXTERNAL_ADDRESS** (0x17): 可变长度主机名 + real_ip
|
|
149
|
+
|
|
150
|
+
**特性**:
|
|
151
|
+
- 序列化时只发送实际内容长度,末尾添加 `\0\0`
|
|
152
|
+
- 反序列化时接受任意长度,不要求 `\0\0`
|
|
153
|
+
- 相比固定长度节省大量带宽(例如:512 bytes → 12 bytes)
|
|
154
|
+
- 详见 `VARIABLE_LENGTH_STRINGS.md`
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 🧪 测试
|
|
159
|
+
|
|
160
|
+
### 测试套件
|
|
161
|
+
所有测试已迁移到 `tests/` 目录作为正式单元测试:
|
|
162
|
+
1. `tests/ctos-stoc.spec.ts` - CTOS/STOC 基础协议测试 (10 tests) ✅
|
|
163
|
+
2. `tests/srvpro-roomlist.spec.ts` - SRVPro 房间列表测试 (6 tests) ✅
|
|
164
|
+
3. `tests/chat-protocols.spec.ts` - 可变长度字符串协议测试 (14 tests) ✅
|
|
165
|
+
|
|
166
|
+
**测试结果**: ✅ 96 passed / 96 total
|
|
167
|
+
|
|
168
|
+
### 运行测试
|
|
169
|
+
```bash
|
|
170
|
+
# 构建
|
|
171
|
+
npm run build
|
|
172
|
+
|
|
173
|
+
# 运行测试
|
|
174
|
+
npx tsx test-ctos-stoc.ts
|
|
175
|
+
npx tsx test-srvpro-roomlist.ts
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 📦 构建和测试结果
|
|
181
|
+
|
|
182
|
+
### 构建
|
|
183
|
+
```bash
|
|
184
|
+
✓ [build] cjs -> dist/index.cjs 155.5kb
|
|
185
|
+
✓ [build] esm -> dist/index.mjs 145.2kb
|
|
186
|
+
✓ [types] Declarations generated dist/index.d.ts
|
|
187
|
+
✓ No linter errors
|
|
188
|
+
✓ No TypeScript errors
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 测试 ⭐ NEW
|
|
192
|
+
```bash
|
|
193
|
+
✓ Test Suites: 7 passed, 7 total
|
|
194
|
+
✓ Tests: 96 passed, 96 total
|
|
195
|
+
✓ Time: 10.371 s
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 📚 文档
|
|
201
|
+
|
|
202
|
+
| 文件 | 说明 |
|
|
203
|
+
|------|------|
|
|
204
|
+
| `CTOS_STOC_IMPLEMENTATION.md` | 详细的协议实现文档 |
|
|
205
|
+
| `IMPLEMENTATION_SUMMARY.md` | 实现总结和设计决策 |
|
|
206
|
+
| `VARIABLE_LENGTH_STRINGS.md` | 可变长度字符串实现说明 |
|
|
207
|
+
| `REAL_IP_STRING_UPDATE.md` | real_ip 字段改为 string 类型说明 |
|
|
208
|
+
| `TESTS_MIGRATION.md` | 测试迁移总结 ⭐ NEW |
|
|
209
|
+
| `FINAL_SUMMARY.md` | 最终完成总结(本文件)|
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 🔗 依赖关系
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
ygopro-msg-encode
|
|
217
|
+
├── ygopro-deck-encode ^1.0.15 (卡组编解码)
|
|
218
|
+
└── ygopro-yrp-encode ^1.0.1 (录像编解码)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 📖 参考源码
|
|
224
|
+
|
|
225
|
+
实现参照以下 YGOPro 源码:
|
|
226
|
+
- ✅ `/home/nanahira/ygo/ygopro/gframe/network.h`
|
|
227
|
+
- HostInfo, CTOS/STOC 结构体定义
|
|
228
|
+
- 所有协议的标识符定义
|
|
229
|
+
- ✅ `/home/nanahira/ygo/ygopro/gframe/duelclient.cpp`
|
|
230
|
+
- STOC_SRVPRO_ROOMLIST 实现(第 413-463 行)
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## ✨ 特色功能
|
|
235
|
+
|
|
236
|
+
### 1. 类型安全
|
|
237
|
+
- 所有协议都有完整的 TypeScript 类型定义
|
|
238
|
+
- 自动生成 `.d.ts` 声明文件
|
|
239
|
+
|
|
240
|
+
### 2. 自动序列化/反序列化
|
|
241
|
+
```typescript
|
|
242
|
+
// 序列化
|
|
243
|
+
const payload = protocol.toPayload();
|
|
244
|
+
|
|
245
|
+
// 反序列化
|
|
246
|
+
const parsed = YGOProCtos.getInstanceFromPayload(payload);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 3. Registry 自动识别
|
|
250
|
+
```typescript
|
|
251
|
+
// 自动识别协议类型
|
|
252
|
+
const msg = YGOProStoc.getInstanceFromPayload(data);
|
|
253
|
+
if (msg instanceof YGOProStocGameMsg) {
|
|
254
|
+
// 处理游戏消息
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### 4. 深拷贝支持
|
|
259
|
+
```typescript
|
|
260
|
+
const copy = protocol.copy();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 🎯 使用示例
|
|
266
|
+
|
|
267
|
+
### CTOS 协议
|
|
268
|
+
```typescript
|
|
269
|
+
import { YGOProCtos, YGOProCtosPlayerInfo } from 'ygopro-msg-encode';
|
|
270
|
+
|
|
271
|
+
const playerInfo = new YGOProCtosPlayerInfo();
|
|
272
|
+
playerInfo.name = [0x0041, 0x0042, 0x0043, ...]; // "ABC"
|
|
273
|
+
|
|
274
|
+
const payload = playerInfo.toPayload();
|
|
275
|
+
const parsed = YGOProCtos.getInstanceFromPayload(payload);
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### STOC 协议
|
|
279
|
+
```typescript
|
|
280
|
+
import { YGOProStoc, YGOProStocErrorMsg } from 'ygopro-msg-encode';
|
|
281
|
+
|
|
282
|
+
const error = new YGOProStocErrorMsg();
|
|
283
|
+
error.msg = 2;
|
|
284
|
+
error.code = 0x12345678;
|
|
285
|
+
|
|
286
|
+
const payload = error.toPayload();
|
|
287
|
+
const parsed = YGOProStoc.getInstanceFromPayload(payload);
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### UPDATE_DECK
|
|
291
|
+
```typescript
|
|
292
|
+
import { YGOProCtosUpdateDeck } from 'ygopro-msg-encode';
|
|
293
|
+
import YGOProDeck from 'ygopro-deck-encode';
|
|
294
|
+
|
|
295
|
+
const updateDeck = new YGOProCtosUpdateDeck();
|
|
296
|
+
updateDeck.deck = new YGOProDeck({
|
|
297
|
+
main: [12345, 67890],
|
|
298
|
+
extra: [11111],
|
|
299
|
+
side: [22222],
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const payload = updateDeck.toPayload();
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### GAME_MSG
|
|
306
|
+
```typescript
|
|
307
|
+
import { YGOProStocGameMsg, YGOProMsgHint } from 'ygopro-msg-encode';
|
|
308
|
+
|
|
309
|
+
const gameMsg = new YGOProStocGameMsg();
|
|
310
|
+
const hint = new YGOProMsgHint();
|
|
311
|
+
hint.type = 1;
|
|
312
|
+
hint.player = 0;
|
|
313
|
+
hint.desc = 0x1234;
|
|
314
|
+
gameMsg.msg = hint;
|
|
315
|
+
|
|
316
|
+
const payload = gameMsg.toPayload();
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## ✅ 验收清单
|
|
322
|
+
|
|
323
|
+
- [x] 建立 CTOS/STOC 模块结构
|
|
324
|
+
- [x] 实现 19 个 CTOS 协议
|
|
325
|
+
- [x] 实现 24 个 STOC 协议
|
|
326
|
+
- [x] 处理所有 struct padding
|
|
327
|
+
- [x] 实现 UPDATE_DECK 特殊封装(ygopro-deck-encode)
|
|
328
|
+
- [x] 实现 REPLAY 特殊封装(ygopro-yrp-encode)
|
|
329
|
+
- [x] 实现 GAME_MSG 特殊封装(YGOProMessages)
|
|
330
|
+
- [x] 实现 SRVPRO_ROOMLIST(根据 duelclient.cpp)
|
|
331
|
+
- [x] 实现可变长度字符串协议
|
|
332
|
+
- [x] CTOS_CHAT
|
|
333
|
+
- [x] STOC_CHAT
|
|
334
|
+
- [x] CTOS_EXTERNAL_ADDRESS
|
|
335
|
+
- [x] real_ip 改为 string 类型(支持 IPv6 映射)⭐ NEW
|
|
336
|
+
- [x] 创建 HostInfo 公共结构
|
|
337
|
+
- [x] 配置 Registry 正确的 offset
|
|
338
|
+
- [x] 修正数组字段写法
|
|
339
|
+
- [x] 实现 fromPartial 方法
|
|
340
|
+
- [x] 实现 copy 方法
|
|
341
|
+
- [x] 更新主导出文件
|
|
342
|
+
- [x] 构建测试通过
|
|
343
|
+
- [x] 无 Linter 错误
|
|
344
|
+
- [x] 无 TypeScript 错误
|
|
345
|
+
- [x] 创建 Jest 单元测试(96 个测试全部通过)⭐ NEW
|
|
346
|
+
- [x] 编写完整文档
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 🎉 项目完成
|
|
351
|
+
|
|
352
|
+
**日期**: 2026-02-02
|
|
353
|
+
**状态**: ✅ 完成
|
|
354
|
+
**构建**: ✅ 通过
|
|
355
|
+
**测试**: ✅ 可用
|
|
356
|
+
|
|
357
|
+
所有 CTOS 和 STOC 协议已完整实现,代码质量良好,文档齐全!
|