补齐虎牙宝典活动与商城WSS协议
This commit is contained in:
@@ -31,6 +31,7 @@ from .taf_protocol import TafInputStream, TafOutputStream, TafStruct, TafType
|
|||||||
from .wup_protocol import WupRequest, WupResponse
|
from .wup_protocol import WupRequest, WupResponse
|
||||||
|
|
||||||
SHOP_WS_HOST = "77bc035c-ws.va.huya.com"
|
SHOP_WS_HOST = "77bc035c-ws.va.huya.com"
|
||||||
|
ACTIVITY_WS_HOST = "d35bf373-ws.va.huya.com"
|
||||||
# 商城端点 baseinfo (conn4, h5_/index.html) — 商城业务 shopMiddleUI 走此通道
|
# 商城端点 baseinfo (conn4, h5_/index.html) — 商城业务 shopMiddleUI 走此通道
|
||||||
# wsLaunch tReq: lUid=0, sGuid="", sUA="webh5&0.0.1&websocket&&h5_/index.html"
|
# wsLaunch tReq: lUid=0, sGuid="", sUA="webh5&0.0.1&websocket&&h5_/index.html"
|
||||||
SHOP_BASEINFO = "DBYAJiV3ZWJoNSYwLjAuMSZ3ZWJzb2NrZXQmJmg1Xy9pbmRleC5odG1sNgxIVVlBJlpIJjIwNTJGAFYAbHYAhgCWAKgM"
|
SHOP_BASEINFO = "DBYAJiV3ZWJoNSYwLjAuMSZ3ZWJzb2NrZXQmJmg1Xy9pbmRleC5odG1sNgxIVVlBJlpIJjIwNTJGAFYAbHYAhgCWAKgM"
|
||||||
@@ -41,6 +42,20 @@ WSS_BIZ_UA = "web&1.0.0&huya"
|
|||||||
WSS_COOKIE_UA = "webh5&0.0.1&websocket&&diypc_52775"
|
WSS_COOKIE_UA = "webh5&0.0.1&websocket&&diypc_52775"
|
||||||
WSS_SHOP_SCENE = 4
|
WSS_SHOP_SCENE = 4
|
||||||
|
|
||||||
|
|
||||||
|
class _ActivityConfigReq(TafStruct):
|
||||||
|
def __init__(self, user):
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
def write_to(self, os: TafOutputStream):
|
||||||
|
os.write_struct(0, self.user)
|
||||||
|
os.write_map(1, {})
|
||||||
|
os.write_string(2, "huya")
|
||||||
|
os.write_list(3, [])
|
||||||
|
|
||||||
|
def read_from(self, _ins):
|
||||||
|
pass
|
||||||
|
|
||||||
# seq 按消息类型固定 (HAR 实证,跨两次抓包一致)
|
# seq 按消息类型固定 (HAR 实证,跨两次抓包一致)
|
||||||
SEQ_HEARTBEAT = 0x1D00000D
|
SEQ_HEARTBEAT = 0x1D00000D
|
||||||
SEQ_WSLAUNCH = 0x1D000078
|
SEQ_WSLAUNCH = 0x1D000078
|
||||||
@@ -341,6 +356,66 @@ class HuyaWssClient:
|
|||||||
self.logger("[初始化] 完成 ✓")
|
self.logger("[初始化] 完成 ✓")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
async def initialize_activity(self, uid: int, guid: str, cookie: str):
|
||||||
|
"""活动通道初始化:heartbeat -> wsLaunch -> AUTH -> getConfig -> confirm。"""
|
||||||
|
await self.send_heartbeat()
|
||||||
|
launch_rsp = await self.call_ws_launch_activity(uid, guid)
|
||||||
|
if launch_rsp is None:
|
||||||
|
return False
|
||||||
|
await self.send_auth(cookie)
|
||||||
|
await self.call_get_config_activity(uid, cookie)
|
||||||
|
await self.send_confirm()
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def call_ws_launch_activity(self, uid: int, guid: str = "", timeout: float = 10.0):
|
||||||
|
ua = WSS_COOKIE_UA
|
||||||
|
os = TafOutputStream()
|
||||||
|
os.write_struct_begin(0)
|
||||||
|
os.write_int64(0, int(uid or 0))
|
||||||
|
os.write_string(1, guid or "")
|
||||||
|
os.write_string(2, ua)
|
||||||
|
os.write_string(3, "HUYA&ZH&2052")
|
||||||
|
os.write_struct_begin(4)
|
||||||
|
for i in range(5):
|
||||||
|
os.write_string(i, "")
|
||||||
|
os.write_struct_end()
|
||||||
|
os.write_struct_end()
|
||||||
|
wup = WupRequest()
|
||||||
|
wup.setServant("launch")
|
||||||
|
wup.setFunc("wsLaunch")
|
||||||
|
wup.setRequestId(-1)
|
||||||
|
wup.iTimeout = 0
|
||||||
|
wup.newdata["tReq"] = os.get_bytes()
|
||||||
|
body = self._encode_rpc_body(wup.encode())
|
||||||
|
msg = WssMessage(WssCommand.RPC_REQUEST, SEQ_WSLAUNCH, body)
|
||||||
|
future = asyncio.Future()
|
||||||
|
self.rpc_queue.append(future)
|
||||||
|
await self.ws.send(msg.encode())
|
||||||
|
try:
|
||||||
|
response = await asyncio.wait_for(future, timeout)
|
||||||
|
except TimeoutError:
|
||||||
|
if future in self.rpc_queue:
|
||||||
|
self.rpc_queue.remove(future)
|
||||||
|
return None
|
||||||
|
self._parse_launch_response(response)
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def call_get_config_activity(self, uid: int, cookie: str, timeout: float = 10.0):
|
||||||
|
user = self._build_activity_user(uid, cookie)
|
||||||
|
req = _ActivityConfigReq(user)
|
||||||
|
return await self.call_rpc("mobileui", "getConfig", req, None, timeout=timeout)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _build_activity_user(uid: int, cookie: str):
|
||||||
|
from .activity_structs import ActivityUserId
|
||||||
|
|
||||||
|
user = ActivityUserId()
|
||||||
|
user.lUid = int(uid or 0)
|
||||||
|
user.sHuYaUA = WSS_COOKIE_UA
|
||||||
|
user.sCookie = HuyaWssClient._normalize_biz_cookie(cookie)
|
||||||
|
return user
|
||||||
|
|
||||||
async def call_ws_launch_shop(self, timeout: float = 10.0):
|
async def call_ws_launch_shop(self, timeout: float = 10.0):
|
||||||
"""商城版 wsLaunch (匿名, 无 lUid/sGuid, 与 conn4 格式一致)"""
|
"""商城版 wsLaunch (匿名, 无 lUid/sGuid, 与 conn4 格式一致)"""
|
||||||
ua = "webh5&0.0.1&websocket&&h5_/index.html"
|
ua = "webh5&0.0.1&websocket&&h5_/index.html"
|
||||||
@@ -656,6 +731,71 @@ class HuyaWssClient:
|
|||||||
"shopMiddleUI", "getGoodsInfoV5", req, GoodsInfoRsp, timeout=15.0
|
"shopMiddleUI", "getGoodsInfoV5", req, GoodsInfoRsp, timeout=15.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def get_act_info(self, act_id: int):
|
||||||
|
from .activity_structs import GetActInfoReq, GetActInfoResp
|
||||||
|
|
||||||
|
req = GetActInfoReq()
|
||||||
|
req.actId = int(act_id or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getActInfo", req, GetActInfoResp)
|
||||||
|
|
||||||
|
async def get_act_task_detail(self, uid: int, cookie: str, act_id: int):
|
||||||
|
from .activity_structs import GetActTaskDetailReq, GetActTaskDetailResp
|
||||||
|
|
||||||
|
req = GetActTaskDetailReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.actId = int(act_id or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getActTaskDetail", req, GetActTaskDetailResp)
|
||||||
|
|
||||||
|
async def get_act_user_task_detail(self, uid: int, cookie: str, act_id: int):
|
||||||
|
from .activity_structs import GetActUserTaskDetailReq, GetActUserTaskDetailResp
|
||||||
|
|
||||||
|
req = GetActUserTaskDetailReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.actId = int(act_id or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getActUserTaskDetail", req, GetActUserTaskDetailResp)
|
||||||
|
|
||||||
|
async def get_user_score(self, uid: int, cookie: str, sid: int):
|
||||||
|
from .activity_structs import GetUserScoreReq, GetUserScoreResp
|
||||||
|
|
||||||
|
req = GetUserScoreReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.sid = int(sid or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getUserScore", req, GetUserScoreResp)
|
||||||
|
|
||||||
|
async def get_act_prize_list(self, uid: int, cookie: str, sid: int):
|
||||||
|
from .activity_structs import GetActPrizeListReq, GetActPrizeListResp
|
||||||
|
|
||||||
|
req = GetActPrizeListReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.sid = int(sid or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getActPrizeList", req, GetActPrizeListResp)
|
||||||
|
|
||||||
|
async def get_act_prize_detail(self, uid: int, cookie: str, sid: int, pid: int):
|
||||||
|
from .activity_structs import GetActPrizeDetailReq, GetActPrizeDetailResp
|
||||||
|
|
||||||
|
req = GetActPrizeDetailReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.sid = int(sid or 0)
|
||||||
|
req.pid = int(pid or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getActPrizeDetail", req, GetActPrizeDetailResp)
|
||||||
|
|
||||||
|
async def score_exchange_prize(self, uid: int, cookie: str, sid: int, pid: int):
|
||||||
|
from .activity_structs import ScoreExchangePrizeReq, ScoreExchangePrizeResp
|
||||||
|
|
||||||
|
req = ScoreExchangePrizeReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.sid = int(sid or 0)
|
||||||
|
req.pid = int(pid or 0)
|
||||||
|
return await self.call_rpc("webActUI", "scoreExchangePrize", req, ScoreExchangePrizeResp)
|
||||||
|
|
||||||
|
async def get_user_prize_records(self, uid: int, cookie: str, sid: int):
|
||||||
|
from .activity_structs import GetUserPrizeRecordsReq, GetUserPrizeRecordsResp
|
||||||
|
|
||||||
|
req = GetUserPrizeRecordsReq()
|
||||||
|
req.userId = self._build_activity_user(uid, cookie)
|
||||||
|
req.sid = int(sid or 0)
|
||||||
|
return await self.call_rpc("webActUI", "getUserPrizeRecords", req, GetUserPrizeRecordsResp)
|
||||||
|
|
||||||
async def list_pay_channels(
|
async def list_pay_channels(
|
||||||
self, uid: int, guid: str, cookie: str, spu_id: str, sku_id: int = 0,
|
self, uid: int, guid: str, cookie: str, spu_id: str, sku_id: int = 0,
|
||||||
supplier_id: int = 87401,
|
supplier_id: int = 87401,
|
||||||
|
|||||||
Reference in New Issue
Block a user