run_zone19_create_kill.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # -*- coding: utf-8 -*-
  2. """
  3. run_zone19_create_kill.py —— 一键脚本: 登录 → 逐鹿19区创角 → 进游戏 → 开喝药 → 到比奇大城 → 杀3怪
  4. 用法:
  5. .venv/bin/python run_zone19_create_kill.py [--name 角色名] [--kill 3] [--minutes 3]
  6. """
  7. import argparse
  8. import json
  9. import os
  10. import random
  11. import socket
  12. import sys
  13. import threading
  14. import time
  15. import requests as rq
  16. import urllib3
  17. urllib3.disable_warnings()
  18. HERE = os.path.dirname(os.path.abspath(__file__))
  19. sys.path.insert(0, HERE)
  20. from encode6bitbuf_final import encode6, decode6 # noqa: E402
  21. import login_996pc as L # noqa: E402
  22. import cq2_pure_enter as P # noqa: E402
  23. from combat_bot import CombatBot, send_init_frames, DIRS, log, pack_point, lo16, hi16, proto_map_name, enter_game_gate_v2 # noqa: E402
  24. from mir_map import load as map_load # noqa: E402
  25. from quest_bot3 import PushBot, run_fsm # noqa: E402
  26. # 逐鹿19区 server id (serverlist.json 中逐鹿19区)
  27. ZONE_19 = 14504561
  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, default=ZONE_19)
  33. ap.add_argument("--name", default=None)
  34. ap.add_argument("--port", type=int, default=0)
  35. ap.add_argument("--kill", type=int, default=3)
  36. ap.add_argument("--minutes", type=float, default=5.0)
  37. args = ap.parse_args()
  38. # 1. 登录
  39. print(f"[1/6] 登录 {args.user} ...", flush=True)
  40. s = rq.Session()
  41. j, _ = L.do_login(s, args.user, args.password)
  42. if j.get("code") != 200:
  43. raise SystemExit(f"[!] 登录失败: {j.get('msg')}")
  44. jwt = j["data"]["token"]
  45. uid = (j["data"].get("userInfo") or {}).get("id") or P.UID
  46. print(f" uid={uid}", flush=True)
  47. # 2. 随机名字
  48. name = args.name or ("萌新" + str(random.randint(1000, 9999)))
  49. print(f"[2/6] 角色名: {name}", flush=True)
  50. # 3. EnterGameClient (zone)
  51. print(f"[3/6] EnterGameClient(zone={args.zone})...", flush=True)
  52. r = P.enter_game(s, jwt, args.zone)
  53. if r.get("code") != 200:
  54. raise SystemExit(f"[!] 进区失败: {r.get('msg')}")
  55. # 4. 登录服握手+创角
  56. print(f"[4/6] 登录服握手+创角...", flush=True)
  57. ports = [args.port] if args.port else [8041, 8021, 8061, 8001]
  58. key32 = sid = tkey = game_port = None
  59. got_name = None
  60. for pt in ports:
  61. try:
  62. key32, sid, rname, tkey, game_port = P.login_gate(
  63. args.zone, jwt, name, pt, uid)
  64. if key32:
  65. got_name = rname
  66. print(f" 登录端口={pt} 角色={rname} 游戏端口={game_port}", flush=True)
  67. break
  68. except SystemExit as e:
  69. print(f" 端口{pt}失败: {e}", flush=True)
  70. except Exception as e:
  71. print(f" 端口{pt}失败: {str(e)[:80]}", flush=True)
  72. if not key32:
  73. raise SystemExit("[!] 所有候选端口失败")
  74. name = got_name or name
  75. # 5. 用 v2 协议连游戏服(避免 SC658 不下发)
  76. print(f"[5/6] 连接游戏服 (v2)...", flush=True)
  77. g = enter_game_gate_v2(args.zone, name, tkey, sid, game_port, uid)
  78. bot = PushBot(g, sid, name)
  79. P.heartbeat_loop(g, sid, bot.lock)
  80. # 等 SC658
  81. t0 = time.time()
  82. while time.time() - t0 < 12:
  83. bot.pump(0.3)
  84. if 658 in bot.frame_log:
  85. break
  86. if 658 not in bot.frame_log:
  87. g.close()
  88. raise SystemExit("[!] SC658 超时, 世界未初始化")
  89. print(f" SC658 ✓ ({time.time()-t0:.1f}s)", flush=True)
  90. # 6. 发送 17 帧初始化
  91. send_init_frames(bot, uid)
  92. for _ in range(24):
  93. bot.pump(0.5)
  94. if bot.me["id"] and bot.me.get("mapname"):
  95. break
  96. log(f"进世界: map={bot.me.get('mapname')} @{bot.me['x']},{bot.me['y']} uid={bot.me.get('uid')}")
  97. # 7. 跑 run_fsm — 内部会触发 喝药/CS3031/renwu_mov→等待地图→NPC→比奇大城→杀怪
  98. kills = run_fsm(bot, g, args.kill, args.minutes)
  99. log(f"[完成] kills={kills}")
  100. return kills
  101. if __name__ == "__main__":
  102. main()