Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
Making the code buildable again as well as adding a little flair by adding an icon to it in the makefile

Although I wasn't able to get it buildable on the latest version of Python I did figure out the install instructions after messing around the code for a few hours

also removed the website components since in my opinion they were redundant and the task can be completed using the readme markdown
  • Loading branch information
Kickskii committed Aug 26, 2023
1 parent fa87a17 commit 5da240b
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 176 deletions.
25 changes: 14 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
NAME:=nexus_autodl
NAME := nexus_autodl

ifeq ($(OS),Windows_NT)
PATHSEP:=;
PATHSEP := ;
else
PATHSEP:=:
PATHSEP := :
endif

all: yapf lint mypy build
# Update these paths with the correct paths to your Python executables
PYTHON_EXEC := C:\Py37\python.exe
YAPF_PATH := C:\py37\Scripts\yapf.exe
MYPY_PATH := C:\py37\Scripts\mypy.exe
BUILD_PATH := C:\py37\Scripts\pyinstaller.exe

all: yapf mypy build

build: $(NAME).py
pyinstaller --clean -F --add-data 'templates$(PATHSEP)templates' $<
$(BUILD_PATH) --clean -F --add-data 'templates$(PATHSEP)templates' --icon icon.ico $<

clean:
$(RM) -r build dist *.spec

lint: $(NAME).py
pylint --max-line-length 120 $<

mypy: $(NAME).py
mypy $<
$(MYPY_PATH) $<

yapf: $(NAME).py
yapf -i --style style.yapf $<
$(PYTHON_EXEC) $(YAPF_PATH) -i --style style.yapf $<

.PHONY: build clean lint mypy yapf
.PHONY: build clean mypy yapf
45 changes: 36 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
# Nexus AutoDL
# Nexus AutoDL
When utilizing [Nexus Mods](https://nexusmods.com/) for Game Modding, the typical procedure involves manually clicking the download button each time a new mod is added to the download queue.
However, this manual process can become problematic when dealing with tools such as [Wabbajack](https://www.wabbajack.org/) or [Portmod](https://gitlab.com/portmod/portmod), which may involve numerous mods, potentially numbering in the hundreds or even thousands.

<p align="center">
<img alt="Nexus AutoDL" src="https://raw.githubusercontent.com/parsiad/nexus-autodl/master/assets/img/logo.png">
</p>
To address this issue, Nexus AutoDL serves as an autoclicker designed to streamline and automate this process. While Nexus AutoDL is active, it continuously monitors the screen for instances when a download button for a Nexus Mod(the "Slow Download" button) or Collections button from Vortex becomes visible.
In such cases, Nexus AutoDL takes action by automatically clicking the download button, effectively removing the need for manual intervention. This automation significantly enhances the efficiency and convenience of the mod downloading experience.
## Note
Using a bot to download from Nexus is in direct violation of their TOS:

When downloading mods from [Nexus Mods](https://nexusmods.com), you have to manually click on a download button every time a new mod is added to the queue.
Since modlists supported by tools like [Wabbajack](https://www.wabbajack.org) and [Portmod](https://gitlab.com/portmod/portmod) often have tens or hundreds of mods, this can be very time consuming.
Nexus AutoDL is an autoclicker (a.k.a., autodownloader, bot) that helps automate this process for you.
Specifically, while Nexus AutoDL is running, any time a [mod](https://raw.githubusercontent.com/parsiad/nexus-autodl/master/assets/mod_download_page.jpg) or [collection](https://raw.githubusercontent.com/parsiad/nexus-autodl/master/assets/vortex_download_page.jpg) download page is visible on your screen, Nexus AutoDL will attempt to click the download button.
> Attempting to download files or otherwise record data offered through our services (including but not limited to the Nexus Mods website and the Nexus Mods API) in a fashion that drastically exceeds the expected average, through the use of software automation or otherwise, is prohibited without expressed permission. Users found in violation of this policy will have their account suspended.
Use this at your own risk.

# Changelog
added an icon to the exe
changed code a little so as to make it buildable again
updated readme with build instructions

## Download
Check [Releases](https://github.com/Kickskii/fork-NexusAutodl/releases)
## BuildingNexus-AutoDL

👉 [Visit the website](https://parsiad.github.io/nexus-autodl) 👈 to download
install [Python 3.7](https://www.python.org/downloads/release/python-370/)
#### upgrade pip
```python -m pip install --upgrade pip```
#### Install required dependencies
``` pip install yapf
pip install mypy
pip install pyinstaller
pip install pillow
pip install pyautogui
pip install numpy
pip install click
pip install opencv-python==3.4.2.16
pip install opencv-contrib-python==3.4.2.16
python -m pip install types-Pillow
```
install Make from [GnuWin32](https://sourceforge.net/projects/gnuwin32/files/make/3.81/) and add the executable to PATH
navigate to folder with makefile and run in powershell
```make all```
#### current requires python3.7 use opencv version 3.4.2.16 otherwise SIFT does not work could maybe fix using ORB function for newer OpenCV version
72 changes: 0 additions & 72 deletions assets/css/styles.css

This file was deleted.

Binary file removed assets/img/bg.jpg
Binary file not shown.
Binary file removed assets/img/logo.png
Binary file not shown.
Binary file removed assets/mod_download_page.jpg
Binary file not shown.
Binary file removed assets/vortex_download_page.jpg
Binary file not shown.
Binary file added icon.ico
Binary file not shown.
72 changes: 0 additions & 72 deletions index.html

This file was deleted.

26 changes: 14 additions & 12 deletions nexus_autodl.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
from numpy import ndarray as NDArray
import click
import cv2 as cv # type: ignore
# Import xfeatures2d from cv2 module
from cv2 import xfeatures2d
import numpy as np
import PIL # type: ignore
import PIL.ImageOps # type: ignore
import pyautogui # type: ignore
from PIL import Image, ImageOps


# ... (Previous click options and function comments remain the same)
@click.command()
@click.option('--sleep_max', default=5.)
@click.option('--sleep_min', default=0.)
Expand All @@ -44,12 +45,13 @@ class _Template(NamedTuple):
name: str
threshold: int


# Define the main function to find and click templates
def _find_and_click(templates: List[_Template]) -> None:
screenshot_image = pyautogui.screenshot()
screenshot = _image_to_grayscale_array(screenshot_image)
for template in templates:
sift = cv.SIFT_create() # pylint: disable=no-member
# Change cv.SIFT_create() to cv.xfeatures2d.SIFT_create() to use xfeatures2d
sift = cv.xfeatures2d.SIFT_create() # pylint: disable=no-member
_, template_descriptors = sift.detectAndCompute(template.array, mask=None)
screenshot_keypoints, screenshot_descriptors = sift.detectAndCompute(screenshot, mask=None)
matcher = cv.BFMatcher() # pylint: disable=no-member
Expand All @@ -66,9 +68,9 @@ def _find_and_click(templates: List[_Template]) -> None:
return
logging.info('No matches found')


# ... (Previous _get_templates functions remain the same)
def _get_templates() -> List[_Template]: # pylint: disable=too-many-locals
templates = []
templates: List[_Template] = [] # Add the type annotation here
try:
root_dir = sys._MEIPASS # type: ignore # pylint: disable=no-member,protected-access
except AttributeError:
Expand All @@ -82,18 +84,18 @@ def _get_templates() -> List[_Template]: # pylint: disable=too-many-locals
sorted_groups = sorted(groups, key=lambda t: int(t[0]))
for index, threshold, name in sorted_groups:
path = os.path.join(templates_dir, f'{index}_{threshold}_{name}.png')
image = PIL.Image.open(path) # pylint: disable=no-member
image = Image.open(path)
array = _image_to_grayscale_array(image)
template = _Template(array=array, name=name, threshold=int(threshold))
templates.append(template)
return templates


def _image_to_grayscale_array(image: PIL.Image.Image) -> NDArray:
image = PIL.ImageOps.grayscale(image)
# ... (Previous _image_to_grayscale_array functions remain the same)
def _image_to_grayscale_array(image: Image.Image) -> NDArray:
image = ImageOps.grayscale(image)
array = np.array(image)
return array


# Execute the main function only if the script is run directly
if __name__ == '__main__':
run() # pylint: disable=no-value-for-parameter

0 comments on commit 5da240b

Please sign in to comment.