probe_real_server.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """Look up sid 14403981 (the server the USER ACTUALLY selected in the SAZ
  2. capture — session 753 EnterGameClient body) in the cached srvlist, then
  3. send CS 2001 with THAT server's exact main_serverid/port.
  4. All previous probes used 霸业-series servers (14414736-41) from getTodayOpen,
  5. but the task target is 玖扬复古176 (group tag 1000514, main 14301060) —
  6. a completely different group!
  7. """
  8. import asyncio
  9. import base64
  10. import json
  11. import random
  12. import struct
  13. import sys
  14. from pathlib import Path
  15. sys.path.insert(0, "src")
  16. from cq2_sdk.utils.encoding import encode6bit
  17. raw = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json").read_bytes()
  18. text = raw.decode("utf-8", errors="replace")
  19. idx = text.find("eyJ")
  20. b64 = text[idx:].rstrip()
  21. padded = b64 + "=" * ((-len(b64)) % 4)
  22. env = json.loads(base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace"))
  23. uid = str(env["uid"])
  24. pwd_enc = encode6bit(env["token"].encode()).decode("ascii")
  25. ch_enc = encode6bit(env.get("channel", "110585").encode()).decode("ascii")
  26. BODY = f"{uid}/{pwd_enc}/{ch_enc}/1/0"
  27. srv = json.loads(
  28. Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\cq\cache_206923\ResServerlist.txt_206923").read_text(encoding="utf-8")
  29. )
  30. # 1. Find the user's actual server 14403981
  31. # serverData is a LIST of server dicts (fields d/p/s/u/m/n/t/g/w/c)
  32. target = None
  33. target_group = None
  34. groups = {g["tag"]: g["name"] for g in srv.get("serverGroup", [])}
  35. for s in srv.get("serverData", []):
  36. if str(s.get("d")) == "14403981":
  37. target = s
  38. target_group = groups.get(s.get("t"))
  39. break
  40. print("=== user's ACTUAL server from SAZ (14403981) ===")
  41. if target:
  42. print(f"group: {target_group} (tag={target.get('t')})")
  43. print(f"sid={target.get('d')} port={target.get('p')} proxyport={target.get('x')} state={target.get('s')}")
  44. print(f"host={target.get('i')}")
  45. print(f"all fields: {json.dumps(target, ensure_ascii=False)}")
  46. else:
  47. print("NOT FOUND in cached srvlist — trying live srvlist")
  48. # 2. Also list a few 玖扬 group servers (t=1000514) with state=1
  49. print()
  50. print("=== 玖扬复古176 (t=1000514) open servers (first 6) ===")
  51. jiuyang = [s for s in srv.get("serverData", []) if str(s.get("t")) == "1000514" and str(s.get("s")) == "1"]
  52. for s in jiuyang[:6]:
  53. print(f" sid={s.get('d')} port={s.get('p')} proxy={s.get('x','')} name={s.get('n','')}")
  54. # 3. Probe CS 2001 against the user's actual server + a couple 玖扬 servers
  55. IPS = ["47.118.169.147", "47.118.169.153", "47.118.172.233"]
  56. async def probe(sid: int, port: int, main_sid: int, label: str, ip: str = IPS[1]) -> None:
  57. p1 = random.randint(100_000_000, 2_100_000_000) & 0xFFFF00FF
  58. frame = (
  59. struct.pack("<6i", 2001, 900000, p1, main_sid, port, len(BODY.encode()))
  60. + BODY.encode()
  61. )
  62. try:
  63. r, w = await asyncio.wait_for(asyncio.open_connection(ip, 12000), timeout=5)
  64. except Exception as e:
  65. print(f" {label}: connect {type(e).__name__}")
  66. return
  67. try:
  68. w.write(frame)
  69. await w.drain()
  70. total = b""
  71. t0 = asyncio.get_event_loop().time()
  72. while asyncio.get_event_loop().time() - t0 < 4:
  73. try:
  74. chunk = await asyncio.wait_for(r.read(4096), timeout=1.5)
  75. if not chunk:
  76. break
  77. total += chunk
  78. if len(total) >= 6:
  79. break
  80. except asyncio.TimeoutError:
  81. if total:
  82. break
  83. if total:
  84. same = total == b"\x00" * 6
  85. note = "" if same else " *** DIFFERENT REPLY — PROGRESS! ***"
  86. print(f" {label}: {len(total)}B {total.hex()[:40]}{note}")
  87. else:
  88. print(f" {label}: no reply")
  89. finally:
  90. w.close()
  91. try:
  92. await w.wait_closed()
  93. except Exception:
  94. pass
  95. async def main():
  96. print()
  97. print("=== CS 2001 probes (corrected: user's real server + 玖扬 opens) ===")
  98. if target:
  99. main_sid = int(target.get("m") or target.get("d"))
  100. port = int(target.get("p"))
  101. await probe(int(target["d"]), port, main_sid, f"user-server 14403981 (main={main_sid}, port={port})")
  102. await asyncio.sleep(0.5)
  103. for s in jiuyang[:3]:
  104. sid = int(s["d"])
  105. main_sid = int(s.get("m") or sid)
  106. port = int(s["p"])
  107. await probe(sid, port, main_sid, f"玖扬 sid={sid} (main={main_sid}, port={port})")
  108. await asyncio.sleep(0.5)
  109. # also the group main 14301060
  110. await probe(14301060, int(next((x["p"] for x in srv["serverData"] if str(x.get("d")) == "14301060"), 8001)), 14301060, "玖扬战区 main=14301060")
  111. asyncio.run(main())