From 6cdcb6d952b59e42ccf1c0533471ee2d03370dc5 Mon Sep 17 00:00:00 2001 From: Xi Xu Date: Sat, 17 May 2025 19:54:14 +0800 Subject: [PATCH] Update run.py --- run.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/run.py b/run.py index 5af46d4..3b0ddcf 100644 --- a/run.py +++ b/run.py @@ -38,13 +38,34 @@ COORDINATES = { "captcha_input": (1851, 570), # CAPTCHA input field "captcha_region": (1628, 550, 1776, 592), # Screen region containing CAPTCHA image } + +# Pixel check points and expected colors for each UI stage +PIXEL_CHECKS = { + "miniprogram_loaded": { + "position": (1505, 229), + "color": (54, 61, 77), + "timeout": 5, + }, + "reservation_page_loaded": { + "position": (1019, 351), + "color": (255, 161, 18), + "timeout": 5, + }, + "venue_page_loaded": { + "position": (1038, 133), + "color": (255, 161, 18), + "timeout": 5, + }, + "court_page_loaded": { + "position": (1192, 988), + "color": (149, 152, 159), + "timeout": 3, + }, + "court_selected": {"position": (1138, 993), "color": (46, 49, 66), "timeout": 3}, +} + CAPTCHA_CHECK_PIXEL = (1109, 987) # Pixel to check for CAPTCHA presence CAPTCHA_CHECK_COLOR = (46, 49, 66) # Expected color when CAPTCHA is visible -WAIT_TIMES = { - "short": 0.2, - "long": 0.4, - "captcha": 0.05, -} # Wait durations in seconds def wait_until_scheduled_time(): @@ -66,10 +87,45 @@ def wait_until_scheduled_time(): logging.info(f"Sleeping for {time_to_sleep:.2f} seconds") time.sleep(time_to_sleep) while datetime.now() < target_time: - time.sleep(0.1) + time.sleep(0.01) logging.info("Starting reservation process") +def wait_for_pixel_color(position, color, timeout=5, check_interval=0.01): + """ + Wait until the pixel at the given position changes to the expected color or timeout is reached. + + Args: + position (tuple): (x, y) coordinates of the pixel to check + color (tuple): Expected RGB color value (r, g, b) + timeout (float): Maximum time to wait in seconds + check_interval (float): Time between checks in seconds + + Returns: + bool: True if the pixel color matched, False if timeout was reached + """ + x, y = position + start_time = time.time() + logging.info(f"Waiting for pixel at ({x}, {y}) to change to color {color}") + + while time.time() - start_time < timeout: + pixel_color = Image.fromarray( + np.array(pyautogui.screenshot(region=(x, y, 1, 1))) + ).getpixel((0, 0)) + + # Check if colors are close enough (allow small variations) + if pixel_color == color: + logging.info(f"Pixel color matched: {pixel_color}") + return True + + time.sleep(check_interval) + + logging.warning( + f"Timeout waiting for pixel at ({x}, {y}) to change to {color}, current color: {pixel_color}" + ) + return False + + def click_at(position_name): """ Click at a predefined position on the screen. @@ -97,7 +153,7 @@ def hold_and_drag(start_position_name, end_position_name): ) pyautogui.moveTo(start_x, start_y) pyautogui.mouseDown() - pyautogui.moveTo(end_x, end_y, duration=0.3) # duration for a smoother drag + pyautogui.moveTo(end_x, end_y, duration=0.25) # duration for a smoother drag pyautogui.mouseUp() @@ -130,7 +186,8 @@ def input_captcha(text): text (str): CAPTCHA text to input """ click_at("captcha_input") - time.sleep(WAIT_TIMES["short"]) + # Wait briefly for input focus + time.sleep(0.01) pyautogui.hotkey("ctrl", "a") # Select all existing text pyautogui.typewrite(text) @@ -158,23 +215,23 @@ def main(): pyautogui.FAILSAFE = False # Disable failsafe to prevent interruptions wait_until_scheduled_time() - # Click on the mini-program icon to open the reservation interface and move it to the screen right edge + # Click on the mini-program icon to open the reservation interface click_at("miniprogram_icon") - time.sleep(WAIT_TIMES["short"]) + + # Move window to the edge hold_and_drag("title_bar", "right_edge") - time.sleep(WAIT_TIMES["short"]) + wait_for_pixel_color(**PIXEL_CHECKS["miniprogram_loaded"]) # Navigate through reservation interface click_at("reservation_button") - time.sleep(WAIT_TIMES["long"]) + wait_for_pixel_color(**PIXEL_CHECKS["reservation_page_loaded"]) click_at("venue_button") - time.sleep(WAIT_TIMES["long"]) + wait_for_pixel_color(**PIXEL_CHECKS["venue_page_loaded"]) click_at("badminton_button") - time.sleep(WAIT_TIMES["short"]) click_at("reserve_button") - time.sleep(WAIT_TIMES["short"]) + wait_for_pixel_color(**PIXEL_CHECKS["court_page_loaded"]) click_at("court_selection") - time.sleep(WAIT_TIMES["short"]) + wait_for_pixel_color(**PIXEL_CHECKS["court_selected"]) click_at("confirm_button") # Handle CAPTCHA if presented @@ -184,9 +241,9 @@ def main(): logging.info(f"CAPTCHA attempt {captcha_attempts}") captcha_text = solve_captcha() input_captcha(captcha_text) - time.sleep(WAIT_TIMES["captcha"]) + time.sleep(0.05) click_at("confirm_button") - time.sleep(WAIT_TIMES["short"]) + time.sleep(0.2) # Report final status if captcha_attempts >= 10: