feat(exit_game): implement exit game functionality with confirmation dialog
This commit is contained in:
parent
0a6af51340
commit
976f0f7241
File diff suppressed because one or more lines are too long
@ -21,8 +21,10 @@ No force-kill fallback if the graceful path doesn't verify -- matches this
|
|||||||
project's "abort cleanly on unknown state rather than guess" convention
|
project's "abort cleanly on unknown state rather than guess" convention
|
||||||
(gem_shop/bounty) rather than reaching for driver.kill_game().
|
(gem_shop/bounty) rather than reaching for driver.kill_game().
|
||||||
|
|
||||||
Not yet live-tested: navigation.is_modal_open's generic dim-probe hasn't
|
Confirmed live (2026-07-18) via a standalone `exit_game` run: the
|
||||||
been confirmed specifically against this dialog's own visual layout.
|
is_modal_open dim-probe correctly detected the exit-confirmation dialog
|
||||||
|
after Escape, and the game closed cleanly after Enter. Not yet exercised
|
||||||
|
as the tail end of a full daily/q4h preset run specifically.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ba_auto import navigation
|
from ba_auto import navigation
|
||||||
|
|||||||
@ -56,9 +56,9 @@ DEFAULT_ORDER = ["login", "mailbox", "cafe", "stamina", "gem_shop", "circle"]
|
|||||||
# ends the session (Escape then Enter on the confirmed true home screen
|
# ends the session (Escape then Enter on the confirmed true home screen
|
||||||
# raises and confirms Blue Archive's own "exit the game?" dialog), so like
|
# raises and confirms Blue Archive's own "exit the game?" dialog), so like
|
||||||
# every other resource-spending/session-affecting task it's opt-in only, not
|
# every other resource-spending/session-affecting task it's opt-in only, not
|
||||||
# in DEFAULT_ORDER. Not yet live-tested -- see
|
# in DEFAULT_ORDER. Confirmed live standalone (2026-07-18); not yet
|
||||||
# ba_auto/reference_notes/mapping.md's "Exit game" row before trusting it
|
# exercised specifically as the tail end of a full daily/q4h preset run --
|
||||||
# unattended.
|
# see ba_auto/reference_notes/mapping.md's "Exit game" row.
|
||||||
PRESETS = {
|
PRESETS = {
|
||||||
"daily": [
|
"daily": [
|
||||||
"login", "event_sweep", "cafe", "event_sweep", "circle", "lesson",
|
"login", "event_sweep", "cafe", "event_sweep", "circle", "lesson",
|
||||||
|
|||||||
2
plan.md
2
plan.md
@ -914,7 +914,7 @@ Wired in as opt-in only (added `exit_game` to `TASKS` in `ba_daily.py`), appende
|
|||||||
|
|
||||||
One real bug found and fixed before any live test, while reasoning through what happens next: `ba_daily.py`'s centralized `_run_task` always calls `navigation.return_to_home` in its post-task `finally` block and prints a warning if it returns False. `return_to_home` already bails out gracefully (returns False, doesn't crash) when the window doesn't exist, added for login.py's cold-start case -- but that means after `exit_game` succeeds, this same finally-block would print a misleading "could not confirm return to home screen after task finished" warning on every single `daily`/`q4h` run that reaches it, even though nothing is wrong. Fixed by skipping the post-task check entirely when `driver.window_exists()` is already False.
|
One real bug found and fixed before any live test, while reasoning through what happens next: `ba_daily.py`'s centralized `_run_task` always calls `navigation.return_to_home` in its post-task `finally` block and prints a warning if it returns False. `return_to_home` already bails out gracefully (returns False, doesn't crash) when the window doesn't exist, added for login.py's cold-start case -- but that means after `exit_game` succeeds, this same finally-block would print a misleading "could not confirm return to home screen after task finished" warning on every single `daily`/`q4h` run that reaches it, even though nothing is wrong. Fixed by skipping the post-task check entirely when `driver.window_exists()` is already False.
|
||||||
|
|
||||||
**Not yet live-tested.** `navigation.is_modal_open`'s generic dim-probe has not been specifically confirmed against this dialog's own visual layout -- needs a real run to confirm the Escape press actually raises it and that the dim-probe correctly reads it as open, before trusting this unattended in cron. Get explicit go-ahead before the first live test, since it deliberately ends a real game session.
|
**Confirmed live**: a standalone `./ba_dailies.sh exit_game` run, user-reported "works well" -- `navigation.is_modal_open`'s generic dim-probe correctly detected the exit-confirmation dialog after Escape, and Enter closed the game cleanly (`driver.window_exists()` verified false). Not yet exercised as the tail end of a full `daily`/`q4h` preset run specifically (only standalone so far).
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|||||||
33
pull_logs.sh
33
pull_logs.sh
@ -6,7 +6,20 @@ set -euo pipefail
|
|||||||
# nik-gpu into this repo's scratchpad/ba_logs/ for local reading (e.g. in
|
# nik-gpu into this repo's scratchpad/ba_logs/ for local reading (e.g. in
|
||||||
# VS Code). Local dev tooling only, not part of the ba_dailies.sh
|
# VS Code). Local dev tooling only, not part of the ba_dailies.sh
|
||||||
# game-automation launcher -- same category as setup.sh/clean_scratchpad.sh.
|
# game-automation launcher -- same category as setup.sh/clean_scratchpad.sh.
|
||||||
# Read-only on the remote side: never writes back to nik-gpu.
|
#
|
||||||
|
# After a successful pull, also deletes the just-synced *.log files on the
|
||||||
|
# remote side (per explicit user request), so ~/ba_logs/ doesn't grow
|
||||||
|
# forever. This makes the remote side no longer read-only, unlike before --
|
||||||
|
# gated behind ba_cron_run.sh's own shared flock (~/ba_logs/ba_dailies.lock)
|
||||||
|
# to stay safe: that script holds this exact lock for its ENTIRE run,
|
||||||
|
# wrapping the whole `>> "$LOG_FILE"` append span, which can last many
|
||||||
|
# minutes (e.g. the "daily" preset's arena fights/event sweeps). If this
|
||||||
|
# script's own non-blocking flock attempt on the same lock file fails, a
|
||||||
|
# cron run is currently in progress -- deletion is skipped for this
|
||||||
|
# invocation (the local copy already pulled above is kept regardless)
|
||||||
|
# rather than risking `rm` unlinking a log file out from under an open
|
||||||
|
# write fd, which would silently lose that run's remaining log output to
|
||||||
|
# an unlinked inode with no error and no way to recover it.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./pull_logs.sh [host]
|
# ./pull_logs.sh [host]
|
||||||
@ -21,3 +34,21 @@ mkdir -p "$DEST"
|
|||||||
rsync -av "$HOST:ba_logs/" "$DEST/"
|
rsync -av "$HOST:ba_logs/" "$DEST/"
|
||||||
|
|
||||||
echo "Synced $HOST:~/ba_logs/ -> $DEST"
|
echo "Synced $HOST:~/ba_logs/ -> $DEST"
|
||||||
|
|
||||||
|
DELETE_RESULT="$(ssh "$HOST" bash -s <<'REMOTE'
|
||||||
|
LOCK_FILE="$HOME/ba_logs/ba_dailies.lock"
|
||||||
|
exec 9>"$LOCK_FILE"
|
||||||
|
if flock -n 9; then
|
||||||
|
rm -f "$HOME"/ba_logs/*.log
|
||||||
|
echo "DELETED"
|
||||||
|
else
|
||||||
|
echo "SKIPPED"
|
||||||
|
fi
|
||||||
|
REMOTE
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [ "$DELETE_RESULT" = "DELETED" ]; then
|
||||||
|
echo "Deleted *.log on $HOST:~/ba_logs/ (already synced above)"
|
||||||
|
else
|
||||||
|
echo "Skipped remote log deletion -- a cron run is currently in progress on $HOST (local copy above is still up to date; rerun later to clear the remote logs)"
|
||||||
|
fi
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user