#!/usr/bin/env python3 """虎牙铸币机 —— 全管线编排: mid(铸) → doLaunch 收 sGuid → 零设备注册链 → WUP 登录验证. 铸币闭环 (docs/HUYA_HDID_ALGORITHM_GEN.md §11.8): sGuid = f(mid) —— 服务端按 mid(LiveUserbase→tUAEx→t5=sMId, 16hex) 确定性签发。 mid 可任意铸造 → doLaunch 收 32hex sGuid → 登录帧 t1.t0(hdid) 用该 sGuid。 用法: python tools/device_mint.py --mint-only [mid] # 只铸币: mid → sGuid python tools/device_mint.py --login [--mid X] # 铸币 → 注册链 → 登录 python tools/device_mint.py --control # 金样本 hdid 登录 (对照基线) python tools/device_mint.py --matrix # 双雨矩阵: 3 个 mid ×2 复跑 + 登录 输出: cred hex / NEED_RISK / REJECTED 对照; 事件实时打印。 """ from __future__ import annotations import hashlib import sys from pathlib import Path HERE = Path(__file__).resolve().parent if str(HERE) not in sys.path: sys.path.insert(0, str(HERE)) from huya_launch_mint import DEFAULT_PROFILE, mint_sguid # noqa: E402 try: from huya_device_register import gen_fresh_identity, login_with_registered # noqa: E402 HAVE_REG = True except Exception: # pragma: no cover HAVE_REG = False GOLDEN_HDID32 = "ed0db8334cadd236c00cadf7e11ab5a5" # 金样本 HDID32 (登录t1.t0设备证书, 对照基线) URL = "https://wup.huya.com" def mint_couple(mid: str, times: int = 2) -> list[str | None]: """同一 mid 铸币多次, 验证确定性。""" out = [] for _ in range(times): out.append(mint_sguid(DEFAULT_PROFILE, mid=mid, url=URL)) return out def full_mint_login(account: str, password: str, mid: str) -> str: """铸币→注册链→登录 (铸币 hdid), 返回 cred hex / NEED_RISK / REJECTED。""" sguid = mint_sguid(DEFAULT_PROFILE, mid=mid, url=URL) print(f"[mint] mid={mid} -> sGuid={sguid}") if not sguid: return "REJECTED:no-sguid" if not HAVE_REG: return "REJECTED:no-reg-chain" t1, t2, t5 = gen_fresh_identity() print(f"[reg] t1(appkey回声)={t1}") print(f"[reg] t2(action)={t2[:16]}... len={len(t2)}") print(f"[reg] t5(device_id)={t5}") out = login_with_registered(t2, t5, account, password, golden_hdid=sguid) print(f"[login] 铸币hdid={sguid} -> {_brief(out)}") return out def full_control_login(account: str, password: str) -> str: """对照: 金样本 hdid 登录 (注册链仍走零设备)。""" if not HAVE_REG: return "REJECTED:no-reg-chain" t1, t2, t5 = gen_fresh_identity() print(f"[reg] t1={t1} t2={t2[:16]}... t5={t5}") out = login_with_registered(t2, t5, account, password, golden_hdid=GOLDEN_HDID32) print(f"[login] 金样本HDID32={GOLDEN_HDID32} -> {_brief(out)}") return out def _brief(out: str) -> str: if out.startswith(("0a", "0b")): return "cred " + out[:16] + "..." return out def main() -> int: argv = sys.argv[1:] if len(argv) >= 2 and argv[0] == "--mint-only": mid = argv[1] if len(argv) > 1 else DEFAULT_PROFILE["mid"] r = mint_couple(mid, times=3) print(f"mid={mid} 铸币×3: {r}") ok = len({x for x in r}) == 1 and r[0] is not None print("确定性:", "✅ 三次同值" if ok else "❌ 不一致/失败") return 0 if ok else 2 if len(argv) >= 3 and argv[0] in ("--login", "--control", "--matrix"): acct, pwd = argv[1], argv[2] if "--mid" in argv: mid = argv[argv.index("--mid") + 1] else: mid = DEFAULT_PROFILE["mid"] if argv[0] == "--login": out = full_mint_login(acct, pwd, mid) print("最终:", _brief(out)) return 0 if out.startswith(("0a", "0b")) else 1 if argv[0] == "--control": out = full_control_login(acct, pwd) print("最终:", _brief(out)) return 0 if out.startswith(("0a", "0b")) else 1 # --matrix: 3 mid ×2 复跑 (确定性) + 铸币登录 vs 金样本登录 print("=== 铸币确定性矩阵 (mid → sGuid ×2) ===") mids = [DEFAULT_PROFILE["mid"], "9c41d0a7b3e5f281", "31415f26a7c8b9d0"] for m in mids: r = mint_couple(m, times=2) print(f"mid={m}: {r} {'✅' if len({x for x in r}) == 1 and r[0] else '❌'}") print("\n=== 铸币 hdid 登录 (零设备注册链) ===") out1 = full_mint_login(acct, pwd, mid) print("\n=== 对照: 金样本 hdid 登录 ===") out2 = full_control_login(acct, pwd) print(f"\n铸币 hdid -> {_brief(out1)}") print(f"金样本 -> {_brief(out2)}") return 0 if out1.startswith(("0a", "0b")) else 1 print(__doc__) return 2 if __name__ == "__main__": raise SystemExit(main())