Skip to content

Commit

Permalink
linting fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jwlkns committed Apr 17, 2023
1 parent a7f8aa8 commit e8d9173
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 52 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"python.linting.flake8Enabled": true,
"python.linting.enabled": true
"python.linting.enabled": true,
"python.linting.flake8Args": ["--ignore", "E111,E114,E501,E121,E722"]
}
18 changes: 10 additions & 8 deletions src/aoe2de_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from logic import Logic
from utils import base_path


class App():
def __init__(self):
self.logic = Logic()
Expand All @@ -31,11 +32,11 @@ def on_closing():
# Log text box content to file
with open(base_path() / "log.txt", "w+") as file:
file.write(self.text_box.get(1.0, "end-1c"))

self.window.destroy()

self.window.protocol("WM_DELETE_WINDOW", on_closing)

self.upper_frame = tk.Frame(master=self.window)
self.upper_frame.pack(side="top", expand=True, fill="both", padx=10, pady=(10, 5))
self.upper_frame.columnconfigure(0, weight=1)
Expand All @@ -51,14 +52,14 @@ def on_closing():
self.lower_frame = tk.Frame(master=self.window)
self.lower_frame.pack(side="bottom", expand=True, fill="both", padx=10, pady=(5, 10))

self.selected_patch_title = tk.StringVar()
self.selected_patch_title = tk.StringVar()

patch_titles = [f"{p['version']} - {time.strftime('%d/%m/%Y', time.gmtime(p['date']))}" for p in self.patch_list]

self.lbl_select_patch = ttk.Label(master=self.upper_frame, text="Target version")
self.lbl_select_patch.grid(row=0, column=0, sticky="e")
self.lbl_select_patch.grid(row=0, column=0, sticky="e")
self.cmb_select_patch = ttk.Combobox(self.upper_frame, state="readonly", textvariable=self.selected_patch_title, values=[p for p in patch_titles])
self.cmb_select_patch.current(0) # Set default value
self.cmb_select_patch.current(0) # Set default value
self.cmb_select_patch.grid(row=0, column=1, sticky="w")

self.btn_patch = ttk.Button(master=self.upper_frame, text="Patch", command=self._patch)
Expand Down Expand Up @@ -129,7 +130,7 @@ def work():
self._disable_input()
self.logic.restore()
self._enable_input()

t = threading.Thread(target=work)
t.start()

Expand All @@ -153,6 +154,7 @@ def _enable_input(self):
self.ent_username.config(state="enabled")
self.ent_password.config(state="enabled")


if __name__ == '__main__':
app = App()
app.start()
app.start()
57 changes: 29 additions & 28 deletions src/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import signal
import tempfile
import re
import time
from queue import Queue
from dataclasses import dataclass

Expand All @@ -17,6 +16,7 @@
from webhook import Webhook
import utils


@dataclass
class Manifest():
depot: int
Expand All @@ -28,14 +28,14 @@ class Manifest():
size_compressed: int
files: list


class Logic:
app_id = 813780

def __init__(self):
self.webhook = Webhook()
# The earliest patch that works was released after directx update
# @TODO Try to figure out a way to patch to earlier patches than this
#self.directx_update_date = time.struct_time((2020, 2, 17, 0, 0, 0, 0, 48, 0))
# @TODO Try to figure out a way to patch to earlier patches than this: time.struct_time((2020, 2, 17, 0, 0, 0, 0, 48, 0))
self.download_dir = utils.base_path() / "download"
self.manifest_dir = utils.base_path() / "manifests"
self.backup_dir = utils.base_path() / "backup"
Expand Down Expand Up @@ -166,7 +166,7 @@ def cancel_downloads(self):
for process in self.process_queue.queue:
process.kill(signal.SIGTERM)

def _download_patch(self, username: str, password: str, target_version: int):
def _download_patch(self, username: str, password: str, target_version: int):
"""Download the given patch using the steam account credentials.
Args:
Expand All @@ -182,8 +182,8 @@ def _download_patch(self, username: str, password: str, target_version: int):
if not (utils.check_dotnet()):
print("DOTNET Core required but not found!")
return False
update_list = []

update_list = []
tmp_files = []

# Remove previous download folder if it exists
Expand Down Expand Up @@ -237,7 +237,7 @@ def _download_patch(self, username: str, password: str, target_version: int):
changes = self._get_filelist(username, password, depot_id, current_manifest_id, target_manifest_id)

# Files have changed, store changes to temp file and add to update list
if not changes is None:
if changes is not None:
# Create temp file
tmp = tempfile.NamedTemporaryFile(mode="w", delete=False)

Expand All @@ -249,12 +249,12 @@ def _download_patch(self, username: str, password: str, target_version: int):
tmp.close()

# Add update element to list
update_list.append({ 'depot_id': depot_id, 'manifest_id': target_manifest_id, 'filelist': tmp.name })
update_list.append({'depot_id': depot_id, 'manifest_id': target_manifest_id, 'filelist': tmp.name})
else:
print(f"Depot ID not matching, discarding pair ({current_depot['depot_id']}, {target_depot['depot_id']})")

print("Downloading files")

# Loop all necessary updates
for element in update_list:
# Stop if a download didn't succeed
Expand Down Expand Up @@ -323,7 +323,7 @@ def _depot_downloader(self, options: list):
depot_downloader_path = f"\"{str(utils.resource_path('DepotDownloader/DepotDownloader.dll').absolute())}\""

args = ["dotnet", depot_downloader_path] + options

# Spawn process and store in queue
p = pexpect.popen_spawn.PopenSpawn(" ".join(args), encoding="utf-8")
self.process_queue.put(p)
Expand All @@ -345,7 +345,7 @@ def _depot_downloader(self, options: list):
success = True

# Code required
elif response == 1:
elif response == 1:
# Open popup for 2FA Code
# Create temporary parent window to prevent error with visibility
temp = tkinter.Tk()
Expand Down Expand Up @@ -374,7 +374,7 @@ def _depot_downloader(self, options: list):

# Wait for program to finish
p.expect(pexpect.EOF, timeout=None)
except pexpect.exceptions.TIMEOUT as e:
except pexpect.exceptions.TIMEOUT:
print("Error waiting for DepotDownloader to start")
except ConnectionError as e:
print(e)
Expand All @@ -399,11 +399,11 @@ def _download_manifest(self, username: str, password: str, depot_id: int, manife
Returns:
bool: True if successful
"""
args = ["-app", str(self.app_id),
"-depot", str(depot_id),
"-manifest", str(manifest_id),
"-username", username,
"-password", password,
args = ["-app", str(self.app_id),
"-depot", str(depot_id),
"-manifest", str(manifest_id),
"-username", username,
"-password", password,
"-remember-password",
"-dir", str(self.manifest_dir),
"-manifest-only"]
Expand All @@ -426,11 +426,11 @@ def _download_depot(self, username: str, password: str, depot_id: int, manifest_
Returns:
bool: True if successful
"""
args = ["-app", str(self.app_id),
"-depot", str(depot_id),
"-manifest", str(manifest_id),
"-username", username,
"-password", password,
args = ["-app", str(self.app_id),
"-depot", str(depot_id),
"-manifest", str(manifest_id),
"-username", username,
"-password", password,
"-remember-password",
"-dir", str(self.download_dir),
"-filelist", filelist]
Expand Down Expand Up @@ -476,7 +476,7 @@ def _get_filelist(self, username: str, password: str, depot_id: int, current_man
# Find all added files (Result contains added files and files with different hash)
diff_added = list(current_set.difference(target_set))
diff_added_names = set([x[0] for x in diff_added])

# Find all removed files (Remove files with same name but different hash)
removed = set.difference(diff_removed_names, diff_added_names)

Expand Down Expand Up @@ -531,7 +531,8 @@ def _read_manifest(self, file: pathlib.Path):
size_compressed = 0
files = []

line = f.readline() # First line contains depot id
# First line contains depot id
line = f.readline()
depot = re.match(r".* (\d+)", line).groups()[0]

# Second lines is empty
Expand All @@ -540,9 +541,9 @@ def _read_manifest(self, file: pathlib.Path):
line = f.readline()
groups = re.match(r".* : (\d+) \/ (.+)", line).groups()
id = groups[0]
date = groups[1] # (Temporary) workaround since date isn't used anyways.
date = groups[1] # (Temporary) workaround since date isn't used anyways.
# Date format seems to be localized... @TODO find a way to universally parse datestring
#date = time.mktime(time.strptime(groups[1], "%d.%m.%Y %H:%M:%S"))
# date = time.mktime(time.strptime(groups[1], "%d.%m.%Y %H:%M:%S"))

# Fourth line contains number of files
line = f.readline()
Expand Down Expand Up @@ -585,4 +586,4 @@ def _get_game_version(self):
"""
metadata = utils.get_version_number(self.game_dir / "AoE2DE_s.exe")

return (metadata[1] - 101) * 65536 + metadata[2]
return (metadata[1] - 101) * 65536 + metadata[2]
4 changes: 3 additions & 1 deletion src/redirector.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import utils


class IORedirector(object):
def __init__(self, text_widget):
# Store the widget
self.text_widget = text_widget


class StdoutRedirector(IORedirector):
def write(self, text):
utils.log(self.text_widget, text)

def flush(self):
pass
pass
24 changes: 17 additions & 7 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from tkinter import Text

def get_version_number (path: pathlib.Path):

def get_version_number(path: pathlib.Path):
"""Retrieve the version number of a binary file.
Args:
Expand All @@ -29,6 +30,7 @@ def get_version_number (path: pathlib.Path):
version_number = tuple(int(x) for x in proc.stdout.read().strip().split())
return version_number


def log(text_widget: Text, text: str):
"""Logs a given string to the text widget.
Expand All @@ -41,6 +43,7 @@ def log(text_widget: Text, text: str):
text_widget.configure(state="disabled")
text_widget.see("end")


def copy_file_or_dir(source_dir: pathlib.Path, target_dir: pathlib.Path, file: str):
"""Copies a file or a directory recursively into the target directory.
Expand All @@ -54,6 +57,7 @@ def copy_file_or_dir(source_dir: pathlib.Path, target_dir: pathlib.Path, file: s
else:
shutil.copy((source_dir / file).absolute(), (target_dir / file).absolute())


def remove_file_or_dir(path: pathlib.Path):
"""Removes a file or directory recursively. Does not throw an error if file does not exist.
Expand All @@ -65,6 +69,7 @@ def remove_file_or_dir(path: pathlib.Path):
else:
path.unlink(missing_ok=True)


def backup_files(original_dir: pathlib.Path, override_dir: pathlib.Path, backup_dir: pathlib.Path, debug_info: bool):
"""Recursively performs backup of original_dir to backup_dir assuming all files/folder from override_dir will be patched.
Expand All @@ -85,9 +90,10 @@ def backup_files(original_dir: pathlib.Path, override_dir: pathlib.Path, backup_
else:
if debug_info:
print(f"Copy {(original_dir / file).absolute()}")

copy_file_or_dir(original_dir, backup_dir, file)


def remove_patched_files(original_dir: pathlib.Path, override_dir: pathlib.Path, debug_info: bool):
"""Recursively removes all patched files assuming original_dir has been patched with all files from override_dir.
Expand All @@ -104,7 +110,7 @@ def remove_patched_files(original_dir: pathlib.Path, override_dir: pathlib.Path,
# Remove all overridden files
try:
for file in changed_file_list:
# Its a folder, remove its contents
# Its a folder, remove its contents
if (original_dir / file).is_dir():
remove_patched_files(original_dir / file, override_dir / file, debug_info)

Expand All @@ -118,11 +124,12 @@ def remove_patched_files(original_dir: pathlib.Path, override_dir: pathlib.Path,
else:
if debug_info:
print(f"Remove {(original_dir / file).absolute()}")

remove_file_or_dir(original_dir / file)
except BaseException as e:
raise e


def check_dotnet():
"""Checks if dotnet is available.
Expand All @@ -131,19 +138,21 @@ def check_dotnet():
"""
return not (shutil.which("dotnet") is None)


def base_path():
"""Construct the base path to the exe / project.
Returns:
pathlib.Path: The base path of the exectuable or project
"""
"""
# Get absolute path to resource, works for dev and for PyInstaller
if getattr(sys, 'frozen', False):
# PyInstaller creates a temp folder and stores path in _MEIPASS
return pathlib.Path(pathlib.sys.executable).parent
else:
return pathlib.Path()


def resource_path(relative_path: str):
"""Construct the resource patch for a resource.
Expand All @@ -162,7 +171,8 @@ def resource_path(relative_path: str):

return base_path / "res" / relative_path

def clear():

def clear():
"""Clear the screen of the console.
"""
_ = os.system('cls')
_ = os.system('cls')
8 changes: 5 additions & 3 deletions src/utils_win32.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import sys
import win32api

def get_version_number_win32 (path: str):

def get_version_number_win32(path: str):
"""Retrieve the version number of a binary file.
Args:
Expand All @@ -13,9 +14,10 @@ def get_version_number_win32 (path: str):
info = win32api.GetFileVersionInfo(path, "\\")
ms = info['FileVersionMS']
ls = info['FileVersionLS']
return win32api.HIWORD (ms), win32api.LOWORD (ms), win32api.HIWORD (ls), win32api.LOWORD (ls)
return win32api.HIWORD(ms), win32api.LOWORD(ms), win32api.HIWORD(ls), win32api.LOWORD(ls)


if __name__ == '__main__':
path = sys.argv[1]
version = get_version_number_win32(path)
sys.stdout.write(" ".join([str(x) for x in version])+"\n")
sys.stdout.write(" ".join([str(x) for x in version]) + "\n")
Loading

0 comments on commit e8d9173

Please sign in to comment.