diff --git a/fishy/engine/common/qr_detection.py b/fishy/engine/common/qr_detection.py index b995af1..6416820 100644 --- a/fishy/engine/common/qr_detection.py +++ b/fishy/engine/common/qr_detection.py @@ -3,11 +3,38 @@ import re import cv2 import numpy as np +from fishy.engine.common.window import WindowClient detector = cv2.QRCodeDetector() -def image_pre_process(img): +# noinspection PyBroadException +def get_values(window: WindowClient): + values = None + for _ in range(5): + img = window.processed_image(func=_image_pre_process) + if img is None: + logging.debug("Couldn't capture window.") + continue + + if not window.crop: + window.crop = _get_qr_location(img) + if not window.crop: + logging.debug("FishyQR not found.") + continue + img = window.processed_image(func=_image_pre_process) + + values = _get_values_from_image(img) + if not values: + window.crop = None + logging.debug("Values not able to read.") + continue + break + + return values + + +def _image_pre_process(img): scale_percent = 100 # percent of original size width = int(img.shape[1] * scale_percent / 100) height = int(img.shape[0] * scale_percent / 100) @@ -16,7 +43,7 @@ def image_pre_process(img): return img -def get_qr_location(image): +def _get_qr_location(image): """ code from https://stackoverflow.com/a/45770227/4512396 """ @@ -29,16 +56,15 @@ def get_qr_location(image): return [int(x) for x in [p[0][0], p[0][1], p[1][0], p[2][1]]] -# noinspection PyBroadException -def get_values_from_image(img): +def _get_values_from_image(img): h, w = img.shape points = np.array([[(0, 0), (w, 0), (w, h), (0, h)]]) code = detector.decode(img, points)[0] - return parse_qr_code(code) + return _parse_qr_code(code) # this needs to be updated each time qr code format is changed -def parse_qr_code(code): +def _parse_qr_code(code): if not code: return None match = re.match(r'^(-?\d+\.\d+),(-?\d+\.\d+),(-?\d+),(\d+)$', code) diff --git a/fishy/engine/fullautofisher/engine.py b/fishy/engine/fullautofisher/engine.py index 83ccd52..3ce9a54 100644 --- a/fishy/engine/fullautofisher/engine.py +++ b/fishy/engine/fullautofisher/engine.py @@ -3,6 +3,7 @@ import math import time from threading import Thread +from fishy.engine.common import qr_detection from pynput import keyboard, mouse from fishy.engine import SemiFisherEngine @@ -12,8 +13,6 @@ from fishy.engine.fullautofisher.mode.calibrator import Calibrator from fishy.engine.fullautofisher.mode.imode import FullAutoMode from fishy.engine.fullautofisher.mode.player import Player from fishy.engine.fullautofisher.mode.recorder import Recorder -from fishy.engine.common.qr_detection import (get_qr_location, - get_values_from_image, image_pre_process) from fishy.engine.semifisher import fishing_mode from fishy.engine.semifisher.fishing_mode import FishingMode from fishy.helper.config import config @@ -60,7 +59,13 @@ class FullAuto(IEngine): logging.info("starting in 2 secs...") time.sleep(2) - if not self._pre_run_checks(): + if not (type(self.mode) is Calibrator) and not self.calibrator.all_calibrated(): + logging.error("you need to calibrate first") + return + + if not qr_detection.get_values(self.window): + logging.error("FishyQR not found, if its not hidden, try to drag it around, " + "or increase/decrease its size and try again\nStopping engine...") return if config.get("tabout_stop", 1): @@ -73,26 +78,10 @@ class FullAuto(IEngine): logging.error("exception occurred while running full auto mode") print_exc() - def _pre_run_checks(self): - if self.window.get_capture() is None: - logging.error("Game window not found") - return False - - self.window.crop = get_qr_location(self.window.get_capture()) - if self.window.crop is None: - logging.error("FishyQR not found, try to drag it around and try again") - return False - - if not (type(self.mode) is Calibrator) and not self.calibrator.all_calibrated(): - logging.error("you need to calibrate first") - return False - - return True - def start_show(self): def func(): while self.start and WindowClient.running(): - self.window.show(self.show_crop, func=image_pre_process) + self.window.show(self.show_crop) Thread(target=func).start() def stop_on_inactive(self): @@ -111,8 +100,7 @@ class FullAuto(IEngine): todo find a better way of handling None: switch from start bool to state which knows todo its waiting for qr which doesn't block the engine when commanded to close """ - img = self.window.processed_image(func=image_pre_process) - values = get_values_from_image(img) + values = qr_detection.get_values(self.window) return values[:3] if values else None def move_to(self, target) -> bool: diff --git a/fishy/engine/semifisher/engine.py b/fishy/engine/semifisher/engine.py index d7b21df..90833b5 100644 --- a/fishy/engine/semifisher/engine.py +++ b/fishy/engine/semifisher/engine.py @@ -4,10 +4,11 @@ import typing from threading import Thread from typing import Callable, Optional +from fishy.engine.common import qr_detection + from fishy.engine.semifisher.fishing_mode import FishingMode from fishy.engine.common.IEngine import IEngine -from fishy.engine.common.qr_detection import get_qr_location, get_values_from_image, image_pre_process from fishy.engine.common.window import WindowClient from fishy.engine.semifisher import fishing_event, fishing_mode from fishy.engine.semifisher.fishing_event import FishEvent @@ -35,15 +36,6 @@ class SemiFisherEngine(IEngine): Thread(target=self._wait_and_check).start() time.sleep(0.2) - capture = self.window.get_capture() - if capture is None: - logging.error("couldn't get game capture") - return - - self.window.crop = get_qr_location(capture) - if not self.window.crop: - logging.error("FishyQR not found, try to drag it around and try again") - return fishing_event.init() # noinspection PyBroadException @@ -59,15 +51,9 @@ class SemiFisherEngine(IEngine): def _engine_loop(self): skip_count = 0 while self.state == 1 and WindowClient.running(): - capture = self.window.processed_image(func=image_pre_process) - - # if window server crashed - if capture is None: - logging.error("Couldn't capture window stopping engine") - return - # crop qr and get the values from it - self.values = get_values_from_image(capture) + self.values = qr_detection.get_values(self.window) + # if fishyqr fails to get read multiple times, stop the bot if not self.values: if skip_count >= 5: