diag_walk.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # -*- coding: utf-8 -*-
  2. """diag_walk.py — 走路帧布局矩阵对照实验。
  3. 背景: run5-11 比奇走路反复被拒(SC28拉回站桩), 等待图却全通。Lua 源
  4. (handleActionBegin)只有一种布局, 但 moveToNextGrid 先 SetActorMapXY(目标格)
  5. 再触发发送, recog/p3 到底谁是起点谁是目标存在两种读法。本脚本在同一会话
  6. 内依次测试布局变体 × 各走 3 步, 观察 SC28 增量判定接受性:
  7. V1: recog=目标point, p3=起点point (moveToNextGrid 先设目标的读法)
  8. V2: recog=起点point, p3=上一点point (字面 handleActionBegin 读法)
  9. V3: recog=起点point, p3=0 (README 旧布局去 lastPoint)
  10. V4: V1 + 走2格(验证步长语义)
  11. 判定: SC28 新增==0 → 布局被接受。
  12. 用法: .venv/bin/python diag_walk.py [--name 萌新2814]
  13. """
  14. import argparse
  15. import sys
  16. import time
  17. import requests as rq
  18. import urllib3
  19. urllib3.disable_warnings()
  20. HERE = __file__.rsplit("/", 1)[0]
  21. sys.path.insert(0, HERE)
  22. import login_996pc as L # noqa: E402
  23. import quest_bot3 as Q # noqa: E402
  24. from combat_bot import log, pack_point, proto_map_name # noqa: E402
  25. ZONE = 14492170
  26. def run_variant(bot, tag, mid, mk_recog, mk_p1, mk_p2, mk_p3, body, step_len=1, steps=3):
  27. """mk_* 是帧构造器: (d, x, y, nx, ny, last_x, last_y) → 字段值。"""
  28. sc28_b = bot.frame_log.get(28, 0)
  29. for i in range(steps):
  30. x, y = bot.me["x"], bot.me["y"]
  31. d = 2 # 恒向东
  32. nx, ny = x + step_len, y
  33. lx, ly = bot.me.get("last_x", x), bot.me.get("last_y", y)
  34. ctx = (d, x, y, nx, ny, lx, ly)
  35. bot.send(mid, mk_recog(*ctx), mk_p1(*ctx), mk_p2(*ctx), mk_p3(*ctx), body)
  36. bot.me["last_x"], bot.me["last_y"] = x, y
  37. bot.me["x"], bot.me["y"] = nx, ny
  38. t_end = time.time() + 1.2
  39. while time.time() < t_end:
  40. bot.pump(0.15)
  41. bot.tick_step_ack()
  42. sc28_a = bot.frame_log.get(28, 0)
  43. log(f"[{tag}] SC28+={sc28_a - sc28_b} pos=({bot.me['x']},{bot.me['y']})")
  44. return sc28_a - sc28_b == 0
  45. def main():
  46. ap = argparse.ArgumentParser()
  47. ap.add_argument("--name", default="萌新2814")
  48. args = ap.parse_args()
  49. s = rq.Session()
  50. j, _ = L.do_login(s, "longwu988", "Longwu1988")
  51. assert j.get("code") == 200, j.get("msg")
  52. jwt = j["data"]["token"]
  53. uid = str(j["data"]["userInfo"]["id"])
  54. g, bot = Q.enter_world(s, jwt, uid, ZONE, args.name, 0)
  55. log(f"出生: map={bot.me.get('mapname')} @({bot.me['x']},{bot.me['y']}) sid={bot.sid}")
  56. bot.pump(1.5)
  57. m = bot.me.get("mapname")
  58. if m == "等待地图":
  59. log("[!] 出生在等待图(1D走廊不敏感), 重进...")
  60. g.close()
  61. return
  62. bmap = proto_map_name(bot.me).encode()
  63. sid = bot.sid
  64. pt = pack_point # lo16=x hi16=y
  65. def pt_rev(x, y):
  66. return ((x & 0xFFFF) << 16) | (y & 0xFFFF) # lo16=y hi16=x
  67. # W1: CS3012 WALKEX + README CS3013 布局(p1=dir,p2=point,p3=sid)
  68. run_variant(bot, "W1 CS3012 p1=dir p2=pt p3=sid", 3012,
  69. lambda *c: 0, lambda *c: c[0], lambda *c: pt(c[1], c[2]),
  70. lambda *c: sid, bmap)
  71. # W2: CS3011 README 原布局(p1=dir, p2=point, p3=sid)
  72. run_variant(bot, "W2 CS3011 p1=dir p2=pt p3=sid", 3011,
  73. lambda *c: 0, lambda *c: c[0], lambda *c: pt(c[1], c[2]),
  74. lambda *c: sid, bmap)
  75. # W3: CS3011 point 字节序反转(recog=X<<16|Y, p2=dir, p3=lastPoint_rev)
  76. run_variant(bot, "W3 CS3011 pt_rev p2=dir", 3011,
  77. lambda *c: pt_rev(c[1], c[2]), lambda *c: 0,
  78. lambda *c: c[0], lambda *c: pt_rev(c[5], c[6]), bmap)
  79. # W4: CS3013 README 原布局(p1=dir, p2=point, p3=sid)
  80. run_variant(bot, "W4 CS3013 p1=dir p2=pt p3=sid", 3013,
  81. lambda *c: 0, lambda *c: c[0], lambda *c: pt(c[1], c[2]),
  82. lambda *c: sid, bmap)
  83. # W5: CS3011 Lua 源布局(recog=pt, p1=0, p2=dir, p3=lastPoint) — 当前实现
  84. run_variant(bot, "W5 CS3011 recog=pt p2=dir p3=pt", 3011,
  85. lambda *c: pt(c[1], c[2]), lambda *c: 0,
  86. lambda *c: c[0], lambda *c: pt(c[5], c[6]), bmap)
  87. g.close()
  88. log("[diag完成] SC28+=0 的变体即服务器接受的布局")
  89. if __name__ == "__main__":
  90. main()