fix(event_sweep): resolve overlapping button regions to prevent result page closure during sweeps
This commit is contained in:
parent
84790ecb27
commit
a86003cf66
@ -337,7 +337,41 @@ EVENT_STAGE_MODAL_CLOSE_BUTTON = (1704, 271)
|
||||
# x=1150 sits well inside it) while excluding the character-art panel,
|
||||
# confirmed against the same saved false-positive screenshot returning
|
||||
# no match afterward.
|
||||
EVENT_SWEEP_RESULT_BUTTON_REGION = (1000, 700, 1300, 1050)
|
||||
#
|
||||
# A SECOND contamination source found live (2026-07-13, reported by the
|
||||
# user: "the sweep went well, but I think it overclick and closed the
|
||||
# result page"): this region's y1=700 overlaps EVENT_SWEEP_START_BUTTON's
|
||||
# (1400,668) own real cyan-pixel footprint (y 622-715, x 1152-1655 --
|
||||
# measured directly during bounty.py's own identical-bug investigation,
|
||||
# since that modal is confirmed pixel-identical to this one, sharing this
|
||||
# exact button position). Once the real "掃討完了" result dialog is
|
||||
# dismissed and the flow lands back on the bare stage-info modal (matching
|
||||
# this function's own second `ends` condition), 掃討開始 becomes visible
|
||||
# and cyan again -- _find_result_button re-matched its corner, and
|
||||
# click_result_button clicked it, re-opening a fresh AP-usage-confirm
|
||||
# dialog that this loop then had no way to recognize as anything other
|
||||
# than "still a result button showing," matching the user's own "overclick
|
||||
# closed the result page" diagnosis exactly. y1 shifted to 730 (15px clear
|
||||
# of the button's measured 715 bottom edge) to exclude it -- kept wide
|
||||
# enough (through y2=1050) to still cover both a possible SKIP button and
|
||||
# the final OK button of a bulk/MAX sweep's reveal sequence (~120px apart
|
||||
# per story_sweep's own established pattern), since this event's own SKIP
|
||||
# button was never individually pixel-measured. Not yet re-confirmed live
|
||||
# with a fresh real sweep -- see EVENT_SWEEP_RESULT_BUTTON_MIN_PIXELS'
|
||||
# comment for the second half of this fix and its own live-test status.
|
||||
EVENT_SWEEP_RESULT_BUTTON_REGION = (1000, 730, 1300, 1050)
|
||||
|
||||
# A THIRD contamination source, same class bounty.py's own investigation
|
||||
# found in its pixel-identical modal: the stage-info modal's own "獲得期待
|
||||
# 報酬" reward-icon-preview artwork has a handful of pixels that
|
||||
# incidentally fall inside SWEEP_CONFIRM_CYAN's broad range even with no
|
||||
# dialog open. detector.find_color_centroid's min_pixels parameter filters
|
||||
# this out. Value carried over from BOUNTY_RESULT_BUTTON_MIN_PIXELS by
|
||||
# analogy (same shared UI component) rather than freshly measured against
|
||||
# this event's own region -- its search area here is somewhat larger, so
|
||||
# this may need tuning once a fresh live sweep confirms whether it's
|
||||
# actually well-calibrated for this specific region.
|
||||
EVENT_SWEEP_RESULT_BUTTON_MIN_PIXELS = 3000
|
||||
|
||||
# Rotation target: which of stages 9-12 to sweep today, per explicit user
|
||||
# request (2026-07-10) -- "the current event has up to 12 stages, randomly
|
||||
|
||||
@ -215,6 +215,41 @@ re-confirmed against a fresh real bulk sweep (that day's AP was reduced to
|
||||
14/240 by the sweep that surfaced this, too low to force another MAX
|
||||
sweep) -- the fix is validated against the actual recorded false-positive
|
||||
screenshot and the same live code path, just not a full new live sweep.
|
||||
|
||||
The x-narrowing above turned out to not be the whole story either. A real
|
||||
run (2026-07-13, user report: "the sweep went well, but I think it
|
||||
overclick and closed the result page") again logged "unrecognized_state"
|
||||
despite a real successful MAX sweep (rows 08-12 all read correctly, sweep
|
||||
confirmed). Root cause this time: EVENT_SWEEP_RESULT_BUTTON_REGION's
|
||||
y1=700 still overlapped EVENT_SWEEP_START_BUTTON's (1400,668) own real
|
||||
cyan-pixel footprint (y 622-715, x 1152-1655) -- known precisely without
|
||||
needing a fresh live measurement, since bounty.py's own investigation into
|
||||
the identical bug class (its stage-info modal is confirmed pixel-identical
|
||||
to this one, sharing this exact button position) already measured it
|
||||
directly from a real screenshot. Once the real "掃討完了" result dialog is
|
||||
dismissed and the flow lands back on the bare stage-info modal (this
|
||||
function's own second `ends` condition), 掃討開始 becomes visible and
|
||||
cyan again -- _find_result_button re-matched its corner and clicked it,
|
||||
re-opening a fresh AP-usage-confirm dialog this loop had no way to
|
||||
recognize as anything but "still a result button showing," exactly
|
||||
matching the user's own diagnosis. Fixed two ways, both ported directly
|
||||
from bounty.py's own resolution of the identical bug: (1)
|
||||
EVENT_SWEEP_RESULT_BUTTON_REGION's y1 shifted from 700 to 730 (15px clear
|
||||
of the button's measured 715 bottom edge), kept wide through y2=1050 to
|
||||
still cover a possible SKIP-then-OK sequence's ~120px vertical spread,
|
||||
since this event's own SKIP button was never individually pixel-measured;
|
||||
(2) detector.find_color_centroid's min_pixels parameter (added for
|
||||
bounty.py's own second contamination source -- sparse stray pixels in the
|
||||
modal's own reward-icon artwork) applied here too via
|
||||
EVENT_SWEEP_RESULT_BUTTON_MIN_PIXELS, carried over from
|
||||
BOUNTY_RESULT_BUTTON_MIN_PIXELS by analogy rather than freshly measured
|
||||
against this larger region. _watch_sweep_result also gained a third
|
||||
`ends` condition on _is_ap_purchase_prompt (mirroring bounty.py's
|
||||
_is_ticket_purchase_prompt fix) as a second, independent safety layer: if
|
||||
a purchase prompt is ever reached here anyway, it's recognized and
|
||||
cancelled explicitly by _sweep_target rather than left to the blind color
|
||||
search. Not yet re-confirmed live -- deployed but no fresh real sweep run
|
||||
since.
|
||||
"""
|
||||
import datetime
|
||||
import os
|
||||
@ -254,7 +289,10 @@ def _is_ap_purchase_prompt(driver, config):
|
||||
|
||||
|
||||
def _find_result_button(driver, config):
|
||||
return detector.find_color_centroid(config.EVENT_SWEEP_RESULT_BUTTON_REGION, *config.SWEEP_CONFIRM_CYAN)
|
||||
return detector.find_color_centroid(
|
||||
config.EVENT_SWEEP_RESULT_BUTTON_REGION, *config.SWEEP_CONFIRM_CYAN,
|
||||
min_pixels=config.EVENT_SWEEP_RESULT_BUTTON_MIN_PIXELS,
|
||||
)
|
||||
|
||||
|
||||
def _count_raised_above_one(driver, config):
|
||||
@ -432,6 +470,22 @@ def _watch_sweep_result(driver, config):
|
||||
# SKIP/OK sequence has even started) still can't be mistaken for
|
||||
# "swept" -- only "modal gone after we've actually clicked through
|
||||
# something" counts.
|
||||
#
|
||||
# A THIRD ends condition, added 2026-07-13 after a real user report
|
||||
# ("the sweep went well, but I think it overclick and closed the
|
||||
# result page"): EVENT_SWEEP_RESULT_BUTTON_REGION used to overlap
|
||||
# EVENT_SWEEP_START_BUTTON's own real footprint (see that config
|
||||
# constant's comment), so once the real result dialog was dismissed and
|
||||
# the bare stage-info modal reappeared, _find_result_button could
|
||||
# re-match 掃討開始 itself and click it -- re-opening a fresh AP-usage-
|
||||
# confirm dialog this loop had no way to recognize as anything but
|
||||
# "still a result button." The region is now fixed to exclude that
|
||||
# button's footprint, but this explicit check (mirroring bounty.py's
|
||||
# own identical `_is_ticket_purchase_prompt` fix for the same bug
|
||||
# class) is a second, independent layer: if a purchase/insufficient-AP
|
||||
# prompt is ever reached here anyway, for any reason, it's recognized
|
||||
# and handled explicitly by the caller rather than left to a blind
|
||||
# color search that could otherwise re-click into it.
|
||||
clicked_any = {"value": False}
|
||||
|
||||
def click_result_button(d):
|
||||
@ -442,6 +496,7 @@ def _watch_sweep_result(driver, config):
|
||||
d.wait(1.5)
|
||||
|
||||
ends = {
|
||||
(lambda d, c: _is_ap_purchase_prompt(d, c)): "prompted_to_purchase",
|
||||
(lambda d, c: _is_stage_modal_open(d, c) and _find_result_button(d, c) is None): "swept",
|
||||
(lambda d, c: clicked_any["value"] and not _is_stage_modal_open(d, c) and _find_result_button(d, c) is None): "swept",
|
||||
}
|
||||
@ -525,6 +580,14 @@ def _sweep_target(driver, config, stage, count):
|
||||
outcome = _watch_sweep_result(driver, config)
|
||||
print(f"[event_sweep] result: {outcome}")
|
||||
|
||||
if outcome == "prompted_to_purchase":
|
||||
# See _watch_sweep_result's own comment -- cancel this dialog
|
||||
# explicitly rather than let _close_stage_modal's plain Escape loop
|
||||
# be the only thing standing between it and a real AP purchase.
|
||||
print("[event_sweep] AP-purchase prompt detected after the sweep -- cancelling without purchasing")
|
||||
driver.click(*config.SWEEP_CONFIRM_CANCEL_BUTTON)
|
||||
driver.wait(1)
|
||||
|
||||
if not _close_stage_modal(driver, config):
|
||||
print("[event_sweep] warning: could not confirm stage info modal closed -- leaving it open rather than pressing further keys blindly")
|
||||
return outcome
|
||||
|
||||
10
plan.md
10
plan.md
@ -584,6 +584,16 @@ This is the same failure class `CLAUDE.md` already documents for the mailbox/caf
|
||||
|
||||
**Status**: both bugs fixed. The originally reported bug (stage 9 unreadable) is fully confirmed via a real successful live sweep. The `_watch_sweep_result` mislabeling's real root cause is now understood and fixed (previous fix attempt addressed a real but secondary issue); confirmed against the actual live false-positive condition, awaiting one more full live sweep to confirm the outcome log itself reads `"swept"` next time AP allows.
|
||||
|
||||
#### Phase 14 follow-up #7: `_find_result_button` re-clicking 掃討開始 itself (2026-07-13)
|
||||
|
||||
**Reported**: a real MAX sweep of stage 12 completed successfully (all 5 stage rows OCR'd correctly, sweep confirmed) but still logged `unrecognized_state`. The user's own diagnosis: "the sweep went well, but I think it overclick and closed the result page."
|
||||
|
||||
Follow-up #6's x-narrowing (1000-1300) turned out to not be the whole fix. Root cause, identified without needing a fresh live sweep: `EVENT_SWEEP_RESULT_BUTTON_REGION`'s y1=700 still overlapped `EVENT_SWEEP_START_BUTTON`'s (1400,668) own real cyan-pixel footprint (y 622-715, x 1152-1655) — this is the **exact same bug class** just fixed in `bounty.py` (see Phase 15's own writeup below), and since bounty's stage-info modal is confirmed pixel-identical to this one (sharing this exact button position), its already-measured footprint could be reused directly rather than re-deriving it. Once the real "掃討完了" result dialog is dismissed and the flow lands back on the bare stage-info modal, 掃討開始 becomes visible and cyan again — `_find_result_button` re-matched its corner and clicked it, re-opening a fresh AP-usage-confirm dialog the loop had no way to recognize as anything but "still a result button," exactly matching the user's own diagnosis.
|
||||
|
||||
**Fixed by porting bounty.py's own resolution directly**: (1) `EVENT_SWEEP_RESULT_BUTTON_REGION`'s y1 shifted 700→730 (15px clear of the button's measured 715 edge), kept wide through y2=1050 to still cover a possible SKIP-then-OK sequence's ~120px spread since this event's own SKIP button was never individually measured; (2) `detector.find_color_centroid`'s `min_pixels` parameter applied here too via a new `EVENT_SWEEP_RESULT_BUTTON_MIN_PIXELS` (3000, carried over from `BOUNTY_RESULT_BUTTON_MIN_PIXELS` by analogy — same shared UI component, though this region is somewhat larger so it may need its own tuning); (3) `_watch_sweep_result` gained a third `ends` condition on `_is_ap_purchase_prompt` (mirroring bounty's `_is_ticket_purchase_prompt` fix) as an independent safety layer.
|
||||
|
||||
**Confirmed live at zero AP cost**: opened the real stage-12 modal (view only, no count raised, no sweep confirmed) and directly compared `_find_result_button` against the OLD region (falsely matched `(1226, 707)`, sitting right on 掃討開始's own corner) vs. the NEW region+min_pixels (correctly returned `None` on the same resting screen). **Not yet re-confirmed with a fresh full real sweep** reaching an actual `"swept"` log — that requires spending real AP again, deferred pending the user's go-ahead.
|
||||
|
||||
### Phase 15: Bounty
|
||||
|
||||
Reference: `module/rewarded_task.py`. Local: `ba_auto/tasks/bounty.py`.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user