probe_game_login.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. """Decode env.json (robust) and attempt cq2 TCP game login with live credentials.
  2. Strategy:
  3. 1. Read uid/token from env.json (account-level credentials, still alive)
  4. 2. Probe the game gateway for BOTH gameids (206923 = 玖扬复古176 from srvlist,
  5. 218620 = whatever was launched last)
  6. 3. Send CS 2001 login frame with the env.json credentials
  7. 4. See if the server replies with SC 529 (login key) — proving the TCP path works
  8. """
  9. import asyncio
  10. import base64
  11. import json
  12. import os
  13. import sys
  14. from pathlib import Path
  15. sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, "src"))
  16. from cq2_sdk.env_loader import load_env
  17. load_env()
  18. from cq2_sdk.transport.tcp import TcpClient
  19. if hasattr(sys.stdout, "reconfigure"):
  20. sys.stdout.reconfigure(encoding="utf-8", errors="replace")
  21. def decode_env() -> dict:
  22. p = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json")
  23. text = p.read_bytes().decode("utf-8", errors="replace")
  24. idx = text.find("eyJ")
  25. if idx < 0:
  26. idx = text.find("MeyJ")
  27. if idx < 0:
  28. return {}
  29. b64 = text[idx:].rstrip()
  30. padded = b64 + "=" * (-len(b64) % 4)
  31. dec = base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace")
  32. obj, _ = json.JSONDecoder().raw_decode(dec)
  33. return obj if isinstance(obj, dict) else {}
  34. async def probe(host: str, port: int) -> bool:
  35. try:
  36. r, w = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
  37. w.close()
  38. return True
  39. except Exception:
  40. return False
  41. async def try_login(host: str, port: int, uid: str, token: str, server_id: int, label: str) -> None:
  42. print(f"--- {label}: {host}:{port} serverId={server_id} ---")
  43. tcp = TcpClient(host, port)
  44. try:
  45. await tcp.connect()
  46. except Exception as e:
  47. print(f" connect failed: {e}")
  48. return
  49. try:
  50. # CS 2001: attach = "account/password/otpType/otpCode"
  51. attach = f"{uid}/{token}/1/0"
  52. await tcp.send(2001, recog=900000, param1=0, param2=server_id, param3=0, body=attach.encode())
  53. try:
  54. hdr, body = await tcp.recv(timeout=8.0)
  55. print(f" REPLY msg_id={hdr.msg_id} recog={hdr.recog}")
  56. print(f" body[:150]: {body[:150]!r}")
  57. if hdr.msg_id == 529:
  58. print(" >>> SUCCESS: SC 529 login key received!")
  59. elif hdr.msg_id == 503:
  60. print(" >>> 503 = auth failed (token expired/wrong format) — but TCP protocol WORKS")
  61. except asyncio.TimeoutError:
  62. print(" TIMEOUT: no reply (frame format or encryption mismatch)")
  63. finally:
  64. await tcp.close()
  65. async def main() -> None:
  66. env = decode_env()
  67. uid = str(env.get("uid", ""))
  68. token = str(env.get("token", ""))
  69. print(f"credentials: uid={uid} token=***REDACTED***(len={len(token)})")
  70. print()
  71. # Gateway candidates
  72. targets = [
  73. ("jycq-206923.dhsf.xqhuyu.com", 8001, 14414738, "玖扬复古176 (srvlist serverId)"),
  74. ("jycq-218620.dhsf.xqhuyu.com", 8001, 0, "last-launched game"),
  75. ]
  76. print("=== Port probe ===")
  77. for host, port, sid, label in targets:
  78. reachable = await probe(host, port)
  79. print(f" {host}:{port} {'OPEN' if reachable else 'CLOSED'} ({label})")
  80. print()
  81. print("=== TCP login attempts ===")
  82. for host, port, sid, label in targets:
  83. if await probe(host, port):
  84. await try_login(host, port, uid, token, sid, label)
  85. print()
  86. asyncio.run(main())