"""虎牙手机号自动注册流程。""" from __future__ import annotations import threading import time from dataclasses import dataclass from datetime import datetime from core.sms_provider import SmsLine, SmsProviderClient from .login import HuyaLoginError from .sms_login import login_huya_sms, normalize_huya_phone, send_huya_sms_code @dataclass class HuyaAutoRegisterResult: """单个手机号自动注册结果。""" phone: str provider: str success: bool status: str message: str cookie: str = "" code: str = "" sdid: str = "" normalized_phone: str = "" attempts: int = 0 def _sleep_or_stop(stop_event: threading.Event | None, seconds: float) -> bool: """等待一小段时间;返回 False 表示收到停止信号。""" if seconds <= 0: return not (stop_event and stop_event.is_set()) if stop_event: return not stop_event.wait(seconds) time.sleep(seconds) return True def register_huya_with_sms_line( item: SmsLine, wait_seconds: float = 180, poll_interval: float = 5, stop_event: threading.Event | None = None, ) -> HuyaAutoRegisterResult: """使用固定手机号和接码地址完成虎牙短信注册/登录。""" phone = item.phone.strip() normalized_phone = normalize_huya_phone(phone) wait_seconds = max(15.0, float(wait_seconds or 180)) poll_interval = max(1.0, float(poll_interval or 5)) if stop_event and stop_event.is_set(): return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="stopped", message="已停止", normalized_phone=normalized_phone, ) sent_at = datetime.now() try: code_result = send_huya_sms_code(phone=phone) except HuyaLoginError as exc: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=str(exc), normalized_phone=normalized_phone, ) except Exception as exc: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=f"发送虎牙短信失败: {exc}", normalized_phone=normalized_phone, ) if not code_result.success or not code_result.state: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=code_result.message or "发送虎牙短信失败", sdid=code_result.sdid, normalized_phone=normalized_phone, ) client = SmsProviderClient() deadline = time.monotonic() + wait_seconds attempts = 0 last_message = "等待验证码" while time.monotonic() < deadline: if stop_event and stop_event.is_set(): return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="stopped", message="已停止", sdid=code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) attempts += 1 poll_result = client.poll(item, after_time=sent_at) last_message = poll_result.message or last_message if poll_result.has_code: try: login_result = login_huya_sms( authcode=poll_result.code, state=code_result.state, phone=phone, ) except HuyaLoginError as exc: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=str(exc), code=poll_result.code, sdid=code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) except Exception as exc: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=f"提交虎牙短信登录失败: {exc}", code=poll_result.code, sdid=code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) if login_result.success and login_result.cookie: return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=True, status="success", message="注册/登录成功", cookie=login_result.cookie, code=poll_result.code, sdid=login_result.sdid or code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=login_result.message or "虎牙短信登录失败", code=poll_result.code, sdid=login_result.sdid or code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) remaining = deadline - time.monotonic() if remaining <= 0: break if not _sleep_or_stop(stop_event, min(poll_interval, remaining)): return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="stopped", message="已停止", sdid=code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, ) return HuyaAutoRegisterResult( phone=phone, provider=item.provider, success=False, status="error", message=f"等待验证码超时: {last_message}", sdid=code_result.sdid, normalized_phone=normalized_phone, attempts=attempts, )