run_create_role_and_autoheal.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # -*- coding: utf-8 -*-
  2. """
  3. run_create_role_and_autoheal.py —— 最小链路: 登录 → 选区 → 创角 → 进游戏 → 开喝药
  4. 基于 传奇_bak 实验工程已验证模块组装 (cq2_pure_enter + login_996pc)
  5. 用法:
  6. .venv-mac/bin/python run_create_role_and_autoheal.py --zone <区ID> [--name 角色名] [--port 8041]
  7. 端口规则: 8001/8021/8041/8061 轮询; 游戏端口=登录端口+2 (SC525自动下发)
  8. """
  9. import argparse
  10. import json
  11. import random
  12. import socket
  13. import struct
  14. import sys
  15. import time
  16. import threading
  17. import os
  18. import requests as rq
  19. import urllib3
  20. urllib3.disable_warnings()
  21. HERE = os.path.dirname(os.path.abspath(__file__))
  22. sys.path.insert(0, HERE)
  23. from encode6bitbuf_final import encode6, decode6 # noqa: E402
  24. import login_996pc as L # noqa: E402
  25. import cq2_pure_enter as P # noqa: E402
  26. def log(m):
  27. print(f"[{time.strftime('%H:%M:%S')}] {m}", flush=True)
  28. def main():
  29. ap = argparse.ArgumentParser()
  30. ap.add_argument("-u", "--user", default="longwu988")
  31. ap.add_argument("-p", "--password", default="Longwu1988")
  32. ap.add_argument("--zone", type=int, required=True)
  33. ap.add_argument("--port", type=int, default=0, help="0=自动轮询8001/8021/8041/8061")
  34. ap.add_argument("--name", default=None)
  35. args = ap.parse_args()
  36. name = args.name or ("萌新" + str(random.randint(1000, 9999)))
  37. # ---------- 1. HTTP登录(极验滑块自动) ----------
  38. log("[1/6] HTTP登录...")
  39. s = rq.Session()
  40. j, _ = L.do_login(s, args.user, args.password)
  41. if j.get("code") != 200:
  42. raise SystemExit(f"[!] 登录失败: {j.get('msg')}")
  43. jwt = j["data"]["token"]
  44. uid = (j["data"].get("userInfo") or {}).get("id") or P.UID
  45. log(f" uid={uid}")
  46. # ---------- 2. EnterGameClient(平台记录) ----------
  47. log("[2/6] EnterGameClient...")
  48. r = P.enter_game(s, jwt, args.zone)
  49. if r.get("code") != 200:
  50. raise SystemExit(f"[!] 进区失败: {r.get('msg')}")
  51. # ---------- 3. 登录服: 2001→529→104→530→100→520/101→521→103→525 ----------
  52. log("[3/6] 登录服握手+创角...")
  53. ports = [args.port] if args.port else [8041, 8021, 8061, 8001]
  54. key32 = sid = tkey = game_port = None
  55. got_name = None
  56. for pt in ports:
  57. try:
  58. key32, sid, rname, tkey, game_port = P.login_gate(
  59. args.zone, jwt, name, pt, uid)
  60. if key32:
  61. got_name = rname
  62. log(f" 登录端口={pt} 角色票据OK 游戏端口={game_port}")
  63. break
  64. except SystemExit as e:
  65. # 529超时/无角色等以 SystemExit 抛出;端口轮询语义下换下一端口重试
  66. log(f" 端口{pt}失败: {e}")
  67. except Exception as e:
  68. log(f" 端口{pt}失败: {str(e)[:80]}")
  69. if not key32:
  70. raise SystemExit("[!] 所有候选端口失败")
  71. name = got_name or name
  72. # ---------- 4. 连游戏服 + 17帧初始化 ----------
  73. log("[4/6] 连接游戏服...")
  74. g = P.enter_game_gate(args.zone, name, tkey, sid, game_port, uid)
  75. time.sleep(2)
  76. log("[5/6] 发送17帧初始化序列...")
  77. P.send_init_sequence(g, sid, uid)
  78. log(" 初始化完成")
  79. # ---------- 6. 开喝药(先于心跳执行,避免socket并发写) ----------
  80. log("[6/6] 开启喝药保护...")
  81. state = P.enable_auto_heal(g, sid, want_on=True)
  82. log(f" 喝药状态: {state}")
  83. # ---------- 7. 心跳保活(喝药完成后启动,延长会话) ----------
  84. lock = threading.Lock()
  85. P.heartbeat_loop(g, sid, lock)
  86. log(" 心跳已启动,保持60秒在线验证...")
  87. time.sleep(60)
  88. g.close()
  89. log(f"[完成] 区={args.zone} 角色={name} 喝药={state}")
  90. if __name__ == "__main__":
  91. main()