2020-04-17 13:08:26 +00:00
|
|
|
import logging
|
2020-04-17 12:45:22 +00:00
|
|
|
import time
|
|
|
|
from enum import Enum
|
2020-04-17 13:08:26 +00:00
|
|
|
from logging import StreamHandler
|
2020-04-16 23:14:33 +00:00
|
|
|
from tkinter import *
|
2020-04-17 01:58:09 +00:00
|
|
|
from tkinter.ttk import *
|
|
|
|
from ttkthemes import ThemedTk
|
2020-04-17 12:45:22 +00:00
|
|
|
from waiting import wait
|
|
|
|
import threading
|
|
|
|
|
|
|
|
from fishy.systems.config import Config
|
|
|
|
|
|
|
|
|
2020-04-17 13:08:26 +00:00
|
|
|
class GUIStreamHandler(StreamHandler):
|
|
|
|
def __init__(self, gui):
|
|
|
|
StreamHandler.__init__(self)
|
|
|
|
self.gui = gui
|
|
|
|
|
|
|
|
def emit(self, record):
|
|
|
|
msg = self.format(record)
|
|
|
|
self.gui.writeToLog(msg)
|
|
|
|
|
|
|
|
|
2020-04-17 12:45:22 +00:00
|
|
|
class Callback(Enum):
|
|
|
|
START = 0,
|
|
|
|
SHORTCUT = 1,
|
|
|
|
CHECK_PIXELVAL = 2,
|
|
|
|
LOG_DUMP = 3
|
|
|
|
|
|
|
|
|
|
|
|
class GUICallback:
|
|
|
|
def __init__(self, start_callback=None,
|
|
|
|
shortcut_callback=None,
|
|
|
|
check_pixelval_callback=None,
|
|
|
|
log_dump_callback=None
|
|
|
|
):
|
|
|
|
self.start_callback = start_callback
|
|
|
|
self.shortcut_callback = shortcut_callback
|
|
|
|
self.check_pixelval_callback = check_pixelval_callback
|
|
|
|
self.log_dump_callback = log_dump_callback
|
|
|
|
|
|
|
|
def call(self, callback_enum, args=None):
|
|
|
|
to_call = None
|
|
|
|
if callback_enum == Callback.START:
|
|
|
|
to_call = self.start_callback
|
|
|
|
elif callback_enum == Callback.SHORTCUT:
|
|
|
|
to_call = self.shortcut_callback
|
|
|
|
elif callback_enum == Callback.CHECK_PIXELVAL:
|
|
|
|
to_call = self.check_pixelval_callback
|
|
|
|
elif callback_enum == Callback.LOG_DUMP:
|
|
|
|
to_call = self.log_dump_callback
|
|
|
|
|
|
|
|
if to_call is None:
|
|
|
|
return
|
|
|
|
|
|
|
|
threading.Thread(target=to_call, args=(*args,)).start()
|
|
|
|
|
|
|
|
|
|
|
|
class GUI:
|
|
|
|
|
2020-04-17 13:08:26 +00:00
|
|
|
def __init__(self,config: Config, gui_callback=None):
|
2020-04-17 12:45:22 +00:00
|
|
|
self.callbacks = GUICallback() if gui_callback is None else gui_callback
|
|
|
|
self.config = config
|
|
|
|
self.start_restart = False
|
|
|
|
self.destroyed = True
|
|
|
|
self.root = None
|
|
|
|
self._log_strings = []
|
|
|
|
self.console = None
|
|
|
|
|
|
|
|
def create(self):
|
|
|
|
self.root = ThemedTk(theme="equilux", background=True)
|
|
|
|
self.root.title("Fiishybot for Elder Scrolls Online")
|
|
|
|
self.root.geometry('650x550')
|
|
|
|
|
|
|
|
# region menu
|
|
|
|
menubar = Menu(self.root)
|
|
|
|
|
|
|
|
filemenu = Menu(menubar, tearoff=0)
|
|
|
|
filemenu.add_command(label="Create Shortcut", command=lambda: self.callbacks.call(Callback.SHORTCUT))
|
|
|
|
filemenu.add_command(label="{} Dark Mode".format("Disable" if self.config.get("dark_mode", True) else "Enable"),
|
|
|
|
command=self._toggle_mode)
|
|
|
|
menubar.add_cascade(label="File", menu=filemenu)
|
|
|
|
|
|
|
|
debug_menu = Menu(menubar, tearoff=0)
|
|
|
|
debug_menu.add_command(label="Check PixelVal",
|
|
|
|
command=lambda: self.callbacks.call(Callback.CHECK_PIXELVAL))
|
|
|
|
debug_menu.add_command(label="Log Dump")
|
|
|
|
menubar.add_cascade(label="Debug", menu=debug_menu, command=lambda: self.callbacks.call(Callback.LOG_DUMP))
|
|
|
|
self.root.config(menu=menubar)
|
|
|
|
# endregion
|
|
|
|
|
|
|
|
# region console
|
|
|
|
self.console = Text(self.root, state='disabled', wrap='none', background="#707070", fg="#ffffff")
|
|
|
|
self.console.pack(fill=BOTH, expand=True, pady=(15, 15), padx=(5, 5))
|
|
|
|
self.console.mark_set("sentinel", INSERT)
|
|
|
|
self.console.config(state=DISABLED)
|
|
|
|
|
|
|
|
controls_frame = Frame(self.root)
|
|
|
|
# endregion
|
|
|
|
|
|
|
|
# region controls
|
|
|
|
left_frame = Frame(controls_frame)
|
|
|
|
|
|
|
|
Label(left_frame, text="IP").grid(row=0, column=0)
|
|
|
|
ip = Entry(left_frame)
|
|
|
|
ip.grid(row=0, column=1)
|
|
|
|
|
|
|
|
Label(left_frame, text="Fullscreen: ").grid(row=1, column=0, pady=(5, 5))
|
|
|
|
borderless = Checkbutton(left_frame)
|
|
|
|
borderless.grid(row=1, column=1)
|
|
|
|
|
|
|
|
left_frame.grid(row=0, column=0)
|
|
|
|
|
|
|
|
right_frame = Frame(controls_frame)
|
|
|
|
|
|
|
|
Label(right_frame, text="Action Key:").grid(row=0, column=0)
|
|
|
|
action_key_entry = Entry(right_frame)
|
|
|
|
action_key_entry.grid(row=0, column=1)
|
|
|
|
action_key_entry.insert(0, "e")
|
|
|
|
|
|
|
|
Label(right_frame, text="Press start").grid(row=1, columnspan=2, pady=(5, 5))
|
|
|
|
|
|
|
|
right_frame.grid(row=0, column=1, padx=(50, 0))
|
|
|
|
|
|
|
|
controls_frame.pack()
|
|
|
|
|
|
|
|
Button(self.root, text="START", width=25,
|
|
|
|
command=lambda: self.callbacks.call(Callback.START,
|
|
|
|
(ip.get(), action_key_entry.get(), borderless.instate(['selected'])))
|
|
|
|
).pack(pady=(15, 15))
|
|
|
|
# endregion
|
|
|
|
|
|
|
|
self._apply_theme(self.config.get("dark_mode", True))
|
|
|
|
self.root.update()
|
|
|
|
self.root.minsize(self.root.winfo_width(), self.root.winfo_height())
|
|
|
|
self.root.protocol("WM_DELETE_WINDOW", self._set_destroyed)
|
|
|
|
self.destroyed = False
|
|
|
|
while True:
|
|
|
|
self.root.update()
|
|
|
|
self._update_console()
|
|
|
|
|
|
|
|
if self.start_restart:
|
|
|
|
self.root.destroy()
|
|
|
|
self.root.quit()
|
|
|
|
self.start_restart = False
|
|
|
|
self.create()
|
|
|
|
if self.destroyed:
|
|
|
|
break
|
|
|
|
time.sleep(0.01)
|
|
|
|
|
|
|
|
def _apply_theme(self, dark):
|
|
|
|
self.root["theme"] = "equilux" if dark else "breeze"
|
|
|
|
self.console["background"] = "#707070" if dark else "#ffffff"
|
|
|
|
self.console["fg"] = "#ffffff" if dark else "#000000"
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
threading.Thread(target=self.create, args=()).start()
|
|
|
|
|
|
|
|
def _toggle_mode(self):
|
|
|
|
self.config.set("dark_mode", not self.config.get("dark_mode", True))
|
|
|
|
self.start_restart = True
|
|
|
|
|
|
|
|
def _set_destroyed(self):
|
|
|
|
self.destroyed = True
|
|
|
|
|
|
|
|
def writeToLog(self, msg):
|
|
|
|
self._log_strings.append(msg)
|
|
|
|
|
|
|
|
def _update_console(self):
|
|
|
|
while len(self._log_strings) > 0:
|
|
|
|
msg = self._log_strings.pop(0)
|
|
|
|
numlines = self.console.index('end - 1 line').split('.')[0]
|
|
|
|
self.console['state'] = 'normal'
|
|
|
|
if int(numlines) >= 50: # delete old lines
|
|
|
|
self.console.delete(1.0, 2.0)
|
|
|
|
if self.console.index('end-1c') != '1.0': # new line for each log
|
|
|
|
self.console.insert('end', '\n')
|
|
|
|
self.console.insert('end', msg)
|
|
|
|
self.console.see("end") # scroll to bottom
|
|
|
|
self.console['state'] = 'disabled'
|
|
|
|
|
|
|
|
|
|
|
|
def start(ip, actionkey, fullscreen):
|
2020-04-17 13:08:26 +00:00
|
|
|
logging.info(f"{ip}, {actionkey}, {fullscreen}")
|
2020-04-17 12:45:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
config = Config()
|
|
|
|
gui = GUI(config=config, gui_callback=GUICallback(start_callback=start))
|
|
|
|
gui.start()
|
|
|
|
wait(lambda: not gui.destroyed)
|
|
|
|
while not gui.destroyed:
|
|
|
|
gui.writeToLog("yo")
|
|
|
|
time.sleep(1)
|
|
|
|
|
2020-04-16 23:14:33 +00:00
|
|
|
|
2020-04-17 12:45:22 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|