abstracted code into classes and different python files

This commit is contained in:
DESKTOP-JVKHS7I\Adam 2019-02-08 03:33:28 +05:30
parent 0f686ee50a
commit ca78219163
7 changed files with 295 additions and 229 deletions

60
fishing_event.py Normal file
View File

@ -0,0 +1,60 @@
from fishing_mode import *
class FishEvent(ABC):
@abstractmethod
def onEnterCallback(self, previousMode):
pass
@abstractmethod
def onExitCallback(self, currentMode):
pass
class HookEvent(FishEvent):
def onEnterCallback(self, previousMode):
G.fishCaught += 1
timeToHook = time.time() - G.stickInitTime
print("HOOOOOOOOOOOOOOOOOOOOOOOK....... " + str(G.fishCaught) + " caught " + " in " + str(
round_float(timeToHook)) + " secs")
pyautogui.press('e')
def onExitCallback(self, currentMode):
pass
class LookEvent(FishEvent):
def onEnterCallback(self, previousMode):
pyautogui.press('e')
def onExitCallback(self, currentMode):
pass
class IdleEvent(FishEvent):
def __init__(self, use_net):
self.use_net = use_net
def onEnterCallback(self, previousMode):
G.fishCaught = 0
if self.use_net:
net.sendHoleDeplete(G.fishCaught)
if previousMode.name == "hook":
print("HOLE DEPLETED")
elif previousMode.name == "stick":
print("FISHING INTERRUPTED")
def onExitCallback(self, currentMode):
pass
class StickEvent(FishEvent):
def onEnterCallback(self, previousMode):
G.stickInitTime = time.time()
def onExitCallback(self, currentMode):
pass

54
fishing_mode.py Normal file
View File

@ -0,0 +1,54 @@
from window import *
class FishingMode:
HValues = [60, 18, 100]
Threshold = int(arguments["--hook-threshold"])
CurrentCount = 0
PrevLabel = -1
CurrentMode = None
PrevMode = None
Modes = []
def __init__(self, name, label, event):
self.name = name
self.label = label
self.event = event
FishingMode.Modes.append(self)
@staticmethod
def GetByLabel(label):
for m in FishingMode.Modes:
if m.label == label:
return m
@staticmethod
def Loop(hueValue, pause):
current_label = 3
for i, val in enumerate(FishingMode.HValues):
if hueValue == val:
current_label = i
# check if it passes threshold, if so change labelNum
if FishingMode.PrevLabel == current_label:
FishingMode.CurrentCount += 1
else:
FishingMode.CurrentCount = 0
FishingMode.PrevLabel = current_label
if FishingMode.CurrentCount >= FishingMode.Threshold:
FishingMode.CurrentMode = FishingMode.GetByLabel(current_label)
if not pause and FishingMode.CurrentMode != FishingMode.PrevMode and FishingMode.PrevMode is not None:
if FishingMode.PrevMode.event is not None:
FishingMode.PrevMode.event.onExitCallback(FishingMode.CurrentMode)
if FishingMode.CurrentMode.event is not None:
FishingMode.CurrentMode.event.onEnterCallback(FishingMode.PrevMode)
FishingMode.PrevMode = FishingMode.CurrentMode

264
fishy.py
View File

@ -1,108 +1,4 @@
"""Fishy
Usage:
fishy.py -h | --help
fishy.py -v | --version
fishy.py [--ip=<ipv4>] [--hook-threshold=<int>] [--check-frequency=<hz>] [--no-resize]
Options:
-h, --help Show this screen.
-v, --version Show version.
--ip=<ipv4> Local Ip Address of the android phone.
--hook-threshold=<int> Threshold amount for classifier after which label changes [default: 3].
--check-frequency=<hz> Sleep after loop in s [default: 10].
"""
VERSION = "0.1.0"
print("Fishy " + VERSION + " for Elder Scrolls Online")
try:
from docopt import docopt
arguments = docopt(__doc__)
if arguments["--version"]:
quit()
print("Loading, Please Wait...")
import imutils as imutils
import numpy as np
from PIL import ImageGrab
import cv2
import pyautogui
import time
import fishy_network as net
from fishy_config import config_win
from pynput.keyboard import Key, Listener
from decimal import Decimal
from win32api import GetSystemMetrics
import pickle
except Exception:
raise
controls = {"stop": [Key.f11, "f11"], "debug": [Key.f10, "f10"], "pause": [Key.f9, "f9"], "configPL": [Key.f8, "f8"]}
stop = False
pause = False
debug = False
configPL = False
IMG_SIZE = 100
LR = 1e-3
STICK_TIMEOUT = 30.0
NONE_TIMEOUT = 5.0
IP_ADDRESS = arguments["--ip"]
bbox = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
try:
pixelLoc = pickle.load(open("pixelLoc.pickle", "rb"))
except (OSError, IOError) as e:
pixelLoc = [[240, 31], [241, 32]]
def process_img(original_img):
"""
Convert image into hsv and crop it to select the required pixel
:param original_img: image grabbed from screen
:return: processed image in hsv
"""
original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2HSV)
# y:y+h, x:x+w
croped_img = original_img[pixelLoc[0][1]:pixelLoc[1][1], pixelLoc[0][0]:pixelLoc[1][0]]
return croped_img
def process_show(original_img):
"""
Converts image into rgb and crop it to select the required pixel then scale it up for debuging
:param original_img: image grabbed from screen
:return: proessed image in rgb
"""
original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
# y:y+h, x:x+w
croped_img = original_img[pixelLoc[0][1]:pixelLoc[1][1], pixelLoc[0][0]:pixelLoc[1][0]]
croped_img = imutils.resize(croped_img, width=200)
return croped_img
def round_float(v, ndigits=2, rt_str=False):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
def pullStick(fishCaught, timeToHook):
"""
Hooks the fish
:param fishCaught: fish cout to be displayed
:param timeToHook: time took to hook the fish
:return: void
"""
print("HOOOOOOOOOOOOOOOOOOOOOOOK....... " + str(fishCaught) + " caught " + " in " + str(
round_float(timeToHook)) + " secs")
pyautogui.press('e')
# Timer(0.5, pressE).start()
from pixel_loc import *
def on_release(key):
@ -111,29 +7,22 @@ def on_release(key):
:param key: key released
:return: void
"""
global stop, pause, debug, configPL
if controls["pause"][0] == key:
pause = not pause
if pause:
if G.controls["pause"][0] == key:
G.pause = not G.pause
if G.pause:
print("PAUSED")
else:
print("STARTED")
elif controls["debug"][0] == key:
debug = not debug
elif G.controls["debug"][0] == key:
G.debug = not G.debug
elif controls["stop"][0] == key:
stop = True
elif G.controls["stop"][0] == key:
G.stop = True
elif controls["configPL"][0] == key:
configPL = not configPL
def updatePixelLoc():
global pixelLoc
x, y = pyautogui.position()
pixelLoc = [[x, y], [x + 1, y + 1]]
elif G.controls["configPL"][0] == key:
G.configPL = not G.configPL
def startFishing():
@ -141,123 +30,44 @@ def startFishing():
Starts the fishing codde
:return: void
"""
global stop, pause, debug
pause = True
showedControls = True
debug = False
stop = False
holeDepleteSent = True
timerStarted = False
use_net = False
hooked = False
configPixelSave = True
threwStick = False
fishCaught = 0
prevLabel = 0
labelNum = 3
hVals = [60, 18, 100]
current_thresh = 0
stickInitTime = time.time()
if not arguments["--no-resize"]:
config_win()
ctrl_help = controls["configPL"][1] + ": config pixel value\n" + controls["pause"][1] + ": start or pause\n" + \
controls["debug"][1] + ": start debug\n" + controls["stop"][1] + ": quit\n"
print(ctrl_help)
use_net = arguments["--ip"] is not None
if use_net:
net.initialize(arguments["--ip"])
if IP_ADDRESS is not None:
use_net = True
net.initialize(IP_ADDRESS)
threshold = int(arguments["--hook-threshold"])
sleepFor = (1 / float(arguments["--check-frequency"]))
FishingMode("hook", 0, HookEvent())
FishingMode("stick", 1, StickEvent())
FishingMode("look", 2, LookEvent())
FishingMode("idle", 3, IdleEvent(use_net))
fishPixWindow = Window("fishPixWindow", PixelLoc.val, 1, cv2.COLOR_BGR2HSV)
fishPixDebugWindow = Window("fishPixDebugWindow", PixelLoc.val, 200, cv2.COLOR_BGR2RGB)
Log.ctrl()
# todo
with Listener(on_release=on_release):
while not stop:
while not G.stop:
time.sleep(sleepFor)
# image grab
screen = np.array(ImageGrab.grab(bbox=bbox))
new_screen = process_img(screen)
hueValue = new_screen[0][0][0]
Window.Loop()
Log.Loop()
# find currentlable
currentLabel = 3
for i, val in enumerate(hVals):
if hueValue == val:
currentLabel = i
pixelVal = (PixelLoc.val[0], PixelLoc.val[1], PixelLoc.val[0] + 1, PixelLoc.val[1] + 1)
fishPixWindow.crop = pixelVal
fishPixDebugWindow.crop = pixelVal
hueValue = fishPixWindow.getCapture()[0][0][0]
FishingMode.Loop(hueValue, G.pause)
fishPixDebugWindow.show(G.debug or G.configPL)
if G.debug or G.configPL:
Log.ou(str(FishingMode.CurrentMode.label) + ":" + str(hueValue))
PixelLoc.Loop()
# check if it passes threshold, if so change labelNum
if prevLabel == currentLabel:
current_thresh += 1
else:
current_thresh = 0
prevLabel = currentLabel
if current_thresh >= threshold:
labelNum = currentLabel
# use label num
if not pause:
# fish caught
if labelNum == 0:
if not hooked:
fishCaught += 1
timeToHook = time.time() - stickInitTime
pullStick(fishCaught, timeToHook)
hooked = True
# fishing
if labelNum == 1:
hooked = False
if not timerStarted:
stickInitTime = time.time()
timerStarted = True
if (time.time() - stickInitTime) >= STICK_TIMEOUT:
print("STICK TIMED OUT, THROWING AGAIN")
pyautogui.press('e')
timerStarted = False
else:
timerStarted = False
# looking on hole
if labelNum == 2:
if not threwStick:
pyautogui.press('e')
threwStick = True
else:
threwStick = False
# not looking on hole
if labelNum == 3:
if not holeDepleteSent:
if fishCaught > 0:
print("HOLE DEPLETED")
if use_net:
net.sendHoleDeplete(fishCaught)
fishCaught = 0
holeDepleteSent = True
else:
holeDepleteSent = False
if debug or configPL:
print(str(labelNum) + ":" + str(hueValue))
cv2.imshow('image', process_show(screen))
showedControls = False
else:
if not showedControls:
showedControls = True
print(ctrl_help)
cv2.destroyAllWindows()
if configPL:
updatePixelLoc()
configPixelSave = False
elif not configPixelSave:
pickle.dump(pixelLoc, open("pixelLoc.pickle", "wb"))
cv2.waitKey(25)
Log.LoopEnd()
Window.LoopEnd()
if __name__ == "__main__":

View File

@ -8,10 +8,12 @@ MESSAGE = "yo"
RETRY_LIMIT = 5
IP = 0
def initialize(ip):
global s, IP
IP = ip
def send_message(message, count=1):
try:
s = socket.socket()
@ -33,5 +35,6 @@ def sendHoleDeplete(count):
send_message(jsonString)
##initialize("192.168.0.192")
##sendHoleDeplete(2)
if __name__ == "__main__":
initialize("192.168.0.192")
sendHoleDeplete(2)

87
init.py Normal file
View File

@ -0,0 +1,87 @@
"""Fishy
Usage:
fishy.py -h | --help
fishy.py -v | --version
fishy.py [--ip=<ipv4>] [--hook-threshold=<int>] [--check-frequency=<hz>] [--no-resize]
Options:
-h, --help Show this screen.
-v, --version Show version.
--ip=<ipv4> Local Ip Address of the android phone.
--hook-threshold=<int> Threshold amount for classifier after which label changes [default: 3].
--check-frequency=<hz> Sleep after loop in s [default: 10].
"""
VERSION = "0.1.0"
print("Fishy " + VERSION + " for Elder Scrolls Online")
try:
from docopt import docopt
arguments = docopt(__doc__)
if arguments["--version"]:
quit()
print("Loading, Please Wait...")
import imutils as imutils
import numpy as np
from PIL import ImageGrab
import cv2
import pyautogui
import time
import fishy_network as net
from fishy_config import config_win
from pynput.keyboard import Key, Listener
from decimal import Decimal
from win32api import GetSystemMetrics
import pickle
import win32gui
from abc import ABC, abstractmethod
except Exception:
raise
class G:
fishCaught = 0
stickInitTime = 0
controls = {"stop": [Key.f11, "f11"], "debug": [Key.f10, "f10"], "pause": [Key.f9, "f9"],
"configPL": [Key.f8, "f8"]}
stop = False
pause = True
debug = 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):
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)

20
pixel_loc.py Normal file
View File

@ -0,0 +1,20 @@
from fishing_event import *
class PixelLoc:
configPixelSaved = True
try:
val = pickle.load(open("pixelLoc.pickle", "rb"))
except (OSError, IOError) as e:
val = (240, 31)
@staticmethod
def Loop():
if G.configPL:
x, y = pyautogui.position()
PixelLoc.val = (x, y)
PixelLoc.configPixelSaved = False
elif not PixelLoc.configPixelSaved:
pickle.dump(PixelLoc.val, open("pixelLoc.pickle", "wb"))
PixelLoc.configPixelSaved = True

32
window.py Normal file
View File

@ -0,0 +1,32 @@
from init import *
class Window:
Screen = None
def __init__(self, name, crop, scale, color):
self.color = color
self.crop = crop
self.scale = scale
self.name = name
@staticmethod
def Loop():
bbox = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
Window.Screen = np.array(ImageGrab.grab(bbox=bbox))
@staticmethod
def LoopEnd():
cv2.waitKey(25)
def show(self, show):
if show:
cv2.imshow(self.name, self.getCapture())
else:
cv2.destroyWindow(self.name)
def getCapture(self):
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 = imutils.resize(temp_img, width=self.scale)
return temp_img