reset_role_lib.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # -*- coding: utf-8 -*-
  2. """
  3. reset_role_lib.py —— 删角工具(复用 apilot.host 的删角链, 独立于 quest_bot3)。
  4. """
  5. import json
  6. import random
  7. import sys
  8. import time
  9. HERE = __file__.rsplit("/", 1)[0]
  10. ROOT = "/Users/zlwu/work/00code/传奇"
  11. sys.path.insert(0, ROOT)
  12. sys.path.insert(0, HERE)
  13. from encode6bitbuf_final import decode6, encode6 # noqa: E402
  14. from combat_bot import log # noqa: E402
  15. from apilot.host import Host # noqa: E402
  16. GAME_ID = 206923
  17. CHANNEL = "110585"
  18. def _list_roles(h, zone, port):
  19. h._send(2001, random.randint(1, 2**30), zone, port, 0, 0,
  20. h.build_2001_body(h.uid, h.jwt))
  21. f529 = h._wait_for(529, 15)[0]
  22. if f529 is None:
  23. raise RuntimeError("529 超时")
  24. key32 = decode6(f529.body).split(b"/")[0]
  25. h._send(104, 0, 0, 0, 0, 1, encode6(key32))
  26. _, sid = h._recv_with_pre(530, 15)
  27. if not sid:
  28. raise RuntimeError("530 超时")
  29. h.nc.set_sdata(sid)
  30. h._send(100, random.randint(1, 2**30), zone, port, sid, 2,
  31. f"{h.uid}/{sid}/{zone}/{CHANNEL}/{GAME_ID}/".encode() + key32)
  32. dl = time.time() + 15
  33. while time.time() < dl:
  34. for f in h.pump(0.2):
  35. if f.msg_id == 520 and f.body:
  36. b = f.body
  37. if all(0x3C <= c <= 0x7B for c in b[:200]):
  38. b = decode6(b)
  39. try:
  40. return json.loads(b), sid
  41. except Exception:
  42. pass
  43. raise RuntimeError("520 角色列表超时")
  44. def delete_roles(zone, user, pwd, names):
  45. h = Host(zone, user, pwd, state_dir="/tmp/quest3_reset")
  46. h.http_login()
  47. h.boot_lua()
  48. for port in (8041, 8021, 8061, 8001):
  49. try:
  50. h.connect_login_gate(port)
  51. roles, sid = _list_roles(h, zone, port)
  52. break
  53. except Exception as e:
  54. log(f" 端口{port}: {str(e)[:60]}")
  55. h.nc.disconnect()
  56. else:
  57. raise SystemExit("[!] 登录链失败, 无法删角")
  58. lst = roles.get("list") or []
  59. log(f" 当前角色: {[c.get('chr') for c in lst]}")
  60. for c in lst:
  61. nm = c.get("chr")
  62. if nm in names:
  63. h._tail = 2
  64. ok = h._delete_role(c["UserID"], 15)
  65. log(f" 删角 {nm}(last={c.get('last')}): {'✓ 523' if ok else '✗ 失败'}")
  66. h.nc.disconnect()