fishyboteso/fishy/engine/fullautofisher/engine.py
DESKTOP-JVKHS7I\Adam decfdfb994 - auto update fixed
- keyboard ghosting for full auto fixed
2020-06-26 00:21:12 +05:30

219 lines
6.3 KiB
Python

import math
import cv2
import logging
import time
import numpy as np
import pywintypes
import pytesseract
from fishy.engine.IEngine import IEngine
from fishy.engine.window import Window
from pynput import keyboard, mouse
from fishy.helper import Config, hotkey
mse = mouse.Controller()
kb = keyboard.Controller()
rotate_by = 30
def sign(x):
return -1 if x < 0 else 1
def get_crop_coods(window):
Window.loop()
img = window.get_capture()
img = cv2.inRange(img, 0, 1)
Window.loop_end()
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, x + w, y + h
def image_pre_process(img):
scale_percent = 200 # 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)
img = cv2.bitwise_not(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)
vals = text.split(":")
return float(vals[0]), float(vals[1]), float(vals[2])
except Exception:
logging.error("Couldn't read coods")
return None
def unassign_keys():
keys = ["up", "down", "left", "right"]
for k in keys:
hotkey.free_key(k)
class FullAuto(IEngine):
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
if self.factors is None:
logging.warning("Please callibrate first")
def run(self):
logging.info("Loading please wait...")
self.initalize_keys()
try:
Window.init(False)
except pywintypes.error:
logging.info("Game window not found")
self.toggle_start()
return
self.window = Window(color=cv2.COLOR_RGB2GRAY)
self.window.crop = get_crop_coods(self.window)
self.tesseract_dir = self.config.get("tesseract_dir", None)
if self.tesseract_dir is None:
logging.warning("Can't start without Tesseract Directory")
self.gui.bot_started(False)
self.toggle_start()
return
if self.get_gui is not None:
self.gui.bot_started(True)
logging.info("Controlls:\nUP: Callibrate\nLEFT: Print Coordinates\nDOWN: Set target\nRIGHT: Move to target")
while self.start:
Window.loop()
# self.window.show("test", func=image_pre_process)
Window.loop_end()
self.gui.bot_started(False)
unassign_keys()
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")
return
if self.factors is None:
logging.error("you need to callibrate first")
return
current = self.get_coods()
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}")
angle_diff = target_angle - current[2]
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)
kb.press('w')
time.sleep(walking_time)
kb.release('w')
print("done")
def initalize_keys(self):
hotkey.set_hotkey("left", lambda: logging.info(self.get_coods()))
hotkey.set_hotkey("up", lambda: self.callibrate())
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("right", lambda: self.move_to(self.config.get("target", None)))
if __name__ == '__main__':
logging.getLogger("").setLevel(logging.DEBUG)
# noinspection PyTypeChecker
bot = FullAuto(Config(), None)
hotkey.initalize()
bot.toggle_start()