# -*- coding: utf-8 -*- """ reset_role.py —— 删角重创(新手任务重置)后立即跑 quest_bot3 验证全流程。 用法: .venv/bin/python reset_role.py --zone 14492165 --name 斗士9906 \ -u z1098210167 -p yang535006 [--kill 2] 协议: CS102 删角色(LoginProxy:RequestDeleteRole, body=UserID, p3=0, tail 严格递增; 服务器只受理删 last=1 当前选中角色, 523=成功/524=失败)。 """ import argparse import json import random import subprocess import sys import time ROOT = "/Users/zlwu/work/00code/传奇" sys.path.insert(0, ROOT) HERE = __file__.rsplit("/", 1)[0] sys.path.insert(0, HERE) from encode6bitbuf_final import decode6, encode6 # noqa: E402 from combat_bot import log # noqa: E402 from apilot.host import Host # noqa: E402 GAME_ID = 206923 CHANNEL = "110585" def list_roles(h, zone, port): """走 2001→529→104→530→100→520 拿角色列表。""" h._send(2001, random.randint(1, 2**30), zone, port, 0, 0, h.build_2001_body(h.uid, h.jwt)) f529 = h._wait_for(529, 15)[0] if f529 is None: raise SystemExit("[!] 529 超时") key32 = decode6(f529.body).split(b"/")[0] h._send(104, 0, 0, 0, 0, 1, encode6(key32)) _, sid = h._recv_with_pre(530, 15) if not sid: raise SystemExit("[!] 530 超时") h.nc.set_sdata(sid) h._send(100, random.randint(1, 2**30), zone, port, sid, 2, f"{h.uid}/{sid}/{zone}/{CHANNEL}/{GAME_ID}/".encode() + key32) dl = time.time() + 15 while time.time() < dl: for f in h.pump(0.2): if f.msg_id == 520 and f.body: b = f.body if all(0x3C <= c <= 0x7B for c in b[:200]): b = decode6(b) try: return json.loads(b), sid except Exception: pass raise SystemExit("[!] 520 角色列表超时") def reset_role(zone, user, pwd, name): h = Host(zone, user, pwd, state_dir="/tmp/quest3_reset") h.http_login() h.boot_lua() roles = None for port in (8041, 8021, 8061, 8001): 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" 角色列表: {[c.get('chr') for c in lst]}") target = next((c for c in lst if c.get("chr") == name), None) if target is not None: h._tail = 2 ok = h._delete_role(target["UserID"], 15) log(f" 删角 {name}(last={target.get('last')}): {'523 成功' if ok else '失败/超时'}") if not ok: raise SystemExit("[!] 删角失败") h.nc.disconnect() # 新连接同名重创(新手任务重置) r = h.run_create_role(name=name) return r def main(): ap = argparse.ArgumentParser() ap.add_argument("--zone", type=int, default=14492165) ap.add_argument("--name", default="斗士9906") ap.add_argument("-u", "--user", default="z1098210167") ap.add_argument("-p", "--password", default="yang535006") ap.add_argument("--kill", type=int, default=2) args = ap.parse_args() log(f"[reset] 删角重创 {args.name} @区{args.zone}") r = reset_role(args.zone, args.user, args.password, args.name) log(f"[reset] 重创结果: name={r.get('role_name')} ticket={str(r.get('ticket'))[:24]}...") if r.get("role_name") != args.name: raise SystemExit(f"[!] 重创名字不符: {r.get('role_name')}") log("[reset] 完成 — 启动 quest_bot3") cmd = [f"{HERE}/.venv/bin/python", f"{HERE}/quest_bot3.py", "--zone", str(args.zone), "--name", args.name, "-u", args.user, "-p", args.password, "--kill", str(args.kill), "--minutes", "25"] raise SystemExit(subprocess.call(cmd)) if __name__ == "__main__": main()