From 2990b1a652b6dff797373b5ab6735b887c2e0af6 Mon Sep 17 00:00:00 2001 From: raphael60650 Date: Sat, 17 Jul 2021 22:23:58 +0200 Subject: [PATCH] created a Option class, merged get_github_file with Track and install_mod with Game --- main.pyw | 7 +- source/Game.py | 140 +++++++++++++++++++++- source/Option.py | 34 ++++++ source/Track.py | 32 ++++- source/__init__.py | 237 +++++++++++++++++++------------------- source/check_update.py | 2 +- source/definition.py | 112 +++++++++--------- source/get_github_file.py | 31 ----- source/install_mod.py | 137 ---------------------- source/log_error.py | 11 +- source/option.py | 32 ----- source/patch_track.py | 87 ++++++-------- source/translate.py | 5 +- source/wszst.py | 11 ++ 14 files changed, 432 insertions(+), 446 deletions(-) create mode 100644 source/Option.py delete mode 100644 source/get_github_file.py delete mode 100644 source/install_mod.py delete mode 100644 source/option.py diff --git a/main.pyw b/main.pyw index 5b6bfbd..b072889 100644 --- a/main.pyw +++ b/main.pyw @@ -22,14 +22,13 @@ class ClassApp(): from source.StateButton import StateButton from source.patch_file import patch_file from source.patch_bmg import patch_bmg - from source.install_mod import install_mod from source.restart import restart from source.patch_img_desc import patch_img_desc from source.log_error import log_error - from source.get_github_file import get_github_file - from source.patch_track import patch_track, patch_autoadd + from source.patch_track import patch_track from source.patch_image import patch_image - from source.option import load_option, change_option + + from source.Option import Option from source.CT_Config import CT_Config from source.Game import Game, InvalidGamePath, InvalidFormat diff --git a/source/Game.py b/source/Game.py index a852a95..6adcaea 100644 --- a/source/Game.py +++ b/source/Game.py @@ -1,5 +1,9 @@ from . import wszst from .definition import * +from threading import Thread +import subprocess +import shutil +import json import glob import os @@ -10,6 +14,7 @@ region_id_to_name = { "E": "USA" } + class InvalidGamePath(Exception): def __init__(self): super().__init__("This path is not valid !") @@ -60,8 +65,139 @@ class Game: self.region_ID = self.game_ID[3] self.region = region_id_to_name[self.region_ID] if self.region_ID in region_id_to_name else self.region - def install_mod(self): - pass + def patch_autoadd(self, auto_add_dir: str = "./file/auto-add"): + if os.path.exists(auto_add_dir): shutil.rmtree(auto_add_dir) + if not os.path.exists(self.path + "/tmp/"): os.makedirs(self.path + "/tmp/") + subprocess.run(["./tools/szs/wszst", "AUTOADD", get_nodir(self.path) + "/files/Race/Course/", + "--DEST", get_nodir(self.path) + "/tmp/auto-add/"], + creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path), + check=True, stdout=subprocess.PIPE) + shutil.move(self.path + "/tmp/auto-add/", auto_add_dir) + shutil.rmtree(self.path + "/tmp/") + + def install_mod(self, gui): + def func(): + try: + with open("./fs.json") as f: fs = json.load(f) + + # This part is used to estimate the max_step + extracted_file = [] + max_step, step = 1, 0 + + def count_rf(path): + nonlocal max_step + max_step += 1 + if get_extension(path) == "szs": + if not (os.path.realpath(path) in extracted_file): + extracted_file.append(os.path.realpath(path)) + max_step += 1 + + for fp in fs: + for f in glob.glob(self.path + "/files/" + fp, recursive=True): + if type(fs[fp]) == str: + count_rf(path=f) + elif type(fs[fp]) == dict: + for nf in fs[fp]: + if type(fs[fp][nf]) == str: + count_rf(path=f) + elif type(fs[fp][nf]) == list: + for ffp in fs[fp][nf]: count_rf(path=f) + ### + extracted_file = [] + max_step += 4 # PATCH main.dol and PATCH lecode.bin, converting, changing ID + # self.Progress(show=True, indeter=False, statut=self.translate("Installing mod"), max=max_step, step=0) + + def replace_file(path, file, subpath="/"): + # self.Progress(statut=self.translate("Editing", "\n", get_nodir(path)), add=1) + extension = get_extension(path) + + if extension == "szs": + if not (os.path.realpath(path) in extracted_file): + subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(path), "-d", get_nodir(path) + ".d", + "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(path), + check=True, stdout=subprocess.PIPE) + extracted_file.append(os.path.realpath(path)) + + szs_extract_path = path + ".d" + if os.path.exists(szs_extract_path + subpath): + if subpath[-1] == "/": + filecopy(f"./file/{file}", szs_extract_path + subpath + file) + else: + filecopy(f"./file/{file}", szs_extract_path + subpath) + + elif path[-1] == "/": + filecopy(f"./file/{file}", path + file) + else: + filecopy(f"./file/{file}", path) + + for fp in fs: + for f in glob.glob(self.path + "/files/" + fp, recursive=True): + if type(fs[fp]) == str: + replace_file(path=f, file=fs[fp]) + elif type(fs[fp]) == dict: + for nf in fs[fp]: + if type(fs[fp][nf]) == str: + replace_file(path=f, subpath=nf, file=fs[fp][nf]) + elif type(fs[fp][nf]) == list: + for ffp in fs[fp][nf]: replace_file(path=f, subpath=nf, file=ffp) + + for file in extracted_file: + # self.Progress(statut=self.translate("Recompilating", "\n", get_nodir(file)), add=1) + subprocess.run(["./tools/szs/wszst", "CREATE", get_nodir(file) + ".d", "-d", get_nodir(file), + "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file), + check=True, stdout=subprocess.PIPE) + if os.path.exists(file + ".d"): shutil.rmtree(file + ".d") + + # self.Progress(statut=self.translate("Patch main.dol"), add=1) + subprocess.run(["./tools/szs/wstrt", "patch", get_nodir(self.path) + "/sys/main.dol", "--clean-dol", + "--add-lecode"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path), + check=True, stdout=subprocess.PIPE) + + # self.Progress(statut=self.translate("Patch lecode.bin"), add=1) + + shutil.copytree("./file/Track/", self.path+"/files/Race/Course/", dirs_exist_ok=True) + if not(os.path.exists(self.path+"/tmp/")): os.makedirs(self.path+"/tmp/") + filecopy("./file/CTFILE.txt", self.path+"/tmp/CTFILE.txt") + filecopy("./file/lpar-default.txt", self.path + "/tmp/lpar-default.txt") + filecopy(f"./file/lecode-{self.region}.bin", self.path + f"/tmp/lecode-{self.region}.bin") + + subprocess.run( + ["./tools/szs/wlect", "patch", f"./tmp/lecode-{self.region}.bin", "-od", + f"./files/rel/lecode-{self.region}.bin", "--track-dir", "./files/Race/Course/", + "--move-tracks", "./files/Race/Course/", "--le-define", "./tmp/CTFILE.txt", "--lpar", + "./tmp/lpar-default.txt", "--overwrite"], + creationflags=CREATE_NO_WINDOW, cwd=self.path, check=True, stdout=subprocess.PIPE) + + shutil.rmtree(self.path + "/tmp/") + + output_format = gui.stringvar_game_format.get() + # self.Progress(statut=self.translate("Converting to", " ", output_format), add=1) + + if output_format in ["ISO", "WBFS", "CISO"]: + path_game_format: str = os.path.realpath(self.path + "/../MKWFaraphel." + output_format.lower()) + subprocess.run(["./tools/wit/wit", "COPY", get_nodir(self.path), "--DEST", + get_nodir(path_game_format), f"--{output_format.lower()}", "--overwrite"], + creationflags=CREATE_NO_WINDOW, cwd=get_dir(path_game_format), + check=True, stdout=subprocess.PIPE) + shutil.rmtree(self.path) + self.path = path_game_format + + # self.Progress(statut=self.translate("Changing game's ID"), add=1) + subprocess.run(["./tools/wit/wit", "EDIT", get_nodir(self.path), "--id", + f"RMC{self.region_ID}60", "--name", + f"Mario Kart Wii Faraphel {gui.ctconfig.version}", "--modify", "ALL"], + creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path), + check=True, stdout=subprocess.PIPE) + + # messagebox.showinfo(self.translate("End"), self.translate("The mod has been installed !")) + + except: pass # self.log_error() + finally: pass # self.Progress(show=False) + + t = Thread(target=func) + t.setDaemon(True) + t.start() + return t def convert_to(self, format: str = "FST"): """ diff --git a/source/Option.py b/source/Option.py new file mode 100644 index 0000000..1eef262 --- /dev/null +++ b/source/Option.py @@ -0,0 +1,34 @@ +import json +import os + + +class Option: + def __init__(self): + self.language = "en" + self.format = "FST" + self.disable_download = False + self.del_track_after_conv = False + self.dont_check_for_update = False + self.dont_check_track_sha1 = False + self.process_track = 8 + + def load_from_json(self, option_json: dict): + for key, value in option_json.items(): # load all value in the json as class attribute + setattr(self, key, value) + + def load_from_file(self, option_file: str = "./option.json"): + if os.path.exists(option_file): + with open(option_file, encoding="utf-8") as file: + file_json = json.load(file) + self.load_from_json(file_json) + + def save_to_file(self, option_file: str = "./option.json"): + option_json: dict = self.__dict__ # this return all attribute of the class as a dict + with open(option_file, "w", encoding="utf-8") as file: + json.dump(option_json, file, ensure_ascii=False) + + def edit(self, option, value, need_restart=False, gui=None): + if type(value) in [str, int, bool]: setattr(self, option, value) + else: setattr(self, option, value.get()) + self.save_to_file() + if need_restart: gui.restart() diff --git a/source/Track.py b/source/Track.py index 4503c14..512a106 100644 --- a/source/Track.py +++ b/source/Track.py @@ -1,11 +1,14 @@ from .definition import * import source.wszst +import requests +import os class Track: def __init__(self, name: str = "_", file_wu8: str = None, file_szs: str = None, prefix: str = None, suffix: str = None, author="Nintendo", special="T11", music="T11", new=True, sha1: str = None, since_version: str = None, - score: int = 0, warning: int = 0, note: str = "", *args, **kwargs): + score: int = 0, warning: int = 0, note: str = "", track_wu8_dir: str = "./file/Track-WU8/", + track_szs_dir: str = "./file/Track/", *args, **kwargs): self.name = name # Track name self.prefix = prefix # Prefix, often used for game or original console like Wii U, DS, ... @@ -19,8 +22,8 @@ class Track: self.score = score # Track score between 1 and 3 stars self.warning = warning # Track bug level (1 = minor, 2 = major) self.note = note # Note about the track - self.file_wu8 = f"./file/Track-WU8/{self.get_track_name()}.wu8" - self.file_szs = f"./file/Track/{self.get_track_name()}.szs" + self.file_wu8 = f"{track_wu8_dir}/{self.get_track_name()}.wu8" + self.file_szs = f"{track_szs_dir}/{self.get_track_name()}.szs" def __repr__(self): return f"{self.get_track_name()} sha1={self.sha1} score={self.score}" @@ -32,8 +35,8 @@ class Track: name = (prefix + self.name + suffix) return name - def load_from_json(self, track: dict): - for key, value in track.items(): # load all value in the json as class attribute + def load_from_json(self, track_json: dict): + for key, value in track_json.items(): # load all value in the json as class attribute setattr(self, key, value) def get_track_formatted_name(self, highlight_track_from_version: str = None): @@ -67,7 +70,24 @@ class Track: def convert_wu8_to_szs(self): return source.wszst.normalize(src_file=self.file_wu8, use_popen=True) - def download_wu8(self): pass + def download_wu8(self): + returncode = 0 + + dl = requests.get(get_github_content_root(self) + self.file_wu8, allow_redirects=True, stream=True) + if os.path.exists(self.file_wu8): + if int(dl.headers['Content-Length']) == os.path.getsize(self.file_wu8): return 1 + else: returncode = 3 + + if dl.status_code == 200: # if page is found + with open(self.file_wu8, "wb") as file: + chunk_size = 4096 + for i, chunk in enumerate(dl.iter_content(chunk_size=chunk_size)): + file.write(chunk) + file.flush() + return returncode + else: + print(f"error {dl.status_code} {self.file_wu8}") + return -1 def check_sha1(self): if source.wszst.sha1(self.file_wu8) == self.sha1: return 0 diff --git a/source/__init__.py b/source/__init__.py index b536c58..6d72756 100644 --- a/source/__init__.py +++ b/source/__init__.py @@ -9,154 +9,149 @@ from .definition import * from .check_update import check_update from .translate import translate from .CT_Config import * +from .Option import * from .Game import * def __init__(self): - try: - self.root = Tk() + self.root = Tk() - self.load_option() - self.ctconfig = CT_Config() - self.ctconfig.load_ctconfig_file("./ct_config.json") + self.option = Option() + self.option.load_from_file("./option.json") + self.ctconfig = CT_Config() + self.ctconfig.load_ctconfig_file("./ct_config.json") - self.is_dev_version = False # Is this installer version a dev ? - self.stringvar_language = StringVar(value=self.option["language"]) - self.stringvar_game_format = StringVar(value=self.option["format"]) - self.boolvar_disable_download = BooleanVar(value=self.option["disable_download"]) - self.boolvar_del_track_after_conv = BooleanVar(value=self.option["del_track_after_conv"]) - self.boolvar_dont_check_for_update = BooleanVar(value=self.option["dont_check_for_update"]) - self.boolvar_dont_check_track_sha1 = BooleanVar(value=self.option["dont_check_track_sha1"]) - self.intvar_process_track = IntVar(value=self.option["process_track"]) - self.boolvar_use_1star_track = BooleanVar(value=True) - self.boolvar_use_2star_track = BooleanVar(value=True) - self.boolvar_use_3star_track = BooleanVar(value=True) - self.stringvar_mark_track_from_version = StringVar(value="None") + self.is_dev_version = False # Is this installer version a dev ? + self.stringvar_language = StringVar(value=self.option.language) + self.stringvar_game_format = StringVar(value=self.option.format) + self.boolvar_disable_download = BooleanVar(value=self.option.disable_download) + self.boolvar_del_track_after_conv = BooleanVar(value=self.option.del_track_after_conv) + self.boolvar_dont_check_for_update = BooleanVar(value=self.option.dont_check_for_update) + self.boolvar_dont_check_track_sha1 = BooleanVar(value=self.option.dont_check_track_sha1) + self.intvar_process_track = IntVar(value=self.option.process_track) + self.boolvar_use_1star_track = BooleanVar(value=True) + self.boolvar_use_2star_track = BooleanVar(value=True) + self.boolvar_use_3star_track = BooleanVar(value=True) + self.stringvar_mark_track_from_version = StringVar(value="None") - self.root.title(self.translate("MKWFaraphel Installer")) - self.root.resizable(False, False) - self.root.iconbitmap(bitmap="./icon.ico") + self.root.title(self.translate("MKWFaraphel Installer")) + self.root.resizable(False, False) + self.root.iconbitmap(bitmap="./icon.ico") - if not(self.boolvar_dont_check_for_update.get()): self.check_update() + if not(self.boolvar_dont_check_for_update.get()): self.check_update() - self.menu_bar = Menu(self.root) - self.root.config(menu=self.menu_bar) + self.menu_bar = Menu(self.root) + self.root.config(menu=self.menu_bar) - self.menu_language = Menu(self.menu_bar, tearoff=0) - self.menu_bar.add_cascade(label=self.translate("Language"), menu=self.menu_language) - self.menu_language.add_radiobutton(label="Français", variable=self.stringvar_language, value="fr", command=lambda: self.change_option("language", "fr", restart=True)) - self.menu_language.add_radiobutton(label="English", variable=self.stringvar_language, value="en", command=lambda: self.change_option("language", "en", restart=True)) + self.menu_language = Menu(self.menu_bar, tearoff=0) + self.menu_bar.add_cascade(label=self.translate("Language"), menu=self.menu_language) + self.menu_language.add_radiobutton(label="Français", variable=self.stringvar_language, value="fr", command=lambda: self.option.edit("language", "fr", restart=True)) + self.menu_language.add_radiobutton(label="English", variable=self.stringvar_language, value="en", command=lambda: self.option.edit("language", "en", restart=True)) - self.menu_format = Menu(self.menu_bar, tearoff=0) - self.menu_bar.add_cascade(label=self.translate("Format"), menu=self.menu_format) - self.menu_format.add_radiobutton(label=self.translate("FST (Directory)"), variable=self.stringvar_game_format, value="FST", command=lambda: self.change_option("format", "FST")) - self.menu_format.add_radiobutton(label="ISO", variable=self.stringvar_game_format, value="ISO", command=lambda: self.change_option("format", "ISO")) - self.menu_format.add_radiobutton(label="CISO", variable=self.stringvar_game_format, value="CISO", command=lambda: self.change_option("format", "CISO")) - self.menu_format.add_radiobutton(label="WBFS", variable=self.stringvar_game_format, value="WBFS", command=lambda: self.change_option("format", "WBFS")) + self.menu_format = Menu(self.menu_bar, tearoff=0) + self.menu_bar.add_cascade(label=self.translate("Format"), menu=self.menu_format) + self.menu_format.add_radiobutton(label=self.translate("FST (Directory)"), variable=self.stringvar_game_format, value="FST", command=lambda: self.option.edit("format", "FST")) + self.menu_format.add_radiobutton(label="ISO", variable=self.stringvar_game_format, value="ISO", command=lambda: self.option.edit("format", "ISO")) + self.menu_format.add_radiobutton(label="CISO", variable=self.stringvar_game_format, value="CISO", command=lambda: self.option.edit("format", "CISO")) + self.menu_format.add_radiobutton(label="WBFS", variable=self.stringvar_game_format, value="WBFS", command=lambda: self.option.edit("format", "WBFS")) - self.menu_trackselection = Menu(self.menu_bar, tearoff=0) - self.menu_bar.add_cascade(label=self.translate("Track selection"), menu=self.menu_trackselection) - self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 1 ","star"), variable=self.boolvar_use_1star_track) - self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 2 ","stars"), variable=self.boolvar_use_2star_track) - self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 3 ","stars"), variable=self.boolvar_use_3star_track) - self.menu_trackselection.add_separator() - self.menu_marktrackversion = Menu(self.menu_trackselection, tearoff=0) - self.menu_trackselection.add_cascade(label=self.translate("Mark all tracks from version"), menu=self.menu_marktrackversion) - self.menu_marktrackversion.add_radiobutton(label=self.translate("None"), variable=self.stringvar_mark_track_from_version, value="None") - for version in self.ctconfig.all_version: - self.menu_marktrackversion.add_radiobutton(label=f"v{version}", variable=self.stringvar_mark_track_from_version, value=version) + self.menu_trackselection = Menu(self.menu_bar, tearoff=0) + self.menu_bar.add_cascade(label=self.translate("Track selection"), menu=self.menu_trackselection) + self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 1 ","star"), variable=self.boolvar_use_1star_track) + self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 2 ","stars"), variable=self.boolvar_use_2star_track) + self.menu_trackselection.add_checkbutton(label=self.translate("Select"," 3 ","stars"), variable=self.boolvar_use_3star_track) + self.menu_trackselection.add_separator() + self.menu_marktrackversion = Menu(self.menu_trackselection, tearoff=0) + self.menu_trackselection.add_cascade(label=self.translate("Mark all tracks from version"), menu=self.menu_marktrackversion) + self.menu_marktrackversion.add_radiobutton(label=self.translate("None"), variable=self.stringvar_mark_track_from_version, value="None") + for version in self.ctconfig.all_version: + self.menu_marktrackversion.add_radiobutton(label=f"v{version}", variable=self.stringvar_mark_track_from_version, value=version) - self.menu_advanced = Menu(self.menu_bar, tearoff=0) - self.menu_bar.add_cascade(label=self.translate("Advanced"), menu=self.menu_advanced) - self.menu_advanced.add_checkbutton(label=self.translate("Disable downloads"), variable=self.boolvar_disable_download, command=lambda: self.change_option("disable_download", self.boolvar_disable_download)) - self.menu_advanced.add_checkbutton(label=self.translate("Delete track after wu8 to szs conversion"), variable=self.boolvar_del_track_after_conv, command=lambda: self.change_option("del_track_after_conv", self.boolvar_del_track_after_conv)) - self.menu_advanced.add_checkbutton(label=self.translate("Don't check for update"), variable=self.boolvar_dont_check_for_update, command=lambda: self.change_option("dont_check_for_update", self.boolvar_dont_check_for_update)) - self.menu_advanced.add_checkbutton(label=self.translate("Don't check track's sha1"), variable=self.boolvar_dont_check_track_sha1, command=lambda: self.change_option("dont_check_track_sha1",self.boolvar_dont_check_track_sha1)) + self.menu_advanced = Menu(self.menu_bar, tearoff=0) + self.menu_bar.add_cascade(label=self.translate("Advanced"), menu=self.menu_advanced) + self.menu_advanced.add_checkbutton(label=self.translate("Disable downloads"), variable=self.boolvar_disable_download, command=lambda: self.option.edit("disable_download", self.boolvar_disable_download)) + self.menu_advanced.add_checkbutton(label=self.translate("Delete track after wu8 to szs conversion"), variable=self.boolvar_del_track_after_conv, command=lambda: self.option.edit("del_track_after_conv", self.boolvar_del_track_after_conv)) + self.menu_advanced.add_checkbutton(label=self.translate("Don't check for update"), variable=self.boolvar_dont_check_for_update, command=lambda: self.option.edit("dont_check_for_update", self.boolvar_dont_check_for_update)) + self.menu_advanced.add_checkbutton(label=self.translate("Don't check track's sha1"), variable=self.boolvar_dont_check_track_sha1, command=lambda: self.option.edit("dont_check_track_sha1",self.boolvar_dont_check_track_sha1)) - self.menu_advanced.add_separator() - self.menu_advanced.add_command(label=self.translate("Number of track conversion process", " :")) - self.menu_advanced.add_radiobutton(label=self.translate("1 ", "process"), variable=self.intvar_process_track, value=1, command=lambda: self.change_option("process_track", 1)) - self.menu_advanced.add_radiobutton(label=self.translate("2 ", "process"), variable=self.intvar_process_track, value=2, command=lambda: self.change_option("process_track", 2)) - self.menu_advanced.add_radiobutton(label=self.translate("4 ", "process"), variable=self.intvar_process_track, value=4, command=lambda: self.change_option("process_track", 4)) - self.menu_advanced.add_radiobutton(label=self.translate("8 ", "process"), variable=self.intvar_process_track, value=8, command=lambda: self.change_option("process_track", 8)) + self.menu_advanced.add_separator() + self.menu_advanced.add_command(label=self.translate("Number of track conversion process", " :")) + self.menu_advanced.add_radiobutton(label=self.translate("1 ", "process"), variable=self.intvar_process_track, value=1, command=lambda: self.option.edit("process_track", 1)) + self.menu_advanced.add_radiobutton(label=self.translate("2 ", "process"), variable=self.intvar_process_track, value=2, command=lambda: self.option.edit("process_track", 2)) + self.menu_advanced.add_radiobutton(label=self.translate("4 ", "process"), variable=self.intvar_process_track, value=4, command=lambda: self.option.edit("process_track", 4)) + self.menu_advanced.add_radiobutton(label=self.translate("8 ", "process"), variable=self.intvar_process_track, value=8, command=lambda: self.option.edit("process_track", 8)) - self.frame_language = Frame(self.root) - self.frame_language.grid(row=1, column=1, sticky="E") + self.frame_language = Frame(self.root) + self.frame_language.grid(row=1, column=1, sticky="E") - self.frame_game_path = LabelFrame(self.root, text=self.translate("Original game")) - self.frame_game_path.grid(row=2, column=1) + self.frame_game_path = LabelFrame(self.root, text=self.translate("Original game")) + self.frame_game_path.grid(row=2, column=1) - entry_game_path = Entry(self.frame_game_path, width=50) - entry_game_path.grid(row=1, column=1, sticky="NEWS") + entry_game_path = Entry(self.frame_game_path, width=50) + entry_game_path.grid(row=1, column=1, sticky="NEWS") - def select_path(): - path = filedialog.askopenfilename(filetypes=((self.translate("Wii game"), - r"*.iso *.wbfs main.dol *.wia *.ciso"),)) - if os.path.exists(path): - entry_game_path.delete(0, END) - entry_game_path.insert(0, path) + def select_path(): + path = filedialog.askopenfilename(filetypes=((self.translate("Wii game"), + r"*.iso *.wbfs main.dol *.wia *.ciso"),)) + if os.path.exists(path): + entry_game_path.delete(0, END) + entry_game_path.insert(0, path) - Button(self.frame_game_path, text="...", relief=RIDGE, command=select_path).grid(row=1, column=2, sticky="NEWS") + Button(self.frame_game_path, text="...", relief=RIDGE, command=select_path).grid(row=1, column=2, sticky="NEWS") - self.frame_game_path_action = Frame(self.frame_game_path) # Extract and do everything button - self.frame_game_path_action.grid(row=2, column=1, columnspan=2, sticky="NEWS") - self.frame_game_path_action.columnconfigure(1, weight=1) + self.frame_game_path_action = Frame(self.frame_game_path) # Extract and do everything button + self.frame_game_path_action.grid(row=2, column=1, columnspan=2, sticky="NEWS") + self.frame_game_path_action.columnconfigure(1, weight=1) - def use_path(): - def func(): - self.frame_action.grid_forget() - try: - self.game = Game(path = entry_game_path.get()) - self.Progress(show=True, indeter=True, statut=self.translate("Extracting the game...")) - self.game.extract_game() - self.frame_action.grid(row=3, column=1, sticky="NEWS") - except InvalidGamePath: - messagebox.showerror(self.translate("Error"), self.translate("The file path in invalid")) - except InvalidFormat: - messagebox.showerror(self.translate("Error"), self.translate("This game's format is invalid")) - except: - self.log_error() - finally: - self.Progress(show=False) + def use_path(): + def func(): + self.frame_action.grid_forget() + try: + self.game = Game(path = entry_game_path.get()) + self.Progress(show=True, indeter=True, statut=self.translate("Extracting the game...")) + self.game.extract_game() + self.frame_action.grid(row=3, column=1, sticky="NEWS") + except InvalidGamePath: + messagebox.showerror(self.translate("Error"), self.translate("The file path in invalid")) + except InvalidFormat: + messagebox.showerror(self.translate("Error"), self.translate("This game's format is invalid")) + except: + self.log_error() + finally: + self.Progress(show=False) + t = Thread(target=func) + t.setDaemon(True) + t.start() + return t + + self.button_game_extract = Button(self.frame_game_path_action, text=self.translate("Extract file"), + relief=RIDGE, command=use_path) + self.button_game_extract.grid(row=1, column=1, sticky="NEWS") + + def do_everything(): + def func(): + use_path().join() + self.patch_file().join() + self.game.install_mod(self).join() + + if messagebox.askyesno(self.translate("Experimental functionality"), + self.translate("This will extract the selected ROM, prepare files and install mod. " + "Do you wish to continue ?")): t = Thread(target=func) t.setDaemon(True) t.start() - return t - self.button_game_extract = Button(self.frame_game_path_action, text=self.translate("Extract file"), - relief=RIDGE, command=use_path) - self.button_game_extract.grid(row=1, column=1, sticky="NEWS") - - def do_everything(): - def func(): - use_path().join() - self.patch_file().join() - self.install_mod().join() - - if messagebox.askyesno(self.translate("Experimental functionality"), - self.translate("This will extract the selected ROM, prepare files and install mod. " - "Do you wish to continue ?")): - t = Thread(target=func) - t.setDaemon(True) - t.start() - - self.button_do_everything = Button(self.frame_game_path_action, text=self.translate("Do everything"), - relief=RIDGE, command=do_everything) - self.button_do_everything.grid(row=1, column=2, sticky="NEWS") + self.button_do_everything = Button(self.frame_game_path_action, text=self.translate("Do everything"), relief=RIDGE, command=do_everything) + self.button_do_everything.grid(row=1, column=2, sticky="NEWS") - self.frame_action = LabelFrame(self.root, text=self.translate("Action")) + self.frame_action = LabelFrame(self.root, text=self.translate("Action")) - self.button_prepare_file = Button(self.frame_action, text=self.translate("Prepare files"), relief=RIDGE, - command=self.patch_file, width=45) - self.button_prepare_file.grid(row=1, column=1, columnspan=2, sticky="NEWS") - self.button_install_mod = Button(self.frame_action, text=self.translate("Install mod"), relief=RIDGE, - command=self.install_mod, width=45) - # Install mod button will only appear after prepare file step + self.button_prepare_file = Button(self.frame_action, text=self.translate("Prepare files"), relief=RIDGE, command=self.patch_file, width=45) + self.button_prepare_file.grid(row=1, column=1, columnspan=2, sticky="NEWS") + self.button_install_mod = Button(self.frame_action, text=self.translate("Install mod"), relief=RIDGE, command=lambda: self.game.install_mod(self), width=45) + # Install mod button will only appear after prepare file step - self.progressbar = ttk.Progressbar(self.root) - self.progresslabel = Label(self.root) - - except: - self.log_error() + self.progressbar = ttk.Progressbar(self.root) + self.progresslabel = Label(self.root) diff --git a/source/check_update.py b/source/check_update.py index f2cce4d..993c6a0 100644 --- a/source/check_update.py +++ b/source/check_update.py @@ -46,6 +46,6 @@ def check_update(self): except requests.ConnectionError: messagebox.showwarning(self.translate("Warning"), self.translate("Can't connect to internet. Download will be disabled.")) - self.option["disable_download"] = True + self.option.disable_download = True except: self.log_error() diff --git a/source/definition.py b/source/definition.py index 08035e5..ae290af 100644 --- a/source/definition.py +++ b/source/definition.py @@ -23,67 +23,67 @@ bmgID_track_move = { "T61": 0x701b, "T62": 0x701f, "T63": 0x7017, "T64": 0x7012, "T71": 0x7015, "T72": 0x701e, "T73": 0x701d, "T74": 0x7011, "T81": 0x7018, "T82": 0x7016, "T83": 0x7013, "T84": 0x701c, - } +} trackname_color = { - "MSRDS": "\\\\c{green}MSRDS\\\\c{off}", - "CTR": "\\\\c{YOR4}CTR\\\\c{off}", - "CTTR": "\\\\c{YOR5}CTTR\\\\c{off}", - "CNR": "\\\\c{YOR5}CNR\\\\c{off}", - "DKR": "\\\\c{YOR6}DKR\\\\c{off}", - "LCP": "\\\\c{green}LCP\\\\c{off}", - "LEGO-R": "\\\\c{red2}LEGO-R\\\\c{off}", - "MP9": "\\\\c{YOR0}MP9\\\\c{off}", - "MSUSA": "\\\\c{green}MSUSA\\\\c{off}", - "FZMV": "\\\\c{YOR2}FZMV\\\\c{off}", - "KAR": "\\\\c{green}KAR\\\\c{off}", - "KO": "\\\\c{YOR5}KO\\\\c{off}", - "FZ": "\\\\c{YOR2}FZ\\\\c{off}", - "RV": "\\\\c{white}RV\\\\c{off}", - "SADX": "\\\\c{blue2}SADX\\\\c{off}", - "SCR": "\\\\c{YOR2}SCR\\\\c{off}", - "SH": "\\\\c{red}SH\\\\c{off}", - "SM64": "\\\\c{red1}SM64\\\\c{off}", - "SMB1": "\\\\c{red2}SMB1\\\\c{off}", - "SMB2": "\\\\c{red3}SMB2\\\\c{off}", - "SSBB": "\\\\c{red4}SSBB\\\\c{off}", - "SMS": "\\\\c{YOR6}SMS\\\\c{off}", - "SMO": "\\\\c{YOR7}SMO\\\\c{off}", - "VVVVVV": "\\\\c{blue}VVVVVV\\\\c{off}", - "WF": "\\\\c{green}WF\\\\c{off}", - "WP": "\\\\c{yellow}WP\\\\c{off}", - "Zelda OoT": "\\\\c{green}Zelda OoT\\\\c{off}", - "Zelda TP": "\\\\c{green}Zelda TP\\\\c{off}", - "Zelda WW": "\\\\c{green}Zelda WW\\\\c{off}", - "PMWR": "\\\\c{yellow}PMWR\\\\c{off}", - "SHR": "\\\\c{green}SHR\\\\c{off}", - "SK64": "\\\\c{green}SK64\\\\c{off}", - "SMG": "\\\\c{red2}SMG\\\\c{off}", - "Spyro 1": "\\\\c{blue}Spyro 1\\\\c{off}", + "MSRDS": "\\\\c{green}MSRDS\\\\c{off}", + "CTR": "\\\\c{YOR4}CTR\\\\c{off}", + "CTTR": "\\\\c{YOR5}CTTR\\\\c{off}", + "CNR": "\\\\c{YOR5}CNR\\\\c{off}", + "DKR": "\\\\c{YOR6}DKR\\\\c{off}", + "LCP": "\\\\c{green}LCP\\\\c{off}", + "LEGO-R": "\\\\c{red2}LEGO-R\\\\c{off}", + "MP9": "\\\\c{YOR0}MP9\\\\c{off}", + "MSUSA": "\\\\c{green}MSUSA\\\\c{off}", + "FZMV": "\\\\c{YOR2}FZMV\\\\c{off}", + "KAR": "\\\\c{green}KAR\\\\c{off}", + "KO": "\\\\c{YOR5}KO\\\\c{off}", + "FZ": "\\\\c{YOR2}FZ\\\\c{off}", + "RV": "\\\\c{white}RV\\\\c{off}", + "SADX": "\\\\c{blue2}SADX\\\\c{off}", + "SCR": "\\\\c{YOR2}SCR\\\\c{off}", + "SH": "\\\\c{red}SH\\\\c{off}", + "SM64": "\\\\c{red1}SM64\\\\c{off}", + "SMB1": "\\\\c{red2}SMB1\\\\c{off}", + "SMB2": "\\\\c{red3}SMB2\\\\c{off}", + "SSBB": "\\\\c{red4}SSBB\\\\c{off}", + "SMS": "\\\\c{YOR6}SMS\\\\c{off}", + "SMO": "\\\\c{YOR7}SMO\\\\c{off}", + "VVVVVV": "\\\\c{blue}VVVVVV\\\\c{off}", + "WF": "\\\\c{green}WF\\\\c{off}", + "WP": "\\\\c{yellow}WP\\\\c{off}", + "Zelda OoT": "\\\\c{green}Zelda OoT\\\\c{off}", + "Zelda TP": "\\\\c{green}Zelda TP\\\\c{off}", + "Zelda WW": "\\\\c{green}Zelda WW\\\\c{off}", + "PMWR": "\\\\c{yellow}PMWR\\\\c{off}", + "SHR": "\\\\c{green}SHR\\\\c{off}", + "SK64": "\\\\c{green}SK64\\\\c{off}", + "SMG": "\\\\c{red2}SMG\\\\c{off}", + "Spyro 1": "\\\\c{blue}Spyro 1\\\\c{off}", - "Wii U": "\\\\c{red4}Wii U\\\\c{off}", - "Wii": "\\\\c{blue}Wii\\\\c{off}", + "Wii U": "\\\\c{red4}Wii U\\\\c{off}", + "Wii": "\\\\c{blue}Wii\\\\c{off}", - "3DS": "\\\\c{YOR3}3DS\\\\c{off}", - "DS": "\\\\c{white}DS\\\\c{off}", - "GCN": "\\\\c{blue2}GCN\\\\c{off}", - "GBA": "\\\\c{blue1}GBA\\\\c{off}", - "N64": "\\\\c{red}N64\\\\c{off}", - "SNES": "\\\\c{green}SNES\\\\c{off}", - "RMX": "\\\\c{YOR4}RMX\\\\c{off}", - "MKT": "\\\\c{YOR5}MKT\\\\c{off}", - "GP": "\\\\c{YOR6}GP\\\\c{off}", + "3DS": "\\\\c{YOR3}3DS\\\\c{off}", + "DS": "\\\\c{white}DS\\\\c{off}", + "GCN": "\\\\c{blue2}GCN\\\\c{off}", + "GBA": "\\\\c{blue1}GBA\\\\c{off}", + "N64": "\\\\c{red}N64\\\\c{off}", + "SNES": "\\\\c{green}SNES\\\\c{off}", + "RMX": "\\\\c{YOR4}RMX\\\\c{off}", + "MKT": "\\\\c{YOR5}MKT\\\\c{off}", + "GP": "\\\\c{YOR6}GP\\\\c{off}", - "Boost": "\\\\c{YOR3}Boost\\\\c{off}", + "Boost": "\\\\c{YOR3}Boost\\\\c{off}", - "★★★": "\\\\c{YOR2}★★★\\\\c{off}", - "★★☆": "\\\\c{YOR2}★★☆\\\\c{off}", - "★☆☆": "\\\\c{YOR2}★☆☆\\\\c{off}", - "★★★!": "\\\\c{YOR4}★★★\\\\c{off}", - "★★☆!": "\\\\c{YOR4}★★☆\\\\c{off}", - "★☆☆!": "\\\\c{YOR4}★☆☆\\\\c{off}", - "★★★!!": "\\\\c{YOR6}★★★\\\\c{off}", - "★★☆!!": "\\\\c{YOR6}★★☆\\\\c{off}", - "★☆☆!!": "\\\\c{YOR6}★☆☆\\\\c{off}", + "★★★": "\\\\c{YOR2}★★★\\\\c{off}", + "★★☆": "\\\\c{YOR2}★★☆\\\\c{off}", + "★☆☆": "\\\\c{YOR2}★☆☆\\\\c{off}", + "★★★!": "\\\\c{YOR4}★★★\\\\c{off}", + "★★☆!": "\\\\c{YOR4}★★☆\\\\c{off}", + "★☆☆!": "\\\\c{YOR4}★☆☆\\\\c{off}", + "★★★!!": "\\\\c{YOR6}★★★\\\\c{off}", + "★★☆!!": "\\\\c{YOR6}★★☆\\\\c{off}", + "★☆☆!!": "\\\\c{YOR6}★☆☆\\\\c{off}", } diff --git a/source/get_github_file.py b/source/get_github_file.py deleted file mode 100644 index b035286..0000000 --- a/source/get_github_file.py +++ /dev/null @@ -1,31 +0,0 @@ -import requests -import os - -from .definition import * - - -def get_github_file(self, file): - try: - returncode = 0 - if self.boolvar_disable_download.get(): return 2 - - dl = requests.get(get_github_content_root(self)+file, allow_redirects=True, stream=True) - if os.path.exists(file): - if int(dl.headers['Content-Length']) == os.path.getsize(file): return 1 - else: returncode = 3 - - if dl.status_code == 200: # if page is found - with open(file, "wb") as file: - chunk_size = 4096 - for i, chunk in enumerate(dl.iter_content(chunk_size=chunk_size)): - file.write(chunk) - file.flush() - return returncode - else: - print(f"error {dl.status_code} {file}") - return -1 - except: - self.log_error() - return -1 - -# TODO: if version > github version, do not search in master branch but dev branch diff --git a/source/install_mod.py b/source/install_mod.py deleted file mode 100644 index 11f3e26..0000000 --- a/source/install_mod.py +++ /dev/null @@ -1,137 +0,0 @@ -from tkinter import messagebox -from threading import Thread -import subprocess -import shutil -import json -import glob -import os - -from .definition import * - - -def install_mod(self): - def func(): - try: - with open("./fs.json") as f: - fs = json.load(f) - - # This part is used to estimate the max_step - extracted_file = [] - max_step, step = 1, 0 - - def count_rf(path): - nonlocal max_step - max_step += 1 - if get_extension(path) == "szs": - if not (os.path.realpath(path) in extracted_file): - extracted_file.append(os.path.realpath(path)) - max_step += 1 - - for fp in fs: - for f in glob.glob(self.game.path + "/files/" + fp, recursive=True): - if type(fs[fp]) == str: - count_rf(path=f) - elif type(fs[fp]) == dict: - for nf in fs[fp]: - if type(fs[fp][nf]) == str: - count_rf(path=f) - elif type(fs[fp][nf]) == list: - for ffp in fs[fp][nf]: count_rf(path=f) - ### - extracted_file = [] - max_step += 4 # PATCH main.dol and PATCH lecode.bin, converting, changing ID - self.Progress(show=True, indeter=False, statut=self.translate("Installing mod"), max=max_step, step=0) - - def replace_file(path, file, subpath="/"): - self.Progress(statut=self.translate("Editing", "\n", get_nodir(path)), add=1) - extension = get_extension(path) - - if extension == "szs": - if not (os.path.realpath(path) in extracted_file): - subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(path), "-d", get_nodir(path) + ".d", - "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(path), - check=True, stdout=subprocess.PIPE) - extracted_file.append(os.path.realpath(path)) - - szs_extract_path = path + ".d" - if os.path.exists(szs_extract_path + subpath): - if subpath[-1] == "/": - filecopy(f"./file/{file}", szs_extract_path + subpath + file) - else: - filecopy(f"./file/{file}", szs_extract_path + subpath) - - elif path[-1] == "/": - filecopy(f"./file/{file}", path + file) - else: - filecopy(f"./file/{file}", path) - - for fp in fs: - for f in glob.glob(self.game.path + "/files/" + fp, recursive=True): - if type(fs[fp]) == str: - replace_file(path=f, file=fs[fp]) - elif type(fs[fp]) == dict: - for nf in fs[fp]: - if type(fs[fp][nf]) == str: - replace_file(path=f, subpath=nf, file=fs[fp][nf]) - elif type(fs[fp][nf]) == list: - for ffp in fs[fp][nf]: replace_file(path=f, subpath=nf, file=ffp) - - for file in extracted_file: - self.Progress(statut=self.translate("Recompilating", "\n", get_nodir(file)), add=1) - subprocess.run(["./tools/szs/wszst", "CREATE", get_nodir(file) + ".d", "-d", get_nodir(file), - "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file), - check=True, stdout=subprocess.PIPE) - if os.path.exists(file + ".d"): shutil.rmtree(file + ".d") - - self.Progress(statut=self.translate("Patch main.dol"), add=1) - subprocess.run(["./tools/szs/wstrt", "patch", get_nodir(self.game.path) + "/sys/main.dol", "--clean-dol", - "--add-lecode"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.game.path), - check=True, stdout=subprocess.PIPE) - - self.Progress(statut=self.translate("Patch lecode.bin"), add=1) - - shutil.copytree("./file/Track/", self.game.path+"/files/Race/Course/", dirs_exist_ok=True) - if not(os.path.exists(self.game.path+"/tmp/")): os.makedirs(self.game.path+"/tmp/") - filecopy("./file/CTFILE.txt", self.game.path+"/tmp/CTFILE.txt") - filecopy("./file/lpar-default.txt", self.game.path + "/tmp/lpar-default.txt") - filecopy(f"./file/lecode-{self.game.region}.bin", self.game.path + f"/tmp/lecode-{self.game.region}.bin") - - subprocess.run( - ["./tools/szs/wlect", "patch", f"./tmp/lecode-{self.game.region}.bin", "-od", - f"./files/rel/lecode-{self.game.region}.bin", "--track-dir", "./files/Race/Course/", - "--move-tracks", "./files/Race/Course/", "--le-define", "./tmp/CTFILE.txt", "--lpar", - "./tmp/lpar-default.txt", "--overwrite"], - creationflags=CREATE_NO_WINDOW, cwd=self.game.path, check=True, stdout=subprocess.PIPE) - - shutil.rmtree(self.game.path + "/tmp/") - - outputformat = self.stringvar_game_format.get() - self.Progress(statut=self.translate("Converting to", " ", outputformat), add=1) - - if outputformat in ["ISO", "WBFS", "CISO"]: - path_game_format: str = os.path.realpath(self.game.path + "/../MKWFaraphel." + outputformat.lower()) - subprocess.run(["./tools/wit/wit", "COPY", get_nodir(self.game.path), "--DEST", - get_nodir(path_game_format), f"--{outputformat.lower()}", "--overwrite"], - creationflags=CREATE_NO_WINDOW, cwd=get_dir(path_game_format), - check=True, stdout=subprocess.PIPE) - shutil.rmtree(self.game.path) - self.game.path = path_game_format - - self.Progress(statut=self.translate("Changing game's ID"), add=1) - subprocess.run(["./tools/wit/wit", "EDIT", get_nodir(self.game.path), "--id", - f"RMC{self.game.region_ID}60", "--name", - f"Mario Kart Wii Faraphel {self.ctconfig.version}", "--modify", "ALL"], - creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.game.path), - check=True, stdout=subprocess.PIPE) - - messagebox.showinfo(self.translate("End"), self.translate("The mod has been installed !")) - - except: self.log_error() - finally: self.Progress(show=False) - - t = Thread(target=func) - t.setDaemon(True) - t.start() - return t - -# TODO: use wszst module instead of subprocess diff --git a/source/log_error.py b/source/log_error.py index fb55032..e151457 100644 --- a/source/log_error.py +++ b/source/log_error.py @@ -1,8 +1,9 @@ import traceback -from tkinter import messagebox -def log_error(self): - error = traceback.format_exc() - with open("./error.log", "a") as f: f.write(f"---\n{error}\n") - messagebox.showerror(self.translate("Error"), self.translate("An error occured", " :", "\n", error, "\n\n")) \ No newline at end of file +def log_error(func): + try: func() + except Exception: + error = traceback.format_exc() + with open("./error.log", "a") as f: f.write(f"---\n{error}\n") + # messagebox.showerror(self.translate("Error"), self.translate("An error occured", " :", "\n", error, "\n\n")) \ No newline at end of file diff --git a/source/option.py b/source/option.py deleted file mode 100644 index 35ad8f3..0000000 --- a/source/option.py +++ /dev/null @@ -1,32 +0,0 @@ -import json -import os - -default_option = { - "language": "en", - "format": "FST", - "disable_download": False, - "del_track_after_conv": False, - "dont_check_for_update": False, - "dont_check_track_sha1": False, - "process_track": 8 -} - -with open("./translation.json", encoding="utf-8") as f: - translation_dict = json.load(f) - - -def change_option(self, option, value, restart=False): - if type(value) in [str, int, bool]: self.option[option] = value - else: self.option[option] = value.get() - with open("./option.json", "w", encoding="utf-8") as f: json.dump(self.option, f, ensure_ascii=False) - if restart: self.restart() - - -def load_option(self): - if not(os.path.exists("./option.json")): - with open("./option.json", "w", encoding="utf-8") as f: json.dump(default_option, f, ensure_ascii=False) - with open("./option.json", encoding="utf-8") as f: self.option = json.load(f) - - for option_key, option_value in default_option.items(): - if not(option_key in self.option): - self.option[option_key] = option_value \ No newline at end of file diff --git a/source/patch_track.py b/source/patch_track.py index d6b7e2f..3467b21 100644 --- a/source/patch_track.py +++ b/source/patch_track.py @@ -1,21 +1,7 @@ -from .definition import * from tkinter import messagebox -import subprocess -import shutil import os -def patch_autoadd(self): - if os.path.exists("./file/auto-add"): shutil.rmtree("./file/auto-add") - if not os.path.exists(self.game.path + "/tmp/"): os.makedirs(self.game.path + "/tmp/") - subprocess.run(["./tools/szs/wszst", "AUTOADD", get_nodir(self.game.path) + "/files/Race/Course/", - "--DEST", get_nodir(self.game.path) + "/tmp/auto-add/"], - creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.game.path), - check=True, stdout=subprocess.PIPE) - shutil.move(self.game.path + "/tmp/auto-add/", "./file/auto-add/") - shutil.rmtree(self.game.path + "/tmp/") - - def patch_track(self): max_process = self.intvar_process_track.get() process_list = {} @@ -35,42 +21,43 @@ def patch_track(self): if os.path.getsize(_track) < 1000: # File under this size are corrupted os.remove(_track) - while True: - download_returncode = self.get_github_file(track.file_wu8) - if download_returncode == -1: # can't download - error_count += 1 - if error_count > error_max: # Too much track wasn't correctly converted - messagebox.showerror( - self.translate("Error"), - self.translate("Too much tracks had a download issue.")) - return -1 + if not self.boolvar_disable_download.get(): + while True: + download_returncode = track.download_wu8() + if download_returncode == -1: # can't download + error_count += 1 + if error_count > error_max: # Too much track wasn't correctly converted + messagebox.showerror( + self.translate("Error"), + self.translate("Too much tracks had a download issue.")) + return -1 + else: + messagebox.showwarning(self.translate("Warning"), + self.translate("Can't download this track !", + f" ({error_count} / {error_max})")) + elif download_returncode == 2: break # if download is disabled, don't check sha1 + + if track.sha1: + if not self.boolvar_dont_check_track_sha1.get(): + if not track.check_sha1(): # Check si le sha1 du fichier est le bon + error_count += 1 + if error_count > error_max: # Too much track wasn't correctly converted + messagebox.showerror( + self.translate("Error"), + self.translate("Too much tracks had an issue during sha1 check.")) + return -1 + continue + + break + + if not (os.path.exists(track.file_szs)) or download_returncode == 3: # returncode 3 is track has been updated + if os.path.exists(track.file_wu8): + process_list[track_file] = track.convert_wu8_to_szs() else: - messagebox.showwarning(self.translate("Warning"), - self.translate("Can't download this track !", - f" ({error_count} / {error_max})")) - elif download_returncode == 2: break # if download is disabled, don't check sha1 - - if track.sha1: - if not self.boolvar_dont_check_track_sha1.get(): - if not track.check_sha1(): # Check si le sha1 du fichier est le bon - error_count += 1 - if error_count > error_max: # Too much track wasn't correctly converted - messagebox.showerror( - self.translate("Error"), - self.translate("Too much tracks had an issue during sha1 check.")) - return -1 - continue - - break - - if not (os.path.exists(track.file_szs)) or download_returncode == 3: # returncode 3 is track has been updated - if os.path.exists(track.file_wu8): - process_list[track_file] = track.convert_wu8_to_szs() - else: - messagebox.showerror(self.translate("Error"), - self.translate("Can't convert track.\nEnable track download and retry.")) - return -1 - elif self.boolvar_del_track_after_conv.get(): os.remove(track.file_wu8) + messagebox.showerror(self.translate("Error"), + self.translate("Can't convert track.\nEnable track download and retry.")) + return -1 + elif self.boolvar_del_track_after_conv.get(): os.remove(track.file_wu8) return 0 def clean_process(): @@ -94,7 +81,7 @@ def patch_track(self): else: # if the error max hasn't been reach messagebox.showwarning( self.translate("Warning"), - self.translate("The track", " ", get_track_wu8(track_file), + self.translate("The track", " ", track.file_wu8, "do not have been properly converted.", f" ({error_count} / {error_max})")) else: diff --git a/source/translate.py b/source/translate.py index 2025b47..d8f0fa9 100644 --- a/source/translate.py +++ b/source/translate.py @@ -1,4 +1,7 @@ -from .option import translation_dict +import json + +with open("./translation.json", encoding="utf-8") as f: + translation_dict = json.load(f) def translate(self, *texts, lang=None): diff --git a/source/wszst.py b/source/wszst.py index fab2de7..36dc9b6 100644 --- a/source/wszst.py +++ b/source/wszst.py @@ -32,6 +32,11 @@ def normalize(src_file: str, dest_dir: str = "./file/Track/", dest_name: str = " def extract(file: str, dest_dir: str): + """ + :param file: game's file to extract (can be WBFS, ISO, CISO) + :param dest_dir: where to extract the game + :return: ? + """ subprocess.run(["./tools/wit/wit", "EXTRACT", get_nodir(file), "--DEST", dest_dir], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file)) @@ -51,3 +56,9 @@ def wlect_patch(file: str, ctfile_path: str = "./tmp/CTFILE.txt", lpar_path: str = "./tmp/lpar-default.txt"): pass + + +def edit(): pass + + +def autoadd(): pass \ No newline at end of file