Beispiel #1
0
    def run(self):
        """
        Starts the fishing
        code explained in comments in detail
        """
        fishing_event.init()
        self.fishPixWindow = WindowClient(color=cv2.COLOR_RGB2HSV)

        # check for game window and stuff
        self.gui.bot_started(True)

        if self.get_gui:
            logging.info(
                "Starting the bot engine, look at the fishing hole to start fishing"
            )
            Thread(target=self._wait_and_check).start()

        while self.start and WindowClient.running():
            capture = self.fishPixWindow.get_capture()

            if capture is None:
                # if window server crashed
                self.gui.bot_started(False)
                self.toggle_start()
                continue

            self.fishPixWindow.crop = PixelLoc.val
            fishing_mode.loop(capture[0][0])

        logging.info("Fishing engine stopped")
        self.gui.bot_started(False)
        fishing_event.unsubscribe()
        self.fishPixWindow.destory()
Beispiel #2
0
 def _crash_safe(self):
     logging.debug(f"starting {self.name} engine thread")
     self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name=f"{self.name} debug")
     self.gui.bot_started(True)
     try:
         self.run()
     except Exception:
         logging.error(f"Unhandled exception occurred while running {self.name} engine")
         print_exc()
     self.state = 0
     self.gui.bot_started(False)
     self.window.destroy()
     logging.debug(f"{self.name} engine thread safely exiting")
Beispiel #3
0
    def run(self):

        addons_req = [libgps, lam2, fishyqr]
        for addon in addons_req:
            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")

        try:
            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")

            if not self.calibrator.all_callibrated():
                logging.error("you need to calibrate first")

            self.fisher.toggle_start()
            fishing_event.unsubscribe()

            self.controls.initialize()
            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:
            traceback.print_exc()

            if self.window.get_capture() is None:
                logging.error("Game window not found")

        self.gui.bot_started(False)
        self.controls.unassign_keys()
        self.window.show(False)
        logging.info("Quitting")
        self.window.destory()
        self.fisher.toggle_start()
Beispiel #4
0
    def run(self):
        self.show_crop = False
        FullAuto.state = State.NONE

        self.gui.bot_started(True)
        fishing_event.unsubscribe()
        self.fisher.toggle_start()

        self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")

        try:
            if self.calibrate.crop is None:
                self.calibrate.update_crop(enable_crop=False)
            self.window.crop = self.calibrate.crop

            if not is_tesseract_installed():
                logging.info("tesseract not found")
                downlaoad_and_extract_tesseract()

            if not self.calibrate.all_callibrated():
                logging.error("you need to callibrate first")

            self.controls.initialize()
            while self.start and WindowClient.running():
                self.window.show(self.show_crop, func=image_pre_process)
                if not self.show_crop:
                    time.sleep(0.1)
        except:
            traceback.print_exc()

            if self.window.get_capture() is None:
                logging.error("Game window not found")

        self.gui.bot_started(False)
        self.controls.unassign_keys()
        self.window.show(False)
        logging.info("Quitting")
        self.window.destory()
        self.fisher.toggle_start()
Beispiel #5
0
def get_values(window: WindowClient):
    values = None
    for _ in range(5):
        img = window.processed_image(func=_image_pre_process)
        if img is None:
            logging.debug("Couldn't capture window.")
            continue

        if not window.crop:
            window.crop = _get_qr_location(img)
            if not window.crop:
                logging.debug("FishyQR not found.")
                continue
            img = window.processed_image(func=_image_pre_process)

        values = _get_values_from_image(img)
        if not values:
            window.crop = None
            logging.debug("Values not able to read.")
            continue
        break

    return values
Beispiel #6
0
    def _engine_loop(self):
        skip_count = 0
        while self.state == 1 and WindowClient.running():
            # crop qr and get the values from it
            self.values = qr_detection.get_values(self.window)

            # if fishyqr fails to get read multiple times, stop the bot
            if not self.values:
                if skip_count >= 5:
                    logging.error(
                        "Couldn't read values from FishyQR, Stopping engine..."
                    )
                    return
                skip_count += 1
                time.sleep(0.1)
            else:
                skip_count = 0

            if self.values:
                fishing_mode.loop(self.values[3])
            self.first_loop_done = True
            time.sleep(0.1)
Beispiel #7
0
class SemiFisherEngine(IEngine):
    def __init__(self, gui_ref: Optional['Callable[[], GUI]']):
        super().__init__(gui_ref)
        self.fishPixWindow = None

    def run(self):
        """
        Starts the fishing
        code explained in comments in detail
        """
        fishing_event.init()
        self.fishPixWindow = WindowClient(color=cv2.COLOR_RGB2HSV)

        # check for game window and stuff
        self.gui.bot_started(True)

        if self.get_gui:
            logging.info(
                "Starting the bot engine, look at the fishing hole to start fishing"
            )
            Thread(target=self._wait_and_check).start()

        while self.start and WindowClient.running():
            capture = self.fishPixWindow.get_capture()

            if capture is None:
                # if window server crashed
                self.gui.bot_started(False)
                self.toggle_start()
                continue

            self.fishPixWindow.crop = PixelLoc.val
            fishing_mode.loop(capture[0][0])

        logging.info("Fishing engine stopped")
        self.gui.bot_started(False)
        fishing_event.unsubscribe()
        self.fishPixWindow.destory()

    def _wait_and_check(self):
        time.sleep(10)
        if not FishEvent.FishingStarted and self.start:
            logging.warning(
                "Doesn't look like fishing has started \nCheck out #read-me-first on our discord channel to troubleshoot the issue"
            )

    def show_pixel_vals(self):
        def show():
            freq = 0.5
            t = 0
            while t < 10.0:
                t += freq
                logging.debug(
                    str(FishingMode.CurrentMode) + ":" +
                    str(self.fishPixWindow.get_capture()[0][0]))
                time.sleep(freq)

        logging.debug("Will display pixel values for 10 seconds")
        time.sleep(5)
        Thread(target=show, args=()).start()

    def toggle_start(self):
        self.start = not self.start
        if self.start:
            self.thread = Thread(target=self.run)
            self.thread.start()
Beispiel #8
0
 def func():
     while self.start and WindowClient.running():
         self.window.show(self.show_crop)
Beispiel #9
0
class FullAuto(IEngine):
    rotate_by = 30
    state = State.NONE

    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)
        self._hole_found_flag = False
        self._curr_rotate_y = 0

        self.fisher = SemiFisherEngine(None)
        self.calibrate = Calibrate(self)
        self.test = Test(self)
        self.controls = Controls(controls.get_controls(self))
        self.show_crop = False

    def run(self):
        self.show_crop = False
        FullAuto.state = State.NONE

        self.gui.bot_started(True)
        fishing_event.unsubscribe()
        self.fisher.toggle_start()

        self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="Full auto debug")

        try:
            if self.calibrate.crop is None:
                self.calibrate.update_crop(enable_crop=False)
            self.window.crop = self.calibrate.crop

            if not is_tesseract_installed():
                logging.info("tesseract not found")
                downlaoad_and_extract_tesseract()

            if not self.calibrate.all_callibrated():
                logging.error("you need to callibrate first")

            self.controls.initialize()
            while self.start and WindowClient.running():
                self.window.show(self.show_crop, func=image_pre_process)
                if not self.show_crop:
                    time.sleep(0.1)
        except:
            traceback.print_exc()

            if self.window.get_capture() is None:
                logging.error("Game window not found")

        self.gui.bot_started(False)
        self.controls.unassign_keys()
        self.window.show(False)
        logging.info("Quitting")
        self.window.destory()
        self.fisher.toggle_start()

    def get_coods(self):
        img = self.window.processed_image(func=image_pre_process)
        return get_values_from_image(img)

    def move_to(self, target):
        if target is None:
            logging.error("set target first")
            return

        if not self.calibrate.all_callibrated():
            logging.error("you need to callibrate first")
            return

        current = self.get_coods()
        print(f"Moving from {(current[0], current[1])} to {target}")
        move_vec = target[0] - current[0], target[1] - current[1]

        dist = math.sqrt(move_vec[0] ** 2 + move_vec[1] ** 2)
        print(f"distance: {dist}")
        if dist < 5e-05:
            print("distance very small skipping")
            return

        target_angle = math.degrees(math.atan2(-move_vec[1], move_vec[0])) + 90
        from_angle = current[2]

        self.rotate_to(target_angle, from_angle)

        walking_time = dist / self.calibrate.move_factor
        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 from_angle is None:
            _, _, from_angle = self.get_coods()

        if target_angle < 0:
            target_angle = 360 + target_angle
        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.calibrate.rot_factor) * -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 look_for_hole(self):
        self._hole_found_flag = False

        if FishingMode.CurrentMode == fishing_mode.State.LOOK:
            return True

        def found_hole(e):
            if e == fishing_mode.State.LOOK:
                self._hole_found_flag = True

        fishing_mode.subscribers.append(found_hole)

        t = 0
        while not self._hole_found_flag and t <= self.calibrate.time_to_reach_bottom / 3:
            mse.move(0, FullAuto.rotate_by)
            time.sleep(0.05)
            t += 0.05
        while not self._hole_found_flag and t > 0:
            mse.move(0, -FullAuto.rotate_by)
            time.sleep(0.05)
            t -= 0.05

        self._curr_rotate_y = t
        fishing_mode.subscribers.remove(found_hole)
        return self._hole_found_flag

    def rotate_back(self):
        while self._curr_rotate_y > 0.01:
            mse.move(0, -FullAuto.rotate_by)
            time.sleep(0.05)
            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)
            self.thread.start()
Beispiel #10
0
class IEngine:

    def __init__(self, gui_ref: 'Callable[[], GUI]'):
        self.get_gui = gui_ref
        # 0 - off, 1 - running, 2 - quitting
        self.state = 0
        self.window = None
        self.thread = None
        self.name = "default"

    @property
    def gui(self):
        if self.get_gui is None:
            return GUIFuncsMock()

        return self.get_gui().funcs

    @property
    def start(self):
        return self.state == 1

    def toggle_start(self):
        if self.state == 0:
            self.turn_on()
        else:
            self.turn_off()

    def turn_on(self):
        self.state = 1
        self.thread = Thread(target=self._crash_safe)
        self.thread.start()

    def join(self):
        if self.thread:
            logging.debug(f"waiting for {self.name} engine")
            self.thread.join()

    def turn_off(self):
        """
        this method only signals the thread to close using start flag,
        its the responsibility of the thread to shut turn itself off
        """
        if self.state == 1:
            logging.debug(f"sending turn off signal to {self.name} engine")
            self.state = 2
        else:
            logging.debug(f"{self.name} engine already signaled to turn off ")
            # todo: implement force turn off on repeated calls

    # noinspection PyBroadException
    def _crash_safe(self):
        logging.debug(f"starting {self.name} engine thread")
        self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name=f"{self.name} debug")
        self.gui.bot_started(True)
        try:
            self.run()
        except Exception:
            logging.error(f"Unhandled exception occurred while running {self.name} engine")
            print_exc()
        self.state = 0
        self.gui.bot_started(False)
        self.window.destroy()
        logging.debug(f"{self.name} engine thread safely exiting")

    def run(self):
        raise NotImplementedError