Files
live-hub-py/docs/HUYA_精英宝典-后端与9.1抓包对照.md
T

10 KiB
Raw Blame History

虎牙精英宝典后端与 9.1 全流程抓包对照

结论

当前后端不是“完全不能用”,而是保留了旧版 HTTP/WUP 兜底链路;最新浏览器链路已经切换为两个长连接 WSS:活动/绑定通道和商城/支付通道。查询和下单的多数字段与抓包兼容,真正需要优先更新的是兑换闭环、支付后订单状态和权益回查。

对照矩阵

优先级 领域 9.1 实际链路 当前后端 判断 更新动作
P0 支付监听 orderDetailV5(orderId) 重复查询,状态最终为 50 queryUserOrderList,同时尝试 shopMiddleUI/revenueWebUI 不一致 增加 orderDetailV5 结构和方法,按订单号轮询;以订单状态 50/已支付时间作为完成依据
P0 支付超时 未支付仍是待支付/取消状态 huya_runner_recharge.py:535-537 将 timeout 标为 success 业务错误 超时改为 pendingtimeout,不能写成功;前端显示“等待支付超时”
P0 WSS 会话 活动通道 d35bf373-ws.va.huya.com,商城通道 wsapi.huya.com;每个会话有 launch、register、confirm、递增 requestId HuyaBatchRunner 全部调用 HuyaHttpClientcdnws.api.huya.com 单次 HTTP 架构不一致 优先实现可复用的 WSS sessionHTTP 保留为显式 fallback,并记录 fallback 原因和重试次数
P1 商城身份字段 最新商城业务 UserId.sHuYaUA=web&1.0.0&huyasGuid 为空 HTTP _build_user 使用 webh5&0.0.1&websocket...,并从 Cookie 派生 sGuid 字段不一致 商城 WSS 优先;HTTP fallback 也应拆分商城 UserId,按最新 UA/空 guid 构造
P1 兑换前置 getActPrizeDetail(sid=2203,pid),随后才 scoreExchangePrize huya_runner_goods.py:327-329 直接提交兑换 缺步骤 增加 GetActPrizeDetailReq/Resp;提交前校验 isCanExchange、活动时间、库存、今日/用户限制和积分余额
P1 兑换回查 成功后依次回查 getUserScoregetUserPrizeRecordsgetEntityPrizeFieldMapgetModuleAddress 成功后立即结束任务 缺步骤 将扣分、记录和地址状态写入任务结果,并更新 HuyaAccount.points
P1 活动初始化 getActInfogetActUserTaskDetailgetUserScoregetUserPrizeRecords 等并行查询 query_act_tasks 只调用 getActTaskDetail 信息不完整 增加 snapshot 任务或让页面初始化批量创建这些查询任务
P1 权益到账 支付完成后仍需回查宝典积分/用户任务 只回查商城订单列表 信息不完整 订单完成后调用积分和用户任务接口,明确“已支付”和“宝典权益到账”两个状态
P2 商品详情 getGoodsInfoV5 直接返回 spu=hy-5879340sku=5370360、场景 4 当前会先从任务详情发现 SPU,再以 sku=0 查询详情 兼容但脆弱 固定业务默认值仅作候选;优先使用实时商品详情返回的 SKU,不依赖任务类型 67
P2 商品详情 gameId 最新 getGoodsInfoV5 请求的 gameId 为空字符串 huya_runner_recharge.py:385-395 传入 game_id="0" 细节不一致 查询商品详情改为空字符串;createOrderV5gameId="0" 仍保持不变
P2 下单字段 orderType=6src=4orderScene=4bizType=5gameCategoryId=507gameId="0" create_order 已按相同字段写入 基本一致 保留,增加请求快照脱敏日志以便字段回归
P2 支付提交 payOrderSubmitV5(order,Zfb,QrCode,callback,env) 返回支付宝网关 URL 当前 HTTP 手工构造 WUP,字段基本一致 兼容但非同链路 迁移到商城 WSS;未迁移前保留 HTTP fallback
P2 支付渠道 listPayChannelV5,返回 Zfb/Weixin 直接使用配置渠道 缺运行时校验 下单前读取可用渠道,不支持配置值时回退或报错
P2 配置 本次活动 sid=2203、绑定活动 9271、外部活动响应为 17096 outer_act_id 默认 9504 且执行器未实际使用 配置过期/死字段 默认值改为当前活动值或删除该字段;将外部活动 ID 从 getLiveLinkParam 响应传递,不手填签名
P2 数据隔离 业务响应随账号、绑定状态和库存变化 HuyaGoodsSnapshotHuyaRechargeGoodsSnapshot 为全局快照 并发风险 至少按 sid/spu 隔离;兑换可用性必须以执行账号的实时查询为准

已对上的部分

  • ActivityUserIdlUidsHuYaUA、Cookie 前缀和空 Token 形态与 9.1 活动帧兼容。
  • scoreExchangePrize 的主体字段 userId/sid/pid/ip/clientEnv/source/isRole 已有结构,样本中后三项为空、isRole=1 与默认值一致。
  • 商城 CreateOrderReqV5 已覆盖抓包中的完整 tag 0-32;orderType=6 和场景 4 正确。
  • payOrderSubmitV5 的回调 URL、ZfbQrCode 和环境 map 已覆盖抓包字段。
  • CreateOrderReqV5 的下单 gameId="0" 与抓包一致;只有商品详情查询的 gameId 应为空字符串。
  • Cookie、baseinfo、WUP requestId、支付宝订单和签名没有被当作固定常量,方向正确。

推荐更新顺序(按依赖关系)

之前的顺序有两个问题:把支付状态修复放在协议补齐之前,且把 WSS 迁移放在写操作之后。这样会先扩大旧链路的行为面,无法判断是业务字段还是传输方式导致失败。建议按下面的依赖顺序推进,每一步都能独立验证和回滚。

0. 固化 9.1 契约和回归样本

整理脱敏的请求/响应 fixture,明确活动通道、商城通道、WUP tag、状态码和动态字段边界。先不改线上任务行为,只增加解码测试。验收条件:9.1 中的关键 RPC 能稳定解码,动态 Cookie、签名、订单号不会进入 fixture。

1. 先修配置和身份模型

sid=2203bindActId=9271outerActId=17096moduleId=20051scene=4sourceId=yellowcarlist 统一为活动配置;商城 UserId 与活动 UserId 分开,商城使用最新 sHuYaUA/空 sGuid 规则。此步只影响参数构造,不启用新写操作。

2. 补齐只读协议方法和响应结构

优先实现并测试:

getActInfo
getActUserTaskDetail
getActPrizeDetail
getEntityPrizeFieldMap
getModuleAddress
listPayChannelV5
orderDetailV5

只读方法齐全后,才能用服务端实时数据做兑换和支付前置判断;不要先改 scoreExchangePrize 或支付提交。

3. 建立统一传输层,再做只读灰度

抽象活动 WSS session 和商城 WSS session,复用 launch/register/confirm、requestId FIFO、断线和超时处理。先让查询接口走 WSS,失败时明确记录原因并 fallback 到 HTTP;连续验证成功后再切换写接口。不要在每个 runner 中分别临时建 WebSocket。

4. 先做快照和数据隔离

页面初始化改为一次读取活动信息、用户任务、积分、奖品和记录;商品/充值商品快照至少按 sid + spu/pid 隔离,执行账号始终以实时详情覆盖快照。此步完成后 UI 可以展示真实状态,但仍不触发兑换或支付。

5. 重写兑换状态机

严格按以下顺序:

实时 getActPrizeDetail
  -> 校验 isCanExchange/活动时间/库存/今日限制/用户限制/可用积分
  -> scoreExchangePrize
  -> getUserScore + getUserPrizeRecords
  -> getEntityPrizeFieldMap + getModuleAddress

成功、已兑换、余额不足、库存不足、需要地址和未知错误分别落库;收到成功响应后使用幂等键阻止重复提交。只有四项回查完成,任务才标记为兑换完成。

6. 重写开通和支付状态机

严格按以下顺序:

getGoodsInfoV5
  -> listPayChannelV5
  -> checkHyProtocolV5 / checkUserBuyAuth
  -> createOrderV5(orderType=6)
  -> payOrderSubmitV5(Zfb|Weixin, QrCode)
  -> 立即 orderDetailV5 轮询
  -> 支付完成后回查宝典积分和用户任务

orderDetailV5 必须先于 runner 改造完成;queryUserOrderList 只能作为兼容 fallback。支付状态拆成 created/pending/paid/timeout/cancelled/error,超时绝不能标记 success。二维码生成后任务保持 running/pending,不能因为 runner 线程尚未结束而隐藏二维码。

7. 最后接入 UI 和批量执行

UI 只调用统一任务 API:查询使用快照任务,兑换和开通使用状态机任务;通过任务 WebSocket 推送二维码、订单状态和最终权益状态。先单账号灰度,再开启并发批量,避免旧的全局商品快照污染多个账号。

8. 清理旧链路

连续灰度验证通过后,删除 create_order 的 orderType 猜测和支付列表轮询主路径;保留 HTTP fallback、失败原因、超时和回滚开关。最后再迁移旧版虎牙任务入口,避免影响非精英宝典功能。

不应照搬抓包的字段

UID、Cookie、guid、baseinfo、WUP requestId、支付宝 payOrderId、ctoken、二维码 URL、t/code/sig、用户点击时间和 RSA2 签名均为运行时动态值。它们只能来自当前登录态、前序响应或运行时生成,不能写入默认配置或测试 fixture。

本轮已实施

  • 增加 getActInfogetActUserTaskDetailgetActPrizeDetail 和详情响应结构。
  • 兑换提交前读取实时详情和积分,校验可兑换状态、库存、时间窗口和余额;成功后回查积分和兑换记录。
  • 增加 orderDetailV5 请求/响应结构,支付监听优先按订单号查询,旧订单列表作为 fallback。
  • 支付超时改为终态 timeout,不再误报成功;支付完成后回查活动积分。
  • 商城 HTTP fallback 的 UserId 改为 9.1 商城 UA/空 guid 形态;商品详情 gameId 改为空字符串,下单仍使用 gameId="0"
  • 外部活动默认值由旧值更新为 17096,已有旧配置会在读取时迁移。

仍待下一轮实施:将批处理执行器从 HTTP fallback 迁移到统一活动/商城 WSS session;补齐 listPayChannelV5checkHyProtocolV5getMyPromotioncalcOrderPromotioncheckUserBuyAuth 的显式前置调用;按账号隔离商品快照。