fix(cafe): resolve invite ticket cooldown misread as list opened, preventing cascading errors
This commit is contained in:
parent
e814b3d803
commit
a0e1965353
File diff suppressed because one or more lines are too long
@ -24,6 +24,20 @@ had just taken the account's highest-affection students -- then invited
|
|||||||
row 3 cleanly. Both newly-invited students were immediately patted
|
row 3 cleanly. Both newly-invited students were immediately patted
|
||||||
successfully in the same run, income was claimed, and the task returned
|
successfully in the same run, income was claimed, and the task returned
|
||||||
cleanly to the true home screen with no warnings anywhere in the log.
|
cleanly to the true home screen with no warnings anywhere in the log.
|
||||||
|
|
||||||
|
A follow-up real-usage bug (2026-07-14, reported with a screenshot after
|
||||||
|
the ticket used above went on cooldown): _open_invite_list originally
|
||||||
|
verified only "did the header stop reading as a plain subscreen", which
|
||||||
|
is also true when the ticket is on cooldown and the click raises a
|
||||||
|
"通知" notice ("待機時間が経過した後に、再度招待することができます。")
|
||||||
|
directly instead of opening the list -- misread as "list opened", it then
|
||||||
|
sent _ensure_invite_sort/_try_invite_row's row/sort-control coordinates
|
||||||
|
into a dialog that has none of them, repeatedly. Fixed by checking
|
||||||
|
navigation.is_modal_open (a real dialog's darker dim) before the
|
||||||
|
list-opened check: a dialog appearing before any row was clicked can only
|
||||||
|
mean the ticket click itself raised one directly, so this now dismisses
|
||||||
|
it via SWEEP_CONFIRM_BUTTON and returns False (skip invite this room)
|
||||||
|
instead of proceeding.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ba_auto import detector, navigation
|
from ba_auto import detector, navigation
|
||||||
@ -159,9 +173,37 @@ def _open_invite_list(driver, config):
|
|||||||
# list-with-no-nested-dialog state actually produces (confirmed live:
|
# list-with-no-nested-dialog state actually produces (confirmed live:
|
||||||
# MODAL_DIM_PROBE read (252,145,165) with just the list open, which
|
# MODAL_DIM_PROBE read (252,145,165) with just the list open, which
|
||||||
# fails is_modal_open's all-channels-under-150 check).
|
# fails is_modal_open's all-channels-under-150 check).
|
||||||
|
#
|
||||||
|
# But that same "not on subscreen" reading is also produced by a
|
||||||
|
# completely different case: when the ticket is on cooldown, clicking
|
||||||
|
# the icon does NOT open the list at all -- it raises a "通知" dialog
|
||||||
|
# directly ("待機時間が経過した後に、再度招待することができます。",
|
||||||
|
# confirmed live 2026-07-14 via a real user report + screenshot) with
|
||||||
|
# the same dimming. The original version of this check couldn't tell
|
||||||
|
# the two apart and treated the cooldown notice as "list opened",
|
||||||
|
# which then sent _ensure_invite_sort/_try_invite_row's fixed row/
|
||||||
|
# sort-control coordinates into a dialog that doesn't have any of
|
||||||
|
# them -- exactly the "keep pressing the invite when it's not
|
||||||
|
# available and causing this popup and fail" the user reported.
|
||||||
|
#
|
||||||
|
# A real dialog (navigation.is_modal_open, which needs the DARKER
|
||||||
|
# reading a nested "通知" card produces, not just the list's own lighter
|
||||||
|
# dim) can only legitimately appear here if the ticket click itself
|
||||||
|
# opened one directly -- the list view has no dialog on top of it yet
|
||||||
|
# at this point, since no row has been clicked. So checking
|
||||||
|
# is_modal_open first, before the list-opened check, cleanly
|
||||||
|
# distinguishes "cooldown notice fired instead of the list" from "the
|
||||||
|
# list opened normally" and lets this dismiss the notice safely rather
|
||||||
|
# than misreading it as success.
|
||||||
for attempt in range(1, ROOM_OPEN_RETRIES + 1):
|
for attempt in range(1, ROOM_OPEN_RETRIES + 1):
|
||||||
driver.click(*config.CAFE_INVITE_TICKET_ICON)
|
driver.click(*config.CAFE_INVITE_TICKET_ICON)
|
||||||
driver.wait(2)
|
driver.wait(2)
|
||||||
|
if navigation.is_modal_open(driver):
|
||||||
|
title = detector.read_text(config.CAFE_INVITE_DIALOG_TITLE_RECT, psm=6, lang="jpn")
|
||||||
|
print(f"[cafe] invite ticket click opened a dialog instead of the list (title: '{title}') -- likely on cooldown, treating invitation as unavailable")
|
||||||
|
driver.click(*config.SWEEP_CONFIRM_BUTTON)
|
||||||
|
driver.wait(1)
|
||||||
|
return False
|
||||||
if not navigation.is_on_subscreen(driver):
|
if not navigation.is_on_subscreen(driver):
|
||||||
return True
|
return True
|
||||||
print(f"[cafe] invitation ticket list not detected after click (attempt {attempt}/{ROOM_OPEN_RETRIES})")
|
print(f"[cafe] invitation ticket list not detected after click (attempt {attempt}/{ROOM_OPEN_RETRIES})")
|
||||||
|
|||||||
10
plan.md
10
plan.md
@ -334,6 +334,16 @@ Live-calibrated on nik-gpu (free — panning and patting don't spend a limited r
|
|||||||
|
|
||||||
**Confirmed live with real game-state changes** (patting affects real affection, though it's a free, repeatable daily action, not a limited resource like the invite ticket): a full `cafe` run patted a real sparkle in room 2 (`score=0.997`) specifically after panning to an extreme — the sparkle would not necessarily have been visible from the room's default load position — while room 1 found nothing in either view that run (expected: sparkles are on a per-student cooldown, most checks legitimately find nothing). The task completed cleanly end-to-end (both rooms' invite-then-farm sequence, income claimed, confirmed clean return to home) with no warnings anywhere in the log.
|
**Confirmed live with real game-state changes** (patting affects real affection, though it's a free, repeatable daily action, not a limited resource like the invite ticket): a full `cafe` run patted a real sparkle in room 2 (`score=0.997`) specifically after panning to an extreme — the sparkle would not necessarily have been visible from the room's default load position — while room 1 found nothing in either view that run (expected: sparkles are on a per-student cooldown, most checks legitimately find nothing). The task completed cleanly end-to-end (both rooms' invite-then-farm sequence, income claimed, confirmed clean return to home) with no warnings anywhere in the log.
|
||||||
|
|
||||||
|
#### Phase 6 follow-up #4: invite ticket cooldown misread as "list opened" (2026-07-14)
|
||||||
|
|
||||||
|
Real-usage bug report with a screenshot, filed once the account's invite ticket (spent twice during follow-up #2's live test, same day) went on cooldown: "I have problem with the script keep pressing the invite when it's not available and causing this popup and fail." The screenshot showed a "通知" dialog reading "待機時間が経過した後に、再度招待することができます。" ("you can invite again after the wait time passes") with a single OK/Enter button, no cancel.
|
||||||
|
|
||||||
|
Root cause: `_open_invite_list`'s check (`not navigation.is_on_subscreen(driver)`, added in follow-up #2 above) verifies only "something opened that dims the header" — true for the real MomoTalk list AND for this cooldown notice alike, since both dim `SUBSCREEN_HEADER_PROBE` the same way. It returned `True` (list opened) for the cooldown case too, so `_invite_student` proceeded straight into `_ensure_invite_sort`/`_try_invite_row`'s fixed sort-dropdown/row coordinates — none of which exist on this small single-button dialog — causing the cascading wrong clicks and failure the user reported.
|
||||||
|
|
||||||
|
Fix: check `navigation.is_modal_open` (the darker "real dialog" reading, not the list's own lighter dim) immediately after the ticket-icon click, before the list-opened check. A dialog appearing at this exact point can only mean the click itself raised one directly — no row has been clicked yet, so the normal per-row invite-confirm dialog can't be it. When detected, `_open_invite_list` now OCRs the title for logging, dismisses via the shared `SWEEP_CONFIRM_BUTTON` (same "通知" component position reused throughout this project), and returns `False` — which `_invite_student`'s existing (unchanged) fallback already handles correctly: skip the invite, log it, move on to farming.
|
||||||
|
|
||||||
|
**Confirmed live** (`live-test-runner` agent, real `cafe` run with the ticket confirmed still on cooldown for both rooms): both rooms logged `invite ticket click opened a dialog instead of the list (title: '...') -- likely on cooldown, treating invitation as unavailable` immediately, no cascading errors or misclicks followed, and the task proceeded normally to farming/income-claim and ended cleanly (exit 0, true home screen confirmed via screenshot). OCR of the dialog title came back noisy (`'通和 X'` instead of `'通知'`) but this doesn't matter — the fix's branch doesn't depend on the title text, only on `is_modal_open` firing before any row was clicked.
|
||||||
|
|
||||||
### Phase 7: setup.sh update
|
### Phase 7: setup.sh update
|
||||||
|
|
||||||
**Status: Done — `setup.sh` deploys `ba_daily.py` and `ba_auto/`.** `scripts/ba_dailies_legacy.sh` and `scripts/detect_and_click.py` were deleted once mailbox and cafe both migrated off them (Phases 5–6); `setup.sh` no longer references either.
|
**Status: Done — `setup.sh` deploys `ba_daily.py` and `ba_auto/`.** `scripts/ba_dailies_legacy.sh` and `scripts/detect_and_click.py` were deleted once mailbox and cafe both migrated off them (Phases 5–6); `setup.sh` no longer references either.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user