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