mirror of
https://github.com/fishyboteso/fishyboteso.git
synced 2024-08-30 18:32:13 +00:00
abstracted modules of fullauto engine into different scripts
This commit is contained in:
@ -2,6 +2,9 @@ import math
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from fishy.engine.fullautofisher.engine import FullAuto
|
from fishy.engine.fullautofisher.engine import FullAuto
|
||||||
from pynput import keyboard, mouse
|
from pynput import keyboard, mouse
|
||||||
|
|
||||||
@ -13,30 +16,77 @@ from fishy.helper.hotkey import Key
|
|||||||
mse = mouse.Controller()
|
mse = mouse.Controller()
|
||||||
kb = keyboard.Controller()
|
kb = keyboard.Controller()
|
||||||
|
|
||||||
"""
|
offset = 0
|
||||||
-1 callibrating speed and rotation,
|
|
||||||
0, waiting for looking up and first f8,
|
|
||||||
1, waiting for reaching down and second f8,
|
|
||||||
2 done
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class Calibrate():
|
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):
|
||||||
|
config.get("full_auto_factors", {}).get(key)
|
||||||
|
|
||||||
|
|
||||||
|
class Calibrate:
|
||||||
def __init__(self, engine: FullAuto):
|
def __init__(self, engine: FullAuto):
|
||||||
self._callibrate_state = -1
|
self._callibrate_state = -1
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
|
|
||||||
def f8_pressed(self):
|
# region getters
|
||||||
self._callibrate_state += 1
|
@property
|
||||||
|
def crop(self):
|
||||||
|
return _get_factor("crop")
|
||||||
|
|
||||||
def callibrate(self):
|
@property
|
||||||
logging.debug("Callibrating...")
|
def move_factor(self):
|
||||||
_callibrate_state = -1
|
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 and self.move_factor and self.rot_factor
|
||||||
|
|
||||||
|
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)
|
||||||
|
self.engine.window.crop = self.engine.crop
|
||||||
|
_update_factor("crop", crop)
|
||||||
|
|
||||||
|
def walk_calibrate(self):
|
||||||
walking_time = 3
|
walking_time = 3
|
||||||
rotate_times = 50
|
|
||||||
|
|
||||||
# region rotate and move
|
|
||||||
coods = self.engine.get_coods()
|
coods = self.engine.get_coods()
|
||||||
if coods is None:
|
if coods is None:
|
||||||
return
|
return
|
||||||
@ -53,6 +103,17 @@ class Calibrate():
|
|||||||
return
|
return
|
||||||
x2, y2, rot2 = coods
|
x2, y2, rot2 = coods
|
||||||
|
|
||||||
|
move_factor = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / walking_time
|
||||||
|
_update_factor("move_factor", move_factor)
|
||||||
|
|
||||||
|
def rotate_calibrate(self):
|
||||||
|
rotate_times = 50
|
||||||
|
|
||||||
|
coods = self.engine.get_coods()
|
||||||
|
if coods is None:
|
||||||
|
return
|
||||||
|
_, _, rot2 = coods
|
||||||
|
|
||||||
for _ in range(rotate_times):
|
for _ in range(rotate_times):
|
||||||
mse.move(FullAuto.rotate_by, 0)
|
mse.move(FullAuto.rotate_by, 0)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
@ -65,13 +126,17 @@ class Calibrate():
|
|||||||
if rot3 > rot2:
|
if rot3 > rot2:
|
||||||
rot3 -= 360
|
rot3 -= 360
|
||||||
|
|
||||||
move_factor = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / walking_time
|
|
||||||
rot_factor = (rot3 - rot2) / rotate_times
|
rot_factor = (rot3 - rot2) / rotate_times
|
||||||
# endregion
|
_update_factor("rot_factor", rot_factor)
|
||||||
|
|
||||||
|
def time_to_reach_bottom_callibrate(self):
|
||||||
|
self._callibrate_state = 0
|
||||||
|
|
||||||
|
def _f8_pressed():
|
||||||
|
self._callibrate_state += 1
|
||||||
|
|
||||||
logging.info("Now loop up and press f8")
|
logging.info("Now loop up and press f8")
|
||||||
|
hotkey.set_hotkey(Key.F8, _f8_pressed)
|
||||||
hotkey.set_hotkey(Key.F8, self.f8_pressed)
|
|
||||||
|
|
||||||
wait_until(lambda: self._callibrate_state == 1)
|
wait_until(lambda: self._callibrate_state == 1)
|
||||||
|
|
||||||
@ -81,11 +146,7 @@ class Calibrate():
|
|||||||
while self._callibrate_state == 1:
|
while self._callibrate_state == 1:
|
||||||
mse.move(0, FullAuto.rotate_by)
|
mse.move(0, FullAuto.rotate_by)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
|
hotkey.free_key(Key.F8)
|
||||||
|
|
||||||
time_to_reach_bottom = time.time() - y_cal_start_time
|
time_to_reach_bottom = time.time() - y_cal_start_time
|
||||||
|
_update_factor("time_to_reach_bottom", time_to_reach_bottom)
|
||||||
self.engine.factors = move_factor, rot_factor, time_to_reach_bottom
|
|
||||||
config.set("full_auto_factors", self.engine.factors)
|
|
||||||
logging.info(self.engine.factors)
|
|
||||||
|
|
||||||
hotkey.free_key(Key.F8)
|
|
||||||
|
60
fishy/engine/fullautofisher/controls.py
Normal file
60
fishy/engine/fullautofisher/controls.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from fishy.helper import hotkey
|
||||||
|
|
||||||
|
from fishy.engine.fullautofisher.engine import FullAuto
|
||||||
|
from fishy.helper.config import config
|
||||||
|
from fishy.helper.hotkey import Key
|
||||||
|
|
||||||
|
|
||||||
|
def get_controls(engine: FullAuto):
|
||||||
|
from fishy.engine.fullautofisher.calibrate import Calibrate
|
||||||
|
from fishy.engine.fullautofisher.recorder import Recorder
|
||||||
|
from fishy.engine.fullautofisher.player import Player
|
||||||
|
|
||||||
|
controls = [
|
||||||
|
# ("MAIN", {
|
||||||
|
# Key.RIGHT: Player(engine).start_route,
|
||||||
|
# Key.UP: Calibrate(engine).callibrate,
|
||||||
|
# Key.LEFT: Recorder(engine).start_recording,
|
||||||
|
# Key.DOWN: change_state
|
||||||
|
# }),
|
||||||
|
# ("COODS", {
|
||||||
|
# Key.RIGHT: print_coods,
|
||||||
|
# Key.UP: engine.update_crop,
|
||||||
|
# Key.LEFT: toggle_show,
|
||||||
|
# Key.DOWN: change_state
|
||||||
|
# }),
|
||||||
|
# ("TEST1", {
|
||||||
|
# Key.RIGHT: set_target,
|
||||||
|
# Key.UP: rotate_to_90,
|
||||||
|
# Key.LEFT: move_to_target,
|
||||||
|
# Key.DOWN: change_state
|
||||||
|
# })
|
||||||
|
]
|
||||||
|
|
||||||
|
return controls
|
||||||
|
|
||||||
|
|
||||||
|
class Controls:
|
||||||
|
def __init__(self, controls, first=0):
|
||||||
|
self.current_menu = first - 1
|
||||||
|
self.controls = controls
|
||||||
|
|
||||||
|
def change_state(self):
|
||||||
|
self.current_menu += 1
|
||||||
|
if self.current_menu == len(self.controls):
|
||||||
|
self.current_menu = 0
|
||||||
|
|
||||||
|
help_str = F"CONTROLS: {self.controls[self.current_menu][0]}"
|
||||||
|
for key, func in self.controls[self.current_menu][1].items():
|
||||||
|
hotkey.set_hotkey(key, func)
|
||||||
|
help_str += f"\n{key.value}: {func.__name__}"
|
||||||
|
logging.info(help_str)
|
||||||
|
|
||||||
|
def unassign_keys(self):
|
||||||
|
keys = []
|
||||||
|
for c in self.controls:
|
||||||
|
for k in c[1].keys():
|
||||||
|
if k not in keys:
|
||||||
|
hotkey.free_key(k)
|
@ -10,6 +10,9 @@ import time
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pytesseract
|
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.semifisher.fishing_mode import FishingMode
|
||||||
|
|
||||||
from fishy.engine import SemiFisherEngine
|
from fishy.engine import SemiFisherEngine
|
||||||
@ -22,53 +25,11 @@ from pynput import keyboard, mouse
|
|||||||
from fishy.helper import hotkey, helper
|
from fishy.helper import hotkey, helper
|
||||||
from fishy.helper.config import config
|
from fishy.helper.config import config
|
||||||
from fishy.helper.downloader import download_file_from_google_drive
|
from fishy.helper.downloader import download_file_from_google_drive
|
||||||
|
from fishy.helper.helper import sign
|
||||||
from fishy.helper.hotkey import Key
|
from fishy.helper.hotkey import Key
|
||||||
|
|
||||||
mse = mouse.Controller()
|
mse = mouse.Controller()
|
||||||
kb = keyboard.Controller()
|
kb = keyboard.Controller()
|
||||||
offset = 0
|
|
||||||
|
|
||||||
|
|
||||||
def downlaoad_and_extract_tesseract():
|
|
||||||
logging.info("Tesseract-OCR downlaoding, Please wait...")
|
|
||||||
|
|
||||||
f = tempfile.NamedTemporaryFile(delete=False)
|
|
||||||
download_file_from_google_drive("16llzcBlaCsG9fm-rY2dD4Gvopnhm3XoE", f)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
logging.info("Tesseract-OCR downloaded, now installing")
|
|
||||||
|
|
||||||
addon_dir = os.path.join(os.environ["APPDATA"], "Tesseract-OCR")
|
|
||||||
with ZipFile(f.name, 'r') as z:
|
|
||||||
z.extractall(path=addon_dir)
|
|
||||||
|
|
||||||
logging.info("Tesseract-OCR installed")
|
|
||||||
|
|
||||||
|
|
||||||
def is_tesseract_installed():
|
|
||||||
return os.path.exists(os.path.join(os.environ["APPDATA"], "Tesseract-OCR"))
|
|
||||||
|
|
||||||
|
|
||||||
def sign(x):
|
|
||||||
return -1 if x < 0 else 1
|
|
||||||
|
|
||||||
|
|
||||||
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 image_pre_process(img):
|
def image_pre_process(img):
|
||||||
@ -81,55 +42,32 @@ def image_pre_process(img):
|
|||||||
return img
|
return img
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyBroadException
|
|
||||||
def get_values_from_image(img, tesseract_dir):
|
|
||||||
try:
|
|
||||||
pytesseract.pytesseract.tesseract_cmd = tesseract_dir + '/tesseract.exe'
|
|
||||||
tessdata_dir_config = f'--tessdata-dir "{tesseract_dir}" -c tessedit_char_whitelist=0123456789.'
|
|
||||||
|
|
||||||
text = pytesseract.image_to_string(img, lang="eng", config=tessdata_dir_config)
|
|
||||||
text = text.replace(" ", "")
|
|
||||||
vals = text.split(":")
|
|
||||||
return float(vals[0]), float(vals[1]), float(vals[2])
|
|
||||||
except Exception:
|
|
||||||
logging.error("Couldn't read coods")
|
|
||||||
cv2.imwrite(f"fail_{str(uuid.uuid4())[:8]}", img)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class FullAuto(IEngine):
|
class FullAuto(IEngine):
|
||||||
rotate_by = 30
|
rotate_by = 30
|
||||||
|
|
||||||
def __init__(self, gui_ref):
|
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)
|
super().__init__(gui_ref)
|
||||||
self.factors = config.get("full_auto_factors", None)
|
|
||||||
self._tesseract_dir = None
|
|
||||||
self._target = None
|
|
||||||
self.crop = config.get("full_auto_crop")
|
|
||||||
|
|
||||||
if self.factors is None:
|
|
||||||
logging.warning("Please callibrate first")
|
|
||||||
|
|
||||||
self._hole_found_flag = False
|
self._hole_found_flag = False
|
||||||
self._curr_rotate_y = 0
|
self._curr_rotate_y = 0
|
||||||
|
|
||||||
self.fisher = SemiFisherEngine(None)
|
self.fisher = SemiFisherEngine(None)
|
||||||
self.controls = Controls(self.get_controls())
|
self.controls = Controls(controls.get_controls(self))
|
||||||
|
self.calibrate = Calibrate(self)
|
||||||
|
self.test = Test(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def show(self):
|
def show_crop(self):
|
||||||
return config.get("show_window_full_auto", False)
|
return config.get("show_window_full_auto", False)
|
||||||
|
|
||||||
@show.setter
|
@show_crop.setter
|
||||||
def show(self, x):
|
def show_crop(self, x):
|
||||||
config.set("show_window_full_auto", x)
|
config.set("show_window_full_auto", x)
|
||||||
|
|
||||||
def update_crop(self):
|
|
||||||
self.show = True
|
|
||||||
self.crop = get_crop_coods(self.window)
|
|
||||||
config.set("full_auto_crop", self.crop)
|
|
||||||
self.window.crop = self.crop
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
logging.info("Loading please wait...")
|
logging.info("Loading please wait...")
|
||||||
self.gui.bot_started(True)
|
self.gui.bot_started(True)
|
||||||
@ -137,19 +75,18 @@ class FullAuto(IEngine):
|
|||||||
self.fisher.toggle_start()
|
self.fisher.toggle_start()
|
||||||
|
|
||||||
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")
|
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")
|
||||||
if self.crop is None:
|
if self.calibrate.crop is None:
|
||||||
self.update_crop()
|
self.calibrate.update_crop(enable_crop=False)
|
||||||
self.window.crop = self.crop
|
self.window.crop = self.calibrate.crop
|
||||||
|
|
||||||
self._tesseract_dir = os.path.join(os.environ["APPDATA"], "Tesseract-OCR")
|
|
||||||
if not is_tesseract_installed():
|
if not is_tesseract_installed():
|
||||||
logging.info("tesseract not found")
|
logging.info("tesseract not found")
|
||||||
downlaoad_and_extract_tesseract()
|
downlaoad_and_extract_tesseract()
|
||||||
|
|
||||||
self.controls.change_state()
|
self.controls.change_state()
|
||||||
while self.start and WindowClient.running():
|
while self.start and WindowClient.running():
|
||||||
self.window.show(self.show, func=image_pre_process)
|
self.window.show(self.show_crop, func=image_pre_process)
|
||||||
if not self.show:
|
if not self.show_crop:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
self.gui.bot_started(False)
|
self.gui.bot_started(False)
|
||||||
@ -160,14 +97,15 @@ class FullAuto(IEngine):
|
|||||||
self.fisher.toggle_start()
|
self.fisher.toggle_start()
|
||||||
|
|
||||||
def get_coods(self):
|
def get_coods(self):
|
||||||
return get_values_from_image(self.window.processed_image(func=image_pre_process), self._tesseract_dir)
|
img = self.window.processed_image(func=image_pre_process)
|
||||||
|
return get_values_from_image(img)
|
||||||
|
|
||||||
def move_to(self, target):
|
def move_to(self, target):
|
||||||
if target is None:
|
if target is None:
|
||||||
logging.error("set target first")
|
logging.error("set target first")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.factors is None:
|
if not self.calibrate.all_callibrated():
|
||||||
logging.error("you need to callibrate first")
|
logging.error("you need to callibrate first")
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -186,7 +124,7 @@ class FullAuto(IEngine):
|
|||||||
|
|
||||||
self.rotate_to(target_angle, from_angle)
|
self.rotate_to(target_angle, from_angle)
|
||||||
|
|
||||||
walking_time = dist / self.factors[0]
|
walking_time = dist / self.calibrate.move_factor
|
||||||
print(f"walking for {walking_time}")
|
print(f"walking for {walking_time}")
|
||||||
kb.press('w')
|
kb.press('w')
|
||||||
time.sleep(walking_time)
|
time.sleep(walking_time)
|
||||||
@ -208,7 +146,7 @@ class FullAuto(IEngine):
|
|||||||
if abs(angle_diff) > 180:
|
if abs(angle_diff) > 180:
|
||||||
angle_diff = (360 - abs(angle_diff)) * sign(angle_diff) * -1
|
angle_diff = (360 - abs(angle_diff)) * sign(angle_diff) * -1
|
||||||
|
|
||||||
rotate_times = int(angle_diff / self.factors[1]) * -1
|
rotate_times = int(angle_diff / self.calibrate.rot_factor) * -1
|
||||||
|
|
||||||
print(f"rotate_times: {rotate_times}")
|
print(f"rotate_times: {rotate_times}")
|
||||||
|
|
||||||
@ -229,7 +167,7 @@ class FullAuto(IEngine):
|
|||||||
fishing_mode.subscribers.append(found_hole)
|
fishing_mode.subscribers.append(found_hole)
|
||||||
|
|
||||||
t = 0
|
t = 0
|
||||||
while not self._hole_found_flag and t <= self.factors[2] / 3:
|
while not self._hole_found_flag and t <= self.calibrate.time_to_reach_bottom / 3:
|
||||||
mse.move(0, FullAuto.rotate_by)
|
mse.move(0, FullAuto.rotate_by)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
t += 0.05
|
t += 0.05
|
||||||
@ -248,78 +186,6 @@ class FullAuto(IEngine):
|
|||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
self._curr_rotate_y -= 0.05
|
self._curr_rotate_y -= 0.05
|
||||||
|
|
||||||
def get_controls(self):
|
|
||||||
from fishy.engine.fullautofisher.calibrate import Calibrate
|
|
||||||
from fishy.engine.fullautofisher.recorder import Recorder
|
|
||||||
from fishy.engine.fullautofisher.player import Player
|
|
||||||
|
|
||||||
def change_state():
|
|
||||||
self.controls.change_state()
|
|
||||||
|
|
||||||
def print_coods():
|
|
||||||
logging.info(self.get_coods())
|
|
||||||
|
|
||||||
def set_target():
|
|
||||||
t = self.get_coods()[:-1]
|
|
||||||
config.set("target", t)
|
|
||||||
print(f"target_coods are {t}")
|
|
||||||
|
|
||||||
def move_to_target():
|
|
||||||
self.move_to(config.get("target"))
|
|
||||||
|
|
||||||
def rotate_to_90():
|
|
||||||
self.rotate_to(90)
|
|
||||||
|
|
||||||
def toggle_show():
|
|
||||||
self.show = not self.show
|
|
||||||
|
|
||||||
controls = [
|
|
||||||
("MAIN", {
|
|
||||||
Key.RIGHT: Player(self).start_route,
|
|
||||||
Key.UP: Calibrate(self).callibrate,
|
|
||||||
Key.LEFT: Recorder(self).start_recording,
|
|
||||||
Key.DOWN: change_state
|
|
||||||
}),
|
|
||||||
("COODS", {
|
|
||||||
Key.RIGHT: print_coods,
|
|
||||||
Key.UP: self.update_crop,
|
|
||||||
Key.LEFT: toggle_show,
|
|
||||||
Key.DOWN: change_state
|
|
||||||
}),
|
|
||||||
("TEST1", {
|
|
||||||
Key.RIGHT: set_target,
|
|
||||||
Key.UP: rotate_to_90,
|
|
||||||
Key.LEFT: move_to_target,
|
|
||||||
Key.DOWN: change_state
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
return controls
|
|
||||||
|
|
||||||
|
|
||||||
class Controls:
|
|
||||||
def __init__(self, controls, first=0):
|
|
||||||
self.current_menu = first - 1
|
|
||||||
self.controls = controls
|
|
||||||
|
|
||||||
def change_state(self):
|
|
||||||
self.current_menu += 1
|
|
||||||
if self.current_menu == len(self.controls):
|
|
||||||
self.current_menu = 0
|
|
||||||
|
|
||||||
help_str = F"CONTROLS: {self.controls[self.current_menu][0]}"
|
|
||||||
for key, func in self.controls[self.current_menu][1].items():
|
|
||||||
hotkey.set_hotkey(key, func)
|
|
||||||
help_str += f"\n{key.value}: {func.__name__}"
|
|
||||||
logging.info(help_str)
|
|
||||||
|
|
||||||
def unassign_keys(self):
|
|
||||||
keys = []
|
|
||||||
for c in self.controls:
|
|
||||||
for k in c[1].keys():
|
|
||||||
if k not in keys:
|
|
||||||
hotkey.free_key(k)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logging.getLogger("").setLevel(logging.DEBUG)
|
logging.getLogger("").setLevel(logging.DEBUG)
|
||||||
|
@ -75,6 +75,7 @@ class Player:
|
|||||||
logging.info("starting fishing")
|
logging.info("starting fishing")
|
||||||
self.hole_complete_flag = False
|
self.hole_complete_flag = False
|
||||||
helper.wait_until(lambda: self.hole_complete_flag or not self.start_moving_flag)
|
helper.wait_until(lambda: self.hole_complete_flag or not self.start_moving_flag)
|
||||||
|
self.engine.rotate_back()
|
||||||
else:
|
else:
|
||||||
logging.info("no hole found")
|
logging.info("no hole found")
|
||||||
# if found start fishing and wait for hole to complete
|
# if found start fishing and wait for hole to complete
|
||||||
|
48
fishy/engine/fullautofisher/tesseract.py
Normal file
48
fishy/engine/fullautofisher/tesseract.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import uuid
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
|
||||||
|
import pytesseract
|
||||||
|
|
||||||
|
from fishy.helper.downloader import download_file_from_google_drive
|
||||||
|
|
||||||
|
directory = os.path.join(os.environ["APPDATA"], "Tesseract-OCR")
|
||||||
|
|
||||||
|
|
||||||
|
def downlaoad_and_extract_tesseract():
|
||||||
|
logging.info("Tesseract-OCR downlaoding, Please wait...")
|
||||||
|
|
||||||
|
f = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
download_file_from_google_drive("16llzcBlaCsG9fm-rY2dD4Gvopnhm3XoE", f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
logging.info("Tesseract-OCR downloaded, now installing")
|
||||||
|
|
||||||
|
with ZipFile(f.name, 'r') as z:
|
||||||
|
z.extractall(path=directory)
|
||||||
|
|
||||||
|
logging.info("Tesseract-OCR installed")
|
||||||
|
|
||||||
|
|
||||||
|
def is_tesseract_installed():
|
||||||
|
return os.path.exists(os.path.join(os.environ["APPDATA"], "Tesseract-OCR"))
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
|
def get_values_from_image(img):
|
||||||
|
try:
|
||||||
|
pytesseract.pytesseract.tesseract_cmd = directory + '/tesseract.exe'
|
||||||
|
tessdata_dir_config = f'--tessdata-dir "{directory}" -c tessedit_char_whitelist=0123456789.'
|
||||||
|
|
||||||
|
text = pytesseract.image_to_string(img, lang="eng", config=tessdata_dir_config)
|
||||||
|
text = text.replace(" ", "")
|
||||||
|
vals = text.split(":")
|
||||||
|
return float(vals[0]), float(vals[1]), float(vals[2])
|
||||||
|
except Exception:
|
||||||
|
logging.error("Couldn't read coods, make sure 'crop' calibration is correct")
|
||||||
|
cv2.imwrite(f"fail_{str(uuid.uuid4())[:8]}", img)
|
||||||
|
return None
|
35
fishy/engine/fullautofisher/test.py
Normal file
35
fishy/engine/fullautofisher/test.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from fishy.engine.fullautofisher.engine import FullAuto
|
||||||
|
from fishy.helper.config import config
|
||||||
|
|
||||||
|
|
||||||
|
class Test:
|
||||||
|
def __init__(self, engine: FullAuto):
|
||||||
|
self.engine = engine
|
||||||
|
self.target = None
|
||||||
|
|
||||||
|
def print_coods(self):
|
||||||
|
logging.info(self.engine.get_coods())
|
||||||
|
|
||||||
|
def set_target(self):
|
||||||
|
self.target = self.engine.get_coods()
|
||||||
|
logging.info(f"target_coods are {self.target}")
|
||||||
|
|
||||||
|
def move_to_target(self):
|
||||||
|
if not self.target:
|
||||||
|
logging.info("please set a target first")
|
||||||
|
self.engine.move_to(self.target)
|
||||||
|
|
||||||
|
def rotate_to_target(self):
|
||||||
|
if not self.target:
|
||||||
|
logging.info("please set a target first")
|
||||||
|
self.engine.rotate_to(self.target[2])
|
||||||
|
|
||||||
|
def look_for_hole(self):
|
||||||
|
logging.info("looking for a hole")
|
||||||
|
|
||||||
|
if self.engine.look_for_hole():
|
||||||
|
logging.info("found a hole")
|
||||||
|
else:
|
||||||
|
logging.info("no hole found")
|
@ -34,6 +34,10 @@ def wait_until(func):
|
|||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def sign(x):
|
||||||
|
return -1 if x < 0 else 1
|
||||||
|
|
||||||
|
|
||||||
def open_web(website):
|
def open_web(website):
|
||||||
"""
|
"""
|
||||||
Opens a website on browser,
|
Opens a website on browser,
|
||||||
|
Reference in New Issue
Block a user