完善虎牙积分查询日志
This commit is contained in:
@@ -10,7 +10,7 @@ class ActivityUserId(TafStruct):
|
||||
self.lUid: int = 0
|
||||
self.sGuid: str = ""
|
||||
self.sToken: str = ""
|
||||
self.sHuYaUA: str = "web&1.0&huya"
|
||||
self.sHuYaUA: str = "webh5&0.0.1&websocket&&diypc_52775"
|
||||
self.sCookie: str = ""
|
||||
self.iTokenType: int = 0
|
||||
self.sDeviceInfo: str = ""
|
||||
|
||||
+48
-14
@@ -42,7 +42,7 @@ class WSConnectParaInfo(TafStruct):
|
||||
def __init__(self):
|
||||
self.lUid: int = 0
|
||||
self.sGuid: str = ""
|
||||
self.sUA: str = "webh5&0.0.1&websocket&&diypc_52775"
|
||||
self.sUA: str = HTTP_HUYA_UA
|
||||
self.sAppSrc: str = "HUYA&ZH&2052"
|
||||
self.sMid: str = ""
|
||||
self.sExp: str = ""
|
||||
@@ -53,7 +53,7 @@ class WSConnectParaInfo(TafStruct):
|
||||
self.mCustomHeaders: dict = {}
|
||||
|
||||
def write_to(self, os: TafOutputStream):
|
||||
# 与浏览器一致: 空字符串也写 (HAR 实证 tag4/5/7/8 都写了空串)
|
||||
# 与浏览器一致: 可为空的字段也显式写入。
|
||||
if self.lUid:
|
||||
os.write_int64(0, self.lUid)
|
||||
else:
|
||||
@@ -70,7 +70,17 @@ class WSConnectParaInfo(TafStruct):
|
||||
os.write_map(10, self.mCustomHeaders)
|
||||
|
||||
def read_from(self, ins: TafInputStream):
|
||||
pass
|
||||
self.lUid = ins.read_int64(0, default=self.lUid)
|
||||
self.sGuid = ins.read_string(1, default=self.sGuid)
|
||||
self.sUA = ins.read_string(2, default=self.sUA)
|
||||
self.sAppSrc = ins.read_string(3, default=self.sAppSrc)
|
||||
self.sMid = ins.read_string(4, default=self.sMid)
|
||||
self.sExp = ins.read_string(5, default=self.sExp)
|
||||
self.iTokenType = ins.read_int32(6, default=self.iTokenType)
|
||||
self.sToken = ins.read_string(7, default=self.sToken)
|
||||
self.sCookie = ins.read_string(8, default=self.sCookie)
|
||||
self.sTraceId = ins.read_string(9, default=self.sTraceId)
|
||||
self.mCustomHeaders = ins.read_map(10)
|
||||
|
||||
|
||||
def _gen_trace_id() -> str:
|
||||
@@ -84,20 +94,16 @@ def generate_http_baseinfo(uid: int, guid: str, cookie: str,
|
||||
"""
|
||||
构造 HTTP POST 的 baseinfo URL 参数
|
||||
|
||||
HAR 实证: getGoodsInfoV5 的 baseinfo lUid=0, sCookie="" (身份靠 Wup body 的 userId.sCookie)
|
||||
HAR 实证: 当前 cdnws HTTP RPC 的 baseinfo 会带 lUid 和完整 Cookie。
|
||||
"""
|
||||
info = WSConnectParaInfo()
|
||||
info.lUid = 0 # HAR 实证: baseinfo 里 lUid=0
|
||||
info.lUid = int(uid or 0)
|
||||
info.sGuid = guid
|
||||
info.sUA = "webh5&0.0.1&websocket&&diypc_52775"
|
||||
info.sUA = HTTP_HUYA_UA
|
||||
info.sAppSrc = "HUYA&ZH&2052"
|
||||
info.sCookie = "" # HAR 实证: baseinfo 不带 cookie, cookie 在 Wup body
|
||||
info.sCookie = cookie or ""
|
||||
info.sTraceId = trace_id or _gen_trace_id()
|
||||
|
||||
os = TafOutputStream()
|
||||
os.write_struct_begin(0) # WSConnectParaInfo 是顶层 struct? 实际 baseinfo 是裸 struct 字段
|
||||
# 实际 HAR baseinfo 解码: 顶层直接是字段(tag0 lUid...), 不包 STRUCT_BEGIN
|
||||
# 重置, 不写 STRUCT_BEGIN
|
||||
os = TafOutputStream()
|
||||
info.write_to(os)
|
||||
raw = os.get_bytes()
|
||||
@@ -168,7 +174,7 @@ class HuyaHttpClient:
|
||||
from .activity_structs import ActivityUserId
|
||||
user = ActivityUserId()
|
||||
user.lUid = uid
|
||||
user.sHuYaUA = "web&1.0&huya"
|
||||
user.sHuYaUA = HTTP_HUYA_UA
|
||||
user.sCookie = cookie or ""
|
||||
return user
|
||||
|
||||
@@ -184,7 +190,7 @@ class HuyaHttpClient:
|
||||
method: 方法名 (getGoodsInfoV5)
|
||||
req_struct: 请求结构体 (TafStruct)
|
||||
rsp_class: 响应类
|
||||
uid/guid/cookie: 用于构造 baseinfo (cookie 主要放 Wup body)
|
||||
uid/guid/cookie: 用于构造 baseinfo,业务请求体也会按各接口需要携带
|
||||
"""
|
||||
# 1. 构造 Wup 请求体
|
||||
wup = WupRequest()
|
||||
@@ -199,7 +205,7 @@ class HuyaHttpClient:
|
||||
url = f"https://{CDNWS_HOST}/?baseinfo={baseinfo}"
|
||||
|
||||
self.logger(f"[HTTP] POST {service}.{method}")
|
||||
self.logger(f"[HTTP] URL: {url[:100]}...")
|
||||
self.logger(f"[HTTP] URL: https://{CDNWS_HOST}/?baseinfo=<redacted>")
|
||||
self.logger(f"[HTTP] 发送 body: {len(wup_data)} 字节, hex前60: {wup_data[:60].hex()}")
|
||||
|
||||
# 3. POST
|
||||
@@ -239,6 +245,9 @@ class HuyaHttpClient:
|
||||
result = wup_resp.readStruct("tRsp", rsp_class)
|
||||
if result is None:
|
||||
result = wup_resp.readStruct("tResp", rsp_class)
|
||||
if result is not None and hasattr(result, "to_dict"):
|
||||
decoded = json.dumps(result.to_dict(), ensure_ascii=False, separators=(",", ":"))
|
||||
self.logger(f"[HTTP] 解码 tRsp: {decoded}")
|
||||
return result
|
||||
|
||||
# ---------- 业务便捷方法 ----------
|
||||
@@ -381,3 +390,28 @@ class HuyaHttpClient:
|
||||
if result is None:
|
||||
result = wup_resp.readStruct("tResp", PayOrderRes)
|
||||
return result
|
||||
|
||||
|
||||
def _self_check():
|
||||
uid = 1199647239697
|
||||
cookie = "yyuid=1199647239697; udb_passport=test"
|
||||
trace_id = "0123456789abcdef:0123456789abcdef:0:0"
|
||||
|
||||
encoded = generate_http_baseinfo(uid, "", cookie, trace_id=trace_id)
|
||||
raw = base64.b64decode(urllib.parse.unquote(encoded))
|
||||
|
||||
parsed = WSConnectParaInfo()
|
||||
parsed.read_from(TafInputStream(raw))
|
||||
|
||||
assert parsed.lUid == uid
|
||||
assert parsed.sUA == HTTP_HUYA_UA
|
||||
assert parsed.sCookie == cookie
|
||||
assert parsed.sTraceId == trace_id
|
||||
|
||||
user = HuyaHttpClient._build_activity_user(uid, cookie)
|
||||
assert user.sHuYaUA == HTTP_HUYA_UA
|
||||
assert user.sCookie == cookie
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_self_check()
|
||||
|
||||
@@ -6,6 +6,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from loguru import logger
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from core.huya import HuyaHttpClient
|
||||
@@ -42,6 +43,9 @@ class HuyaBatchRunner:
|
||||
self._stop.set()
|
||||
|
||||
def _push_log(self, level: str, message: str):
|
||||
if level != "result" and message:
|
||||
log_func = getattr(logger, level, logger.info)
|
||||
log_func(f"[huya] {message}")
|
||||
if self.log_queue and self.loop:
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
self.log_queue.put({"level": level, "message": message}),
|
||||
@@ -113,7 +117,7 @@ class HuyaBatchRunner:
|
||||
self._mark_task(worker_db, task, "failed", "账号 Cookie 为空")
|
||||
return
|
||||
|
||||
client = HuyaHttpClient(logger=lambda _msg: None)
|
||||
client = HuyaHttpClient(logger=lambda msg: self._push_log("info", f"[{uid}] {msg}"))
|
||||
response = client.query_user_score(uid=uid, cookie=cookie, sid=sid_int)
|
||||
if response is None:
|
||||
self._mark_task(worker_db, task, "error", "虎牙积分接口无响应")
|
||||
|
||||
Reference in New Issue
Block a user