fix(huya): 查询积分改走积分中心新接口(含成长等级)

旧活动接口 webActUI.getUserScore 对任何 sid 都返回 603「活动已结束」
(接口已下线,与工作台 SID/活动配置无关),刷新积分只会报错。

- 协议层新增两个 RPC(WSS + HTTP 双侧同签名):
  shopMiddleUI.getRedeemNeedGoods(tag2=当前积分、tag3=兑换门槛,
  兑换商品号 POINTS_REDEEM_GOODS_NUM=8315982,传错直接 500)
  与 GameBizUI.getGrowLevelUserInfo(成长值/成长等级/昵称/头像)
- 新增结构体 GetRedeemNeedGoodsReq / GetGrowLevelUserInfoReq,
  与 HuyaEliteWssSession 透传
- 服务层 _execute_query_points 主源改为积分中心接口,结果带
  points/redeem_threshold/grow_level/grow_value,并同步 account.points;
  接口无响应时才回退旧活动接口并如实报告其 603 返回
- 开通支付成功后的积分刷新同样改走积分中心接口
- 前端任务页积分结果优先读 points(兼容旧记录的 available_score),
  并在有成长等级时一并展示
- 新增 tests/test_huya_points_query.py:真机响应字节回归 + 请求参数
  字面量断言 + 服务层积分来源/回退语义(已做反向验证)

真机验证:HTTP 通道取到积分 280 / 门槛 20 / 成长等级 3
This commit is contained in:
yml2213
2026-10-15 15:32:46 +08:00
parent b5d8d5b5d8
commit 905a7ef22c
8 changed files with 508 additions and 21 deletions
+6
View File
@@ -273,5 +273,11 @@ class HuyaEliteWssSession:
def get_follow_wechat_status(self, **kwargs):
return self._run(self.client.get_follow_wechat_status(**kwargs))
def get_redeem_need_goods(self, **kwargs):
return self._run(self.client.get_redeem_need_goods(**kwargs))
def get_grow_level_user_info(self, **kwargs):
return self._run(self.client.get_grow_level_user_info(**kwargs))
__all__ = ["HuyaEliteWssSession"]
+48
View File
@@ -29,6 +29,7 @@ from .wss_client import (
ORDER_BIZ_TYPE,
ORDER_SCENE,
POINTS_PAY_CALLBACK,
POINTS_REDEEM_GOODS_NUM,
SHOP_APP_SCENE,
)
from .wup_protocol import WupRequest, WupResponse
@@ -1448,6 +1449,53 @@ class HuyaHttpClient:
)
return self._raw_from_wup(resp) if isinstance(resp, WupResponse) else None
def get_redeem_need_goods(
self,
uid: int,
guid: str,
cookie: str,
goods_num: int = POINTS_REDEEM_GOODS_NUM,
timeout: float = 15.0,
):
"""shopMiddleUI.getRedeemNeedGoods(当前积分 tag2 / 兑换门槛 tag3)。"""
from .shop_structs import GetRedeemNeedGoodsReq
req = GetRedeemNeedGoodsReq()
req.userId = self._build_shop_user(uid, cookie)
req.shopAppInfo = self._build_shop_app("yellowcarlist", SHOP_APP_SCENE)
req.goodsNum = int(goods_num or 0)
resp = self.call_rpc(
"shopMiddleUI",
"getRedeemNeedGoods",
req,
None,
uid,
guid,
cookie,
timeout=timeout,
)
return self._raw_from_wup(resp) if isinstance(resp, WupResponse) else None
def get_grow_level_user_info(
self, uid: int, guid: str, cookie: str, timeout: float = 15.0
):
"""GameBizUI.getGrowLevelUserInfo(成长值 tag1.tag0 / 等级 tag1.tag1)。"""
from .shop_structs import GetGrowLevelUserInfoReq
req = GetGrowLevelUserInfoReq()
req.userId = self._build_shop_user(uid, cookie)
resp = self.call_rpc(
"GameBizUI",
"getGrowLevelUserInfo",
req,
None,
uid,
guid,
cookie,
timeout=timeout,
)
return self._raw_from_wup(resp) if isinstance(resp, WupResponse) else None
def _self_check():
uid = 1199647239697
+33
View File
@@ -1398,6 +1398,39 @@ class FollowWeChatStatusReq(TafStruct):
pass
class GetRedeemNeedGoodsReq(ShopAppRequest):
"""shopMiddleUI.getRedeemNeedGoods 请求(兑换所需商品 + 当前积分)。
tag2 是兑换商品的数字商品号(抓包为精英宝典兑换商品 ``hy-8315982`` →
``8315982``);传错会返回 500「系统异常」,所以调用方必须给真实商品号。
"""
def __init__(self):
super().__init__()
self.goodsNum: int = 0 # tag 2
def write_to(self, os: TafOutputStream):
os.write_struct(0, self.userId)
os.write_struct(1, self.shopAppInfo)
os.write_int64(2, self.goodsNum)
def read_from(self, ins: TafInputStream):
pass
class GetGrowLevelUserInfoReq(TafStruct):
"""GameBizUI.getGrowLevelUserInfo 请求(抓包 tReq 只有 tag0 UserId)。"""
def __init__(self):
self.userId = UserId() # tag 0
def write_to(self, os: TafOutputStream):
os.write_struct(0, self.userId)
def read_from(self, ins: TafInputStream):
self.userId = ins.read_struct(0, UserId) or self.userId
def shop_spu_number(spu_id: str) -> int:
"""把商品 ID(``hy-8328015``)转成接口需要的数字形式(``8328015``)。"""
text = str(spu_id or "").strip()
+34
View File
@@ -73,6 +73,9 @@ ORDER_BIZ_TYPE = 5
SHOP_APP_SCENE = 7
ORDER_SCENE = 4
PEACE_ELITE_GAME_ID = 9815
# getRedeemNeedGoods 的兑换商品号:抓包里的精英宝典兑换商品 hy-8315982 → 8315982。
# 服务端只认这个商品号(传 0/其它值直接 500「系统异常」)。
POINTS_REDEEM_GOODS_NUM = 8315982
# createOrderV5 的 extraParam.bizParams:标记「积分中心」来源,缺了会走成普通商城单。
JIFENCENTER_BIZ_PARAMS = '{ "jifencenter": 1 }'
@@ -1448,3 +1451,34 @@ class HuyaWssClient:
return await self.call_rpc_raw(
"wupui", "getUserFollowWeChatOfficialStatus", req
)
async def get_redeem_need_goods(
self,
uid: int,
guid: str,
cookie: str,
goods_num: int = POINTS_REDEEM_GOODS_NUM,
):
"""shopMiddleUI.getRedeemNeedGoods — 兑换所需商品与当前积分。
响应:``tag2`` 当前积分、``tag3`` 兑换门槛积分(抓包 + 真机实证)。
"""
from .shop_structs import GetRedeemNeedGoodsReq
req = GetRedeemNeedGoodsReq()
req.userId = self._build_biz_user(uid, cookie)
req.shopAppInfo = self._build_shop_app("yellowcarlist", SHOP_APP_SCENE)
req.goodsNum = int(goods_num or 0)
return await self.call_rpc_raw("shopMiddleUI", "getRedeemNeedGoods", req)
async def get_grow_level_user_info(self, uid: int, guid: str, cookie: str):
"""GameBizUI.getGrowLevelUserInfo — 成长值/成长等级/昵称。
响应:``tag1.tag0`` 成长值、``tag1.tag1`` 成长等级、``tag2`` 昵称、
``tag3`` 头像(抓包 + 真机实证)。
"""
from .shop_structs import GetGrowLevelUserInfoReq
req = GetGrowLevelUserInfoReq()
req.userId = self._build_biz_user(uid, cookie)
return await self.call_rpc_raw("GameBizUI", "getGrowLevelUserInfo", req)