fishyboteso/fishy/engine/fullautofisher/engine.py

222 lines
7.0 KiB
Python
Raw Normal View History

2021-05-09 07:05:51 +00:00
import logging
import math
2021-05-09 07:05:51 +00:00
import time
import traceback
from threading import Thread
import cv2
2021-05-09 07:05:51 +00:00
from pynput import keyboard, mouse
2020-06-01 12:58:18 +00:00
2021-05-09 07:05:51 +00:00
from fishy.constants import fishyqr, lam2, libgps
from fishy.engine import SemiFisherEngine
from fishy.engine.common.IEngine import IEngine
2021-05-09 07:05:51 +00:00
from fishy.engine.common.window import WindowClient
2021-05-02 16:49:44 +00:00
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)
2021-05-09 07:05:51 +00:00
from fishy.engine.semifisher import fishing_event, fishing_mode
from fishy.engine.semifisher.fishing_mode import FishingMode
2021-05-09 07:05:51 +00:00
from fishy.helper import helper, hotkey
from fishy.helper.config import config
from fishy.helper.helper import log_raise, wait_until, is_eso_active
2021-04-18 07:22:57 +00:00
from fishy.helper.helper import sign
2020-06-25 13:40:05 +00:00
mse = mouse.Controller()
kb = keyboard.Controller()
2020-06-01 12:58:18 +00:00
class FullAuto(IEngine):
rotate_by = 30
2020-10-17 19:06:07 +00:00
def __init__(self, gui_ref):
from fishy.engine.fullautofisher.test import Test
super().__init__(gui_ref)
2020-10-15 02:23:15 +00:00
self._hole_found_flag = False
self._curr_rotate_y = 0
2020-10-17 22:35:20 +00:00
self.fisher = SemiFisherEngine(None)
self.calibrator = Calibrator(self)
self.test = Test(self)
self.show_crop = False
self.mode = None
2020-06-01 12:58:18 +00:00
def run(self):
self.gui.bot_started(True)
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")
2021-05-02 16:49:44 +00:00
self.mode = None
if config.get("calibrate", False):
self.mode = Calibrator(self)
elif FullAutoMode(config.get("full_auto_mode", 0)) == FullAutoMode.Player:
self.mode = Player(self)
elif FullAutoMode(config.get("full_auto_mode", 0)) == FullAutoMode.Recorder:
self.mode = Recorder(self)
if not is_eso_active():
logging.info("Waiting for eso window to be active...")
wait_until(lambda: is_eso_active() or not self.start)
if self.start:
logging.info("starting in 2 secs...")
time.sleep(2)
# noinspection PyBroadException
try:
if self.window.get_capture() is None:
log_raise("Game window not found")
self.window.crop = get_qr_location(self.window.get_capture())
if self.window.crop is None:
log_raise("FishyQR not found")
if not (type(self.mode) is Calibrator) and not self.calibrator.all_calibrated():
log_raise("you need to calibrate first")
self.fisher.toggle_start()
fishing_event.unsubscribe()
if self.show_crop:
self.start_show()
if config.get("tabout_stop", 1):
self.stop_on_inactive()
self.mode.run()
except Exception:
traceback.print_exc()
self.start = False
2020-06-01 12:58:18 +00:00
self.gui.bot_started(False)
self.window.show(False)
logging.info("Quitting")
self.window.destory()
self.fisher.toggle_start()
def start_show(self):
def func():
while self.start and WindowClient.running():
self.window.show(self.show_crop, func=image_pre_process)
Thread(target=func).start()
def stop_on_inactive(self):
def func():
wait_until(lambda: not is_eso_active())
self.start = False
Thread(target=func).start()
def get_coords(self):
"""
There is chance that this function give None instead of a QR.
Need to handle manually
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)
return get_values_from_image(img)
def move_to(self, target) -> bool:
current = self.get_coords()
if not current:
return False
2020-06-25 13:40:05 +00:00
print(f"Moving from {(current[0], current[1])} to {target}")
2020-06-25 13:40:05 +00:00
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 True
target_angle = math.degrees(math.atan2(-move_vec[1], move_vec[0])) + 90
from_angle = current[2]
if not self.rotate_to(target_angle, from_angle):
return False
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")
return True
def rotate_to(self, target_angle, from_angle=None) -> bool:
if from_angle is None:
coords = self.get_coords()
if not coords:
return False
_, _, from_angle = coords
2020-06-25 13:40:05 +00:00
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}")
2020-06-25 13:40:05 +00:00
angle_diff = target_angle - from_angle
2020-06-25 13:40:05 +00:00
if abs(angle_diff) > 180:
angle_diff = (360 - abs(angle_diff)) * sign(angle_diff) * -1
2020-06-25 13:40:05 +00:00
rotate_times = int(angle_diff / self.calibrator.rot_factor) * -1
2020-06-25 13:40:05 +00:00
print(f"rotate_times: {rotate_times}")
2020-06-25 13:40:05 +00:00
for _ in range(abs(rotate_times)):
mse.move(sign(rotate_times) * FullAuto.rotate_by * -1, 0)
2020-06-25 13:40:05 +00:00
time.sleep(0.05)
return True
def look_for_hole(self) -> bool:
2020-10-15 02:23:15 +00:00
self._hole_found_flag = False
if FishingMode.CurrentMode == fishing_mode.State.LOOKING:
return True
2020-10-15 02:23:15 +00:00
def found_hole(e):
if e == fishing_mode.State.LOOKING:
2020-10-15 02:23:15 +00:00
self._hole_found_flag = True
fishing_mode.subscribers.append(found_hole)
2020-10-15 02:23:15 +00:00
t = 0
while not self._hole_found_flag and t <= 1.25:
2020-10-15 02:23:15 +00:00
mse.move(0, FullAuto.rotate_by)
time.sleep(0.05)
t += 0.05
while not self._hole_found_flag and t > 0:
2020-10-15 02:23:15 +00:00
mse.move(0, -FullAuto.rotate_by)
time.sleep(0.05)
t -= 0.05
self._curr_rotate_y = t
fishing_mode.subscribers.remove(found_hole)
2020-10-15 02:23:15 +00:00
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):
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)
2020-10-17 22:35:20 +00:00
hotkey.initalize()
# noinspection PyTypeChecker
2020-10-17 19:06:07 +00:00
bot = FullAuto(None)
bot.toggle_start()