run_juece13_wugong_kill100.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/env python3
  2. """run_juece13_wugong_kill100.py — 角色【新角色】→ 蜈蚣洞穴(地牢一层东)杀 N 只.
  3. 复用 AutoFightBehavior(§2.6.4 SC10 修复版) + CaveEnterBehavior 传送链
  4. (@jiuxian_move_1,1,2)。洞穴怪强(dmg60-83) — 沿用矿区验证过的
  5. FLEE_RATIO=0.55 保命; run13 已证 SC10 推送含名字/坐标, 远距发现
  6. (12-17格)同样适用本图。
  7. 用法:
  8. uv run python scripts/run_juece13_wugong_kill100.py -u longwu988 -p Longwu1988 \
  9. --zone 14570166 --name 新角色 [--kills 100] [--minutes 90] [--wait 90]
  10. """
  11. from __future__ import annotations
  12. import argparse
  13. import logging
  14. import sys
  15. import time
  16. sys.path.insert(0, "scripts")
  17. import requests
  18. from run_juece13_mine_farthest import banner, setup_logging
  19. from run_juece13_wugong_autofight import AutoFightBehavior
  20. from run_juece13_wugong_farthest import (
  21. CAVE_MAP,
  22. CaveEnterBehavior,
  23. _cave_walls,
  24. find_farthest,
  25. )
  26. from pbot.bot.runner import pump, run
  27. from pbot.config import Account
  28. from pbot.errors import PbotError
  29. from pbot.game.session import enter_world
  30. from pbot.login.box_client import enter_game_client, login
  31. from pbot.transport.gateway import login_gate_with_retry
  32. from pbot.login.zone_ports import resolve_zone_gateway
  33. from pbot.types import ZoneId
  34. _LOG = logging.getLogger("juece13_wugong100")
  35. def parse_args() -> argparse.Namespace:
  36. """命令行."""
  37. ap = argparse.ArgumentParser()
  38. _ = ap.add_argument("-u", "--user", required=True)
  39. _ = ap.add_argument("-p", "--password", required=True)
  40. _ = ap.add_argument("--zone", type=int, required=True)
  41. _ = ap.add_argument("--name", required=True)
  42. _ = ap.add_argument("--kills", type=int, default=100)
  43. _ = ap.add_argument("--minutes", type=float, default=90.0)
  44. _ = ap.add_argument("--wait", type=float, default=0.0,
  45. help="进图后原地静默秒数(仅心跳+收帧, 不移动不攻击)")
  46. _ = ap.add_argument("--login-port", type=int, default=0)
  47. return ap.parse_args()
  48. def main() -> int:
  49. """登录 → 蜈蚣洞穴 → 静默等待 → 自动战斗至 N 杀或超时 → 退出."""
  50. a = parse_args()
  51. setup_logging()
  52. banner("[0] 洞穴自动战斗: 区=%d 角色=%s 目标=%d杀 时限=%.0fmin 静默=%.0fs",
  53. a.zone, a.name, a.kills, a.minutes, a.wait)
  54. http = requests.Session()
  55. http.trust_env = False
  56. http.verify = False
  57. jwt, uid = login(Account(username=a.user, password=a.password))
  58. _ = enter_game_client(http, jwt, ZoneId(a.zone))
  59. gw_host, conn_port, real_port = (("", a.login_port, a.login_port)
  60. if a.login_port else resolve_zone_gateway(a.zone))
  61. ports = (conn_port,)
  62. key32, sid, real_name, ticket_key, game_port = login_gate_with_retry(
  63. ZoneId(a.zone), jwt, uid, a.name, ports, host=gw_host, real_port=real_port)
  64. _LOG.info("[票据] sid=%d 角色=%s 游戏端口=%d", sid, real_name, game_port)
  65. stop: list[bool] = [False]
  66. conn, world, updater = enter_world(ZoneId(a.zone), real_name, ticket_key,
  67. sid, game_port, uid, stop=stop, host=gw_host)
  68. _LOG.info("[✓] 出生 map=%s @(%d,%d)", world.me.map_name, world.me.x,
  69. world.me.y)
  70. try:
  71. from pbot.game.heal import enable_auto_heal
  72. state = None
  73. for _ in range(2):
  74. state = enable_auto_heal(conn, sid, want_on=True, world=world)
  75. if state == "on":
  76. break
  77. _LOG.warning("[喝药✗] 状态=%s — 重试一轮", state)
  78. time.sleep(1.0)
  79. if state != "on":
  80. _LOG.error("[喝药✗✗] 高危图无喝药保护 — 终止, 拒绝送死")
  81. return 1
  82. _LOG.info("[喝药✓] on")
  83. if world.me.map_name != CAVE_MAP:
  84. banner("[1] 传送蜈蚣洞穴")
  85. bh = CaveEnterBehavior(sid=sid, kill_target=0)
  86. r = run(conn, world, updater, bh, duration_s=300.0)
  87. if world.me.map_name != CAVE_MAP:
  88. _LOG.error("[✗] 传送失败 result=%s", r.value)
  89. return 1
  90. time.sleep(3.0)
  91. _ = pump(conn, world, updater, 2.0)
  92. if a.wait > 0:
  93. banner("[2] 原地静默 %.0f 秒(仅心跳+收帧)", a.wait)
  94. deadline = time.time() + a.wait
  95. while time.time() < deadline:
  96. _ = pump(conn, world, updater, 0.5)
  97. _LOG.info("[静默✓] hp=%d/%d 视野怪=%d 位置=(%d,%d) map=%s",
  98. world.me.hp, world.me.max_hp,
  99. len(world.monsters), world.me.x, world.me.y,
  100. world.me.map_name)
  101. banner("[3] 自动战斗: 目标 %d 杀", a.kills)
  102. af = AutoFightBehavior(
  103. sid=sid, map_name=CAVE_MAP, walls=_cave_walls(),
  104. farthest_fn=find_farthest, kill_goal=a.kills)
  105. r = run(conn, world, updater, af, duration_s=a.minutes * 60)
  106. _LOG.info("[结束] result=%s 击杀=%d/%d 腿=%d 弹回=%d 位置=(%d,%d) "
  107. "hp=%d/%d map=%s",
  108. r.value, af.kills, a.kills, af.legs, af.rejected,
  109. world.me.x, world.me.y, world.me.hp, world.me.max_hp,
  110. world.me.map_name)
  111. return 0 if af.kills >= a.kills else 1
  112. finally:
  113. stop[0] = True
  114. conn.close()
  115. _LOG.info("连接已关闭")
  116. if __name__ == "__main__":
  117. try:
  118. sys.exit(main())
  119. except PbotError as e:
  120. _LOG.error("失败: %s", e.detail)
  121. sys.exit(1)