| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- """Decrypt the game serverlist using XXTEA with the game_signkey from modlist.
- modlist says isEncrypt=1 and provides game_signkey per sub-module:
- 玖扬复古176 (206923): game_signkey = 47f67f306cbdffa3a6606292c1a3fa01
- Per cq2-00 docs, client Lua is XXTEA-encrypted with key=34UFXMgtkz.
- The serverlist is likely XXTEA with game_signkey (hex-decoded or raw).
- Try multiple key derivations.
- """
- import asyncio
- import base64
- import sys
- import httpx
- import xxtea
- if hasattr(sys.stdout, "reconfigure"):
- sys.stdout.reconfigure(encoding="utf-8", errors="replace")
- SIGNKEY_HEX = "47f67f306cbdffa3a6606292c1a3fa01"
- LUA_KEY = "34UFXMgtkz"
- async def main() -> None:
- url = "https://list-box.dhsf.xqhuyu.com/serverlist/110585/serverlist.txt"
- async with httpx.AsyncClient(timeout=15, follow_redirects=True) as c:
- r = await c.get(url)
- raw = r.content
- print(f"downloaded {len(raw)} bytes")
- key_candidates = [
- ("signkey raw ascii (32B)", SIGNKEY_HEX.encode()),
- ("signkey hex-decoded (16B)", bytes.fromhex(SIGNKEY_HEX)),
- ("lua key 34UFXMgtkz", LUA_KEY.encode()),
- ("lua key padded to 16", LUA_KEY.encode().ljust(16, b"\0")),
- ("signkey first16", SIGNKEY_HEX[:16].encode()),
- ]
- for label, key in key_candidates:
- try:
- dec = xxtea.decrypt(raw, key)
- if not dec:
- print(f"[{label}] -> empty result")
- continue
- # Check if it looks like text/JSON
- head = dec[:60]
- printable = sum(1 for b in dec[:200] if 32 <= b < 127 or b in (9, 10, 13))
- ratio = printable / min(len(dec), 200)
- print(f"[{label}] -> {len(dec)} bytes, printable={ratio:.0%}, head={head[:50]!r}")
- if ratio > 0.85:
- print(" *** LOOKS LIKE TEXT! First 500 chars:")
- try:
- txt = dec.decode("utf-8", errors="replace")
- print(txt[:500])
- except Exception:
- pass
- except Exception as e:
- print(f"[{label}] -> error: {type(e).__name__}: {str(e)[:80]}")
- asyncio.run(main())
|