# -*- coding: utf-8 -*- """ run_create_role_and_autoheal.py —— 最小链路: 登录 → 选区 → 创角 → 进游戏 → 开喝药 基于 传奇_bak 实验工程已验证模块组装 (cq2_pure_enter + login_996pc) 用法: .venv-mac/bin/python run_create_role_and_autoheal.py --zone <区ID> [--name 角色名] [--port 8041] 端口规则: 8001/8021/8041/8061 轮询; 游戏端口=登录端口+2 (SC525自动下发) """ import argparse import json import random import socket import struct import sys import time import threading import os import requests as rq import urllib3 urllib3.disable_warnings() HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) from encode6bitbuf_final import encode6, decode6 # noqa: E402 import login_996pc as L # noqa: E402 import cq2_pure_enter as P # noqa: E402 def log(m): print(f"[{time.strftime('%H:%M:%S')}] {m}", flush=True) def main(): ap = argparse.ArgumentParser() ap.add_argument("-u", "--user", default="longwu988") ap.add_argument("-p", "--password", default="Longwu1988") ap.add_argument("--zone", type=int, required=True) ap.add_argument("--port", type=int, default=0, help="0=自动轮询8001/8021/8041/8061") ap.add_argument("--name", default=None) args = ap.parse_args() name = args.name or ("萌新" + str(random.randint(1000, 9999))) # ---------- 1. HTTP登录(极验滑块自动) ---------- log("[1/6] HTTP登录...") s = rq.Session() j, _ = L.do_login(s, args.user, args.password) if j.get("code") != 200: raise SystemExit(f"[!] 登录失败: {j.get('msg')}") jwt = j["data"]["token"] uid = (j["data"].get("userInfo") or {}).get("id") or P.UID log(f" uid={uid}") # ---------- 2. EnterGameClient(平台记录) ---------- log("[2/6] EnterGameClient...") r = P.enter_game(s, jwt, args.zone) if r.get("code") != 200: raise SystemExit(f"[!] 进区失败: {r.get('msg')}") # ---------- 3. 登录服: 2001→529→104→530→100→520/101→521→103→525 ---------- log("[3/6] 登录服握手+创角...") ports = [args.port] if args.port else [8041, 8021, 8061, 8001] key32 = sid = tkey = game_port = None got_name = None for pt in ports: try: key32, sid, rname, tkey, game_port = P.login_gate( args.zone, jwt, name, pt, uid) if key32: got_name = rname log(f" 登录端口={pt} 角色票据OK 游戏端口={game_port}") break except SystemExit as e: # 529超时/无角色等以 SystemExit 抛出;端口轮询语义下换下一端口重试 log(f" 端口{pt}失败: {e}") except Exception as e: log(f" 端口{pt}失败: {str(e)[:80]}") if not key32: raise SystemExit("[!] 所有候选端口失败") name = got_name or name # ---------- 4. 连游戏服 + 17帧初始化 ---------- log("[4/6] 连接游戏服...") g = P.enter_game_gate(args.zone, name, tkey, sid, game_port, uid) time.sleep(2) log("[5/6] 发送17帧初始化序列...") P.send_init_sequence(g, sid, uid) log(" 初始化完成") # ---------- 6. 开喝药(先于心跳执行,避免socket并发写) ---------- log("[6/6] 开启喝药保护...") state = P.enable_auto_heal(g, sid, want_on=True) log(f" 喝药状态: {state}") # ---------- 7. 心跳保活(喝药完成后启动,延长会话) ---------- lock = threading.Lock() P.heartbeat_loop(g, sid, lock) log(" 心跳已启动,保持60秒在线验证...") time.sleep(60) g.close() log(f"[完成] 区={args.zone} 角色={name} 喝药={state}") if __name__ == "__main__": main()