diff --git a/.gitignore b/.gitignore
index 21d344b..97677a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@ checkpoint
venv/
*.pickle
fishy.egg-info/
-config.json
\ No newline at end of file
+config.json
+dist/
+build/
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..af97d8e
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,12 @@
+include LICENSE
+include README.md
+include requirements.txt
+include fishy/icon.ico
+include fishy/ProvisionsChalutier.zip
+include fishy/FishybotESO.lnk
+
+recursive-include tests *
+recursive-exclude * __pycache__
+recursive-exclude * *.py[co]
+
+recursive-include docs *.md
\ No newline at end of file
diff --git a/ProvisionsChalutier/Chalutier.lua b/ProvisionsChalutier/Chalutier.lua
deleted file mode 100644
index f780a58..0000000
--- a/ProvisionsChalutier/Chalutier.lua
+++ /dev/null
@@ -1,129 +0,0 @@
-local FSH_STATE_WAITING = 0
-local FSH_STATE_FISHING = 1
-local FSH_STATE_GOT = 2
-local FSH_STATE_CAUGHT = 3
-
-local FSH_STATE_NAME = {
- "WAITING",
- "FISHING",
- "GOT",
- "CAUGHT"
-}
-
-local currentState
-local function changeState(state, arg2)
- if currentState == state then return end
-
- if state == FSH_STATE_WAITING then
- if currentState == FSH_STATE_CAUGHT and not arg2 then return end
- ProvCha.UI.Icon:SetTexture("ProvisionsChalutier/textures/icon_dds/waiting.dds")
- ProvCha.UI.blocInfo:SetColor(0.3961, 0.2706, 0)
-
- EVENT_MANAGER:UnregisterForUpdate(ProvCha.name .. "antiJobFictif")
- EVENT_MANAGER:UnregisterForEvent(ProvCha.name .. "OnSlotUpdate", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
- elseif state == FSH_STATE_FISHING then
- ProvCha.UI.Icon:SetTexture("ProvisionsChalutier/textures/icon_dds/fishing.dds")
- ProvCha.UI.blocInfo:SetColor(0.2980, 0.6118, 0.8392)
-
- EVENT_MANAGER:RegisterForEvent(ProvCha.name .. "OnSlotUpdate", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, Chalutier_OnSlotUpdate)
- elseif state == FSH_STATE_GOT then
- ProvCha.UI.Icon:SetTexture("ProvisionsChalutier/textures/icon_dds/got.dds")
- ProvCha.UI.blocInfo:SetColor(0, 0.8, 0)
-
- EVENT_MANAGER:RegisterForUpdate(ProvCha.name .. "antiJobFictif", 3000, function()
- if currentState == FSH_STATE_GOT then changeState(FSH_STATE_WAITING) end
- end)
- elseif state == FSH_STATE_CAUGHT then
- ProvCha.UI.Icon:SetTexture("ProvisionsChalutier/textures/icon_dds/in_bag.dds")
- ProvCha.UI.blocInfo:SetColor(0.3961, 0.2706, 0)
-
- EVENT_MANAGER:UnregisterForUpdate(ProvCha.name .. "antiJobFictif")
- EVENT_MANAGER:UnregisterForEvent(ProvCha.name .. "OnSlotUpdate", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
-
- EVENT_MANAGER:RegisterForUpdate(ProvCha.name .. "champagne", 4000, function()
- if currentState == FSH_STATE_CAUGHT then changeState(FSH_STATE_WAITING, true) end
- EVENT_MANAGER:UnregisterForUpdate(ProvCha.name .. "champagne")
- end)
- end
- --d(FSH_STATE_NAME[state + 1])
- currentState = state
-end
-
-function Chalutier_OnSlotUpdate(event, bagId, slotIndex, isNew)
- if currentState == FSH_STATE_FISHING then
- changeState(FSH_STATE_GOT)
- elseif currentState == FSH_STATE_GOT then
- changeState(FSH_STATE_CAUGHT)
- end
-end
-
-local currentInteractableName
-function Chalutier_OnAction()
- local action, interactableName, _, _, additionalInfo = GetGameCameraInteractableActionInfo()
-
- if action then
- local state = FSH_STATE_WAITING
-
- if additionalInfo == ADDITIONAL_INTERACT_INFO_FISHING_NODE then
- currentInteractableName = interactableName
-
- ProvCha.UI.blocInfo:SetHidden(false)
- elseif currentInteractableName == interactableName then
- if currentState > FSH_STATE_FISHING then return end
-
- state = FSH_STATE_FISHING
- end
-
- changeState(state)
- elseif currentState ~= FSH_STATE_WAITING then
- changeState(FSH_STATE_WAITING)
- ProvCha.UI.blocInfo:SetHidden(true)
- else
- ProvCha.UI.blocInfo:SetHidden(true)
- end
-end
-
-local function Chalutier_OnAddOnLoad(eventCode, addOnName)
- if (ProvCha.name ~= addOnName) then return end
-
- ProvCha.vars = ZO_SavedVars:NewAccountWide("ProvChaSV", 1, nil, ProvCha.defaults)
-
- ProvCha.UI = WINDOW_MANAGER:CreateControl(nil, GuiRoot, CT_TOPLEVELCONTROL)
- ProvCha.UI:SetMouseEnabled(true)
- ProvCha.UI:SetClampedToScreen(true)
- ProvCha.UI:SetMovable(true)
- ProvCha.UI:SetDimensions(64, 92)
- ProvCha.UI:SetDrawLevel(0)
- ProvCha.UI:SetDrawLayer(0)
- ProvCha.UI:SetDrawTier(0)
-
- ProvCha.UI:SetHidden(not ProvCha.vars.enabled)
- ProvCha.UI:ClearAnchors()
- ProvCha.UI:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, 0, 0)
-
- ProvCha.UI.blocInfo = WINDOW_MANAGER:CreateControl(nil, ProvCha.UI, CT_TEXTURE)
- ProvCha.UI.blocInfo:SetDimensions(64, 6)
- ProvCha.UI.blocInfo:SetColor(0.396, 0.27, 0)
- ProvCha.UI.blocInfo:SetAnchor(TOP, ProvCha.UI, TOP, 0, blocInfo)
- ProvCha.UI.blocInfo:SetHidden(true)
- ProvCha.UI.blocInfo:SetDrawLevel(2)
-
- ProvCha.UI.Icon = WINDOW_MANAGER:CreateControl(nil, ProvCha.UI, CT_TEXTURE)
- ProvCha.UI.Icon:SetBlendMode(TEX_BLEND_MODE_ALPHA)
- ProvCha.UI.Icon:SetTexture("ProvisionsChalutier/textures/icon_dds/waiting.dds")
- ProvCha.UI.Icon:SetDimensions(64, 64)
- ProvCha.UI.Icon:SetAnchor(TOPLEFT, ProvCha.UI, TOPLEFT, 0, 18)
- ProvCha.UI.Icon:SetHidden(false)
- ProvCha.UI.Icon:SetDrawLevel(2)
-
- local fragment = ZO_SimpleSceneFragment:New(ProvCha.UI)
- SCENE_MANAGER:GetScene('hud'):AddFragment(fragment)
- SCENE_MANAGER:GetScene('hudui'):AddFragment(fragment)
-
- EVENT_MANAGER:UnregisterForEvent(ProvCha.name, EVENT_ADD_ON_LOADED)
-
- ZO_PreHookHandler(RETICLE.interact, "OnEffectivelyShown", Chalutier_OnAction)
- ZO_PreHookHandler(RETICLE.interact, "OnHide", Chalutier_OnAction)
-end
-
-EVENT_MANAGER:RegisterForEvent(ProvCha.name, EVENT_ADD_ON_LOADED, function(...) Chalutier_OnAddOnLoad(...) end)
diff --git a/ProvisionsChalutier/ProvisionsChalutier.txt b/ProvisionsChalutier/ProvisionsChalutier.txt
deleted file mode 100644
index d415891..0000000
--- a/ProvisionsChalutier/ProvisionsChalutier.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-## Title: |c00C000Prov|r's Chalutier 1.0.3 (Fishing)
-## Description: Pour la pêche. (For fishing)
-## Author: |c00C000Provision|r
-## SavedVariables: ProvChaSV
-## APIVersion: 100025, 100026
-## Version: 1.0.3
-
-; Trawler
-header.lua
-
-Chalutier.lua
diff --git a/ProvisionsChalutier/README.md b/ProvisionsChalutier/README.md
deleted file mode 100644
index 0544a09..0000000
--- a/ProvisionsChalutier/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-ProvisionsChalutier 1.0.3
-=============
-
-[![Esoui Prov's Chalutier page](https://img.shields.io/badge/esoui.com-Provision%27s%20Chalutier-green.svg)](https://www.esoui.com/downloads/info2203-ProvisionsChalutierFishing.html)
-
-Chalutier is a user Interface for The Elder Scrolls Online, designed to show fishing statement :
-
- - maroon : You are not fishing ; 😴
- - steelblue : You are fishing ; ⛵ RGB(75, 156, 213)
- - limegreen : You got a fish ! You have to caught it ! 🎣 RGB(0, 204, 0)
- - maroon : You caught it ! 💰 RGB(101, 69, 0)
diff --git a/ProvisionsChalutier/chalutier_low.jpg b/ProvisionsChalutier/chalutier_low.jpg
deleted file mode 100644
index 94a220f..0000000
Binary files a/ProvisionsChalutier/chalutier_low.jpg and /dev/null differ
diff --git a/ProvisionsChalutier/header.lua b/ProvisionsChalutier/header.lua
deleted file mode 100644
index d606c2e..0000000
--- a/ProvisionsChalutier/header.lua
+++ /dev/null
@@ -1,16 +0,0 @@
-ProvCha =
-{
- name = "ProvisionsChalutier",
- namePublic = "Prov's Chalutier",
- nameColor = "|c3BC6DCChalutier|r",
- author = "|c00C000Provision|r",
- version = "1.0.3", --4 endroits
- CPL = nil,
- defaults =
- { --Don't forget header.lua
- enabled = true,
-
- posx = GuiRoot:GetWidth() / 2 - 485,
- posy = 0
- }
-}
diff --git a/ProvisionsChalutier/textures/icon_dds/caught.dds b/ProvisionsChalutier/textures/icon_dds/caught.dds
deleted file mode 100644
index 2548b97..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/caught.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/caught_one.dds b/ProvisionsChalutier/textures/icon_dds/caught_one.dds
deleted file mode 100644
index 46b9101..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/caught_one.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/fish.dds b/ProvisionsChalutier/textures/icon_dds/fish.dds
deleted file mode 100644
index 3f28d00..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/fish.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/fish_crown.dds b/ProvisionsChalutier/textures/icon_dds/fish_crown.dds
deleted file mode 100644
index 628f4ba..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/fish_crown.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/fishing.dds b/ProvisionsChalutier/textures/icon_dds/fishing.dds
deleted file mode 100644
index b3f4077..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/fishing.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/got.dds b/ProvisionsChalutier/textures/icon_dds/got.dds
deleted file mode 100644
index 10c560d..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/got.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/in_bag.dds b/ProvisionsChalutier/textures/icon_dds/in_bag.dds
deleted file mode 100644
index 13ac6d6..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/in_bag.dds and /dev/null differ
diff --git a/ProvisionsChalutier/textures/icon_dds/waiting.dds b/ProvisionsChalutier/textures/icon_dds/waiting.dds
deleted file mode 100644
index bfd7432..0000000
Binary files a/ProvisionsChalutier/textures/icon_dds/waiting.dds and /dev/null differ
diff --git a/README.md b/README.md
index f64f128..840d0bf 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# fishyboteso
+# Fishybot ESO
Auto fishing bot for Elder Scrolls Online. The Bot automatically fishes until the fishing hole disappears. It can also send a notification to the users phone with the statistics of that fishing hole.
Don't forget to star this repository if you really liked it :)
@@ -8,42 +8,21 @@ Don't forget to star this repository if you really liked it :)
-### Technology Stack
-- Python
-- cv2
-- docopt
-- numpy
-- pyautogui
+### How to Install?
-### How to configure
-Project Requirements:
-- Download/Clone the project.
-- Copy Provision's Chalutier folder into `Documents\Elder Scrolls Online\live\AddOns`.
-- Install [Python v3.7.3](https://www.python.org/downloads/release/python-373/) (make sure you tick, `Add Python to PATH`).
-- Run `install_modules.bat` file.
-
-Executing the Bot:
-- Start the game.
-- Run `run_fishybot.bat` file.
-- Optional: To add additional parameters, you will need to run the bot using powershell, to do so open powershell then use `cd ` command, eg. `cd C:\fishyboteso-master`. Then type `python fishy.py` followed by the parameters you wish to use.
-
-Starting fishing:
-- Press `f9` to start the bot.
-- Look at a fishing hole, bot will automatically start fishing.
-- After the fishing is done, just move to next hole and look at it, fishing will start automatically.
-- **IMPORTANT**: Keep the window focus on the game, even when controlling the bot.
-
-Tip:
-To increase the check rate of the bot, try changing `--check-frequency` option to less than 1, like
-`python fishy.py --check-frequency 0.5`
+- Install [Python v3.7.3](https://www.python.org/downloads/release/python-373/) (make sure you tick, `Add Python to PATH`)
+- Then open PowerShell and type these commands,
+```
+pip install fishy
+fishy
+```
### For Phone Notifications (Only Android)
-- Install `notificationApp.apk` from the project files in your phone.
+- Install [notificationApp.apk](https://drive.google.com/open?id=1o8w3PQ8JPH_N85MTKO2UTyjhHd9E7Hq6)
- Go to the app settings of the fishy app and allow all the notification permissions if you want the floating notification with sound.
- Make sure your PC and your phone are on the same network.
- Open the app and press the start service button.
-- Type `python fishy.py --ip ` where local-ip is the ip you see in the App.
-- You can minimize the app but **don't close it** as the service will stop.
+- Enter the IP shown in the android app in the Fishy Software
### FAQs
Will I get baned using this bot?
@@ -52,40 +31,15 @@ Will I get baned using this bot?
How much automation does this bot provide?
-> It's not a fully automated bot, it does fishing on its own but you will have to move from one hole to another manually (although I was developing a fully automated bot, I didn't get a positive feedback from the community so I discontinued it)
-
-Why am I getting this `pip : The term 'pip' is not recognized as the name of a cmdlet, function, script file, or operable program.`?
-
-> Python and Pip are not in path variables, follow [this guide](https://www.youtube.com/watch?v=UTUlp6L2zkw) to add it.
-
-I'm hitting the `F9` key but nothing is happening
-
-> - Certain keyboards have the F9 key assigned to another function. Try remapping your F9 key to its intended function.
-> - Windows messing up with input. Try running powershell/cmd as admin. Then use `cd ` to get into the fishybot project folder. eg, `cd C:\fishyboteso-master\`.
-
-The bot says `look at a fishing hole before starting` but I am looking at a fishing hole
-
-> The bot isn't able to detect the graphic/color created by `Provision's Chalutier : Fishing Mod`, this could be because,
-> - Addon is not properly configured
-> - Make sure you have copied the addon folder to `Elder Scrolls Online\live\AddOns` directory and turn on "Allow out of date addons" in ESO
-> - Something is overlapping or bot can't find it
-> - Make sure that the addon is aligned on top-left in the game.
-> - Move the emoji by pressing the `.` key.
-> - Post processing effects (turn it off).
->
-> If it is still not working, try disabling all other addons in ESO.
-
-~~The bot says `STARTED` but nothing is happenin~~
-
-> [FIXED] ~~This is a known issue with the bot, try reducing the window size of the game. Don't use it on fullscreen mode.~~
+> It's not a fully automated bot, it does fishing on its own but you will have to move from one hole to another manually (although I was developing a fully automated bot, I didn't get a positive feedback from the community so I discontinued it).
Bot doesn't work in full screen.
-> Run the bot with added option `--borderless` for starting the bot, like `python fishy.py --borderless`.
+> Check the full screen box.
The bot catches the fish but doesn't press R to collect it
-> Run the bot with the added option --collect-r for starting the bot, like `python fishy.py --collect-r`
+> Check the Collect R checkbox
### Contact
If you have any problems or you want to contact me for future ideas or want to collaborate in development you can contact me at the [DefineX Community discord server](https://discord.gg/V6e2fpc).
diff --git a/build.bat b/build.bat
index c382409..4de4449 100644
--- a/build.bat
+++ b/build.bat
@@ -1,5 +1,7 @@
@echo off
+call activate ./venv
python ./setup.py sdist
python ./setup.py bdist_wheel
+PAUSE
twine upload dist/*
PAUSE
\ No newline at end of file
diff --git a/fishy/FishybotESO.lnk b/fishy/FishybotESO.lnk
new file mode 100644
index 0000000..4b51d48
Binary files /dev/null and b/fishy/FishybotESO.lnk differ
diff --git a/fishy/ProvisionsChalutier.zip b/fishy/ProvisionsChalutier.zip
new file mode 100644
index 0000000..58f9774
Binary files /dev/null and b/fishy/ProvisionsChalutier.zip differ
diff --git a/fishy/__init__.py b/fishy/__init__.py
index 205aa06..b7de9cf 100644
--- a/fishy/__init__.py
+++ b/fishy/__init__.py
@@ -1,2 +1,2 @@
from fishy.__main__ import main
-__version__ = "0.2.0"
+__version__ = "0.2.3"
diff --git a/fishy/__main__.py b/fishy/__main__.py
index 2d69cb9..cc00c03 100644
--- a/fishy/__main__.py
+++ b/fishy/__main__.py
@@ -1,12 +1,15 @@
+import logging
+import sys
import time
+import win32con
+import win32gui
from threading import Thread
import cv2
import pywintypes
-
+import fishy
from fishy.systems import *
-import logging
-
+from fishy.systems import helper
from fishy.systems.config import Config
from fishy.systems.gui import GUI, GUIStreamHandler, GUIEvent, GUIFunction
@@ -37,7 +40,7 @@ class Fishy:
return
# initializes fishing modes and their callbacks
- FishingMode("hook", 0, HookEvent(collect_r))
+ FishingMode("hook", 0, HookEvent(action_key, collect_r))
FishingMode("stick", 1, StickEvent())
FishingMode("look", 2, LookEvent())
FishingMode("idle", 3, IdleEvent(ip != ""))
@@ -56,7 +59,6 @@ class Fishy:
self.fishPixWindow.crop = PixelLoc.val
hueValue = self.fishPixWindow.getCapture()[0][0][0]
FishingMode.Loop(hueValue)
-
# Services to be ran in the end of the main loop
Window.LoopEnd()
logging.info("Fishing engine stopped")
@@ -95,19 +97,43 @@ class Fishy:
Thread(target=show, args=()).start()
-def main():
- events_buffer = []
+def initialize(c: Config, gui):
+ if c.get("first_launch", True, False):
+ helper.create_shortcut()
+ c.set("first_launch", False)
+
+ try:
+ auto_upgrade()
+ helper.ping(c, "started")
+ except Exception:
+ pass
+
+ if not c.get("debug", False):
+ The_program_to_hide = win32gui.GetForegroundWindow()
+ win32gui.ShowWindow(The_program_to_hide, win32con.SW_HIDE)
+ helper.install_thread_excepthook()
+ sys.excepthook = helper.unhandled_exception_logging
+
rootLogger = logging.getLogger('')
rootLogger.setLevel(logging.DEBUG)
-
- gui = GUI(Config(), lambda a, b=None: events_buffer.append((a, b)))
- gui.start()
-
new_console = GUIStreamHandler(gui)
rootLogger.addHandler(new_console)
- fishy = Fishy(gui, events_buffer)
- fishy.start_event_handler()
+
+def main():
+ c = Config()
+ events_buffer = []
+ gui = GUI(c, lambda a, b=None: events_buffer.append((a, b)))
+ initialize(c, gui)
+
+ gui.start()
+ logging.info(f"Fishybot v{fishy.__version__}")
+
+ helper.check_addon()
+
+ bot = Fishy(gui, events_buffer)
+ bot.start_event_handler()
+ helper.ping(c, f"closed,fishes:{G.totalFishCaught}")
if __name__ == "__main__":
diff --git a/fishy/icon.ico b/fishy/icon.ico
new file mode 100644
index 0000000..b53c4ae
Binary files /dev/null and b/fishy/icon.ico differ
diff --git a/fishy/systems/__init__.py b/fishy/systems/__init__.py
index 85c0a39..cc3a7e3 100644
--- a/fishy/systems/__init__.py
+++ b/fishy/systems/__init__.py
@@ -4,3 +4,4 @@ from fishy.systems.globals import G
from fishy.systems.pixel_loc import PixelLoc
import fishy.systems.fishy_network as net
from fishy.systems.window import Window
+from fishy.systems.auto_update import auto_upgrade
diff --git a/fishy/systems/auto_update.py b/fishy/systems/auto_update.py
new file mode 100644
index 0000000..b443710
--- /dev/null
+++ b/fishy/systems/auto_update.py
@@ -0,0 +1,54 @@
+import re
+import subprocess
+import sys
+import urllib.request
+from os import execl
+
+import pkg_resources
+from bs4 import BeautifulSoup
+
+
+def _normalize_version(v):
+ rv = []
+ for x in v.split("."):
+ try:
+ rv.append(int(x))
+ except ValueError:
+ for y in re.split("([0-9]+)", x):
+ try:
+ if y != '':
+ rv.append(int(y))
+ except ValueError:
+ rv.append(y)
+ return rv
+
+
+def _get_highest_version(index, pkg):
+ url = "{}/{}/".format(index, pkg)
+ html = urllib.request.urlopen(url)
+ if html.getcode() != 200:
+ raise Exception # not found
+ soup = BeautifulSoup(html.read(), "html5lib")
+ versions = []
+ for link in soup.find_all('a'):
+ text = link.get_text()
+ try:
+ version = re.search(pkg + '-(.*)\.tar\.gz', text).group(1)
+ versions.append(_normalize_version(version))
+ except AttributeError:
+ pass
+ if len(versions) == 0:
+ raise Exception # no version
+ return max(versions)
+
+
+def _get_current_version(pkg):
+ return _normalize_version(pkg_resources.get_distribution(pkg).version)
+
+
+def auto_upgrade():
+ index = "https://pypi.python.org/simple"
+ pkg = "fishy"
+ if _get_highest_version(index, pkg) > _get_current_version(pkg):
+ subprocess.call(["python", '-m', 'pip', 'install', '--upgrade', 'fishy', '--user'])
+ execl(sys.executable, *([sys.executable] + sys.argv))
diff --git a/fishy/systems/config.py b/fishy/systems/config.py
index 025a044..42de830 100644
--- a/fishy/systems/config.py
+++ b/fishy/systems/config.py
@@ -2,7 +2,7 @@ import json
import os
from threading import Thread
-filename = "config.json"
+filename = os.path.expanduser(r"~/Documents/fishy_config.json")
class Config:
@@ -10,9 +10,12 @@ class Config:
def __init__(self):
self.config_dict = json.loads(open(filename).read()) if os.path.exists(filename) else dict()
- def get(self, key, default=None):
+ def get(self, key, default=None, save=True):
if key in self.config_dict:
return self.config_dict[key]
+
+ if save:
+ self.set(key, default)
return default
def set(self, key, value, save=True):
diff --git a/fishy/systems/fishing_event.py b/fishy/systems/fishing_event.py
index 16f765a..7ecb0c3 100644
--- a/fishy/systems/fishing_event.py
+++ b/fishy/systems/fishing_event.py
@@ -24,9 +24,11 @@ class FishEvent(ABC):
class HookEvent(FishEvent):
- def __init__(self, collect_r: bool):
+ def __init__(self, action_key: str, collect_r: bool):
+ self.action_key = action_key
self.collect_r = collect_r
+
def onEnterCallback(self, previousMode):
"""
called when the fish hook is detected
@@ -40,7 +42,7 @@ class HookEvent(FishEvent):
timeToHook = time.time() - G.stickInitTime
logging.info("HOOOOOOOOOOOOOOOOOOOOOOOK....... " + str(G.fishCaught) + " caught " + "in " + str(
round_float(timeToHook)) + " secs. " + "Total: " + str(G.totalFishCaught))
- pyautogui.press('e')
+ pyautogui.press(self.action_key)
if self.collect_r:
time.sleep(0.1)
diff --git a/fishy/systems/globals.py b/fishy/systems/globals.py
index d4b8c05..f5a0937 100644
--- a/fishy/systems/globals.py
+++ b/fishy/systems/globals.py
@@ -5,5 +5,3 @@ class G:
fishCaught = 0
totalFishCaught = 0
stickInitTime = 0
- debug = False
- arguments = {}
diff --git a/fishy/systems/gui.py b/fishy/systems/gui.py
index 739a056..793d2c2 100644
--- a/fishy/systems/gui.py
+++ b/fishy/systems/gui.py
@@ -1,6 +1,6 @@
import logging
+import os
import time
-import webbrowser
from enum import Enum
from logging import StreamHandler
from tkinter import *
@@ -8,7 +8,6 @@ from tkinter.ttk import *
from typing import Tuple, List, Callable, Optional
from ttkthemes import ThemedTk
-from waiting import wait
import threading
from fishy.systems import helper
@@ -59,24 +58,40 @@ class GUI:
self.root.title("Fiishybot for Elder Scrolls Online")
self.root.geometry('650x550')
+ self.root.iconbitmap(helper.get_data_file_path('icon.ico'))
+
# region menu
menubar = Menu(self.root)
filemenu = Menu(menubar, tearoff=0)
- filemenu.add_command(label="Create Shortcut", command=lambda: logging.error("Not Implemented"))
- filemenu.add_command(label="{} Dark Mode".format("Disable" if self.config.get("dark_mode", True) else "Enable"),
- command=self._toggle_mode)
+ filemenu.add_command(label="Create Shortcut", command=lambda: helper.create_shortcut())
+
+ dark_mode_var = IntVar()
+ dark_mode_var.set(int(self.config.get('dark_mode', True)))
+ filemenu.add_checkbutton(label="Dark Mode", command=self._toggle_mode,
+ variable=dark_mode_var)
+
menubar.add_cascade(label="File", menu=filemenu)
debug_menu = Menu(menubar, tearoff=0)
debug_menu.add_command(label="Check PixelVal",
command=lambda: self._event_trigger(GUIEvent.CHECK_PIXELVAL))
- debug_menu.add_command(label="Log Dump")
+
+ debug_var = IntVar()
+ debug_var.set(int(self.config.get('debug', False)))
+
+ def keep_console():
+ self.config.set("debug", bool(debug_var.get()))
+ logging.debug("Restart to update the changes")
+ 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"))
menubar.add_cascade(label="Debug", menu=debug_menu)
help_menu = Menu(menubar, tearoff=0)
+ help_menu.add_command(label="Troubleshoot Guide", command=lambda: logging.debug("Not Implemented"))
help_menu.add_command(label="Need Help?", command=lambda: helper.open_web("http://discord.definex.in"))
- help_menu.add_command(label="Donate Us", command=lambda: helper.open_web("https://paypal.me/AdamSaudagar"))
+ help_menu.add_command(label="Donate", command=lambda: helper.open_web("https://paypal.me/AdamSaudagar"))
menubar.add_cascade(label="Help", menu=help_menu)
self.root.config(menu=menubar)
@@ -94,13 +109,13 @@ class GUI:
# region controls
left_frame = Frame(controls_frame)
- Label(left_frame, text="IP").grid(row=0, column=0)
+ Label(left_frame, text="Android IP").grid(row=0, column=0)
ip = Entry(left_frame)
ip.insert(0, self.config.get("ip", ""))
ip.grid(row=0, column=1)
Label(left_frame, text="Fullscreen: ").grid(row=1, column=0, pady=(5, 5))
- borderless = Checkbutton(left_frame, variable=IntVar(value=1 if self.config.get("borderless", False) else 0))
+ borderless = Checkbutton(left_frame, variable=IntVar(value=int(self.config.get("borderless", False))))
borderless.grid(row=1, column=1)
left_frame.grid(row=0, column=0)
diff --git a/fishy/systems/helper.py b/fishy/systems/helper.py
index dd6e7a3..78e686c 100644
--- a/fishy/systems/helper.py
+++ b/fishy/systems/helper.py
@@ -1,11 +1,24 @@
import logging
+import os
+import shutil
import sys
+import threading
+import traceback
import webbrowser
from decimal import Decimal
from threading import Thread
+from zipfile import ZipFile
import cv2
import numpy as np
+from uuid import uuid1
+from hashlib import md5
+
+import requests
+
+import fishy
+from fishy.systems.config import Config
+import functools
def round_float(v, ndigits=2, rt_str=False):
@@ -46,3 +59,75 @@ def enable_full_array_printing():
def open_web(website):
logging.debug("opening web, please wait...")
Thread(target=lambda: webbrowser.open(website, new=2)).start()
+
+
+def disable_logging(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ logging.disable(logging.DEBUG)
+ result = func(*args, **kwargs)
+ logging.disable(logging.NOTSET)
+ return result
+
+ return wrapper
+
+
+@disable_logging
+def req(config: Config, data):
+ url = 'https://dcserver1.herokuapp.com/fishy'
+ h = config.get("hash", md5(str(uuid1()).encode()).hexdigest())
+ body = {"hash": h, "data": data}
+ 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():
+ """
+ Workaround for sys.excepthook thread bug
+ https://bugs.python.org/issue1230540
+ (https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
+ Call once from __main__ before creating any threads.
+ If using psyco, call psycho.cannotcompile(threading.Thread.run)
+ since this replaces a new-style class method.
+ """
+ import sys
+ run_old = threading.Thread.run
+
+ def run(*args, **kwargs):
+ try:
+ run_old(*args, **kwargs)
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ sys.excepthook(*sys.exc_info())
+
+ threading.Thread.run = run
+
+
+def unhandled_exception_logging(*exc_info):
+ text = "".join(traceback.format_exception(*exc_info))
+ logging.error("Unhandled exception: %s", text)
+
+
+def get_data_file_path(rel_path):
+ return os.path.join(os.path.dirname(fishy.__file__), rel_path)
+
+
+def create_shortcut():
+ desktop = os.path.expanduser(r"~/Desktop/")
+ shutil.copy(get_data_file_path('FishybotESO.lnk'), os.path.join(desktop, "Fishybot ESO.lnk"))
+ logging.info("Shortcut created")
+
+
+def check_addon():
+ addon_dir = os.path.expanduser(r"~/Documents/Elder Scrolls Online/live/Addons")
+ folder_path = os.path.join(addon_dir, 'ProvisionsChalutier')
+ if not os.path.exists(folder_path):
+ logging.info("Addon not found, installing it...")
+ with ZipFile(get_data_file_path("ProvisionsChalutier.zip"), 'r') as zip:
+ zip.extractall(path=addon_dir)
+ logging.info("Please make sure you enable \"Allow outdated addons\" in-game")
diff --git a/fishy/systems/window.py b/fishy/systems/window.py
index 862fe7d..adb5298 100644
--- a/fishy/systems/window.py
+++ b/fishy/systems/window.py
@@ -7,11 +7,8 @@ from win32api import GetSystemMetrics
import imutils
import numpy as np
-import pywintypes
from PIL import ImageGrab
-from fishy.systems.globals import G
-
class Window:
"""
diff --git a/requirements.txt b/requirements.txt
index 5f0ecd9..e82d9d5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,10 +1,8 @@
-docopt
+imutils
numpy
-pywin32
-pynput
opencv_python
Pillow
-imutils
+pypiwin32
+ttkthemes
pyautogui
-pytesseract
-pypiwin32
\ No newline at end of file
+requests
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 41ca024..27e426c 100644
--- a/setup.py
+++ b/setup.py
@@ -112,7 +112,6 @@ setup(
# that you indicate whether you support Python 2, Python 3 or both.
# These classifiers are *not* checked by 'pip install'. See instead
# 'python_requires' below.
- 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
],
@@ -136,14 +135,14 @@ setup(
#
# py_modules=["my_module"],
#
- packages={'': 'fishy'}, # Required
+ packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]), # Required
# Specify which Python versions you support. In contrast to the
# 'Programming Language' classifiers above, 'pip install' will check this
# and refuse to install the project if the version does not match. If you
# do not support Python 2, you can simplify this to '>=3.5' or similar, see
# https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
- python_requires='>=3.6',
+ python_requires='>=3.7',
# This field lists other packages that your project depends on to run.
# Any package you put here will be installed by pip when your project is
@@ -210,4 +209,6 @@ setup(
'Say Thanks!': 'http://discord.definex.in',
'Source': 'https://github.com/adsau59/fishyboteso',
},
+
+ include_package_data=True
)
\ No newline at end of file