"""Probe 996box for the actual SMS endpoint URL. Tries common patterns and reports which return 200/4xx (real) vs 404 (wrong). Does NOT trigger actual SMS sending. """ import asyncio import json import sys from pathlib import Path _HERE = Path(__file__).resolve().parent sys.path.insert(0, str(_HERE.parent / "src")) from cq2_sdk.env_loader import load_env load_env(_HERE.parent / ".env") from cq2_sdk.login import Box996Login, ManualGeetestSolver # 常见 996box SMS 接口名猜测 (按概率排序) CANDIDATE_ENDPOINTS = [ "/auth/v3/login/sms/send", # 我之前的猜测 (刚 404) "/auth/v3/login/sendSmsCode", # 另一种命名 "/auth/v3/sms/sendLoginCode", # 常见变体 "/auth/v3/login/safe/sendSms", # 带 safe/ 前缀 "/auth/v3/login/sendSms", # 短版 "/auth/v3/login/sendLoginCode", # 变体 "/v3/login/sms/send", # 无 /auth 前缀 "/auth/v3/login/bySms/send", # bySms 路径 ] LOGIN_BASE = "https://api.jiyuhz.cn" async def probe_one(box, endpoint: str, phone: str = "00000000000") -> tuple[str, int, str]: """Returns (endpoint, status, body_preview). status=0 means network error.""" try: r = await box._request("POST", LOGIN_BASE, endpoint, json_body={"phone": phone, "channel_id": "", "game_id": ""}) # If we got here, 996box returned 2xx body = json.dumps(r, ensure_ascii=False)[:80] return endpoint, 200, body except Exception as e: # httpx raises for 4xx/5xx; Box996Error for non-200 JSON msg = str(e)[:120] # Try to extract status code status = 0 if "404" in msg: status = 404 elif "400" in msg: status = 400 elif "405" in msg: status = 405 elif "Method Not Allowed" in msg: status = 405 return endpoint, status, msg async def main() -> int: box = Box996Login(geetest=ManualGeetestSolver(), device_id="00:15:5d:0a:04:00") print(f"Probing {len(CANDIDATE_ENDPOINTS)} candidate SMS endpoints on 996box...\n") results = [] for ep in CANDIDATE_ENDPOINTS: ep, status, body = await probe_one(box, ep) results.append((ep, status, body)) marker = "[!!! HIT !!!]" if status == 200 else ("[404]" if status == 404 else f"[{status}]") print(f" {marker:<14} {ep:<45} {body[:50]}") print() hits = [r for r in results if r[1] != 404 and r[1] != 0] if not hits: print("[!] No candidate matched. 996box SMS endpoint is not in our guess list.") print(" Need real intel — capture from browser DevTools (see below).") else: print(f"[OK] {len(hits)} candidate(s) returned non-404:") for ep, status, body in hits: print(f" {ep} status={status} body={body[:60]}") return 0 if __name__ == "__main__": sys.exit(asyncio.run(main()))