import math import os import tempfile import traceback import uuid from enum import Enum from threading import Thread from zipfile import ZipFile import cv2 import logging import time import numpy as np import pytesseract from fishy.engine.fullautofisher.tesseract import is_tesseract_installed, downlaoad_and_extract_tesseract, \ get_values_from_image from fishy.engine.semifisher.fishing_mode import FishingMode from fishy.engine import SemiFisherEngine from fishy.engine.common.window import WindowClient from fishy.engine.semifisher import fishing_mode, fishing_event from fishy.engine.common.IEngine import IEngine from pynput import keyboard, mouse from fishy.helper import hotkey, helper from fishy.helper.config import config from fishy.helper.downloader import download_file_from_google_drive from fishy.helper.helper import sign from fishy.helper.hotkey import Key mse = mouse.Controller() kb = keyboard.Controller() def image_pre_process(img): scale_percent = 200 # percent of original size width = int(img.shape[1] * scale_percent / 100) height = int(img.shape[0] * scale_percent / 100) dim = (width, height) img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) img = cv2.bitwise_not(img) return img class State(Enum): NONE = 0 PLAYING = 1 RECORDING = 2 OTHER = 3 class FullAuto(IEngine): rotate_by = 30 state = State.NONE def __init__(self, gui_ref): from fishy.engine.fullautofisher.controls import Controls from fishy.engine.fullautofisher import controls from fishy.engine.fullautofisher.calibrate import Calibrate from fishy.engine.fullautofisher.test import Test super().__init__(gui_ref) self._hole_found_flag = False self._curr_rotate_y = 0 self.fisher = SemiFisherEngine(None) self.calibrate = Calibrate(self) self.test = Test(self) self.controls = Controls(controls.get_controls(self)) self.show_crop = False def run(self): self.show_crop = False FullAuto.state = State.NONE self.gui.bot_started(True) fishing_event.unsubscribe() self.fisher.toggle_start() self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug") try: if self.calibrate.crop is None: self.calibrate.update_crop(enable_crop=False) self.window.crop = self.calibrate.crop if not is_tesseract_installed(): logging.info("tesseract not found") downlaoad_and_extract_tesseract() if not self.calibrate.all_callibrated(): logging.error("you need to callibrate first") self.controls.initialize() while self.start and WindowClient.running(): self.window.show(self.show_crop, func=image_pre_process) if not self.show_crop: time.sleep(0.1) except: traceback.print_exc() if self.window.get_capture() is None: logging.error("Game window not found") self.gui.bot_started(False) self.controls.unassign_keys() self.window.show(False) logging.info("Quitting") self.window.destory() self.fisher.toggle_start() def get_coods(self): img = self.window.processed_image(func=image_pre_process) return get_values_from_image(img) def move_to(self, target): if target is None: logging.error("set target first") return if not self.calibrate.all_callibrated(): logging.error("you need to callibrate first") return current = self.get_coods() print(f"Moving from {(current[0], current[1])} to {target}") move_vec = target[0] - current[0], target[1] - current[1] dist = math.sqrt(move_vec[0] ** 2 + move_vec[1] ** 2) print(f"distance: {dist}") if dist < 5e-05: print("distance very small skipping") return target_angle = math.degrees(math.atan2(-move_vec[1], move_vec[0])) + 90 from_angle = current[2] self.rotate_to(target_angle, from_angle) walking_time = dist / self.calibrate.move_factor print(f"walking for {walking_time}") kb.press('w') time.sleep(walking_time) kb.release('w') print("done") def rotate_to(self, target_angle, from_angle=None): if from_angle is None: _, _, from_angle = self.get_coods() if target_angle < 0: target_angle = 360 + target_angle while target_angle > 360: target_angle -= 360 print(f"Rotating from {from_angle} to {target_angle}") angle_diff = target_angle - from_angle if abs(angle_diff) > 180: angle_diff = (360 - abs(angle_diff)) * sign(angle_diff) * -1 rotate_times = int(angle_diff / self.calibrate.rot_factor) * -1 print(f"rotate_times: {rotate_times}") for _ in range(abs(rotate_times)): mse.move(sign(rotate_times) * FullAuto.rotate_by * -1, 0) time.sleep(0.05) def look_for_hole(self): self._hole_found_flag = False if FishingMode.CurrentMode == fishing_mode.State.LOOK: return True def found_hole(e): if e == fishing_mode.State.LOOK: self._hole_found_flag = True fishing_mode.subscribers.append(found_hole) t = 0 while not self._hole_found_flag and t <= self.calibrate.time_to_reach_bottom / 3: mse.move(0, FullAuto.rotate_by) time.sleep(0.05) t += 0.05 while not self._hole_found_flag and t > 0: mse.move(0, -FullAuto.rotate_by) time.sleep(0.05) t -= 0.05 self._curr_rotate_y = t fishing_mode.subscribers.remove(found_hole) return self._hole_found_flag def rotate_back(self): while self._curr_rotate_y > 0.01: mse.move(0, -FullAuto.rotate_by) time.sleep(0.05) self._curr_rotate_y -= 0.05 def toggle_start(self): if self.start and FullAuto.state != State.NONE: logging.info("Please turn off RECORDING/PLAYING first") return self.start = not self.start if self.start: self.thread = Thread(target=self.run) self.thread.start() if __name__ == '__main__': logging.getLogger("").setLevel(logging.DEBUG) hotkey.initalize() # noinspection PyTypeChecker bot = FullAuto(None) bot.toggle_start()