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.
Files changed (178) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.js +25 -0
  3. package/.prettierrc +4 -0
  4. package/AGENTS.md +12 -0
  5. package/CHANGES.md +270 -0
  6. package/CTOS_STOC_IMPLEMENTATION.md +279 -0
  7. package/FINAL_SUMMARY.md +357 -0
  8. package/FULL_PAYLOAD_SUMMARY.md +491 -0
  9. package/FULL_PAYLOAD_UPDATE.md +598 -0
  10. package/IMPLEMENTATION_SUMMARY.md +294 -0
  11. package/LICENSE +22 -0
  12. package/MSG_IMPLEMENTATION_SUMMARY.md +358 -0
  13. package/OPPONENT_VIEW_SUMMARY.md +387 -0
  14. package/PROJECT_COMPLETE.md +565 -0
  15. package/QUICK_REFERENCE.md +352 -0
  16. package/README.md +494 -0
  17. package/REAL_IP_STRING_UPDATE.md +289 -0
  18. package/TESTS_MIGRATION.md +342 -0
  19. package/VARIABLE_LENGTH_STRINGS.md +224 -0
  20. package/VARIABLE_LENGTH_UPDATE.md +229 -0
  21. package/dist/index.cjs +5131 -0
  22. package/dist/index.cjs.map +7 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.mjs +5185 -0
  25. package/dist/index.mjs.map +7 -0
  26. package/dist/src/binary/binary-meta.d.ts +18 -0
  27. package/dist/src/binary/fill-binary-fields.d.ts +2 -0
  28. package/dist/src/metadata.d.ts +10 -0
  29. package/dist/src/proto-base/payload-base.d.ts +8 -0
  30. package/dist/src/proto-base/registry-base.d.ts +13 -0
  31. package/dist/src/protos/common/host-info.d.ts +12 -0
  32. package/dist/src/protos/common/index.d.ts +1 -0
  33. package/dist/src/protos/ctos/base.d.ts +17 -0
  34. package/dist/src/protos/ctos/index.d.ts +3 -0
  35. package/dist/src/protos/ctos/proto/chat.d.ts +9 -0
  36. package/dist/src/protos/ctos/proto/create-game.d.ts +8 -0
  37. package/dist/src/protos/ctos/proto/external-address.d.ts +12 -0
  38. package/dist/src/protos/ctos/proto/hand-result.d.ts +5 -0
  39. package/dist/src/protos/ctos/proto/hs-notready.d.ts +4 -0
  40. package/dist/src/protos/ctos/proto/hs-ready.d.ts +4 -0
  41. package/dist/src/protos/ctos/proto/hs-start.d.ts +4 -0
  42. package/dist/src/protos/ctos/proto/hs-toduelist.d.ts +4 -0
  43. package/dist/src/protos/ctos/proto/hs-toobserver.d.ts +4 -0
  44. package/dist/src/protos/ctos/proto/index.d.ts +19 -0
  45. package/dist/src/protos/ctos/proto/join-game.d.ts +7 -0
  46. package/dist/src/protos/ctos/proto/kick.d.ts +5 -0
  47. package/dist/src/protos/ctos/proto/leave-game.d.ts +4 -0
  48. package/dist/src/protos/ctos/proto/player-info.d.ts +5 -0
  49. package/dist/src/protos/ctos/proto/request-field.d.ts +4 -0
  50. package/dist/src/protos/ctos/proto/response.d.ts +7 -0
  51. package/dist/src/protos/ctos/proto/surrender.d.ts +4 -0
  52. package/dist/src/protos/ctos/proto/time-confirm.d.ts +4 -0
  53. package/dist/src/protos/ctos/proto/tp-result.d.ts +5 -0
  54. package/dist/src/protos/ctos/proto/update-deck.d.ts +11 -0
  55. package/dist/src/protos/ctos/registry.d.ts +3 -0
  56. package/dist/src/protos/msg/base.d.ts +9 -0
  57. package/dist/src/protos/msg/index.d.ts +3 -0
  58. package/dist/src/protos/msg/proto/add-counter.d.ts +9 -0
  59. package/dist/src/protos/msg/proto/announce-attrib.d.ts +7 -0
  60. package/dist/src/protos/msg/proto/announce-card.d.ts +7 -0
  61. package/dist/src/protos/msg/proto/announce-number.d.ts +7 -0
  62. package/dist/src/protos/msg/proto/announce-race.d.ts +7 -0
  63. package/dist/src/protos/msg/proto/attack-disabled.d.ts +4 -0
  64. package/dist/src/protos/msg/proto/attack.d.ts +12 -0
  65. package/dist/src/protos/msg/proto/battle.d.ts +18 -0
  66. package/dist/src/protos/msg/proto/become-target.d.ts +6 -0
  67. package/dist/src/protos/msg/proto/cancel-target.d.ts +11 -0
  68. package/dist/src/protos/msg/proto/card-hint.d.ts +10 -0
  69. package/dist/src/protos/msg/proto/card-query.d.ts +38 -0
  70. package/dist/src/protos/msg/proto/card-target.d.ts +11 -0
  71. package/dist/src/protos/msg/proto/chain-disabled.d.ts +5 -0
  72. package/dist/src/protos/msg/proto/chain-end.d.ts +4 -0
  73. package/dist/src/protos/msg/proto/chain-negated.d.ts +5 -0
  74. package/dist/src/protos/msg/proto/chain-solved.d.ts +5 -0
  75. package/dist/src/protos/msg/proto/chain-solving.d.ts +5 -0
  76. package/dist/src/protos/msg/proto/chained.d.ts +5 -0
  77. package/dist/src/protos/msg/proto/chaining.d.ts +12 -0
  78. package/dist/src/protos/msg/proto/confirm-cards.d.ts +16 -0
  79. package/dist/src/protos/msg/proto/confirm-decktop.d.ts +14 -0
  80. package/dist/src/protos/msg/proto/confirm-extratop.d.ts +14 -0
  81. package/dist/src/protos/msg/proto/damage-step-end.d.ts +4 -0
  82. package/dist/src/protos/msg/proto/damage-step-start.d.ts +4 -0
  83. package/dist/src/protos/msg/proto/damage.d.ts +6 -0
  84. package/dist/src/protos/msg/proto/deck-top.d.ts +8 -0
  85. package/dist/src/protos/msg/proto/draw.d.ts +8 -0
  86. package/dist/src/protos/msg/proto/equip.d.ts +12 -0
  87. package/dist/src/protos/msg/proto/field-disabled.d.ts +5 -0
  88. package/dist/src/protos/msg/proto/flipsummoned.d.ts +4 -0
  89. package/dist/src/protos/msg/proto/flipsummoning.d.ts +9 -0
  90. package/dist/src/protos/msg/proto/hand-res.d.ts +5 -0
  91. package/dist/src/protos/msg/proto/hint.d.ts +7 -0
  92. package/dist/src/protos/msg/proto/index.d.ts +85 -0
  93. package/dist/src/protos/msg/proto/lpupdate.d.ts +6 -0
  94. package/dist/src/protos/msg/proto/match-kill.d.ts +5 -0
  95. package/dist/src/protos/msg/proto/missed-effect.d.ts +7 -0
  96. package/dist/src/protos/msg/proto/move.d.ts +14 -0
  97. package/dist/src/protos/msg/proto/new-phase.d.ts +5 -0
  98. package/dist/src/protos/msg/proto/new-turn.d.ts +5 -0
  99. package/dist/src/protos/msg/proto/pay-lpcost.d.ts +6 -0
  100. package/dist/src/protos/msg/proto/player-hint.d.ts +7 -0
  101. package/dist/src/protos/msg/proto/pos-change.d.ts +12 -0
  102. package/dist/src/protos/msg/proto/random-selected.d.ts +7 -0
  103. package/dist/src/protos/msg/proto/recover.d.ts +6 -0
  104. package/dist/src/protos/msg/proto/reload-field.d.ts +36 -0
  105. package/dist/src/protos/msg/proto/remove-counter.d.ts +9 -0
  106. package/dist/src/protos/msg/proto/reset-time.d.ts +6 -0
  107. package/dist/src/protos/msg/proto/retry.d.ts +4 -0
  108. package/dist/src/protos/msg/proto/reverse-deck.d.ts +4 -0
  109. package/dist/src/protos/msg/proto/rock-paper-scissors.d.ts +5 -0
  110. package/dist/src/protos/msg/proto/select-battlecmd.d.ts +25 -0
  111. package/dist/src/protos/msg/proto/select-card.d.ts +17 -0
  112. package/dist/src/protos/msg/proto/select-chain.d.ts +19 -0
  113. package/dist/src/protos/msg/proto/select-counter.d.ts +17 -0
  114. package/dist/src/protos/msg/proto/select-disfield.d.ts +7 -0
  115. package/dist/src/protos/msg/proto/select-effectyn.d.ts +11 -0
  116. package/dist/src/protos/msg/proto/select-idlecmd.d.ts +37 -0
  117. package/dist/src/protos/msg/proto/select-option.d.ts +7 -0
  118. package/dist/src/protos/msg/proto/select-place.d.ts +7 -0
  119. package/dist/src/protos/msg/proto/select-position.d.ts +7 -0
  120. package/dist/src/protos/msg/proto/select-sum.d.ts +20 -0
  121. package/dist/src/protos/msg/proto/select-tribute.d.ts +18 -0
  122. package/dist/src/protos/msg/proto/select-unselect-card.d.ts +20 -0
  123. package/dist/src/protos/msg/proto/select-yesno.d.ts +6 -0
  124. package/dist/src/protos/msg/proto/set.d.ts +5 -0
  125. package/dist/src/protos/msg/proto/shuffle-deck.d.ts +5 -0
  126. package/dist/src/protos/msg/proto/shuffle-extra.d.ts +8 -0
  127. package/dist/src/protos/msg/proto/shuffle-hand.d.ts +8 -0
  128. package/dist/src/protos/msg/proto/shuffle-set-card.d.ts +17 -0
  129. package/dist/src/protos/msg/proto/sort-card.d.ts +13 -0
  130. package/dist/src/protos/msg/proto/spsummoned.d.ts +4 -0
  131. package/dist/src/protos/msg/proto/spsummoning.d.ts +9 -0
  132. package/dist/src/protos/msg/proto/start.d.ts +14 -0
  133. package/dist/src/protos/msg/proto/summoned.d.ts +4 -0
  134. package/dist/src/protos/msg/proto/summoning.d.ts +9 -0
  135. package/dist/src/protos/msg/proto/swap-grave-deck.d.ts +5 -0
  136. package/dist/src/protos/msg/proto/swap.d.ts +12 -0
  137. package/dist/src/protos/msg/proto/tag-swap.d.ts +14 -0
  138. package/dist/src/protos/msg/proto/toss-coin.d.ts +7 -0
  139. package/dist/src/protos/msg/proto/toss-dice.d.ts +7 -0
  140. package/dist/src/protos/msg/proto/update-card.d.ts +14 -0
  141. package/dist/src/protos/msg/proto/update-data.d.ts +12 -0
  142. package/dist/src/protos/msg/proto/waiting.d.ts +4 -0
  143. package/dist/src/protos/msg/proto/win.d.ts +6 -0
  144. package/dist/src/protos/msg/registry.d.ts +3 -0
  145. package/dist/src/protos/stoc/base.d.ts +17 -0
  146. package/dist/src/protos/stoc/index.d.ts +3 -0
  147. package/dist/src/protos/stoc/proto/change-side.d.ts +4 -0
  148. package/dist/src/protos/stoc/proto/chat.d.ts +10 -0
  149. package/dist/src/protos/stoc/proto/create-game.d.ts +5 -0
  150. package/dist/src/protos/stoc/proto/deck-count.d.ts +5 -0
  151. package/dist/src/protos/stoc/proto/duel-end.d.ts +4 -0
  152. package/dist/src/protos/stoc/proto/duel-start.d.ts +4 -0
  153. package/dist/src/protos/stoc/proto/error-msg.d.ts +6 -0
  154. package/dist/src/protos/stoc/proto/field-finish.d.ts +4 -0
  155. package/dist/src/protos/stoc/proto/game-msg.d.ts +9 -0
  156. package/dist/src/protos/stoc/proto/hand-result.d.ts +6 -0
  157. package/dist/src/protos/stoc/proto/hs-player-change.d.ts +5 -0
  158. package/dist/src/protos/stoc/proto/hs-player-enter.d.ts +6 -0
  159. package/dist/src/protos/stoc/proto/hs-watch-change.d.ts +5 -0
  160. package/dist/src/protos/stoc/proto/index.d.ts +24 -0
  161. package/dist/src/protos/stoc/proto/join-game.d.ts +6 -0
  162. package/dist/src/protos/stoc/proto/leave-game.d.ts +5 -0
  163. package/dist/src/protos/stoc/proto/replay.d.ts +11 -0
  164. package/dist/src/protos/stoc/proto/select-hand.d.ts +4 -0
  165. package/dist/src/protos/stoc/proto/select-tp.d.ts +4 -0
  166. package/dist/src/protos/stoc/proto/srvpro-roomlist.d.ts +18 -0
  167. package/dist/src/protos/stoc/proto/teammate-surrender.d.ts +4 -0
  168. package/dist/src/protos/stoc/proto/time-limit.d.ts +6 -0
  169. package/dist/src/protos/stoc/proto/tp-result.d.ts +4 -0
  170. package/dist/src/protos/stoc/proto/type-change.d.ts +5 -0
  171. package/dist/src/protos/stoc/proto/waiting-side.d.ts +4 -0
  172. package/dist/src/protos/stoc/registry.d.ts +3 -0
  173. package/dist/src/vendor/ocgcore-constants.d.ts +360 -0
  174. package/dist/src/vendor/script-constants.d.ts +836 -0
  175. package/index.ts +6 -0
  176. package/package.json +74 -0
  177. package/scripts/gen-constants.js +156 -0
  178. package/tsconfig.json +20 -0
@@ -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 协议已完整实现,代码质量良好,文档齐全!