abstracted control and log, removed bool from show method, windows scale bug fixed

This commit is contained in:
DESKTOP-JVKHS7I\Adam 2019-02-15 19:14:49 +05:30
parent ca78219163
commit a9e02686a4
5 changed files with 286 additions and 51 deletions

63
controls.py Normal file
View File

@ -0,0 +1,63 @@
from init import *
class Control:
#todo change to 0
current = 1 if arguments["--debug"] else 0
class Keywords(Enum):
SwitchMode = "switch mode"
StartPause = "start/pause"
Debug = "debug"
Stop = "stop"
ConfigPixLoc = "config pixel location"
ClearPrintOnce = "clear print once"
controls = [
{
"name": "SYSTEM",
"controls": [
[Keywords.SwitchMode, Key.f8],
[Keywords.StartPause, Key.f9],
[Keywords.ConfigPixLoc, Key.f10],
[Keywords.Stop, Key.f11]
]
},
{
"name": "DEBUG",
"controls": [
[Keywords.SwitchMode, Key.f8],
[Keywords.ClearPrintOnce, Key.f9],
[Keywords.Debug, Key.f10],
]
}
]
@staticmethod
def getControlHelp():
s = "\n\nCurrent Mode: " + Control.get()["name"]+"\n"
for c in Control.controls[Control.current]["controls"]:
s += c[0].value + ": " + c[1].name + "\n"
return s
@staticmethod
def get():
return Control.controls[Control.current]
@staticmethod
def find(key):
for c in Control.get()["controls"]:
if key == c[1]:
return c
return None
@staticmethod
def nextState():
Control.current += 1
if Control.current >= len(Control.controls):
Control.current = 0

103
fishy.py
View File

@ -8,22 +8,74 @@ def on_release(key):
:return: void :return: void
""" """
if G.controls["pause"][0] == key: c = Control.find(key)
if c is None:
return
if c[0] == Control.Keywords.StartPause:
G.pause = not G.pause G.pause = not G.pause
if G.pause: if G.pause:
print("PAUSED") print("PAUSED")
else: else:
print("STARTED") print("STARTED")
elif G.controls["debug"][0] == key: elif c[0] == Control.Keywords.Debug:
G.debug = not G.debug G.debug = not G.debug
elif G.controls["stop"][0] == key: elif c[0] == Control.Keywords.Stop:
G.stop = True G.stop = True
elif G.controls["configPL"][0] == key: elif c[0] == Control.Keywords.ConfigPixLoc:
G.configPL = not G.configPL G.configPL = not G.configPL
elif c[0] == Control.Keywords.SwitchMode:
Control.nextState()
Log.ctrl()
elif c[0] == Control.Keywords.ClearPrintOnce:
Log.clearPrintIds()
def ipDebug(img):
# Setup SimpleBlobDetector parameters.
hsvImg = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
lower = (99, 254, 100)
upper = (100, 255, 101)
mask = cv2.inRange(hsvImg, lower, upper)
#mask = cv2.bitwise_not(mask)
# 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.
keypoints = detector.detect(mask)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
draw_keypoints(img, keypoints)
return img
def hsv2rgb(img):
return cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
def startFishing(): def startFishing():
""" """
@ -45,30 +97,57 @@ def startFishing():
FishingMode("look", 2, LookEvent()) FishingMode("look", 2, LookEvent())
FishingMode("idle", 3, IdleEvent(use_net)) FishingMode("idle", 3, IdleEvent(use_net))
fishPixWindow = Window("fishPixWindow", PixelLoc.val, 1, cv2.COLOR_BGR2HSV) fishPixWindow = Window("fishPixWindow", PixelLoc.val, cv2.COLOR_BGR2HSV)
fishPixDebugWindow = Window("fishPixDebugWindow", PixelLoc.val, 200, cv2.COLOR_BGR2RGB)
try:
hwnd = win32gui.FindWindow(None, "Elder Scrolls Online")
rect = win32gui.GetWindowRect(hwnd)
clientRect = win32gui.GetClientRect(hwnd)
windowOffset = math.floor(((rect[2] - rect[0]) - clientRect[2]) / 2)
titleOffset = ((rect[3] - rect[1]) - clientRect[3]) - windowOffset
windowLoc = (rect[0] + windowOffset, rect[1] + titleOffset, rect[2] - windowOffset, rect[3] - windowOffset)
gameScreen = Window("game", windowLoc, cv2.COLOR_BGR2RGB)
except pywintypes.error:
print("Game window not found")
return
Log.ctrl() Log.ctrl()
# todo # todo
time.time()
with Listener(on_release=on_release): with Listener(on_release=on_release):
while not G.stop: while not G.stop:
time.sleep(sleepFor) current_time = time.time()
Window.Loop() Window.Loop()
Log.Loop() Log.Loop()
PixelLoc.Loop()
pixelVal = (PixelLoc.val[0], PixelLoc.val[1], PixelLoc.val[0] + 1, PixelLoc.val[1] + 1) pixelVal = (PixelLoc.val[0], PixelLoc.val[1], PixelLoc.val[0] + 1, PixelLoc.val[1] + 1)
fishPixWindow.crop = pixelVal fishPixWindow.crop = pixelVal
fishPixDebugWindow.crop = pixelVal
hueValue = fishPixWindow.getCapture()[0][0][0] hueValue = fishPixWindow.getCapture()[0][0][0]
FishingMode.Loop(hueValue, G.pause) FishingMode.Loop(hueValue, G.pause)
fishPixDebugWindow.show(G.debug or G.configPL)
if G.debug or G.configPL: if G.configPL:
Log.ou(str(FishingMode.CurrentMode.label) + ":" + str(hueValue)) fishPixWindow.show(resize=200, func=hsv2rgb)
PixelLoc.Loop() Log.ou(str(FishingMode.CurrentMode.label) + ":" + str(fishPixWindow.getCapture()[0][0]))
if G.debug:
rect = win32gui.GetWindowRect(hwnd)
gameScreen.crop = (rect[0] + windowOffset, rect[1] + titleOffset, rect[2] - windowOffset,
rect[3] - windowOffset)
gameScreen.show(func=ipDebug)
Log.LoopEnd() Log.LoopEnd()
Window.LoopEnd() Window.LoopEnd()
frameTime = time.time() - current_time
if frameTime < sleepFor:
time.sleep(sleepFor - frameTime)
if __name__ == "__main__": if __name__ == "__main__":
startFishing() startFishing()

93
init.py
View File

@ -3,14 +3,15 @@
Usage: Usage:
fishy.py -h | --help fishy.py -h | --help
fishy.py -v | --version fishy.py -v | --version
fishy.py [--ip=<ipv4>] [--hook-threshold=<int>] [--check-frequency=<hz>] [--no-resize] fishy.py [--debug] [--ip=<ipv4>] [--hook-threshold=<int>] [--check-frequency=<hz>] [--no-resize]
Options: Options:
-h, --help Show this screen. -h, --help Show this screen.
-v, --version Show version. -v, --version Show version.
--ip=<ipv4> Local Ip Address of the android phone. --ip=<ipv4> Local Ip Address of the android phone.
--hook-threshold=<int> Threshold amount for classifier after which label changes [default: 3]. --hook-threshold=<int> Threshold amount for classifier after which label changes [default: 1].
--check-frequency=<hz> Sleep after loop in s [default: 10]. --check-frequency=<hz> Sleep after loop in s [default: 1].
--debug Start program in debug controls.
""" """
VERSION = "0.1.0" VERSION = "0.1.0"
@ -37,51 +38,81 @@ try:
from win32api import GetSystemMetrics from win32api import GetSystemMetrics
import pickle import pickle
import win32gui import win32gui
import pywintypes
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from enum import Enum
import sys
import numpy as np
import math
except Exception: except Exception:
raise raise
'''
import stack
fishy
pixel_loc
fishing_event
fishing_mode
window
log
controls
init
'''
class G: class G:
fishCaught = 0 fishCaught = 0
stickInitTime = 0 stickInitTime = 0
controls = {"stop": [Key.f11, "f11"], "debug": [Key.f10, "f10"], "pause": [Key.f9, "f9"],
"configPL": [Key.f8, "f8"]}
stop = False stop = False
pause = True pause = True
debug = False debug = False
configPL = False configPL = False
class Log:
ouUsed = False
prevOuUsed = False
ctrl_help = G.controls["configPL"][1] + ": config pixel value\n" + G.controls["pause"][1] + ": start or pause\n" + \
G.controls["debug"][1] + ": start debug\n" + G.controls["stop"][1] + ": quit\n"
@staticmethod
def Loop():
Log.ouUsed = False
@staticmethod
def LoopEnd():
if Log.prevOuUsed and not Log.ouUsed:
print(Log.ctrl_help)
Log.prevOuUsed = Log.ouUsed
@staticmethod
def ctrl():
print(Log.ctrl_help)
@staticmethod
def ou(s):
Log.ouUsed = True
print(s)
def round_float(v, ndigits=2, rt_str=False): def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v) d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits)) v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str: if rt_str:
return v_str return v_str
return Decimal(v_str) return Decimal(v_str)
def draw_keypoints(vis, keypoints, color=(0, 0, 255)):
for kp in keypoints:
x, y = kp.pt
cv2.circle(vis, (int(x), int(y)), 5, color, -1)
def image_resize(image, width=None, height=None, inter = cv2.INTER_AREA):
# initialize the dimensions of the image to be resized and
# grab the image size
dim = None
(h, w) = image.shape[:2]
# if both the width and height are None, then return the
# original image
if width is None and height is None:
return image
# check to see if the width is None
if width is None:
# calculate the ratio of the height and construct the
# dimensions
r = height / float(h)
dim = (int(w * r), height)
# otherwise, the height is None
else:
# calculate the ratio of the width and construct the
# dimensions
r = width / float(w)
dim = (width, int(h * r))
# resize the image
resized = cv2.resize(image, dim, interpolation = inter)
# return the resized image
return resized
# np.set_printoptions(threshold=sys.maxsize)

37
log.py Normal file
View File

@ -0,0 +1,37 @@
from controls import *
class Log:
ouUsed = False
prevOuUsed = False
printIds = []
@staticmethod
def Loop():
Log.ouUsed = False
@staticmethod
def LoopEnd():
if Log.prevOuUsed and not Log.ouUsed:
Log.ctrl()
Log.prevOuUsed = Log.ouUsed
@staticmethod
def ctrl():
print(Control.getControlHelp())
@staticmethod
def ou(s):
Log.ouUsed = True
print(s)
@staticmethod
def po(id, s):
if id not in Log.printIds:
print(s)
Log.printIds.append(id)
@staticmethod
def clearPrintIds():
Log.printIds = []

View File

@ -1,32 +1,57 @@
from init import * from log import *
class Window: class Window:
Screen = None Screen = None
wins = []
def __init__(self, name, crop, scale, color): def __init__(self, name, crop, color, scale=None):
self.color = color self.color = color
self.crop = crop self.crop = crop
self.scale = scale self.scale = scale
self.name = name self.name = name
self.showed = False
Window.wins.append(self)
@staticmethod @staticmethod
def Loop(): def Loop():
bbox = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1)) bbox = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
Window.Screen = np.array(ImageGrab.grab(bbox=bbox)) Window.Screen = np.array(ImageGrab.grab(bbox=bbox))
@staticmethod @staticmethod
def LoopEnd(): def LoopEnd():
cv2.waitKey(25) cv2.waitKey(25)
def show(self, show): for w in Window.wins:
if show:
cv2.imshow(self.name, self.getCapture()) if not w.showed:
else: cv2.destroyWindow(w.name)
cv2.destroyWindow(self.name)
w.showed = False
def getCapture(self): def getCapture(self):
temp_img = cv2.cvtColor(Window.Screen, self.color) temp_img = cv2.cvtColor(Window.Screen, self.color)
temp_img = temp_img[self.crop[1]:self.crop[3], self.crop[0]:self.crop[2]] temp_img = temp_img[self.crop[1]:self.crop[3], self.crop[0]:self.crop[2]]
temp_img = imutils.resize(temp_img, width=self.scale)
if self.scale is not None:
temp_img = cv2.resize(temp_img, (self.scale[0], self.scale[1]), interpolation=cv2.INTER_AREA)
return temp_img return temp_img
def processedImage(self, func=None):
if func is None:
return self.getCapture()
else:
return func(self.getCapture())
def show(self, resize=None, func=None):
img = self.processedImage(func)
if resize is not None:
img = imutils.resize(img, width=resize)
cv2.imshow(self.name, img)
self.showed = True