"""Central configuration for ba-auto-daily, ported from the old ba_dailies.sh.""" import os DISPLAY = ":0" XAUTHORITY = "/run/user/1000/gdm/Xauthority" ENV = {**os.environ, "DISPLAY": DISPLAY, "XAUTHORITY": XAUTHORITY} WINDOW_NAME = "BlueArchive" ASSET_DIR = os.path.expanduser("~/ba_assets") # Runtime working files (probe/detection screenshots); never /tmp, per CLAUDE.md. SCRATCHPAD_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "scratchpad") os.makedirs(SCRATCHPAD_DIR, exist_ok=True) # Refined from (1726, 60): that coordinate sat on the edge of the icon's # hitbox and intermittently missed during live testing. MAILBOX_ICON = (1732, 50) CLAIM_ALL = (1691, 1128) MISSION_ICON = (75, 350) # Background pixel inside the "一括受取" (claim all) button on the Mission # panel: bright yellow (r~250, r-b~180+) when something is claimable, flat # grey (r-b<20) when not. Calibrated live at 1920x1200. MISSION_CLAIM_PROBE = (1600, 1100) CAFE_ICON = (165, 1100) CAFE_ROOM_SWITCH = (190, 160) CAFE_INCOME = (1780, 1105) # Max sparkle-detection attempts per room (hits and misses both count -- # sparkles are on a per-student cooldown, so most checks legitimately find # nothing and the loop keeps polling rather than giving up after one miss). CAFE_MAX_CLICKS_PER_ROOM = 15 CAFE_SPARKLE_TEMPLATE = os.path.join(ASSET_DIR, "cafe_sparkle.png") # Home -> お仕事 (Work hub) -> 任務 (Task) card -> Normal/Hard story region browser. WORK_ICON = (1793, 1138) TASK_CARD = (1370, 450) # Clicking past the last region is a harmless no-op (verified live) -- this # just needs to be >= the number of regions that will ever exist. REGION_RIGHT_ARROW = (1862, 598) REGION_RIGHT_ARROW_MAX_CLICKS = 60 # Stage list panel (right side of the region browser). Scrolling to either # extreme always shows exactly 4 full stage rows, since every region has at # least 5 stages -- scrolling past either end is a harmless no-op (verified # live), so a generous bounded click count is safe. Each stage row's "入場" # (enter) button sits at STAGE_ENTER_X across both scroll extremes; the two # row-position sets below were measured at each extreme. STAGE_LIST_SCROLL_POINT = (1400, 700) STAGE_LIST_SCROLL_CLICKS = 10 STAGE_ENTER_X = 1683 STAGE_ROWS_AT_TOP_Y = (424, 570, 718, 866) STAGE_ROWS_AT_BOTTOM_Y = (483, 630, 778, 926) # 任務情報 (stage info) modal's sweep sub-panel. This modal is wide enough # that navigation.MODAL_DIM_PROBE (960, 200) lands on the modal's own white # card instead of the dimmed backdrop -- use a corner point that's outside # the card in either scroll/region state instead. STAGE_MODAL_PROBE = (1870, 600) SWEEP_MAX_BUTTON = (1631, 507) SWEEP_START_BUTTON = (1400, 670) # The "-" stepper button next to the sweep count: flat grey (240,240,239) # while count is still at its default of 1, vivid orange (255,111,0) once # MAX (or any +) has raised it. Used to verify the MAX click actually landed # instead of trusting a single click blindly, since this gates real AP spend. SWEEP_MINUS_BUTTON_PROBE = (1280, 507) # The modal's own "X" close icon (top-right corner of the white card). # Escape does NOT close this modal (confirmed live: two Escape presses left # it open with focus on the live "任務開始"/start-mission button) -- must # click this explicitly. Pinned via pixel-scanline scan of the glyph's # crossing point, not visual estimation. STAGE_MODAL_CLOSE_BUTTON = (1691, 271)