fix(huya): 查询角色复用协作台账 CK 探针并标记失效

This commit is contained in:
yml2213
2026-10-17 16:18:28 +08:00
parent fe1f959648
commit 2620023db4
3 changed files with 232 additions and 12 deletions
+64 -11
View File
@@ -8,13 +8,16 @@ from typing import TYPE_CHECKING, Any
from sqlalchemy.orm import Session
from ..huya_defaults import HUYA_DEFAULT_OUTER_ACT_ID
from ..models import HuyaAccount, HuyaTask
from .huya_runner_core import HUYA_RECHARGE_SOURCE_ID, HuyaBatchRunnerCore
HUYA_BIND_ROLE_POLL_SECONDS = 180
HUYA_BIND_ROLE_POLL_INTERVAL = 3
HUYA_BIND_ZT_UUID = "b02faae1"
HUYA_BIND_ROOM_ID = "30596253"
from .huya_runner_core import HUYA_RECHARGE_SOURCE_ID, HuyaBatchRunnerCore
# 与外部单协作的新 CK 探针保持一致:HTTP cdnws + 外层活动参数 + 15 秒超时。
HUYA_CK_PROBE_TIMEOUT_SECONDS = 15.0
if TYPE_CHECKING:
from core.huya import HuyaHttpClient
@@ -38,6 +41,7 @@ class BindMixin:
def _mark_task(self, *args: Any, **kwargs: Any) -> None: ...
def _update_task_progress(self, *args: Any, **kwargs: Any) -> None: ...
def _activity_client(self, uid: int, cookie: str): ...
def _http_client(self): ...
@staticmethod
def _role_name(bind_status) -> str:
@@ -103,14 +107,22 @@ class BindMixin:
uid: int,
cookie: str,
b_act_id_int: int,
*,
outer_act_id: str = "",
timeout: float | None = None,
):
"""按活动页逻辑解析绑定状态,优先返回含角色的状态。"""
outer_status = client.check_user_bind_game_account(
uid=uid,
cookie=cookie,
b_act_id=b_act_id_int,
is_use_outer_act_id=1,
)
probe_kwargs: dict[str, Any] = {
"uid": uid,
"cookie": cookie,
"b_act_id": b_act_id_int,
"is_use_outer_act_id": 1,
}
if outer_act_id:
probe_kwargs["outer_act_id"] = outer_act_id
if timeout is not None:
probe_kwargs["timeout"] = timeout
outer_status = client.check_user_bind_game_account(**probe_kwargs)
if outer_status is None:
return None, {}
@@ -144,6 +156,29 @@ class BindMixin:
query_result["bind_status"] = chosen_status.to_dict()
return chosen_status, query_result
def _probe_bind_status(
self,
uid: int,
cookie: str,
b_act_id_int: int,
outer_act_id: str = "",
):
"""用外部单协作的新 CK 探针查角色。
关键点(2026-10-16 真机验证):必须走 HTTP cdnws 只读通道,带上
``outer_act_id`` 和 15 秒超时;响应为 None 就说明这份 CK 已经不认了。
不能再用 WSS 业务会话的默认参数,否则过期 CK 只会表现为“接口无响应”,
任务结果里没有可判定的失效标记。
"""
return self._resolve_bind_status(
self._http_client(),
uid,
cookie,
b_act_id_int,
outer_act_id=outer_act_id or HUYA_DEFAULT_OUTER_ACT_ID,
timeout=HUYA_CK_PROBE_TIMEOUT_SECONDS,
)
def _apply_role_to_account(self, account: HuyaAccount, bind_status, status: str):
role_name = self._role_name(bind_status)
account.status = status
@@ -503,17 +538,35 @@ class BindMixin:
self._mark_task(worker_db, task, "failed", "账号 Cookie 为空")
return
client: Any = self._activity_client(uid, cookie)
bind_status, bind_query_result = self._resolve_bind_status(
client=client,
outer_act_id = str(
self.payload.get("outer_act_id")
or config_info.get("outer_act_id")
or HUYA_DEFAULT_OUTER_ACT_ID
).strip()
bind_status, bind_query_result = self._probe_bind_status(
uid=uid,
cookie=cookie,
b_act_id_int=b_act_id_int,
outer_act_id=outer_act_id,
)
if bind_status is None:
self._mark_task(worker_db, task, "error", "虎牙角色信息接口无响应")
# 新探针没有回包 = 这份 CK 已经不认了,和外部单协作的判定一致。
account.status = "ck_expired"
account.updated_at = datetime.now(UTC)
self._mark_task(
worker_db,
task,
"error",
"虎牙角色信息接口无响应(CK 已失效,请重新登录或重新导入 Cookie)",
{
"bind_act_id": b_act_id_int,
"ck_expired": True,
"ck_expired_reason": "角色信息接口无响应",
},
)
return
if bind_status.status != 200:
# 有回包、只是业务码非 200(例如活动已下线)不算 CK 失效,避免误标红。
self._mark_task(
worker_db,
task,
+9 -1
View File
@@ -58,6 +58,7 @@ class EliteMixin:
def _resolve_uid(self, account_info: dict) -> int: ...
def _shop_client(self, uid: int, cookie: str): ...
def _activity_client(self, uid: int, cookie: str): ...
def _http_client(self): ...
def _mark_task(self, *args: Any, **kwargs: Any) -> None: ...
# 来自 BindMixin
@@ -348,12 +349,19 @@ class EliteMixin:
if not b_act_id_int:
failures.append("未配置绑定 bActId")
else:
bind_client: Any = self._activity_client(uid, cookie)
outer_act_id = str(
self.payload.get("outer_act_id")
or config_info.get("outer_act_id")
or ""
).strip()
bind_client: Any = self._http_client()
bind_status, bind_query_result = self._resolve_bind_status(
client=bind_client,
uid=uid,
cookie=cookie,
b_act_id_int=b_act_id_int,
outer_act_id=outer_act_id,
timeout=15.0,
)
if bind_status is None:
ck_expired = True