import math import logging import time import cv2 import numpy as np from fishy.engine.fullautofisher.engine import FullAuto from pynput import keyboard, mouse from fishy.helper import hotkey from fishy.helper.config import config from fishy.helper.helper import wait_until from fishy.helper.hotkey import Key mse = mouse.Controller() kb = keyboard.Controller() offset = 0 def get_crop_coods(window): img = window.get_capture() img = cv2.inRange(img, 0, 1) cnt, h = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) """ code from https://stackoverflow.com/a/45770227/4512396 """ for i in range(len(cnt)): area = cv2.contourArea(cnt[i]) if 5000 < area < 100000: mask = np.zeros_like(img) cv2.drawContours(mask, cnt, i, 255, -1) x, y, w, h = cv2.boundingRect(cnt[i]) return x, y + offset, x + w, y + h - offset def _update_factor(key, value): full_auto_factors = config.get("full_auto_factors", {}) full_auto_factors[key] = value config.set("full_auto_factors", full_auto_factors) def _get_factor(key): return config.get("full_auto_factors", {}).get(key) class Calibrate: def __init__(self, engine: FullAuto): self._callibrate_state = -1 self.engine = engine # region getters @property def crop(self): return _get_factor("crop") @property def move_factor(self): return _get_factor("move_factor") @property def rot_factor(self): return _get_factor("rot_factor") @property def time_to_reach_bottom(self): return _get_factor("time_to_reach_bottom") # endregion def all_callibrated(self): return self.crop is not None and self.move_factor is not None and self.rot_factor is not None def toggle_show(self): self.engine.show_crop = not self.engine.show_crop def update_crop(self, enable_crop=True): if enable_crop: self.engine.show_crop = True crop = get_crop_coods(self.engine.window) _update_factor("crop", crop) self.engine.window.crop = crop def walk_calibrate(self): walking_time = 3 coods = self.engine.get_coods() if coods is None: return x1, y1, rot1 = coods kb.press('w') time.sleep(walking_time) kb.release('w') time.sleep(0.5) coods = self.engine.get_coods() if coods is None: return x2, y2, rot2 = coods move_factor = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / walking_time _update_factor("move_factor", move_factor) logging.info("done") def rotate_calibrate(self): rotate_times = 50 coods = self.engine.get_coods() if coods is None: return _, _, rot2 = coods for _ in range(rotate_times): mse.move(FullAuto.rotate_by, 0) time.sleep(0.05) coods = self.engine.get_coods() if coods is None: return x3, y3, rot3 = coods if rot3 > rot2: rot3 -= 360 rot_factor = (rot3 - rot2) / rotate_times _update_factor("rot_factor", rot_factor) logging.info("done") def time_to_reach_bottom_callibrate(self): self._callibrate_state = 0 def _f8_pressed(): self._callibrate_state += 1 logging.info("look straight up and press f8") hotkey.set_hotkey(Key.F8, _f8_pressed) wait_until(lambda: self._callibrate_state == 1) logging.info("as soon as you look on the floor, press f8 again") y_cal_start_time = time.time() while self._callibrate_state == 1: mse.move(0, FullAuto.rotate_by) time.sleep(0.05) hotkey.free_key(Key.F8) time_to_reach_bottom = time.time() - y_cal_start_time _update_factor("time_to_reach_bottom", time_to_reach_bottom) logging.info("done")