| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- # -*- coding: utf-8 -*-
- """
- diag_heal.py —— 诊断喝药开关: 登录 → 连入角色 → 发送多种命令 → 打印所有返回帧
- """
- import argparse, os, sys, socket, struct, time, threading, re
- import requests as rq
- import urllib3
- urllib3.disable_warnings()
- HERE = os.path.dirname(os.path.abspath(__file__))
- sys.path.insert(0, HERE)
- import login_996pc as L
- import cq2_pure_enter as P
- from combat_bot import enter_game_gate_v2, log
- from encode6bitbuf_final import encode6, decode6
- ZONE_19 = 14504561
- def send_action(sock, sid, act, index, tail, body_extra=""):
- body = ('{"index":%d,"act":"%s","subid":1}' % (index, act)).encode() if not body_extra else body_extra.encode()
- sock.sendall(encode6(struct.pack("<9i", 0, 3199, 0, 0, 0, sid, 0, len(body), tail)) + body)
- log(f" → 已发 CS3199: act={act!r} index={index} tail={tail}")
- def recv_all(sock, wait=4.0):
- """收 wait 秒内所有帧并打印。"""
- t0 = time.time()
- sock.settimeout(2.0)
- full = b""
- while time.time() - t0 < wait:
- try:
- d = sock.recv(65536)
- if not d: break
- full += d
- except (socket.timeout, OSError):
- continue
- # 解析
- pos = 0
- frames = []
- while pos + 48 <= len(full):
- try:
- h = struct.unpack("<9i", decode6(full[pos:pos+48]))
- except Exception:
- pos += 1; continue
- blen = h[7]
- if blen < 0 or blen > 200000 or pos + 48 + blen > len(full): break
- body = full[pos+48:pos+48+blen]
- frames.append((h[1], body[:200])) # (mid, body预览)
- pos += 48 + blen
- return frames
- 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, default=ZONE_19)
- ap.add_argument("--name", default="萌新4567")
- args = ap.parse_args()
- log(f"[1] 登录 {args.user} ...")
- s = rq.Session()
- j, _ = L.do_login(s, args.user, args.password)
- if j.get("code") != 200: raise SystemExit("登录失败")
- jwt = j["data"]["token"]
- uid = j["data"]["userInfo"]["id"]
- log(f" uid={uid}")
- log(f"[2] EnterGameClient(zone={args.zone}) ...")
- P.enter_game(s, jwt, args.zone)
- log(f"[3] 登录服握手...")
- key32 = sid = tkey = game_port = None
- for pt in [8061, 8041, 8021, 8001]:
- try:
- key32, sid, rname, tkey, game_port = P.login_gate(args.zone, jwt, args.name, pt, uid)
- if key32:
- log(f" 端口={pt} 角色={rname} 游戏端口={game_port}")
- break
- except Exception:
- continue
- if not key32: raise SystemExit("登录失败")
- log(f"[4] 连游戏服 (v2)...")
- g = enter_game_gate_v2(args.zone, rname, tkey, sid, game_port, uid)
- P.heartbeat_loop(g, sid, threading.Lock())
- log(f"[5] 等 SC658 (世界初始化)...")
- t0 = time.time()
- while time.time() - t0 < 10:
- try:
- d = g.recv(65536)
- if not d: break
- if b"SC658" in d or any(b"\x9a\x02" in d for b in [d]): # 658 hex = 0x292
- pass
- # 简单判断: 0x9a02 在 p3 不对, 改为按消息号查
- pos = 0
- while pos + 48 <= len(d):
- try:
- h = struct.unpack("<9i", decode6(d[pos:pos+48]))
- except: break
- if h[1] == 658:
- log(f" SC658 ✓ ({time.time()-t0:.1f}s)")
- break
- blen = h[7]
- if blen < 0 or blen > 200000 or pos+48+blen > len(d): break
- pos += 48 + blen
- else:
- continue
- break
- except (socket.timeout, OSError): continue
- # 不严格等 SC658, 直接继续
- time.sleep(2)
- log(f"\n[6] 尝试开启喝药...")
- log(f" --- 第 1 步: 打开面板 ---")
- send_action(g, sid, "@openmianban,23", 109, 900)
- frames = recv_all(g, wait=3.0)
- log(f" 收到 {len(frames)} 帧")
- for mid, body in frames[:10]:
- body_short = body[:80]
- log(f" mid={mid} body={body_short}")
- log(f"\n --- 第 2 步: 查询喝药状态 ---")
- send_action(g, sid, "@chiyao_kaiqi", 303, 901)
- frames = recv_all(g, wait=3.0)
- log(f" 收到 {len(frames)} 帧")
- state_found = None
- for mid, body in frames:
- body_short = body[:200]
- log(f" mid={mid} body={body_short}")
- if b"yd_cy1" in body:
- m = re.search(rb"id=yd_cy1[^}]*?but_([01])\.png", body, re.S)
- if m:
- state_found = "on" if m.group(1) == b"1" else "off"
- log(f" ★ 喝药状态: {state_found}")
- if state_found is None:
- log(f" ⚠️ 未找到 yd_cy1 状态指示器")
- log(f"\n --- 第 3 步: 发送切换命令 (期望开启) ---")
- send_action(g, sid, "@chiyao_kaiqi", 303, 902)
- frames = recv_all(g, wait=3.0)
- log(f" 收到 {len(frames)} 帧")
- for mid, body in frames[:5]:
- body_short = body[:200]
- log(f" mid={mid} body={body_short}")
- log(f"\n --- 第 4 步: 再次查询状态 ---")
- send_action(g, sid, "@chiyao_kaiqi", 303, 901)
- frames = recv_all(g, wait=3.0)
- state_found = None
- for mid, body in frames:
- if b"yd_cy1" in body:
- m = re.search(rb"id=yd_cy1[^}]*?but_([01])\.png", body, re.S)
- if m:
- state_found = "on" if m.group(1) == b"1" else "off"
- log(f" ★ 喝药状态: {state_found}")
- if state_found is None:
- log(f" ⚠️ 仍未找到 yd_cy1 状态指示器")
- log("\n[完成] 诊断结束 (Ctrl+C 退出)")
- try:
- while True: time.sleep(60)
- except KeyboardInterrupt:
- pass
- if __name__ == "__main__":
- main()
|