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:
Adam Saudagar 2020-10-15 06:56:31 +05:30
parent ee8392e426
commit 66e6a70fba
7 changed files with 284 additions and 78 deletions

View 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()

View 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)

View File

@ -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__':

View 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()

View File

@ -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

View File

@ -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,

View File

@ -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)