mirror of
https://github.com/fishyboteso/fishyboteso.git
synced 2024-08-30 18:32:13 +00:00
integrated fishyqr v0.0.2 for semi fisher
- remove color detection code - move qr detection from full auto into common - refactor both engines to use qr from common
This commit is contained in:
parent
5d18b8538e
commit
8ae46dd5a5
@ -9,6 +9,15 @@ from pyzbar.pyzbar import decode
|
||||
from fishy.helper.helper import get_documents
|
||||
|
||||
|
||||
def image_pre_process(img):
|
||||
scale_percent = 100 # 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)
|
||||
return img
|
||||
|
||||
|
||||
def get_qr_location(og_img):
|
||||
"""
|
||||
code from https://stackoverflow.com/a/45770227/4512396
|
||||
@ -40,7 +49,7 @@ def get_values_from_image(img):
|
||||
try:
|
||||
for qr in decode(img):
|
||||
vals = qr.data.decode('utf-8').split(",")
|
||||
return float(vals[0]), float(vals[1]), float(vals[2])
|
||||
return tuple(float(v) for v in vals)
|
||||
|
||||
logging.error("FishyQR not found")
|
||||
return None
|
@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import math
|
||||
import traceback
|
||||
from enum import Enum
|
||||
from threading import Thread
|
||||
|
||||
@ -75,10 +76,15 @@ def loop_end():
|
||||
cv2.waitKey(25)
|
||||
|
||||
|
||||
# noinspection PyBroadException
|
||||
def run():
|
||||
# todo use config
|
||||
while WindowServer.status == Status.RUNNING:
|
||||
loop()
|
||||
try:
|
||||
loop()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
WindowServer.status = Status.CRASHED
|
||||
loop_end()
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
import math
|
||||
import logging
|
||||
import math
|
||||
import time
|
||||
@ -16,8 +15,8 @@ from fishy.engine.fullautofisher.mode.calibrator import Calibrator
|
||||
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_qr_location,
|
||||
get_values_from_image)
|
||||
from fishy.engine.common.qr_detection import (get_qr_location,
|
||||
get_values_from_image, image_pre_process)
|
||||
from fishy.engine.semifisher import fishing_event, fishing_mode
|
||||
from fishy.engine.semifisher.fishing_mode import FishingMode
|
||||
from fishy.helper import helper, hotkey
|
||||
@ -29,15 +28,6 @@ mse = mouse.Controller()
|
||||
kb = keyboard.Controller()
|
||||
|
||||
|
||||
def image_pre_process(img):
|
||||
scale_percent = 100 # 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)
|
||||
return img
|
||||
|
||||
|
||||
class FullAuto(IEngine):
|
||||
rotate_by = 30
|
||||
|
||||
|
@ -4,14 +4,16 @@ import typing
|
||||
from threading import Thread
|
||||
from typing import Callable, Optional
|
||||
|
||||
import cv2
|
||||
|
||||
from fishy.helper.helper import log_raise
|
||||
from playsound import playsound
|
||||
|
||||
from fishy.engine.common.IEngine import IEngine
|
||||
from fishy.engine.common.qr_detection import get_qr_location, get_values_from_image, image_pre_process
|
||||
from fishy.engine.common.window import WindowClient
|
||||
from fishy.engine.semifisher import fishing_event, fishing_mode
|
||||
from fishy.engine.semifisher.fishing_event import FishEvent
|
||||
from fishy.engine.semifisher.fishing_mode import Colors, FishingMode
|
||||
from fishy.engine.semifisher.pixel_loc import PixelLoc
|
||||
from fishy.helper import helper
|
||||
from fishy.helper.luaparser import sv_color_extract
|
||||
|
||||
@ -22,7 +24,7 @@ if typing.TYPE_CHECKING:
|
||||
class SemiFisherEngine(IEngine):
|
||||
def __init__(self, gui_ref: Optional['Callable[[], GUI]']):
|
||||
super().__init__(gui_ref)
|
||||
self.fishPixWindow = None
|
||||
self.window = None
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
@ -30,34 +32,43 @@ class SemiFisherEngine(IEngine):
|
||||
code explained in comments in detail
|
||||
"""
|
||||
fishing_event.init()
|
||||
self.fishPixWindow = WindowClient()
|
||||
self.window = WindowClient(color=cv2.COLOR_RGB2GRAY, show_name="semifisher debug")
|
||||
|
||||
# check for game window and stuff
|
||||
self.gui.bot_started(True)
|
||||
|
||||
sv_color_extract(Colors)
|
||||
|
||||
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()
|
||||
self.window.crop = get_qr_location(self.window.get_capture())
|
||||
if self.window.crop is None:
|
||||
log_raise("FishyQR not found")
|
||||
|
||||
while self.start and WindowClient.running():
|
||||
capture = self.window.processed_image(func=image_pre_process)
|
||||
|
||||
# if window server crashed
|
||||
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])
|
||||
# crop qr and get the values from it
|
||||
values = get_values_from_image(capture)
|
||||
if values is None:
|
||||
self.gui.bot_started(False)
|
||||
self.toggle_start()
|
||||
continue
|
||||
|
||||
fishing_mode.loop(values[3])
|
||||
time.sleep(0.1)
|
||||
|
||||
self.window.show(False)
|
||||
logging.info("Fishing engine stopped")
|
||||
self.gui.bot_started(False)
|
||||
fishing_event.unsubscribe()
|
||||
self.fishPixWindow.destory()
|
||||
self.window.destory()
|
||||
|
||||
def _wait_and_check(self):
|
||||
time.sleep(10)
|
||||
@ -71,7 +82,7 @@ class SemiFisherEngine(IEngine):
|
||||
t = 0
|
||||
while t < 10.0:
|
||||
t += freq
|
||||
logging.debug(str(FishingMode.CurrentMode) + ":" + str(self.fishPixWindow.get_capture()[0][0]))
|
||||
logging.debug(str(FishingMode.CurrentMode) + ":" + str(self.window.get_capture()[0][0]))
|
||||
time.sleep(freq)
|
||||
|
||||
logging.debug("Will display pixel values for 10 seconds")
|
||||
|
@ -107,7 +107,10 @@ def fisher_callback(event: State):
|
||||
|
||||
|
||||
def on_idle():
|
||||
if FishEvent.previousState in (State.FISHING, State.REELIN):
|
||||
if FishEvent.previousState == State.REELIN:
|
||||
logging.info("HOLE DEPLETED")
|
||||
_sound_and_send_fishy_data()
|
||||
elif FishEvent.previousState == State.FISHING:
|
||||
logging.info("FISHING INTERRUPTED")
|
||||
_sound_and_send_fishy_data()
|
||||
|
||||
|
@ -17,21 +17,6 @@ class State(Enum):
|
||||
DEAD = 15
|
||||
|
||||
|
||||
Colors = {
|
||||
State.IDLE : [255, 255, 255],
|
||||
State.LOOKAWAY : [ 76, 0, 76],
|
||||
State.LOOKING : [101, 69, 0],
|
||||
State.DEPLETED : [ 0, 76, 76],
|
||||
State.NOBAIT : [255, 204, 0],
|
||||
State.FISHING : [ 75, 156, 213],
|
||||
State.REELIN : [ 0, 204, 0],
|
||||
State.LOOT : [ 0, 0, 204],
|
||||
State.INVFULL : [ 0, 0, 51],
|
||||
State.FIGHT : [204, 0, 0],
|
||||
State.DEAD : [ 51, 51, 51]
|
||||
}
|
||||
|
||||
|
||||
def _notify(event):
|
||||
for subscriber in subscribers:
|
||||
subscriber(event)
|
||||
@ -42,17 +27,12 @@ class FishingMode:
|
||||
PrevMode = State.IDLE
|
||||
|
||||
|
||||
def loop(rgb):
|
||||
def loop(state_num: int):
|
||||
"""
|
||||
Executed in the start of the main loop in fishy.py
|
||||
Changes modes, calls mode events (callbacks) when mode is changed
|
||||
|
||||
:param rgb: rgb read by the bot
|
||||
"""
|
||||
FishingMode.CurrentMode = State.IDLE
|
||||
for s in State:
|
||||
if all(rgb == Colors[s]):
|
||||
FishingMode.CurrentMode = s
|
||||
FishingMode.CurrentMode = State(state_num)
|
||||
|
||||
if FishingMode.CurrentMode != FishingMode.PrevMode:
|
||||
_notify(FishingMode.CurrentMode)
|
||||
|
@ -1,66 +0,0 @@
|
||||
import cv2
|
||||
|
||||
|
||||
def get_keypoint_from_image(img):
|
||||
"""
|
||||
convert image int hsv
|
||||
creates a mask for brown color
|
||||
uses blob detection to find a blob in the mask
|
||||
filter the blobs to find the correct one
|
||||
|
||||
:param img: rgb image
|
||||
:return: location of the pixel which is used to detect different fishing states
|
||||
"""
|
||||
|
||||
# Setup SimpleBlobDetector parameters.
|
||||
hsv_img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
|
||||
lower = (99, 254, 100)
|
||||
upper = (100, 255, 101)
|
||||
mask = cv2.inRange(hsv_img, lower, upper)
|
||||
|
||||
# Setup SimpleBlobDetector parameters.
|
||||
params = cv2.SimpleBlobDetector_Params()
|
||||
|
||||
# Change thresholds
|
||||
params.minThreshold = 10
|
||||
params.maxThreshold = 255
|
||||
|
||||
params.filterByColor = True
|
||||
params.blobColor = 255
|
||||
|
||||
params.filterByCircularity = False
|
||||
params.filterByConvexity = False
|
||||
params.filterByInertia = False
|
||||
|
||||
params.filterByArea = True
|
||||
params.minArea = 10.0
|
||||
|
||||
detector = cv2.SimpleBlobDetector_create(params)
|
||||
|
||||
# Detect blobs.
|
||||
key_points = detector.detect(mask)
|
||||
|
||||
if len(key_points) <= 0:
|
||||
return None
|
||||
|
||||
return int(key_points[0].pt[0]), int(key_points[0].pt[1])
|
||||
|
||||
|
||||
class PixelLoc:
|
||||
"""
|
||||
finds the pixel loc and store it
|
||||
"""
|
||||
|
||||
val = None
|
||||
|
||||
@staticmethod
|
||||
def config():
|
||||
"""
|
||||
Uses the game window to get an image of the game screen
|
||||
then uses `GetKeypointFromImage()` to find the Chalutier pixel location
|
||||
:return: false if pixel loc not found
|
||||
"""
|
||||
|
||||
PixelLoc.val = (0, 0, 1, 1)
|
||||
|
||||
return True
|
Loading…
Reference in New Issue
Block a user