Nik Afiq 0707487934 Enhance automation project with story sweep feature and OCR policy updates
- Introduced `story_sweep.py` for Normal/Hard story AP sweeping, allowing users to spend AP on randomly selected stages.
- Updated `CLAUDE.md` to clarify the OCR policy, emphasizing the need to port OCR-driven logic from the reference implementation rather than substituting with non-OCR methods.
- Modified `README.md` and `plan.md` to reflect the new story sweep feature and its operational details.
- Adjusted `setup.sh` to include the new command for running the story sweep.
- Enhanced `driver.py` with a new scroll function for better interaction with the game UI.
- Updated configuration mappings in `config.py` to support the new story sweep functionality.
- Refined existing task modules to ensure consistent state verification and error handling.
2026-07-05 20:19:35 +09:00

77 lines
2.0 KiB
Python

"""Local PC/Steam/Proton control backend (xdotool/scrot wrappers)."""
import os
import subprocess
import time
import cv2
from ba_auto import config
PROBE_SHOT_PATH = os.path.join(config.SCRATCHPAD_DIR, "probe.png")
def run_command(args, **kwargs):
kwargs.setdefault("env", config.ENV)
kwargs.setdefault("check", True)
return subprocess.run(args, **kwargs)
def focus_game():
result = run_command(
["xdotool", "search", "--name", config.WINDOW_NAME],
check=False, capture_output=True, text=True,
)
window_ids = result.stdout.split()
if not window_ids:
raise RuntimeError("Blue Archive window not found. Is the game running?")
run_command(["xdotool", "windowactivate", window_ids[0]])
wait(0.5)
def click(x, y):
# A combined "mousemove X Y click 1" invocation is unreliable here --
# empirically (see plan.md's click-flakiness writeups) the game's input
# handler sometimes misses clicks fired before it's processed the move.
# Splitting into separate commands with a short pause between fixes it.
run_command(["xdotool", "mousemove", str(x), str(y)])
wait(0.2)
run_command(["xdotool", "click", "1"])
wait(0.5)
def move_mouse(x, y):
run_command(["xdotool", "mousemove", str(x), str(y)])
def scroll(x, y, direction, clicks=1):
# xdotool button 4/5 = scroll wheel up/down. A drag (mousedown/move/mouseup)
# does not register as a list-scroll gesture in this Proton client; the
# wheel does.
button = "4" if direction == "up" else "5"
run_command(["xdotool", "mousemove", str(x), str(y)])
wait(0.2)
for _ in range(clicks):
run_command(["xdotool", "click", button])
wait(0.15)
wait(0.3)
def keypress(key):
run_command(["xdotool", "key", key])
wait(0.5)
def screenshot(path):
run_command(["scrot", "-a", "0,0,1920,1200", "-o", path])
def color_at(x, y):
screenshot(PROBE_SHOT_PATH)
image = cv2.imread(PROBE_SHOT_PATH)
b, g, r = image[y, x]
return int(r), int(g), int(b)
def wait(seconds):
time.sleep(seconds)