"""Retry TCP CS 2001 login with CORRECT params, exactly per decrypted LoginProxy.lua. Key corrections vs the failed attempt: 1. param3 = server port (8021), NOT the connect port (12000) 2. param1 = random(100000000, 2100000000) & 0xFFFF00FF (NetStamp fallback) 3. connect to proxyport (12000) — that part was already right 4. body = account/Encode6BitBuf(password)/Encode6BitBuf(channelID)/otpType/otpCode From LoginProxy.lua: sendStr = string.format("%s/%s/%s/%s/%s", account, pwdSession, encodechannelID, otpType, otpCode) recog = 900000 param2 = mainServerId or serverId param3 = serverPort (NOT proxyport!) """ import asyncio import base64 import json import os import random import sys from pathlib import Path sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, "src")) from cq2_sdk.env_loader import load_env load_env() from cq2_sdk.transport.framing import encode_frame, decode_frame from cq2_sdk.utils.encoding import encode6bit if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8", errors="replace") GATEWAY = "gfgame.dhsf.xqhuyu.com" PROXY_PORT = 12000 # connect here SERVER_PORT = 8021 # param3 = this SERVER_ID = 14414738 # user's server (霸业12服) CHANNEL = "110585" # 玖扬复古176 channel def get_creds() -> tuple[str, str]: text = Path(r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json").read_bytes().decode("utf-8", errors="replace") idx = text.find("eyJ") b64 = text[idx:].rstrip() padded = b64 + "=" * (-len(b64) % 4) obj, _ = json.JSONDecoder().raw_decode(base64.urlsafe_b64decode(padded).decode("utf-8", errors="replace")) return str(obj.get("uid", "")), str(obj.get("token", "")) def stamp_param1() -> int: """NetStamp fallback: bit._and(math.random(100000000,2100000000), 0xFFFF00FF).""" r = random.randint(100000000, 2100000000) return r & 0xFFFF00FF async def attempt(uid: str, token: str, sid: int, server_port: int, use_otp: str) -> None: print(f"--- attempt sid={sid} server_port={server_port} otp={use_otp!r} ---") # body per Lua: account / Encode6BitBuf(password) / Encode6BitBuf(channelID) / otpType / otpCode pwd_enc = encode6bit(token.encode()).decode("ascii") ch_enc = encode6bit(CHANNEL.encode()).decode("ascii") send_str = f"{uid}/{pwd_enc}/{ch_enc}/{use_otp}/0" param1 = stamp_param1() frame = encode_frame(2001, 900000, param1, sid, server_port, send_str.encode()) print(f"frame {len(frame)}B: msg=2001 recog=900000 p1={param1} p2={sid} p3={server_port}") print(f"body ({len(send_str)}): {uid}/{pwd_enc[:24]}.../{ch_enc[:12]}.../{use_otp}/0") reader, writer = await asyncio.wait_for(asyncio.open_connection(GATEWAY, PROXY_PORT), timeout=6) try: writer.write(frame) await writer.drain() data = await asyncio.wait_for(reader.read(4096), timeout=8) if not data: print("RESULT: server closed connection (0 bytes)") return print(f"RESULT: got {len(data)} bytes") print(f" hex[:80]: {data[:80].hex()}") try: hdr, body = decode_frame(data) print(f" *** PARSED msg_id={hdr.msg_id} recog={hdr.recog} p1={hdr.param1} p2={hdr.param2} p3={hdr.param3}") print(f" body: {body[:200]!r}") if hdr.msg_id == 529: print(" *** *** SC 529 LOGIN KEY — LOGIN WORKS! *** ***") except Exception as e: print(f" (not a plaintext 24B frame: {e})") finally: writer.close() try: await writer.wait_closed() except Exception: pass async def main() -> None: uid, token = get_creds() print(f"uid={uid} token_len={len(token)}") print(f"gateway={GATEWAY}:{PROXY_PORT} sid={SERVER_ID} server_port={SERVER_PORT}") print() # otpType variants: "0" (none), "1" for otp in ("0", "1"): await attempt(uid, token, SERVER_ID, SERVER_PORT, otp) print() await asyncio.sleep(1) asyncio.run(main())