fix(huya): 结构体尾部字段容错解析(服务端新增 ZERO 字段不再打挂整个 RPC)
真机现象(2026-10-15,外部 CK 导入后查询角色):checkUserBindGameAccount 响应结构 尾部多了 tag6(ZERO 类型 0x6c),共享的 read_struct 读到非 STRUCT_END 直接抛 「期望 STRUCT_END, 实际 0x0c」,整个 RPC 返回 None —— 工作台「查询角色」永远失败。 - taf_protocol:read_struct 收尾改为按 TAF 语义跳过未建模的尾部字段(上限 32 个, 防止解析错位时无限吞字节);新增 skip_to_struct_end() - frame_decoder / shop_structs:抽出 decode_struct_bytes 与 ShopRawRsp.from_payload, WSS 与 HTTP 两条通道共用一份通用解码逻辑(wss_client 同步改用) 验证:tests/test_huya_struct_parse_resilience.py 用真机响应字节回归(含 tag6=ZERO 的 响应能解析出角色「泪雨全是谎言」);按 AGENTS.md 反向验证 —— 注掉 skip_to_struct_end() 即复现线上报错「期望 STRUCT_END, 实际 0x0c」,还原后恢复。 全量 pytest 通过。
This commit is contained in:
@@ -215,6 +215,25 @@ def _decode_wup_body(body: bytes) -> dict:
|
||||
return result
|
||||
|
||||
|
||||
def decode_struct_bytes(data: bytes) -> dict:
|
||||
"""把裸结构体字节解成通用 dict(``tagN`` → 值);非结构体或解析失败返回 {}。
|
||||
|
||||
WSS 与 HTTP 两条通道都要用「未逐字段建模」的通用解码,统一放在这里,
|
||||
避免两边各写一份。
|
||||
"""
|
||||
if not isinstance(data, bytes) or not data:
|
||||
return {}
|
||||
ins = TafInputStream(data)
|
||||
try:
|
||||
_tag, dtype = ins.peek_head()
|
||||
if dtype != TafType.STRUCT_BEGIN:
|
||||
return {}
|
||||
ins.read_head()
|
||||
return _decode_taf_struct(ins)
|
||||
except Exception: # noqa: BLE001 外部接口与任务边界需要保留宽泛异常兜底
|
||||
return {}
|
||||
|
||||
|
||||
def _truncate(obj, max_str=80):
|
||||
"""截断过长的值,使日志紧凑"""
|
||||
if isinstance(obj, str):
|
||||
|
||||
Reference in New Issue
Block a user