fishyboteso/fishy/engine/fullautofisher/engine.py
2021-04-18 12:52:57 +05:30

215 lines
6.4 KiB
Python

import math
import traceback
from enum import Enum
from threading import Thread
import cv2
import logging
import time
from fishy.constants import libgps, fishyqr, lam2
from fishy.engine.fullautofisher.qr_detection import get_values_from_image, get_qr_location
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.helper import sign
mse = mouse.Controller()
kb = keyboard.Controller()
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)
dim = (width, height)
img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
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.calibrator import Calibrator
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.calibrator = Calibrator(self)
self.test = Test(self)
self.controls = Controls(controls.get_controls(self))
self.show_crop = False
def run(self):
addons_req = [libgps, lam2, fishyqr]
for addon in addons_req:
if not helper.addon_exists(*addon):
helper.install_addon(*addon)
FullAuto.state = State.NONE
self.gui.bot_started(True)
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")
try:
self.window.crop = get_qr_location(self.window.get_capture())
if self.window.crop is None:
logging.warning("FishyQR not found")
self.start = False
raise Exception("FishyQR not found")
if not self.calibrator.all_callibrated():
logging.error("you need to calibrate first")
self.fisher.toggle_start()
fishing_event.unsubscribe()
self.controls.initialize()
while self.start and WindowClient.running():
if self.show_crop:
self.window.show(self.show_crop, func=image_pre_process)
else:
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.calibrator.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.calibrator.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.calibrator.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.LOOKING:
return True
def found_hole(e):
if e == fishing_mode.State.LOOKING:
self._hole_found_flag = True
fishing_mode.subscribers.append(found_hole)
t = 0
while not self._hole_found_flag and t <= 1.25:
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()