mirror of
https://github.com/fishyboteso/fishyboteso.git
synced 2024-08-30 18:32:13 +00:00
better hotkey code, moved calibrate to seperate file, created player and recorder for full auto, created rotate_to metho in full auto engine
This commit is contained in:
parent
ee8392e426
commit
66e6a70fba
71
fishy/engine/fullautofisher/Player.py
Normal file
71
fishy/engine/fullautofisher/Player.py
Normal file
@ -0,0 +1,71 @@
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from tkinter.filedialog import asksaveasfile, askopenfile
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto
|
||||
|
||||
from fishy.helper import hotkey
|
||||
from fishy.helper.hotkey import Key
|
||||
|
||||
|
||||
class Player:
|
||||
def __init__(self, engine: FullAuto):
|
||||
self.recording = False
|
||||
self.engine = engine
|
||||
self.timeline = []
|
||||
|
||||
def _mark_hole(self):
|
||||
coods = self.engine.get_coods()
|
||||
self.timeline.append(("check_fish", coods))
|
||||
|
||||
def _stop_recording(self):
|
||||
self.recording = False
|
||||
|
||||
def start_recording(self):
|
||||
file = askopenfile(mode='r', filetypes=[('Python Files', '*.py')])
|
||||
if not file:
|
||||
logging.error("file not selected")
|
||||
return
|
||||
data = json.load(file)
|
||||
if "full_auto_path" not in data:
|
||||
logging.error("incorrect file")
|
||||
return
|
||||
|
||||
self.timeline = data["full_auto_path"]
|
||||
|
||||
for action in self.timeline:
|
||||
if action == "move_to":
|
||||
self.engine.move_to(action[1])
|
||||
elif action == "check_fish":
|
||||
self.engine.move_to(action[1])
|
||||
self.engine.rotate_to(action[1][2])
|
||||
# scan for fish hole
|
||||
# if found start fishing and wait for hole to complete
|
||||
# contine when hole completes
|
||||
|
||||
logging.info("f7 for marking hole, f8 to stop recording")
|
||||
hotkey.set_hotkey(Key.F7, self._mark_hole)
|
||||
hotkey.set_hotkey(Key.F8, self._stop_recording)
|
||||
|
||||
self.recording = True
|
||||
self.timeline = []
|
||||
|
||||
while self.recording:
|
||||
start_time = time.time()
|
||||
coods = self.engine.get_coods()
|
||||
self.timeline.append(("goto", (coods[0], coods[1])))
|
||||
|
||||
time_took = time.time() - start_time
|
||||
if time_took <= Recorder.recording_fps:
|
||||
time.sleep(Recorder.recording_fps - time_took)
|
||||
else:
|
||||
logging.warning("Took too much time to record")
|
||||
|
||||
file = None
|
||||
while not file:
|
||||
file = asksaveasfile(mode='wb', filetypes=[('Fishy File', '*.fishy')])
|
||||
data = {"full_auto_path": self.timeline}
|
||||
json.dump(data, file)
|
||||
file.close()
|
||||
|
87
fishy/engine/fullautofisher/calibrate.py
Normal file
87
fishy/engine/fullautofisher/calibrate.py
Normal file
@ -0,0 +1,87 @@
|
||||
import math
|
||||
import logging
|
||||
import time
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto
|
||||
from pynput import keyboard, mouse
|
||||
|
||||
from fishy.helper import hotkey
|
||||
from fishy.helper.helper import wait_until
|
||||
from fishy.helper.hotkey import Key
|
||||
|
||||
mse = mouse.Controller()
|
||||
kb = keyboard.Controller()
|
||||
|
||||
"""
|
||||
-1 callibrating speed and rotation,
|
||||
0, waiting for looking up and first f8,
|
||||
1, waiting for reaching down and second f8,
|
||||
2 done
|
||||
"""
|
||||
_callibrate_state = -1
|
||||
|
||||
|
||||
def callibrate(engine):
|
||||
global _callibrate_state
|
||||
|
||||
logging.debug("Callibrating...")
|
||||
_callibrate_state = -1
|
||||
|
||||
walking_time = 3
|
||||
rotate_times = 50
|
||||
|
||||
# region rotate and move
|
||||
coods = 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 = engine.get_coods()
|
||||
if coods is None:
|
||||
return
|
||||
x2, y2, rot2 = coods
|
||||
|
||||
for _ in range(rotate_times):
|
||||
mse.move(FullAuto.rotate_by, 0)
|
||||
time.sleep(0.05)
|
||||
|
||||
coods = engine.get_coods()
|
||||
if coods is None:
|
||||
return
|
||||
x3, y3, rot3 = coods
|
||||
|
||||
if rot3 > rot2:
|
||||
rot3 -= 360
|
||||
|
||||
move_factor = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / walking_time
|
||||
rot_factor = (rot3 - rot2) / rotate_times
|
||||
# endregion
|
||||
|
||||
logging.info("Now loop up and press f8, then as soon as the character looks down, press f8 again")
|
||||
|
||||
def f8_pressed():
|
||||
global _callibrate_state
|
||||
_callibrate_state += 1
|
||||
|
||||
hotkey.set_hotkey(Key.F8, f8_pressed)
|
||||
|
||||
wait_until(lambda: _callibrate_state == 1)
|
||||
|
||||
y_cal_start_time = time.time()
|
||||
while _callibrate_state == 1:
|
||||
mse.move(0, FullAuto.rotate_by)
|
||||
time.sleep(0.05)
|
||||
|
||||
time_to_reach_bottom = time.time() - y_cal_start_time
|
||||
|
||||
engine.factors = move_factor, rot_factor, time_to_reach_bottom
|
||||
engine.config.set("full_auto_factors", engine.factors)
|
||||
logging.info(engine.factors)
|
||||
|
||||
hotkey.free_key(Key.F8)
|
@ -8,15 +8,18 @@ import pywintypes
|
||||
import pytesseract
|
||||
|
||||
from fishy.engine.IEngine import IEngine
|
||||
from fishy.engine.fullautofisher.calibrate import callibrate
|
||||
from fishy.engine.window import Window
|
||||
from pynput import keyboard, mouse
|
||||
|
||||
from fishy.helper import Config, hotkey
|
||||
from fishy.helper.helper import wait_until
|
||||
from fishy.helper.hotkey import Key
|
||||
|
||||
mse = mouse.Controller()
|
||||
kb = keyboard.Controller()
|
||||
|
||||
rotate_by = 30
|
||||
|
||||
|
||||
|
||||
def sign(x):
|
||||
@ -68,18 +71,22 @@ def get_values_from_image(img, tesseract_dir):
|
||||
|
||||
|
||||
def unassign_keys():
|
||||
keys = ["up", "down", "left", "right"]
|
||||
keys = [Key.UP, Key.RIGHT, Key.LEFT, Key.RIGHT]
|
||||
for k in keys:
|
||||
hotkey.free_key(k)
|
||||
|
||||
|
||||
class FullAuto(IEngine):
|
||||
rotate_by = 30
|
||||
|
||||
def __init__(self, config, gui_ref):
|
||||
super().__init__(config, gui_ref)
|
||||
self.factors = self.config.get("full_auto_factors", None)
|
||||
self.tesseract_dir = None
|
||||
self.target = None
|
||||
|
||||
self.callibrate_state = -1
|
||||
|
||||
if self.factors is None:
|
||||
logging.warning("Please callibrate first")
|
||||
|
||||
@ -119,45 +126,6 @@ class FullAuto(IEngine):
|
||||
def get_coods(self):
|
||||
return get_values_from_image(self.window.processed_image(func=image_pre_process), self.tesseract_dir)
|
||||
|
||||
def callibrate(self):
|
||||
logging.debug("Callibrating...")
|
||||
walking_time = 3
|
||||
rotate_times = 50
|
||||
|
||||
coods = self.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.get_coods()
|
||||
if coods is None:
|
||||
return
|
||||
x2, y2, rot2 = coods
|
||||
|
||||
for _ in range(rotate_times):
|
||||
mse.move(rotate_by, 0)
|
||||
time.sleep(0.05)
|
||||
|
||||
coods = self.get_coods()
|
||||
if coods is None:
|
||||
return
|
||||
x3, y3, rot3 = coods
|
||||
|
||||
if rot3 > rot2:
|
||||
rot3 -= 360
|
||||
|
||||
rot_factor = (rot3 - rot2) / rotate_times
|
||||
move_factor = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / walking_time
|
||||
self.config.set("full_auto_factors", (move_factor, rot_factor))
|
||||
self.factors = move_factor, rot_factor
|
||||
logging.info(self.factors)
|
||||
|
||||
def move_to(self, target):
|
||||
if target is None:
|
||||
logging.error("set target first")
|
||||
@ -171,43 +139,52 @@ class FullAuto(IEngine):
|
||||
print(f"Moving from {(current[0], current[1])} to {self.target}")
|
||||
move_vec = target[0] - current[0], target[1] - current[1]
|
||||
target_angle = math.degrees(math.atan2(-move_vec[1], move_vec[0]))
|
||||
if target_angle < 0:
|
||||
target_angle = 360 + target_angle
|
||||
target_angle += 90
|
||||
while target_angle > 360:
|
||||
target_angle -= 360
|
||||
print(f"Rotating from {current[2]} to {target_angle}")
|
||||
from_angle = current[2]
|
||||
|
||||
angle_diff = target_angle - current[2]
|
||||
self.rotate_to(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.factors[1]) * -1
|
||||
walking_time = math.sqrt(move_vec[0] ** 2 + move_vec[1] ** 2) / self.factors[0]
|
||||
|
||||
print(f"Rotating by {angle_diff}\nrotate_times {rotate_times}\nwalking_time {walking_time}")
|
||||
|
||||
for _ in range(abs(rotate_times)):
|
||||
mse.move(sign(rotate_times) * rotate_by * -1, 0)
|
||||
time.sleep(0.05)
|
||||
|
||||
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 target_angle is None:
|
||||
_, _, from_angle = self.get_coods()
|
||||
|
||||
if target_angle < 0:
|
||||
target_angle = 360 + target_angle
|
||||
target_angle += 90
|
||||
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.factors[1]) * -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 initalize_keys(self):
|
||||
hotkey.set_hotkey("left", lambda: logging.info(self.get_coods()))
|
||||
hotkey.set_hotkey("up", lambda: self.callibrate())
|
||||
hotkey.set_hotkey(Key.LEFT, lambda: logging.info(self.get_coods()))
|
||||
hotkey.set_hotkey(Key.UP, lambda: callibrate(self))
|
||||
|
||||
def down():
|
||||
t = self.get_coods()[:-1]
|
||||
self.config.set("target", t)
|
||||
print(f"target_coods are {t}")
|
||||
hotkey.set_hotkey("down", down)
|
||||
hotkey.set_hotkey(Key.DOWN, down)
|
||||
|
||||
hotkey.set_hotkey("right", lambda: self.move_to(self.config.get("target", None)))
|
||||
hotkey.set_hotkey(Key.RIGHT, lambda: self.move_to(self.config.get("target", None)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
53
fishy/engine/fullautofisher/recorder.py
Normal file
53
fishy/engine/fullautofisher/recorder.py
Normal file
@ -0,0 +1,53 @@
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from tkinter.filedialog import asksaveasfile
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto
|
||||
|
||||
from fishy.helper import hotkey
|
||||
from fishy.helper.hotkey import Key
|
||||
|
||||
|
||||
class Recorder:
|
||||
recording_fps = 1
|
||||
|
||||
def __init__(self, engine: FullAuto):
|
||||
self.recording = False
|
||||
self.engine = engine
|
||||
self.timeline = []
|
||||
|
||||
def _mark_hole(self):
|
||||
coods = self.engine.get_coods()
|
||||
self.timeline.append(("check_fish", coods))
|
||||
|
||||
def _stop_recording(self):
|
||||
self.recording = False
|
||||
|
||||
def start_recording(self):
|
||||
logging.info("f7 for marking hole, f8 to stop recording")
|
||||
hotkey.set_hotkey(Key.F7, self._mark_hole)
|
||||
hotkey.set_hotkey(Key.F8, self._stop_recording)
|
||||
|
||||
self.recording = True
|
||||
self.timeline = []
|
||||
|
||||
while self.recording:
|
||||
start_time = time.time()
|
||||
coods = self.engine.get_coods()
|
||||
self.timeline.append(("move_to", (coods[0], coods[1])))
|
||||
|
||||
time_took = time.time() - start_time
|
||||
if time_took <= Recorder.recording_fps:
|
||||
time.sleep(Recorder.recording_fps - time_took)
|
||||
else:
|
||||
logging.warning("Took too much time to record")
|
||||
|
||||
files = [('Fishy File', '*.fishy')]
|
||||
file = None
|
||||
while not file:
|
||||
file = asksaveasfile(mode='wb', filetypes=files, defaultextension=files)
|
||||
data = {"full_auto_path": self.timeline}
|
||||
json.dump(data, file)
|
||||
file.close()
|
||||
|
@ -10,6 +10,7 @@ from fishy import helper
|
||||
import typing
|
||||
|
||||
from fishy.helper import hotkey
|
||||
from ..helper.hotkey import Key
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from . import GUI
|
||||
@ -101,7 +102,7 @@ def _create(gui: 'GUI'):
|
||||
gui._root.update()
|
||||
gui._root.minsize(gui._root.winfo_width() + 10, gui._root.winfo_height() + 10)
|
||||
|
||||
hotkey.set_hotkey("f9", gui.funcs.start_engine)
|
||||
hotkey.set_hotkey(Key.F9, gui.funcs.start_engine)
|
||||
|
||||
def set_destroy():
|
||||
gui._destroyed = True
|
||||
|
@ -2,6 +2,7 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
import webbrowser
|
||||
from threading import Thread
|
||||
@ -27,6 +28,11 @@ def empty_function():
|
||||
pass
|
||||
|
||||
|
||||
def wait_until(func):
|
||||
while not func():
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
def open_web(website):
|
||||
"""
|
||||
Opens a website on browser,
|
||||
|
@ -1,26 +1,37 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, Callable
|
||||
|
||||
import keyboard
|
||||
|
||||
from fishy.helper import helper
|
||||
|
||||
hotkeys = {"f9": helper.empty_function,
|
||||
"up": helper.empty_function,
|
||||
"down": helper.empty_function,
|
||||
"left": helper.empty_function,
|
||||
"right": helper.empty_function}
|
||||
|
||||
class Key(Enum):
|
||||
F9 = "f9",
|
||||
F8 = "f8"
|
||||
F7 = "f7"
|
||||
UP = "up",
|
||||
DOWN = "down"
|
||||
LEFT = "left"
|
||||
RIGHT = "right"
|
||||
|
||||
|
||||
def set_hotkey(key, func):
|
||||
hotkeys[key] = func
|
||||
_hotkeys: Dict[Key, Callable] = {}
|
||||
|
||||
|
||||
def _run_callback(k):
|
||||
return lambda: hotkeys[k]()
|
||||
|
||||
|
||||
def free_key(k):
|
||||
set_hotkey(k, helper.empty_function)
|
||||
return lambda: _hotkeys[k]()
|
||||
|
||||
|
||||
def initalize():
|
||||
for k in hotkeys.keys():
|
||||
keyboard.add_hotkey(k, _run_callback(k))
|
||||
for k in Key:
|
||||
_hotkeys[k] = helper.empty_function
|
||||
keyboard.add_hotkey(k.value, _run_callback(k))
|
||||
|
||||
|
||||
def set_hotkey(key: Key, func: Callable):
|
||||
_hotkeys[key] = func
|
||||
|
||||
|
||||
def free_key(k: Key):
|
||||
set_hotkey(k, helper.empty_function)
|
||||
|
Loading…
Reference in New Issue
Block a user