Merge pull request #57 from fishyboteso/detect_with_rgb

Change colors to rgb and read saved-variables from Chalutier Addon for color detection (0.4.6)
This commit is contained in:
Adam Saudagar 2021-05-07 20:52:53 +05:30 committed by GitHub
commit ac83c9c427
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 130 additions and 22 deletions

View File

@ -1,5 +1,5 @@
apiversion = 2
chalutier = ("Chalutier", "https://github.com/fishyboteso/Chalutier/raw/619b4ab0b8ff91746afda855542e886d27b7a794/Chalutier_1.1.2.zip", 112)
chalutier = ("Chalutier", "https://www.esoui.com/downloads/dl2934/Chalutier_1.1.4.zip", 114)
lam2 = ("LibAddonMenu-2.0", "https://www.esoui.com/downloads/dl7/LibAddonMenu-2.0r32.zip", 32)
fishyqr = ("FishyQR", "https://github.com/fishyboteso/FishyQR/files/6329586/FishyQR.zip", 100)

View File

@ -60,8 +60,6 @@ def loop():
temp_screen = np.array(ImageGrab.grab(bbox=bbox))
temp_screen = cv2.cvtColor(temp_screen, cv2.COLOR_BGR2RGB)
rect = win32gui.GetWindowRect(WindowServer.hwnd)
crop = (
rect[0] + WindowServer.windowOffset, rect[1] + WindowServer.titleOffset, rect[2] - WindowServer.windowOffset,

View File

@ -10,12 +10,14 @@ import logging
from fishy.engine.semifisher.fishing_event import FishEvent
from fishy.engine.common.window import WindowClient
from fishy.engine.semifisher.fishing_mode import FishingMode
from fishy.engine.semifisher.fishing_mode import Colors, FishingMode
from fishy.engine.common.IEngine import IEngine
from fishy.engine.semifisher import fishing_mode, fishing_event
from fishy.engine.semifisher.pixel_loc import PixelLoc
from fishy.helper.luaparser import sv_color_extract
if typing.TYPE_CHECKING:
from fishy.gui import GUI
@ -31,11 +33,13 @@ class SemiFisherEngine(IEngine):
code explained in comments in detail
"""
fishing_event.init()
self.fishPixWindow = WindowClient(color=cv2.COLOR_RGB2HSV)
self.fishPixWindow = WindowClient()
# 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()

View File

@ -98,11 +98,14 @@ def fisher_callback(event: State):
State.FIGHT: on_fight,
State.DEAD: on_dead
}
try:
callbacks_map[event]()
FishEvent.previousState = event
except KeyError as ex:
pass
logging.error("KeyError: State " + str(event) + " is not known.")
except TypeError as ex:
logging.error("TypeError when reading state: " + str(event))
def on_idle():

View File

@ -5,17 +5,32 @@ subscribers = []
class State(Enum):
IDLE = [ 0, 0, 255]
LOOKAWAY = [150, 255, 76]
LOOKING = [100, 255, 101]
DEPLETED = [ 30, 255, 76]
NOBAIT = [ 96, 255, 255]
FISHING = [ 18, 165, 213]
REELIN = [ 60, 255, 204]
LOOT = [ 0, 255, 204]
INVFULL = [ 0, 255, 51]
FIGHT = [120, 255, 204]
DEAD = [ 0, 0, 51]
IDLE = 0
LOOKAWAY = 1
LOOKING = 2
DEPLETED = 3
NOBAIT = 5
FISHING = 6
REELIN = 7
LOOT = 8
INVFULL = 9
FIGHT = 14
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:
@ -27,16 +42,16 @@ class FishingMode:
PrevMode = State.IDLE
def loop(hsv):
def loop(rgb):
"""
Executed in the start of the main loop in fishy.py
Changes modes, calls mode events (callbacks) when mode is changed
:param hsv: hsv read by the bot
:param rgb: rgb read by the bot
"""
FishingMode.CurrentMode = State.IDLE
for s in State:
if all(hsv == s.value):
if all(rgb == Colors[s]):
FishingMode.CurrentMode = s
if FishingMode.CurrentMode != FishingMode.PrevMode:

View File

@ -1,4 +1,6 @@
from .auto_update import auto_upgrade, upgrade_avail, versions
from .config import Config
from .helper import open_web, initialize_uid, install_thread_excepthook, unhandled_exception_logging, manifest_file, \
create_shortcut_first, addon_exists, get_addonversion, install_addon, remove_addon, restart, create_shortcut, not_implemented, update
create_shortcut_first, addon_exists, get_addonversion, install_addon, remove_addon, restart, create_shortcut, \
not_implemented, update, get_savedvarsdir
from .luaparser import sv_color_extract

View File

@ -145,11 +145,18 @@ def create_shortcut(anti_ghosting: bool):
logging.error("Couldn't create shortcut")
def get_savedvarsdir():
# noinspection PyUnresolvedReferences
from win32com.shell import shell, shellcon
documents = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
return os.path.join(documents, "Elder Scrolls Online", "live", "SavedVariables")
def get_addondir():
# noinspection PyUnresolvedReferences
from win32com.shell import shell, shellcon
documents = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
return os.path.join(documents, "Elder Scrolls Online", "live", "Addons")
return os.path.join(documents, "Elder Scrolls Online", "live", "Addons")
def addon_exists(name, url=None, v=None):

79
fishy/helper/luaparser.py Normal file
View File

@ -0,0 +1,79 @@
import os
import logging
from math import floor
from .helper import get_savedvarsdir
def _sv_parser(path):
try:
with open(path, "r") as f:
lua = f.read()
"""
bring lua saved-var file into a useable format:
- one line per expression (add \n where needed)
- remove all redundant characters
- make lowercase, split into list of expressions
- remove empty expressions
EXPRESSIONS: A) List-Start "name=", B) Variable assignment "name=val", C) List End "}"
"""
for old, new in ((",","\n"), ("{","{\n"), ("}","}\n"), ("{",""), (",", ""), ("[", ""), ("]", ""), ('"', ""), (" ", "")):
lua = lua.replace(old, new)
lua = lua.lower().split("\n")
lua = [expression for expression in lua if expression]
"""
the lua saved-var file is parsed to a tree of dicts
each line represents either one node in the tree or the end of a subtree
the last symbol of each line decides the type of the node (branch vertex or leaf)
"""
stack = []
root = (dict(),"root")
stack.append(root)
for line in lua:
if line == "":
break
if line[-1] == '=': #subtree start
t = dict()
tname = line.split("=")[0]
stack.append((t,tname))
elif line[-1] == '}': #subtree end
t = stack.pop()
tp = stack.pop()
tp[0][t[1]] = t[0]
stack.append(tp)
else: #new element in tree
name,val = line.split("=")
t = stack.pop()
t[0][name] = val
stack.append(t)
return root[0]
except Exception as ex:
logging.error("Error: '" + str(ex) + "' occured, while parsing ESO variables.")
return None
def sv_color_extract(Colors):
root = _sv_parser(os.path.join(get_savedvarsdir(), "Chalutier.lua"))
if root == None:
return Colors
for i in range(4):
name, root = root.popitem()
colors = []
for i in root["colors"]:
"""
ingame representation of colors range from 0 to 1 in float
these values are scaled by 255
"""
rgb=[
floor(float(root["colors"][i]["r"])*255),
floor(float(root["colors"][i]["g"])*255),
floor(float(root["colors"][i]["b"])*255)
]
colors.append(rgb)
for i,c in enumerate(Colors):
Colors[c] = colors[i]
return Colors