login_matrix.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """Systematic CS 2001 with ALL corrections:
  2. Fix matrix vs previous attempts:
  3. 1. otp tail = literal "1/0" (from LoginOtpPassWordProxy.lua)
  4. 2. param2 = main_serverid = the server's OWN sid (from getTodayOpen:
  5. 霸业12服 sid=14414738 has main_serverid=14414738 — NOT 14414736)
  6. 3. param3 = that server's port from srvlist
  7. 4. Connect to each DNS IP explicitly (proxy rotation may differ per IP)
  8. Also verifies our encode6bit against the real Lua Encode6BitBuf if found.
  9. """
  10. import asyncio
  11. import base64
  12. import json
  13. import random
  14. import struct
  15. import sys
  16. from pathlib import Path
  17. sys.path.insert(0, "src")
  18. from cq2_sdk.utils.encoding import encode6bit
  19. raw = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json").read_bytes()
  20. text = raw.decode("utf-8", errors="replace")
  21. idx = text.find("eyJ")
  22. b64 = text[idx:].rstrip()
  23. padded = b64 + "=" * ((-len(b64)) % 4)
  24. env = json.loads(base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace"))
  25. uid = str(env["uid"])
  26. token = env["token"]
  27. channel = env.get("channel", "110585")
  28. pwd_enc = encode6bit(token.encode()).decode("ascii")
  29. ch_enc = encode6bit(channel.encode()).decode("ascii")
  30. IPS = ["47.118.169.147", "47.118.169.153", "47.118.172.233"]
  31. # (sid, port, label) — from cached srvlist (state=1 open servers)
  32. TARGETS = [
  33. (14414738, 8021, "霸业12服 main=self"),
  34. (14414739, 8061, "霸业13服 main=self"),
  35. (14414741, 8061, "霸业15服(user env sid)"),
  36. ]
  37. async def attempt(ip: str, sid: int, port: int, label: str) -> None:
  38. body = f"{uid}/{pwd_enc}/{ch_enc}/1/0"
  39. p1 = random.randint(100_000_000, 2_100_000_000) & 0xFFFF00FF
  40. frame = struct.pack("<6i", 2001, 900000, p1, sid, port, len(body)) + body.encode()
  41. try:
  42. r, w = await asyncio.wait_for(asyncio.open_connection(ip, 12000), timeout=5)
  43. except Exception as e:
  44. print(f" {ip} {label}: connect {type(e).__name__}")
  45. return
  46. try:
  47. w.write(frame)
  48. await w.drain()
  49. total = b""
  50. import time
  51. t0 = time.time()
  52. while time.time() - t0 < 5:
  53. try:
  54. chunk = await asyncio.wait_for(r.readexactly(6), timeout=1.5)
  55. total += chunk
  56. if len(total) >= 24:
  57. mid, recog, p1r, p2r, p3r, blen = struct.unpack("<6i", total[:24])
  58. print(f" {ip} {label}: *** FRAME msg_id={mid} recog={recog} p2={p2r} blen={blen} ***")
  59. if 0 < blen < 4096:
  60. try:
  61. rest = await asyncio.wait_for(r.readexactly(blen), timeout=3)
  62. print(f" body: {rest[:200]!r}")
  63. except Exception:
  64. pass
  65. return
  66. except asyncio.IncompleteReadError:
  67. break
  68. except (asyncio.TimeoutError, TimeoutError):
  69. if total:
  70. break
  71. if total:
  72. print(f" {ip} {label}: {len(total)}B hex={total.hex()}")
  73. else:
  74. print(f" {ip} {label}: closed 0B")
  75. finally:
  76. w.close()
  77. try:
  78. await w.wait_closed()
  79. except Exception:
  80. pass
  81. async def main():
  82. print(f"uid={uid} channel={channel} tail=/1/0 p2=sid(self) p3=port")
  83. print()
  84. for sid, port, label in TARGETS:
  85. for ip in IPS[:2]: # try 2 IPs per target to limit time
  86. await attempt(ip, sid, port, label)
  87. await asyncio.sleep(0.4)
  88. print()
  89. asyncio.run(main())