probe_gateway.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """Find 玖扬复古176 group servers (t=1000514) and attempt TCP login to the
  2. real game gateway: gfgame.dhsf.xqhuyu.com.
  3. Field map (decoded from cached serverlist):
  4. d = serverId, p = port, s = state(1=open), t = group tag,
  5. i = gateway host (optional, default gfgame.dhsf.xqhuyu.com),
  6. x = alt port, n = server name, u = version
  7. """
  8. import asyncio
  9. import base64
  10. import json
  11. import os
  12. import sys
  13. from pathlib import Path
  14. sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, "src"))
  15. from cq2_sdk.env_loader import load_env
  16. load_env()
  17. from cq2_sdk.transport.tcp import TcpClient
  18. if hasattr(sys.stdout, "reconfigure"):
  19. sys.stdout.reconfigure(encoding="utf-8", errors="replace")
  20. SRVLIST = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\cq\cache_206923\ResServerlist.txt_206923")
  21. DEFAULT_HOST = "gfgame.dhsf.xqhuyu.com"
  22. def get_creds() -> tuple[str, str]:
  23. env_p = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json")
  24. text = env_p.read_bytes().decode("utf-8", errors="replace")
  25. idx = text.find("eyJ")
  26. b64 = text[idx:].rstrip()
  27. padded = b64 + "=" * (-len(b64) % 4)
  28. obj, _ = json.JSONDecoder().raw_decode(base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace"))
  29. return str(obj.get("uid", "")), str(obj.get("token", ""))
  30. async def probe(host: str, port: int) -> bool:
  31. try:
  32. r, w = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
  33. w.close()
  34. return True
  35. except Exception:
  36. return False
  37. async def try_login(host: str, port: int, sid: int, uid: str, token: str, label: str) -> None:
  38. print(f"--- {label}: {host}:{port} sid={sid} ---")
  39. tcp = TcpClient(host, port)
  40. try:
  41. await tcp.connect()
  42. except Exception as e:
  43. print(f" connect failed: {type(e).__name__}: {e}")
  44. return
  45. try:
  46. attach = f"{uid}/{token}/1/0"
  47. await tcp.send(2001, recog=900000, param1=0, param2=sid, param3=0, body=attach.encode())
  48. try:
  49. hdr, body = await tcp.recv(timeout=8.0)
  50. print(f" REPLY msg_id={hdr.msg_id} recog={hdr.recog} p2={hdr.param2} p3={hdr.param3}")
  51. print(f" body[:200]: {body[:200]!r}")
  52. if hdr.msg_id == 529:
  53. print(" >>> SC 529 LOGIN KEY — TCP LOGIN WORKS!!!")
  54. elif hdr.msg_id == 503:
  55. print(" >>> 503 auth failed — but protocol/framing is CORRECT (server understood us)")
  56. else:
  57. print(f" >>> unexpected reply (msg {hdr.msg_id}) — framing may be off")
  58. except asyncio.TimeoutError:
  59. print(" TIMEOUT — no reply")
  60. finally:
  61. await tcp.close()
  62. async def main() -> None:
  63. data = json.loads(SRVLIST.read_text(encoding="utf-8"))
  64. servers = data["serverData"]
  65. # 1. 玖扬复古176 group (t=1000514)
  66. jiuyang = [s for s in servers if str(s.get("t")) == "1000514"]
  67. print(f"玖扬复古176 group servers: {len(jiuyang)}")
  68. for s in jiuyang[:8]:
  69. host = s.get("i") or DEFAULT_HOST
  70. print(f" sid={s.get('d')} port={s.get('p')} state={s.get('s')} host={host} name={s.get('n')}")
  71. # 2. User's last server
  72. mine = [s for s in servers if str(s.get("d")) == "14414738"]
  73. if mine:
  74. s = mine[0]
  75. host = s.get("i") or DEFAULT_HOST
  76. print(f"\nuser's last server: sid={s['d']} port={s['p']} state={s['s']} host={host}")
  77. # 3. creds
  78. uid, token = get_creds()
  79. print(f"creds: uid={uid} token=***(len={len(token)})")
  80. print()
  81. # 4. probe gateway ports
  82. print("=== probe gfgame.dhsf.xqhuyu.com ===")
  83. for port in (8001, 8021, 8041, 8061, 8081, 12000):
  84. ok = await probe(DEFAULT_HOST, port)
  85. print(f" :{port} {'OPEN' if ok else 'closed'}")
  86. print()
  87. # 5. TCP login attempts — user's server + first open 玖扬 server
  88. print("=== TCP login attempts ===")
  89. if mine:
  90. s = mine[0]
  91. host = s.get("i") or DEFAULT_HOST
  92. await try_login(host, int(s["p"]), int(s["d"]), uid, token, "user's server 14414738")
  93. print()
  94. for s in jiuyang:
  95. if str(s.get("s")) == "1":
  96. host = s.get("i") or DEFAULT_HOST
  97. await try_login(host, int(s["p"]), int(s["d"]), uid, token, f"玖扬 {s.get('n')}")
  98. break
  99. asyncio.run(main())