# -*- coding: utf-8 -*- """delete_all_roles.py —— 删除指定区账号下全部角色(循环: 拉列表→删last=1→重拉)。 用法: .venv/bin/python delete_all_roles.py --zone 14504561 -u longwu988 -p Longwu1988 [--dry-run] 协议: CS102 删角色(仅受理 last=1 当前选中角色), 523=成功/524=失败。 删后服务器将剩余角色置为新的选中(last=1), 重拉 SC520 确认后再删下一个。 """ import argparse import json import sys import time HERE = __file__.rsplit("/", 1)[0] sys.path.insert(0, HERE) ROOT = HERE.rsplit("/", 1)[0] sys.path.insert(0, ROOT) from apilot.host import Host, LOGIN_PORTS # noqa: E402 from reset_role import list_roles # noqa: E402 from combat_bot import log # noqa: E402 def delete_all(zone, user, pwd, dry_run=False): h = Host(zone, user, pwd, state_dir="/tmp/zone19_reset") h.http_login() h.boot_lua() deleted = [] # 外层循环: 每删一个角色重连重拉(服务器选中态会变化) for round_i in range(6): roles = None for port in LOGIN_PORTS: try: h.connect_login_gate(port) roles, sid = list_roles(h, zone, port) break except SystemExit as e: log(f" 端口{port}: {e}") h.nc.disconnect() except Exception as e: log(f" 端口{port}: {str(e)[:60]}") h.nc.disconnect() if roles is None: raise SystemExit("[!] 登录链失败") lst = roles.get("list") or [] log(f"[round {round_i}] 角色列表({len(lst)}): " f"{[(c.get('chr'), 'last=' + str(c.get('last'))) for c in lst]}") if not lst: log("[OK] 角色已全部删除") h.nc.disconnect() return deleted # 优先删 last=1; 若无 last 标志则删第一个(实测删第一个不受理时换下一个) target = next((c for c in lst if c.get("last") == 1), lst[0]) name = target.get("chr") if dry_run: log(f" [dry-run] 将删除 {name}(UserID={target['UserID']})") h.nc.disconnect() return [c.get("chr") for c in lst] h._tail = 2 ok = h._delete_role(target["UserID"], 15) log(f" 删角 {name}: {'523 成功' if ok else '失败/超时'}") h.nc.disconnect() if not ok: # 服务器不受理(非选中角色) — 把它标记后尝试列表中下一个 raise SystemExit(f"[!] 删角失败: {name}") deleted.append(name) time.sleep(1.0) raise SystemExit("[!] 超出最大删除轮数") def main(): ap = argparse.ArgumentParser() ap.add_argument("--zone", type=int, required=True) ap.add_argument("-u", "--user", default="longwu988") ap.add_argument("-p", "--password", default="Longwu1988") ap.add_argument("--dry-run", action="store_true") args = ap.parse_args() deleted = delete_all(args.zone, args.user, args.password, args.dry_run) log(f"[完成] 已删除角色: {json.dumps(deleted, ensure_ascii=False)}") if __name__ == "__main__": main()