补充虎牙宝典全流程分析报告
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
# 虎牙精英宝典 9.1 全流程分析(Python / 脱敏)
|
||||||
|
|
||||||
|
branch/field: HUYA_ELITE_FULL_FLOW_9_1
|
||||||
|
|
||||||
|
## 1. 样本与完整性
|
||||||
|
|
||||||
|
- 主样本:`/Users/yml/Desktop/抓包/hy/9.1/9.1`
|
||||||
|
- SHA-256:`807fb951f9daa21e77f33618f1409a99b9b44da829966f328ec8b0614f599d55`
|
||||||
|
- 格式:Charles 会话 ZIP 归档,不是普通 HAR。
|
||||||
|
- 归档成员 2327;`*-meta.json` 1472;请求体 552;响应体 303。
|
||||||
|
- 状态:COMPLETE 1443,EXCEPTION 16,RECEIVING_REQUEST_BODY 12,RECEIVING_RESPONSE_BODY 1。
|
||||||
|
- 结论:该包覆盖扫码登录后的 Web 会话、宝典初始化、游戏账号绑定、积分兑换、商城下单、支付宝二维码和支付后订单状态;比旧的 Reqable/Charles 样本完整。
|
||||||
|
|
||||||
|
`9.1_all` 适合静态资源检索,但没有统一 flow、headers、状态和时序索引。协议重建以 ZIP 为主,静态页面以 `1197-res.html` 等正文为辅。
|
||||||
|
|
||||||
|
## 2. 业务固定值与动态值
|
||||||
|
|
||||||
|
本次页面确认的业务值:`sid=2203`、宝典 `actId=25135`、绑定活动 `bActId=9271`、任务模块 `moduleId=20051`、外部联运活动 `17096`、游戏 `cjm`、组件 `gid=3203`、宝典商品 `spu=hy-5879340`、商品 SKU `5370360`、供应商 `87401`。
|
||||||
|
|
||||||
|
运行时必须重新取得:UID、Cookie、WSS `baseinfo`、WUP requestId、wsLaunch guid、游戏账号信息、`getLiveLinkParam` 的 `t/code/sig`、支付宝 payOrderId/ctoken、订单号和二维码状态。样本中的这些动态值不能硬编码,也不能用旧 Cookie 重放。
|
||||||
|
|
||||||
|
## 3. 登录与宝典初始化
|
||||||
|
|
||||||
|
1. 扫码登录链在登录样本中完成后,`POST /web/cookie/verify`(entry 859)返回 HTTP 业务成功结构,随后浏览器访问宝典页面(entry 1197,HTTP 200)。
|
||||||
|
2. 宝典主 WSS 为 `d35bf373-ws.va.huya.com`(entry 828),完成 `launch.wsLaunch`、`mobileui.getConfig`、心跳/确认和业务 RPC。
|
||||||
|
3. 主链首先调用 `checkUserBindGameAccount`、`getActInfo`、`getActUserTaskDetail`、`getUserScore`、`getUserPrizeRecords`、`getEntityPrizeFieldMap`、`getModuleAddress`、`getLiveLinkParam`。
|
||||||
|
4. `getActInfo` 返回 status 200,活动名“活动+购买任务”,活动时间戳区间、模块 20051、外部活动 17096、游戏 cjm 和组件 3203。
|
||||||
|
|
||||||
|
WSS 帧为二进制 WebSocket payload,前 6 字节是 command/sequence,body 是 WUP/TAF。项目已有 `WssMessage.decode()` 和 `_decode_wup_body()`,同一连接的 requestId 运行时递增;不要把 frame sequence 或样本 requestId 当业务主键。
|
||||||
|
|
||||||
|
## 4. 积分兑换闭环
|
||||||
|
|
||||||
|
### 4.1 绑定和前置查询
|
||||||
|
|
||||||
|
- 首次绑定响应显示游戏“和平精英”;绑定状态会经历未绑定、已绑定和确认后状态,`confirmBindActAccount` 返回 `status=200,msg=请求成功`。
|
||||||
|
- `getLiveLinkParam` 返回外部活动 `17096`、`gameIdList=cjm`、`livePlatId=huya` 和动态 `t/code/sig`。签名算法证据不足,客户端只转发实时响应。
|
||||||
|
- `getActPrizeDetail(sid=2203,pid=12861)` 返回奖品“幸运币礼包(小)”,兑换积分 20,库存/时间/限制字段来自服务端。
|
||||||
|
|
||||||
|
### 4.2 写入与回查
|
||||||
|
|
||||||
|
请求:`webActUI.scoreExchangePrize`,字段为 `userId`、`sid=2203`、`pid=12861`、`ip`、`clientEnv`、`source`、`isRole=1`。本样本的空 `ip/source/clientEnv` 是一次浏览器操作结果,不应成为固定规则。
|
||||||
|
|
||||||
|
响应:`status=200,msg=请求成功`,返回兑换订单标识和 `exchangeInfo(pid=12861,exchangeScore=20,desc=兑换奖品:幸运币礼包(小))`。敏感订单标识已省略。
|
||||||
|
|
||||||
|
写入后浏览器按顺序回查 `getUserScore`、`getUserPrizeRecords`、`getEntityPrizeFieldMap`、`getModuleAddress`。实测积分从可用 300 变为 280,兑换记录新增该奖品、20 分和当日日期;这证明兑换链在该包中闭合。UI 应以回查值为准,并对 `isCanExchange`、活动时间、库存、今日/用户限制和可用积分做二次校验。
|
||||||
|
|
||||||
|
## 5. 开通宝典与支付闭环
|
||||||
|
|
||||||
|
商城 WSS 为 `wsapi.huya.com`(entry 1431),初始化后业务顺序为:
|
||||||
|
|
||||||
|
1. `getGoodsInfoV5(pid=直播间上下文, spuId=hy-5879340, skuId=5370360)`:商品名“精英宝典”,说明“得300积分丨解锁道具兑换权益”,标价 3000(分);响应关联活动绑定信息和 `bActId=9271`。
|
||||||
|
2. `getSupplierInfoV5(supplierId=87401)`:返回“和平精英官方小店”。
|
||||||
|
3. `listPayChannelV5`:可用渠道为 `Zfb`、`Weixin`。
|
||||||
|
4. `checkHyProtocolV5`:协议检查成功,状态 200。
|
||||||
|
5. `PlayMallUI.getMyPromotion`、`calcOrderPromotion`:本单无返利,订单金额为 3000 分/人民币 30.00 的商城商品金额。
|
||||||
|
6. `checkUserBuyAuth`:状态 200,允许创建订单。
|
||||||
|
7. `createOrderV5`:状态 200,返回商城内部订单标识、支付前订单状态和应付金额;样本值已脱敏。
|
||||||
|
8. `payOrderSubmitV5(order, channel=Zfb, payType=QrCode)`:状态 200,返回支付宝网关跳转 URL、支付流水标识和回调地址。URL 中包含 RSA2 签名,客户端应把它当作服务端生成的短期跳转值,不能自行拼接或重签。
|
||||||
|
9. `orderDetailV5(orderId)` 多次轮询:前期订单状态为待支付,支付确认后变为完成状态(状态码 50),支付金额保持 3000;`batchQueryBuyAfterConfig` 随后返回商城后置配置。
|
||||||
|
10. 支付 HTTP 链:支付宝网关 -> `unitradeprod.alipay.com/appAssign.htm` -> `excashier.alipay.com/standard/auth.htm` -> `queryQRStatus.json`。首次查询返回 `qrStatus=normal`,后续查询返回已登录/已确认状态(`qrStatus=2`),二维码状态由支付宝控制,不能由客户端伪造。
|
||||||
|
|
||||||
|
订单状态 50 是商城订单完成证据;宝典页面的购买任务积分/权益应再调用 `getUserScore`、`getActUserTaskDetail` 和相关宝典查询确认,不能仅凭支付宝页面成功推断权益到账。
|
||||||
|
|
||||||
|
## 6. Python 实现建议
|
||||||
|
|
||||||
|
仓库现有 `core.huya.wss_client.HuyaWssClient`、`core.huya.http_client.HuyaHttpClient`、`activity_structs.py` 和 `shop_structs.py` 已覆盖 WUP/TAF 结构及大部分查询。`scripts/huya_elite_client.py` 可作为查询入口:
|
||||||
|
|
||||||
|
```python
|
||||||
|
client.snapshot() # 活动、任务、绑定、奖品、积分、记录
|
||||||
|
# 用户明确确认后:实时 getActPrizeDetail -> scoreExchangePrize -> 三项回查
|
||||||
|
# 开通:getGoodsInfoV5 -> checkUserBuyAuth -> createOrderV5
|
||||||
|
# -> payOrderSubmitV5 -> orderDetailV5 轮询 -> 宝典权益回查
|
||||||
|
```
|
||||||
|
|
||||||
|
建议将状态机拆为 `login_session`、`elite_snapshot`、`exchange`、`purchase` 四步;所有动态字段从前序响应传递,错误时保留服务端 status/msg,不猜测签名算法。写操作默认幂等保护:同一用户、同一 pid 在收到成功响应后不重复提交,只做回查。
|
||||||
|
|
||||||
|
## 7. 证据边界
|
||||||
|
|
||||||
|
- 归档已证明兑换成功和商城订单完成,但没有提供支付宝私钥、服务端签名算法或可脱离当前登录态的重放凭据。
|
||||||
|
- `getEntityPrizeFieldMap`/`getModuleAddress` 在本次兑换奖品上返回无地址,不代表所有实物奖品都无需地址;实际奖品类型必须按最新响应决定。
|
||||||
|
- 订单完成到宝典积分到账可能存在异步延迟,工作台应轮询业务接口而非只看支付状态。
|
||||||
Reference in New Issue
Block a user