diff --git a/src-tauri/backend/utils/image_utils.py b/src-tauri/backend/utils/image_utils.py index 89cd5498..a8813d22 100644 --- a/src-tauri/backend/utils/image_utils.py +++ b/src-tauri/backend/utils/image_utils.py @@ -44,6 +44,11 @@ class ImageUtils: _reader: easyocr.Reader = None + clickable_area = { + "template_support_summon": (0,-7,420,73), + "ok": (-70,-2,175,32) + } + @staticmethod def update_window_dimensions(window_left: int, window_top: int, window_width: int, window_height: int, additional_calibration_required: bool = False): """Updates the window dimensions for PyAutoGUI to perform faster operations in. @@ -851,6 +856,24 @@ def get_button_dimensions(image_name: str) -> Tuple[int, int]: width, height = image.size image.close() return width, height + + @staticmethod + def get_clickable_area(image_name: str) -> Tuple[int, int, int, int]: + """Get the clickable area in /images/buttons/ folder. + + Args: + image_name (str): File name of the image in /images/buttons/ folder. + + Returns: + (Tuple[int, int]): Tuple of the x-offset, y-offset, width and height. + """ + area = ImageUtils.clickable_area.get(image_name) + if area is not None: + return area + + width, height = ImageUtils.get_button_dimensions(image_name) + ImageUtils.clickable_area[image_name] = (0,0,width, height) + return 0,0, width, height @staticmethod def _take_screenshot(): diff --git a/src-tauri/backend/utils/mouse_utils.py b/src-tauri/backend/utils/mouse_utils.py index 4f9398f5..263b2ee0 100644 --- a/src-tauri/backend/utils/mouse_utils.py +++ b/src-tauri/backend/utils/mouse_utils.py @@ -9,6 +9,7 @@ from time import sleep import numpy as np +import math class MouseUtils: @@ -17,6 +18,10 @@ class MouseUtils: """ _hc = pyclick.HumanClicker() + # The lower the more smooth, the higher the more accurate to the speed + mouse_smoothness = max(0.01, Settings.mouse_smoothness/100) + # 1000 to 3000 is tested + mouse_speed = max(1000, 1000 * Settings.custom_mouse_speed) if Settings.enable_bezier_curve_mouse_movement is False: pyautogui.MINIMUM_DURATION = 0.1 @@ -36,11 +41,24 @@ def move_to(x: int, y: int, custom_mouse_speed: float = 0.0): None """ if Settings.enable_bezier_curve_mouse_movement: - # HumanClicker only accepts int as the mouse speed. - if int(custom_mouse_speed) < 1: - custom_mouse_speed = 1 - MouseUtils._hc.move((x, y), duration = custom_mouse_speed, humanCurve = pyclick.HumanCurve(pyautogui.position(), (x, y))) + target_pos = (x,y) + pos = pyautogui.position() + # estimate the mouse move distant with euclidean distant of 2 points + dist = [(a - b)**2 for a, b in zip(pos, target_pos)] + dist = math.sqrt(sum(dist)) + speed = MouseUtils.mouse_speed-np.random.randint(0,300) + # calculate the duration of the mouse movement + dur = 0.1+dist/speed + target_point_cnt = int(dur/MouseUtils.mouse_smoothness) + + if Settings.debug_mode: + MessageLog.print_message( + f"[DEBUG] Duration: {dur}, Number of points: {target_point_cnt})") + + curve = pyclick.HumanCurve(pos, target_pos, targetPoints=target_point_cnt) + + MouseUtils._hc.move((x, y), duration = dur, humanCurve = curve) else: if custom_mouse_speed <= 0.0: custom_mouse_speed = Settings.custom_mouse_speed @@ -50,7 +68,7 @@ def move_to(x: int, y: int, custom_mouse_speed: float = 0.0): return None @staticmethod - def move_and_click_point(x: int, y: int, image_name: str, custom_mouse_speed: float = 0.0, mouse_clicks: int = 1): + def move_and_click_point(x: int, y: int, image_name: str, custom_mouse_speed: float = 0.0, mouse_clicks: int = np.random.randint(1,3)): """Move the cursor to the specified point on the screen and clicks it. Args: @@ -71,24 +89,13 @@ def move_and_click_point(x: int, y: int, image_name: str, custom_mouse_speed: fl if Settings.debug_mode: MessageLog.print_message(f"[DEBUG] New coordinates: ({new_x}, {new_y})") - # Move the mouse to the specified coordinates. - if Settings.enable_bezier_curve_mouse_movement: - # HumanClicker only accepts int as the mouse speed. - if int(custom_mouse_speed) < 1: - custom_mouse_speed = 1 - - MouseUtils._hc.move((new_x, new_y), duration = custom_mouse_speed, humanCurve = pyclick.HumanCurve(pyautogui.position(), (new_x, new_y))) - else: - if custom_mouse_speed <= 0.0: - custom_mouse_speed = Settings.custom_mouse_speed - - pyautogui.moveTo(x, y, duration = custom_mouse_speed, tween = pyautogui.easeInOutQuad) - + MouseUtils.move_to(new_x,new_y, custom_mouse_speed=custom_mouse_speed) + pyautogui.mouseDown() sleep(np.random.uniform(0.02, 0.12)) pyautogui.mouseUp() for i in range (0, mouse_clicks-1): - sleep(np.random.uniform(0.1,0.2)) + sleep(np.random.uniform(0.08,0.16)) pyautogui.mouseDown() sleep(np.random.uniform(0.02, 0.12)) pyautogui.mouseUp() @@ -111,14 +118,16 @@ def _randomize_point(x: int, y: int, image_name: str): Returns: (int, int): Tuple of the newly randomized location to click. """ + from utils.image_utils import ImageUtils # Get the width and height of the template image. - from utils.image_utils import ImageUtils - width, height = ImageUtils.get_button_dimensions(image_name) - if Settings.farming_mode == "GenericV2": + if Settings.farming_mode.endswith("V2"): + x_off, y_off, width, height = ImageUtils.get_clickable_area(image_name) width = np.random.randint(0,width) height = np.random.randint(0,height) - return x+width, y+height + return x+x_off+width, y+y_off+height + + width, height = ImageUtils.get_button_dimensions(image_name) dimensions_x0 = x - (width // 2) dimensions_x1 = x + (width // 2) diff --git a/src-tauri/backend/utils/settings.py b/src-tauri/backend/utils/settings.py index 068b8130..4f159534 100644 --- a/src-tauri/backend/utils/settings.py +++ b/src-tauri/backend/utils/settings.py @@ -61,7 +61,8 @@ class Settings: # #### configuration #### reduce_delay_seconds: float = dictor(_data, "configuration.reduceDelaySeconds", 0.0) enable_bezier_curve_mouse_movement: bool = dictor(_data, "configuration.enableBezierCurveMouseMovement", True) - custom_mouse_speed: float = float(dictor(_data, "configuration.mouseSpeed", 0.2)) + custom_mouse_speed: float = float(dictor(_data, "configuration.mouseSpeed", 1.5)) + mouse_smoothness: float = float(dictor(_data, "configuration.mouseSmoothness", 2)) enable_delay_between_runs: bool = dictor(_data, "configuration.enableDelayBetweenRuns", False) delay_in_seconds: int = dictor(_data, "configuration.delayBetweenRuns", 15) enable_randomized_delay_between_runs: bool = dictor(_data, "configuration.enableRandomizedDelayBetweenRuns", False) diff --git a/src/context/BotStateContext.tsx b/src/context/BotStateContext.tsx index 63551d50..90f9b366 100644 --- a/src/context/BotStateContext.tsx +++ b/src/context/BotStateContext.tsx @@ -46,6 +46,7 @@ export interface Settings { reduceDelaySeconds: number enableBezierCurveMouseMovement: boolean mouseSpeed: number + mouseSmoothness: number enableDelayBetweenRuns: boolean delayBetweenRuns: number enableRandomizedDelayBetweenRuns: boolean @@ -203,7 +204,8 @@ export const defaultSettings: Settings = { configuration: { reduceDelaySeconds: 0.0, enableBezierCurveMouseMovement: true, - mouseSpeed: 0.2, + mouseSpeed: 1.5, + mouseSmoothness: 2, enableDelayBetweenRuns: false, delayBetweenRuns: 15, enableRandomizedDelayBetweenRuns: false, diff --git a/src/pages/ExtraSettings/index.tsx b/src/pages/ExtraSettings/index.tsx index 8771078d..2e8d2b9b 100644 --- a/src/pages/ExtraSettings/index.tsx +++ b/src/pages/ExtraSettings/index.tsx @@ -195,7 +195,7 @@ const ExtraSettings = () => { - + { onChange={(checked) => bsc.setSettings({ ...bsc.settings, configuration: { ...bsc.settings.configuration, enableBezierCurveMouseMovement: checked } })} /> - - {!bsc.settings.configuration.enableBezierCurveMouseMovement ? ( - bsc.setSettings({ ...bsc.settings, configuration: { ...bsc.settings.configuration, mouseSpeed: value } })} - min={0} - step={0.01} - description="Set how fast a mouse operation finishes." - /> - ) : null} + + + + + bsc.setSettings({ ...bsc.settings, configuration: { ...bsc.settings.configuration, mouseSpeed: value } })} + min={0} + step={0.01} + description="Sets the factor on how fast a mouse operation moves." + /> + + + {bsc.settings.configuration.enableBezierCurveMouseMovement ? ( + <> + bsc.setSettings({ ...bsc.settings, configuration: { ...bsc.settings.configuration, mouseSmoothness: value } })} + min={0} + step={0.01} + description="Sets the factor on how smooth the mouse movement should be. A lower value has it more smoother (more points along the curve to pass through) and a high value has it move more rigidly (less points along the curve)." + /> + + ) : null} + +