mirror of
https://github.com/fishyboteso/fishyboteso.git
synced 2024-08-30 18:32:13 +00:00
connected mode select in config with the engine
- restructed player and recorder to work with new system, - remove FullAuto.State
This commit is contained in:
parent
1290c877f1
commit
3ce3c24dd1
@ -4,8 +4,6 @@ from pynput.keyboard import Key
|
||||
|
||||
from fishy.helper import hotkey
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto, State
|
||||
|
||||
|
||||
def get_controls(controls: 'Controls'):
|
||||
controls = [
|
||||
@ -36,10 +34,6 @@ class Controls:
|
||||
logging.info(help_str)
|
||||
|
||||
def select_mode(self, mode):
|
||||
if FullAuto.state != State.NONE:
|
||||
self.log_help()
|
||||
return
|
||||
|
||||
self.current_menu = 0
|
||||
for i, control in enumerate(self.controls):
|
||||
if mode == control[0]:
|
||||
|
@ -8,6 +8,9 @@ import logging
|
||||
import time
|
||||
|
||||
from fishy.constants import libgps, fishyqr, lam2
|
||||
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.fullautofisher.qr_detection import get_values_from_image, get_qr_location
|
||||
from fishy.engine.semifisher.fishing_mode import FishingMode
|
||||
|
||||
@ -19,7 +22,8 @@ from fishy.engine.common.IEngine import IEngine
|
||||
from pynput import keyboard, mouse
|
||||
|
||||
from fishy.helper import hotkey, helper
|
||||
from fishy.helper.helper import sign
|
||||
from fishy.helper.helper import sign, log_raise
|
||||
from fishy.helper.config import config
|
||||
|
||||
mse = mouse.Controller()
|
||||
kb = keyboard.Controller()
|
||||
@ -34,16 +38,8 @@ def image_pre_process(img):
|
||||
return img
|
||||
|
||||
|
||||
class State(Enum):
|
||||
NONE = 0
|
||||
PLAYING = 1
|
||||
RECORDING = 2
|
||||
OTHER = 3
|
||||
|
||||
|
||||
class FullAuto(IEngine):
|
||||
rotate_by = 30
|
||||
state = State.NONE
|
||||
|
||||
def __init__(self, gui_ref):
|
||||
from fishy.engine.fullautofisher.calibrator import Calibrator
|
||||
@ -58,6 +54,8 @@ class FullAuto(IEngine):
|
||||
self.test = Test(self)
|
||||
self.show_crop = False
|
||||
|
||||
self.mode = None
|
||||
|
||||
def run(self):
|
||||
|
||||
addons_req = [libgps, lam2, fishyqr]
|
||||
@ -65,34 +63,33 @@ class FullAuto(IEngine):
|
||||
if not helper.addon_exists(*addon):
|
||||
helper.install_addon(*addon)
|
||||
|
||||
FullAuto.state = State.NONE
|
||||
|
||||
self.gui.bot_started(True)
|
||||
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")
|
||||
self.mode = Player(self) if FullAutoMode(config.get("full_auto_mode", 0)) == FullAutoMode.Player else Recorder(self)
|
||||
|
||||
# todo use config to run player or recorder
|
||||
# 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:
|
||||
logging.warning("FishyQR not found")
|
||||
self.start = False
|
||||
raise Exception("FishyQR not found")
|
||||
log_raise("FishyQR not found")
|
||||
|
||||
if not self.calibrator.all_callibrated():
|
||||
logging.error("you need to calibrate first")
|
||||
log_raise("you need to calibrate first")
|
||||
|
||||
self.fisher.toggle_start()
|
||||
fishing_event.unsubscribe()
|
||||
if self.show_crop:
|
||||
self.start_show()
|
||||
|
||||
while self.start and WindowClient.running():
|
||||
if self.show_crop:
|
||||
self.window.show(self.show_crop, func=image_pre_process)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
except:
|
||||
self.mode.run()
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
if self.window.get_capture() is None:
|
||||
logging.error("Game window not found")
|
||||
self.start = False
|
||||
|
||||
self.gui.bot_started(False)
|
||||
self.window.show(False)
|
||||
@ -100,6 +97,12 @@ class FullAuto(IEngine):
|
||||
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 get_coods(self):
|
||||
img = self.window.processed_image(func=image_pre_process)
|
||||
return get_values_from_image(img)
|
||||
@ -191,10 +194,6 @@ class FullAuto(IEngine):
|
||||
self._curr_rotate_y -= 0.05
|
||||
|
||||
def toggle_start(self):
|
||||
if self.start and FullAuto.state != State.NONE:
|
||||
logging.info("Please turn off RECORDING/PLAYING first")
|
||||
return
|
||||
|
||||
self.start = not self.start
|
||||
if self.start:
|
||||
self.thread = Thread(target=self.run)
|
||||
|
0
fishy/engine/fullautofisher/mode/__init__.py
Normal file
0
fishy/engine/fullautofisher/mode/__init__.py
Normal file
14
fishy/engine/fullautofisher/mode/imode.py
Normal file
14
fishy/engine/fullautofisher/mode/imode.py
Normal file
@ -0,0 +1,14 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class FullAutoMode(Enum):
|
||||
Player = 0
|
||||
Recorder = 1
|
||||
|
||||
|
||||
class IMode(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def run(self):
|
||||
...
|
92
fishy/engine/fullautofisher/mode/player.py
Normal file
92
fishy/engine/fullautofisher/mode/player.py
Normal file
@ -0,0 +1,92 @@
|
||||
import logging
|
||||
import pickle
|
||||
from pprint import pprint
|
||||
|
||||
import typing
|
||||
from threading import Thread
|
||||
|
||||
from fishy.engine.fullautofisher.mode.imode import IMode
|
||||
from fishy.engine.semifisher import fishing_event, fishing_mode
|
||||
from fishy.helper.helper import log_raise, wait_until, kill_thread
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from fishy.engine.fullautofisher.engine import FullAuto
|
||||
|
||||
from fishy.helper import helper
|
||||
from fishy.helper.config import config
|
||||
|
||||
|
||||
def _get_rec_file():
|
||||
file = config.get("full_auto_rec_file")
|
||||
|
||||
if not file:
|
||||
logging.error("Please select a fishy file first from config")
|
||||
return None
|
||||
|
||||
file = open(file, 'rb')
|
||||
data = pickle.load(file)
|
||||
file.close()
|
||||
pprint(data)
|
||||
if "full_auto_path" not in data:
|
||||
logging.error("invalid file")
|
||||
return None
|
||||
return data["full_auto_path"]
|
||||
|
||||
|
||||
class Player(IMode):
|
||||
def __init__(self, engine: 'FullAuto'):
|
||||
self.recording = False
|
||||
self.engine = engine
|
||||
self.hole_complete_flag = False
|
||||
self.start_moving_flag = False
|
||||
self.i = 0
|
||||
self.forward = True
|
||||
self.timeline = None
|
||||
|
||||
def run(self):
|
||||
self._init()
|
||||
while self.engine.start:
|
||||
self._loop()
|
||||
logging.info("player stopped")
|
||||
|
||||
def _init(self):
|
||||
self.timeline = _get_rec_file()
|
||||
if not self.timeline:
|
||||
log_raise("data not found, can't start")
|
||||
logging.info("starting player")
|
||||
|
||||
def _loop(self):
|
||||
action = self.timeline[self.i]
|
||||
|
||||
if action[0] == "move_to":
|
||||
self.engine.move_to(action[1])
|
||||
elif action[0] == "check_fish":
|
||||
self.engine.move_to(action[1])
|
||||
self.engine.rotate_to(action[1][2])
|
||||
fishing_event.subscribe()
|
||||
fishing_mode.subscribers.append(self._hole_complete_callback)
|
||||
# scan for fish hole
|
||||
logging.info("scanning")
|
||||
# if found start fishing and wait for hole to complete
|
||||
if self.engine.look_for_hole():
|
||||
logging.info("starting fishing")
|
||||
self.hole_complete_flag = False
|
||||
helper.wait_until(lambda: self.hole_complete_flag or not self.engine.start)
|
||||
self.engine.rotate_back()
|
||||
else:
|
||||
logging.info("no hole found")
|
||||
# continue when hole completes
|
||||
fishing_event.unsubscribe()
|
||||
fishing_mode.subscribers.remove(self._hole_complete_callback)
|
||||
|
||||
self.i += 1 if self.forward else -1
|
||||
if self.i >= len(self.timeline):
|
||||
self.forward = False
|
||||
self.i = len(self.timeline) - 1
|
||||
elif self.i < 0:
|
||||
self.forward = True
|
||||
self.i = 0
|
||||
|
||||
def _hole_complete_callback(self, e):
|
||||
if e == fishing_event.State.IDLE:
|
||||
self.hole_complete_flag = True
|
@ -4,17 +4,21 @@ import time
|
||||
from pprint import pprint
|
||||
from tkinter.filedialog import asksaveasfile
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto, State
|
||||
import typing
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from fishy.engine.fullautofisher.engine import FullAuto
|
||||
from fishy.engine.fullautofisher.mode.imode import IMode
|
||||
|
||||
from fishy.helper.hotkey import Key
|
||||
from fishy.helper.hotkey_process import HotKey
|
||||
|
||||
|
||||
class Recorder:
|
||||
class Recorder(IMode):
|
||||
recording_fps = 1
|
||||
mark_hole_key = Key.F8
|
||||
|
||||
def __init__(self, engine: FullAuto):
|
||||
def __init__(self, engine: 'FullAuto'):
|
||||
self.recording = False
|
||||
self.engine = engine
|
||||
self.timeline = []
|
||||
@ -24,23 +28,14 @@ class Recorder:
|
||||
self.timeline.append(("check_fish", coods))
|
||||
logging.info("check_fish")
|
||||
|
||||
def toggle_recording(self):
|
||||
if FullAuto.state != State.RECORDING and FullAuto.state != State.NONE:
|
||||
return
|
||||
|
||||
self.recording = not self.recording
|
||||
if self.recording:
|
||||
self._start_recording()
|
||||
|
||||
def _start_recording(self):
|
||||
FullAuto.state = State.RECORDING
|
||||
def run(self):
|
||||
logging.info("starting, press f8 to mark hole")
|
||||
hk = HotKey()
|
||||
hk.start_process(self._mark_hole)
|
||||
|
||||
self.timeline = []
|
||||
|
||||
while self.recording:
|
||||
while self.engine.start:
|
||||
start_time = time.time()
|
||||
coods = None
|
||||
while not coods:
|
||||
@ -68,5 +63,4 @@ class Recorder:
|
||||
pprint(data)
|
||||
pickle.dump(data, file)
|
||||
file.close()
|
||||
FullAuto.state = State.NONE
|
||||
|
@ -1,95 +0,0 @@
|
||||
import logging
|
||||
import pickle
|
||||
from pprint import pprint
|
||||
|
||||
from fishy.engine.semifisher import fishing_event, fishing_mode
|
||||
|
||||
from fishy.engine.fullautofisher.engine import FullAuto, State
|
||||
|
||||
from fishy.helper import helper
|
||||
from fishy.helper.config import config
|
||||
|
||||
|
||||
def _get_rec_file():
|
||||
file = config.get("full_auto_rec_file")
|
||||
|
||||
if not file:
|
||||
logging.error("Please select a fishy file first from config")
|
||||
return None
|
||||
|
||||
file = open(file, 'rb')
|
||||
data = pickle.load(file)
|
||||
file.close()
|
||||
pprint(data)
|
||||
if "full_auto_path" not in data:
|
||||
logging.error("invalid file")
|
||||
return None
|
||||
return data["full_auto_path"]
|
||||
|
||||
|
||||
class Player:
|
||||
def __init__(self, engine: 'FullAuto'):
|
||||
self.recording = False
|
||||
self.engine = engine
|
||||
self.hole_complete_flag = False
|
||||
self.start_moving_flag = False
|
||||
|
||||
def toggle_move(self):
|
||||
if FullAuto.state != State.PLAYING and FullAuto.state != State.NONE:
|
||||
return
|
||||
|
||||
self.start_moving_flag = not self.start_moving_flag
|
||||
if self.start_moving_flag:
|
||||
self._start_route()
|
||||
else:
|
||||
logging.info("Waiting for the last action to finish...")
|
||||
|
||||
def _hole_complete_callback(self, e):
|
||||
if e == fishing_event.State.IDLE:
|
||||
self.hole_complete_flag = True
|
||||
|
||||
def _start_route(self):
|
||||
timeline = _get_rec_file()
|
||||
if not timeline:
|
||||
logging.log("data not found, can't start")
|
||||
return
|
||||
|
||||
FullAuto.state = State.PLAYING
|
||||
logging.info("starting to move")
|
||||
|
||||
forward = True
|
||||
i = 0
|
||||
while self.start_moving_flag:
|
||||
action = timeline[i]
|
||||
|
||||
if action[0] == "move_to":
|
||||
self.engine.move_to(action[1])
|
||||
elif action[0] == "check_fish":
|
||||
self.engine.move_to(action[1])
|
||||
self.engine.rotate_to(action[1][2])
|
||||
fishing_event.subscribe()
|
||||
fishing_mode.subscribers.append(self._hole_complete_callback)
|
||||
# scan for fish hole
|
||||
logging.info("scanning")
|
||||
if self.engine.look_for_hole():
|
||||
logging.info("starting fishing")
|
||||
self.hole_complete_flag = False
|
||||
helper.wait_until(lambda: self.hole_complete_flag or not self.start_moving_flag)
|
||||
self.engine.rotate_back()
|
||||
else:
|
||||
logging.info("no hole found")
|
||||
# if found start fishing and wait for hole to complete
|
||||
# contine when hole completes
|
||||
fishing_event.unsubscribe()
|
||||
fishing_mode.subscribers.remove(self._hole_complete_callback)
|
||||
|
||||
i += 1 if forward else -1
|
||||
if i >= len(timeline):
|
||||
forward = False
|
||||
i = len(timeline) - 1
|
||||
elif i < 0:
|
||||
forward = True
|
||||
i = 0
|
||||
|
||||
logging.info("stopped")
|
||||
FullAuto.state = State.NONE
|
@ -4,6 +4,7 @@ import typing
|
||||
from tkinter.filedialog import askopenfilename
|
||||
|
||||
from fishy.engine.common.event_handler import IEngineHandler
|
||||
from fishy.engine.fullautofisher.mode.imode import FullAutoMode
|
||||
from fishy.helper import helper
|
||||
|
||||
from fishy import web
|
||||
@ -42,17 +43,17 @@ def start_fullfisher_config(gui: 'GUI'):
|
||||
def start_calibrate():
|
||||
...
|
||||
|
||||
def select_radio():
|
||||
...
|
||||
def mode_command():
|
||||
config.set("full_auto_mode", mode_var.get())
|
||||
|
||||
file_name_label = StringVar(value=file_name())
|
||||
radio_var = IntVar()
|
||||
mode_var = IntVar(value=config.get("full_auto_mode", 0))
|
||||
|
||||
Button(controls_frame, text="Recalibrate", command=start_calibrate).grid(row=0, column=0, columnspan=2, pady=(5, 5))
|
||||
Button(controls_frame, text="Calibrate", command=start_calibrate).grid(row=0, column=0, columnspan=2, pady=(5, 5))
|
||||
|
||||
Label(controls_frame, text="Mode: ").grid(row=1, column=0, pady=(5, 0))
|
||||
Radiobutton(controls_frame, text="Player", variable=radio_var, value=0, command=select_radio).grid(row=1, column=1, sticky="w")
|
||||
Radiobutton(controls_frame, text="Recorder", variable=radio_var, value=1, command=select_radio).grid(row=2, column=1, sticky="w", pady=(0, 5))
|
||||
Radiobutton(controls_frame, text="Player", variable=mode_var, value=FullAutoMode.Player.value, command=mode_command).grid(row=1, column=1, sticky="w")
|
||||
Radiobutton(controls_frame, text="Recorder", variable=mode_var, value=FullAutoMode.Recorder.value, command=mode_command).grid(row=2, column=1, sticky="w", pady=(0, 5))
|
||||
|
||||
Button(controls_frame, text="Select fishy file", command=select_file).grid(row=3, column=0, columnspan=2, pady=(5, 0))
|
||||
Label(controls_frame, textvariable=file_name_label).grid(row=4, column=0, columnspan=2, pady=(0, 5))
|
||||
|
@ -1,3 +1,4 @@
|
||||
import ctypes
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
@ -202,8 +203,32 @@ def restart():
|
||||
os.execl(sys.executable, *([sys.executable] + sys.argv))
|
||||
|
||||
|
||||
def log_raise(msg):
|
||||
logging.error(msg)
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
def update():
|
||||
from .config import config
|
||||
|
||||
config.delete("dont_ask_update")
|
||||
restart()
|
||||
|
||||
|
||||
# noinspection PyProtectedMember,PyUnresolvedReferences
|
||||
def _get_id(thread):
|
||||
# returns id of the respective thread
|
||||
if hasattr(thread, '_thread_id'):
|
||||
return thread._thread_id
|
||||
for id, thread in threading._active.items():
|
||||
if thread is thread:
|
||||
return id
|
||||
|
||||
|
||||
def kill_thread(thread):
|
||||
thread_id = _get_id(thread)
|
||||
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id,
|
||||
ctypes.py_object(SystemExit))
|
||||
if res > 1:
|
||||
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
|
||||
print('Exception raise failure')
|
||||
|
Loading…
Reference in New Issue
Block a user