| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- # -*- 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()
|