fishy network removed, integreted web push notificaitons

This commit is contained in:
DESKTOP-JVKHS7I\Adam 2020-04-28 02:49:30 +05:30
parent 36daacbf42
commit b8155ef468
11 changed files with 162 additions and 96 deletions

View File

@ -1,2 +1,2 @@
from fishy.__main__ import main from fishy.__main__ import main
__version__ = "0.2.8" __version__ = "0.3.0"

View File

@ -9,28 +9,26 @@ import cv2
import pywintypes import pywintypes
import fishy import fishy
from fishy.systems import * from fishy.systems import *
from fishy.systems import helper from fishy.systems import helper, web
from fishy.systems.config import Config from fishy.systems.config import Config
from fishy.systems.gui import GUI, GUIEvent, GUIFunction from fishy.systems.gui import GUI, GUIEvent, GUIFunction
class Fishy: class Fishy:
def __init__(self, gui_ref, gui_event_buffer): def __init__(self, gui_ref, gui_event_buffer, config):
self.gui_events = gui_event_buffer self.gui_events = gui_event_buffer
self.start = False self.start = False
self.fishPixWindow = None self.fishPixWindow = None
self.fishy_thread = None self.fishy_thread = None
self.gui = gui_ref self.gui = gui_ref
self.config = config
def start_fishing(self, ip: str, action_key: str, borderless: bool, collect_r: bool): def start_fishing(self, action_key: str, borderless: bool, collect_r: bool):
""" """
Starts the fishing Starts the fishing
code explained in comments in detail code explained in comments in detail
""" """
if ip != "":
net.initialize(ip)
# initialize widow # initialize widow
try: try:
Window.Init(borderless) Window.Init(borderless)
@ -43,7 +41,7 @@ class Fishy:
FishingMode("hook", 0, HookEvent(action_key, collect_r)) FishingMode("hook", 0, HookEvent(action_key, collect_r))
FishingMode("stick", 1, StickEvent()) FishingMode("stick", 1, StickEvent())
FishingMode("look", 2, LookEvent()) FishingMode("look", 2, LookEvent())
FishingMode("idle", 3, IdleEvent(ip != "")) FishingMode("idle", 3, IdleEvent(self.config.get("uid")))
self.fishPixWindow = Window(color=cv2.COLOR_RGB2HSV) self.fishPixWindow = Window(color=cv2.COLOR_RGB2HSV)
@ -97,14 +95,29 @@ class Fishy:
Thread(target=show, args=()).start() Thread(target=show, args=()).start()
def initialize(c: Config, gui): def create_shortcut_first(gui, c):
if c.get("first_launch", True, False): if not c.get("shortcut_created", False):
helper.create_shortcut(gui) helper.create_shortcut(gui)
c.set("first_launch", False) c.set("shortcut_created", True)
def initialize_uid(config: Config):
if config.get("uid") is not None:
return
new_uid = helper.create_new_uid()
if web.register_user(new_uid):
config.set("uid", new_uid)
else:
logging.error("Couldn't register uid, some features might not work")
def initialize(gui, c: Config):
create_shortcut_first(gui, c)
initialize_uid(c)
try: try:
auto_upgrade() auto_upgrade()
helper.ping(c, "started")
except Exception: except Exception:
pass pass
@ -114,6 +127,8 @@ def initialize(c: Config, gui):
helper.install_thread_excepthook() helper.install_thread_excepthook()
sys.excepthook = helper.unhandled_exception_logging sys.excepthook = helper.unhandled_exception_logging
helper.check_addon()
def wait_and_check(): def wait_and_check():
time.sleep(10) time.sleep(10)
@ -129,13 +144,10 @@ def main():
gui.start() gui.start()
logging.info(f"Fishybot v{fishy.__version__}") logging.info(f"Fishybot v{fishy.__version__}")
initialize(c, gui) initialize(gui, c)
helper.check_addon()
bot = Fishy(gui, events_buffer) bot = Fishy(gui, events_buffer)
bot.start_event_handler() bot.start_event_handler()
helper.ping(c, f"closed,fishes:{G.totalFishCaught}")
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -2,6 +2,5 @@ from fishy.systems.fishing_event import HookEvent, StickEvent, LookEvent, IdleEv
from fishy.systems.fishing_mode import FishingMode from fishy.systems.fishing_mode import FishingMode
from fishy.systems.globals import G from fishy.systems.globals import G
from fishy.systems.pixel_loc import PixelLoc from fishy.systems.pixel_loc import PixelLoc
import fishy.systems.fishy_network as net
from fishy.systems.window import Window from fishy.systems.window import Window
from fishy.systems.auto_update import auto_upgrade from fishy.systems.auto_update import auto_upgrade

View File

@ -10,12 +10,9 @@ class Config:
def __init__(self): def __init__(self):
self.config_dict = json.loads(open(filename).read()) if os.path.exists(filename) else dict() self.config_dict = json.loads(open(filename).read()) if os.path.exists(filename) else dict()
def get(self, key, default=None, save=True): def get(self, key, default=None):
if key in self.config_dict: if key in self.config_dict:
return self.config_dict[key] return self.config_dict[key]
if save:
self.set(key, default)
return default return default
def set(self, key, value, save=True): def set(self, key, value, save=True):

View File

@ -8,9 +8,9 @@ from abc import abstractmethod, ABC
import pyautogui import pyautogui
from fishy.systems import web
from fishy.systems.globals import G from fishy.systems.globals import G
from fishy.systems.helper import round_float from fishy.systems.helper import round_float
import fishy.systems.fishy_network as net
class FishEvent(ABC): class FishEvent(ABC):
@ -73,12 +73,12 @@ class IdleEvent(FishEvent):
State when the fishing hole is depleted or the bot is doing nothing State when the fishing hole is depleted or the bot is doing nothing
""" """
def __init__(self, use_net): def __init__(self, uid):
""" """
sets the flag to send notification on phone sets the flag to send notification on phone
:param use_net: true if user wants to send notification on phone :param use_net: true if user wants to send notification on phone
""" """
self.use_net = use_net self.uid = uid
def onEnterCallback(self, previousMode): def onEnterCallback(self, previousMode):
""" """
@ -87,8 +87,7 @@ class IdleEvent(FishEvent):
""" """
G.fishCaught = 0 G.fishCaught = 0
if self.use_net: web.send_hole_deplete(self.uid, G.fishCaught)
net.sendHoleDeplete(G.fishCaught)
if previousMode.name == "hook": if previousMode.name == "hook":
logging.info("HOLE DEPLETED") logging.info("HOLE DEPLETED")

View File

@ -1,40 +0,0 @@
import logging
import socket
import json
PORT = 8023
MESSAGE = "yo"
RETRY_LIMIT = 5
IP = 0
s = None
def initialize(ip):
global s, IP
IP = ip
def send_message(message, count=1):
try:
sock = socket.socket()
sock.connect((IP, PORT))
sock.send(bytes(message, "utf-8"))
sock.close()
except ConnectionRefusedError:
logging.info("Connection Refused, please turn on service on mobile")
except TimeoutError:
logging.info("Timeout Error")
if count < RETRY_LIMIT:
send_message(message, count+1)
def sendHoleDeplete(count):
message = {"action": "holeDeplete", "fishCount": count}
jsonString = json.dumps(message)
send_message(jsonString)
if __name__ == "__main__":
initialize("192.168.0.192")
sendHoleDeplete(2)

View File

@ -6,3 +6,4 @@ class G:
totalFishCaught = 0 totalFishCaught = 0
stickInitTime = 0 stickInitTime = 0
FishingStarted = False FishingStarted = False
_is_subbed = None

View File

@ -1,5 +1,6 @@
import logging import logging
import os import os
import tempfile
import time import time
from enum import Enum from enum import Enum
from logging import StreamHandler from logging import StreamHandler
@ -8,10 +9,10 @@ from tkinter import filedialog, messagebox
from tkinter.ttk import * from tkinter.ttk import *
from typing import Tuple, List, Callable, Optional from typing import Tuple, List, Callable, Optional
import pyqrcode
from ttkthemes import ThemedTk from ttkthemes import ThemedTk
import threading import threading
from fishy.systems import helper
from fishy.systems.config import Config from fishy.systems.config import Config
@ -52,6 +53,7 @@ class GUI:
self.root = None self.root = None
self.console = None self.console = None
self.start_button = None self.start_button = None
self.notif = None
self.thread = threading.Thread(target=self.create, args=()) self.thread = threading.Thread(target=self.create, args=())
@ -61,6 +63,9 @@ class GUI:
rootLogger.addHandler(new_console) rootLogger.addHandler(new_console)
def create(self): def create(self):
from fishy.systems import helper
from fishy.systems import web
self.root = ThemedTk(theme="equilux", background=True) self.root = ThemedTk(theme="equilux", background=True)
self.root.title("Fiishybot for Elder Scrolls Online") self.root.title("Fiishybot for Elder Scrolls Online")
self.root.geometry('650x550') self.root.geometry('650x550')
@ -82,7 +87,7 @@ class GUI:
debug_menu = Menu(menubar, tearoff=0) debug_menu = Menu(menubar, tearoff=0)
debug_menu.add_command(label="Check PixelVal", debug_menu.add_command(label="Check PixelVal",
command=lambda: self._event_trigger(GUIEvent.CHECK_PIXELVAL)) command=lambda: self._event_trigger(GUIEvent.CHECK_PIXELVAL, ()))
debug_var = IntVar() debug_var = IntVar()
debug_var.set(int(self.config.get('debug', False))) debug_var.set(int(self.config.get('debug', False)))
@ -90,6 +95,7 @@ class GUI:
def keep_console(): def keep_console():
self.config.set("debug", bool(debug_var.get())) self.config.set("debug", bool(debug_var.get()))
logging.debug("Restart to update the changes") logging.debug("Restart to update the changes")
debug_menu.add_checkbutton(label="Keep Console", command=keep_console, variable=debug_var) debug_menu.add_checkbutton(label="Keep Console", command=keep_console, variable=debug_var)
debug_menu.add_command(label="Log Dump", command=lambda: logging.error("Not Implemented")) debug_menu.add_command(label="Log Dump", command=lambda: logging.error("Not Implemented"))
@ -116,13 +122,14 @@ class GUI:
# region controls # region controls
left_frame = Frame(controls_frame) left_frame = Frame(controls_frame)
Label(left_frame, text="Android IP").grid(row=0, column=0) Label(left_frame, text="Notification:").grid(row=0, column=0)
ip = Entry(left_frame)
ip.insert(0, self.config.get("ip", "")) self.notif = IntVar(value=int(web.is_subbed(self.config.get('uid'))))
ip.grid(row=0, column=1) Checkbutton(left_frame, command=self.give_notification_link,
variable=self.notif).grid(row=0, column=1)
Label(left_frame, text="Fullscreen: ").grid(row=1, column=0, pady=(5, 5)) Label(left_frame, text="Fullscreen: ").grid(row=1, column=0, pady=(5, 5))
borderless = Checkbutton(left_frame, variable=IntVar(value=int(self.config.get("borderless", False)))) borderless = Checkbutton(left_frame, )
borderless.grid(row=1, column=1) borderless.grid(row=1, column=1)
left_frame.grid(row=0, column=0) left_frame.grid(row=0, column=0)
@ -145,8 +152,7 @@ class GUI:
self.start_button = Button(self.root, text="STOP" if self._bot_running else "START", width=25) self.start_button = Button(self.root, text="STOP" if self._bot_running else "START", width=25)
def start_button_callback(): def start_button_callback():
args = (ip.get(), args = (action_key_entry.get(),
action_key_entry.get(),
borderless.instate(['selected']), borderless.instate(['selected']),
collect_r.instate(['selected'])) collect_r.instate(['selected']))
self._event_trigger(GUIEvent.START_BUTTON, args) self._event_trigger(GUIEvent.START_BUTTON, args)
@ -158,7 +164,7 @@ class GUI:
self._apply_theme(self.config.get("dark_mode", True)) self._apply_theme(self.config.get("dark_mode", True))
self.root.update() self.root.update()
self.root.minsize(self.root.winfo_width(), self.root.winfo_height()) self.root.minsize(self.root.winfo_width()+10, self.root.winfo_height()+10)
self.root.protocol("WM_DELETE_WINDOW", self._set_destroyed) self.root.protocol("WM_DELETE_WINDOW", self._set_destroyed)
self.destroyed = False self.destroyed = False
@ -171,7 +177,7 @@ class GUI:
self.start_restart = False self.start_restart = False
self.create() self.create()
if self.destroyed: if self.destroyed:
self._event_trigger(GUIEvent.QUIT) self._event_trigger(GUIEvent.QUIT, ())
break break
time.sleep(0.01) time.sleep(0.01)
@ -213,8 +219,7 @@ class GUI:
self.console.see("end") # scroll to bottom self.console.see("end") # scroll to bottom
self.console['state'] = 'disabled' self.console['state'] = 'disabled'
def _save_config(self, ip, action_key, borderless, collect_r): def _save_config(self, action_key, borderless, collect_r):
self.config.set("ip", ip, False)
self.config.set("action_key", action_key, False) self.config.set("action_key", action_key, False)
self.config.set("borderless", borderless, False) self.config.set("borderless", borderless, False)
self.config.set("collect_r", collect_r, False) self.config.set("collect_r", collect_r, False)
@ -225,3 +230,52 @@ class GUI:
def call(self, gui_func: GUIFunction, args: Tuple = None): def call(self, gui_func: GUIFunction, args: Tuple = None):
self._function_queue.append((gui_func, args)) self._function_queue.append((gui_func, args))
def give_notification_link(self):
from fishy.systems import web
if web.is_subbed(self.config.get("uid")):
web.unsub(self.config.get("uid"))
return
self.notif.set(0)
def quit_top():
top.destroy()
top_running[0] = False
def check():
if web.is_subbed(self.config.get("uid"), False):
messagebox.showinfo("Note!", "Notification configured successfully!")
web.send_notification(self.config.get("uid"), "Sending a test notification :D")
self.notif.set(1)
quit_top()
else:
messagebox.showerror("Error", "Subscription wasn't successful")
qrcode = pyqrcode.create(web.get_notification_page(self.config.get("uid")))
t = os.path.join(tempfile.gettempdir(), "fishyqr.png")
qrcode.png(t, scale=8)
top_running = [True]
top = Toplevel(background=self.root["background"])
top.minsize(width=500, height=500)
top.title("Notification Setup")
Label(top, text="Step 1.").pack(pady=(5, 5))
Label(top, text="Scan the QR Code on your Phone and press \"Enable Notification\"").pack(pady=(5, 5))
canvas = Canvas(top, width=qrcode.get_png_size(8), height=qrcode.get_png_size(8))
canvas.pack(pady=(5, 5))
Label(top, text="Step 2.").pack(pady=(5, 5))
Button(top, text="Check", command=check).pack(pady=(5, 5))
image = PhotoImage(file=t)
canvas.create_image(0, 0, anchor="nw", image=image)
top.protocol("WM_DELETE_WINDOW", quit_top)
top.grab_set()
while top_running[0]:
top.update()
top.grab_release()

View File

@ -14,12 +14,7 @@ import numpy as np
from uuid import uuid1 from uuid import uuid1
from hashlib import md5 from hashlib import md5
import requests
from whatsmyip.ip import get_ip
from whatsmyip.providers import GoogleDnsProvider
import fishy import fishy
from fishy.systems.config import Config
import functools import functools
from fishy.systems.gui import GUIFunction from fishy.systems.gui import GUIFunction
@ -76,18 +71,8 @@ def disable_logging(func):
return wrapper return wrapper
@disable_logging def create_new_uid():
def req(config: Config, data): return md5(str(uuid1()).encode()).hexdigest()
url = 'https://dcserver1.herokuapp.com/fishy'
ip = get_ip(GoogleDnsProvider)
h = config.get("hash", md5(str(uuid1()).encode()).hexdigest())
body = {"hash": h, "data": data, "ip": ip}
requests.post(url, json=body)
def ping(config: Config, data):
if config.get("check", True, False):
threading.Thread(target=req, args=(config, data,)).start()
def install_thread_excepthook(): def install_thread_excepthook():

57
fishy/systems/web.py Normal file
View File

@ -0,0 +1,57 @@
import requests
from fishy.systems.globals import G
from fishy.systems.helper import disable_logging
domain = "https://fishyeso.herokuapp.com"
user = "/api/user"
notify = "/api/notify"
subscription = "/api/subscription/"
@disable_logging
def register_user(uid):
body = {"uid": uid}
response = requests.post(domain + user, json=body)
print(response.status_code)
return response.ok and response.json()["success"]
def get_notification_page(uid):
return domain+f"?uid={uid}"
@disable_logging
def send_notification(uid, message):
if not is_subbed(uid):
return False
body = {"uid": uid, "message": message}
response = requests.post(domain + notify, json=body)
return response.json()["success"], response.json()["error"]
def send_hole_deplete(uid, fishes_caught):
send_notification(uid, f"Hole depleted, {fishes_caught} fishes caught!")
@disable_logging
def is_subbed(uid, lazy=True):
if lazy and G._is_subbed is not None:
return G._is_subbed
if uid is None:
return False
body = {"uid": uid}
response = requests.get(domain + subscription, params=body)
G._is_subbed = response.json()["subbed"]
return G._is_subbed
@disable_logging
def unsub(uid):
G._is_subbed = False
body = {"uid": uid}
requests.delete(domain + subscription, json=body)

View File

@ -8,3 +8,5 @@ pyautogui
requests requests
beautifulsoup4 beautifulsoup4
whatsmyip whatsmyip
pyqrcode
pypng