Merge pull request #26 from Faraphel/dev

v0.9
This commit is contained in:
Faraphel 2021-07-15 16:28:33 +02:00 committed by GitHub
commit f3a62f8188
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 13675 additions and 333 deletions

View file

@ -5,7 +5,7 @@ import sys
Dir, ext = os.path.splitext(sys.argv[0])
if ext == ".py":
input("Ce code ne doit être lancé que sous sa forme .exe !")
input("This code need to be started from its .exe version !")
exit()
VERSION_FILE_URL = "https://raw.githubusercontent.com/Faraphel/MKWF-Install/master/version"
@ -18,28 +18,26 @@ try:
dl_size = int(dl.headers["Content-Length"])
with open("./download.zip", "wb") as file:
print(f"Téléchargement de la version {gitversion['version']}.{gitversion['subversion']} en cours...")
print(f"Downloading version {gitversion['version']}.{gitversion['subversion']}...")
chunk_size = 1024
for i, chunk in enumerate(dl.iter_content(chunk_size=chunk_size)):
progress = int((i * chunk_size * 100) / dl_size)
print("("+str(progress)+"%) | " + "#" * (progress//5) + "_"* (20 - (progress//5)) + " | " +
str(round(i*chunk_size/1000000,1)) + "Mo/" + str(round(dl_size/1000000,1)) + "Mo", end="\r")
print("("+str(progress)+"%) | " + "#" * (progress//5) + "_" * (20 - (progress//5)) + " | " +
str(round(i*chunk_size/1000000,1)) + "Mo/" + str(round(dl_size/1000000,1)) + "Mo" + " " * 10,
end="\r")
file.write(chunk)
file.flush()
print("fin du téléchargement, début de l'extraction...")
print("end of the download, starting extraction..." + (" " * 10))
with zipfile.ZipFile("./download.zip") as file:
file.extractall("./")
print("fin de l'extraction")
print("end of extraction")
os.remove("./download.zip")
print("lancement de l'application...")
print("restarting application...")
os.startfile(os.path.realpath("./MKWF-Install.exe"))
except Exception as e:
print(f"Impossible d'effectuer la mise à jour :\n\n{str(e)}")
input("Appuyez pour continuer...")
# TODO: Use requests.get("https://api.github.com/repos/Faraphel/MKWF-Install/git/trees/master?recursive=1") to avoid
# redownloading the same files again and again
print(f"Can't update :\n\n{str(e)}")
input("Press to close...")

Binary file not shown.

View file

@ -16,7 +16,7 @@ setup(
license='GPL-3.0',
author='Faraphel',
author_email='rc60650@hotmail.com',
description='Logiciel de mise à jour pour MKWF-Install.',
description='MKWF-Install Updater.',
executables = [Executable("./Updater.py",
target_name = "Updater.exe",
shortcut_name = "MKWF-Install Updater",

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
file/Track-WU8/Shipyard.wu8 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
file/Track-WU8/Town.wu8 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -29,7 +29,7 @@ class ClassApp():
from source.patch_ct_icon import patch_ct_icon
from source.log_error import log_error
from source.get_github_file import get_github_file, check_track_sha1
from source.patch_track import count_track, patch_track, patch_autoadd
from source.patch_track import load_ct_config, patch_track, patch_autoadd, get_trackctname, get_trackname
from source.patch_image import patch_image
from source.option import load_option, change_option

View file

@ -15,6 +15,8 @@ def __init__(self):
self.root = Tk()
self.load_option()
self.load_ct_config()
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"])
@ -22,8 +24,12 @@ def __init__(self):
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 Installateur"))
self.root.title(self.translate("MKWFaraphel Installer"))
self.root.resizable(False, False)
self.root.iconbitmap(bitmap="./icon.ico")
@ -35,43 +41,55 @@ def __init__(self):
self.root.config(menu=self.menu_bar)
self.menu_language = Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label=self.translate("Langage"), menu=self.menu_language)
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_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 (Dossier)"), variable=self.stringvar_game_format, value="FST", command=lambda: self.change_option("format", "FST"))
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_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.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("Avancé"), menu=self.menu_advanced)
self.menu_advanced.add_checkbutton(label=self.translate("Désactiver les téléchargements"), variable=self.boolvar_disable_download, command=lambda: self.change_option("disable_download", self.boolvar_disable_download))
self.menu_advanced.add_checkbutton(label=self.translate("Supprimer les courses wu8 après conversion en szs"), 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("Ne pas vérifier les mises à jour"), 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("Ne pas vérifier le sha1 des courses"), variable=self.boolvar_dont_check_track_sha1, command=lambda: self.change_option("dont_check_track_sha1",self.boolvar_dont_check_track_sha1))
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.add_separator()
self.menu_advanced.add_command(label=self.translate("Nombre de processus de conversion de course :"))
self.menu_advanced.add_radiobutton(label=self.translate("1 processus"), variable=self.intvar_process_track, value=1, command=lambda: self.change_option("process_track", 1))
self.menu_advanced.add_radiobutton(label=self.translate("2 processus"), variable=self.intvar_process_track, value=2, command=lambda: self.change_option("process_track", 2))
self.menu_advanced.add_radiobutton(label=self.translate("4 processus"), variable=self.intvar_process_track, value=4, command=lambda: self.change_option("process_track", 4))
self.menu_advanced.add_radiobutton(label=self.translate("8 processus"), variable=self.intvar_process_track, value=8, command=lambda: self.change_option("process_track", 8))
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.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("Jeu original"))
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")
def select_path():
path = filedialog.askopenfilename(filetypes=((self.translate("Jeu Wii"),
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)
@ -89,14 +107,14 @@ def __init__(self):
self.frame_action.grid_forget()
path = entry_game_path.get()
if not (os.path.exists(path)):
messagebox.showerror(self.translate("Erreur"), self.translate("Le chemin de fichier est invalide"))
messagebox.showerror(self.translate("Error"), self.translate("The file path in invalid"))
return
extension = get_extension(path)
if extension.upper() == "DOL":
if messagebox.askyesno(self.translate("Attention"),
self.translate("Ce dossier sera écrasé si vous installer le mod !\n" +
"Êtes-vous sûr de vouloir l'utiliser ?")):
if messagebox.askyesno(self.translate("Warning"),
self.translate("This directory will be overwritten if you install the "
"mod !\n Are you sure you want to use it ?")):
self.path_mkwf = os.path.realpath(path + "/../../")
else: return
elif extension.upper() in ["ISO", "WBFS", "CSIO"]:
@ -107,7 +125,7 @@ def __init__(self):
if not(os.path.exists(self.path_mkwf)): break
directory_name, i = f"MKWiiFaraphel ({i})", i + 1
self.Progress(show=True, indeter=True, statut=self.translate("Extraction du jeu..."))
self.Progress(show=True, indeter=True, statut=self.translate("Extracting the game..."))
subprocess.call(["./tools/wit/wit", "EXTRACT", get_nodir(path), "--DEST", directory_name]
, creationflags=CREATE_NO_WINDOW, cwd=get_dir(path))
@ -116,23 +134,22 @@ def __init__(self):
self.Progress(show=False)
else:
messagebox.showerror(self.translate("Erreur"), self.translate("Le type de fichier n'est pas reconnu"))
messagebox.showerror(self.translate("Error"), self.translate("This file type is not supported"))
self.Progress(show=False)
return
if glob.glob(self.path_mkwf + "/files/rel/lecode-???.bin"): # if a LECODE file is already here
messagebox.showwarning(self.translate("Attention"),
self.translate("Cette ROM est déjà moddé, " +
"il est déconseillé de l'utiliser pour installer le mod"))
messagebox.showwarning(self.translate("Warning"),
self.translate("This game is already modded, it is not recommended to "
"use it to install the mod"))
try:
with open(self.path_mkwf + "/setup.txt") as f: setup = f.read()
setup = setup[setup.find("!part-id = ")+len("!part-id = "):]
self.original_game_ID = setup[:setup.find("\n")]
except:
messagebox.showwarning(self.translate("Attention"),
self.transate("Impossible de trouver la région de votre jeu.\n"
"la région PAL sera utilisé par défaut."))
messagebox.showwarning(self.translate("Warning"),
self.transate("Can't find game region.\nPAL region will be used."))
self.original_game_ID = "RMCP01"
try:
self.original_region_ID = self.original_game_ID[3]
@ -150,7 +167,7 @@ def __init__(self):
t.start()
return t
self.button_game_extract = Button(self.frame_game_path_action, text=self.translate("Extraire le fichier"),
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")
@ -160,26 +177,26 @@ def __init__(self):
self.patch_file().join()
self.install_mod().join()
if messagebox.askyesno(self.translate("Fonctionnalité expérimentale"),
self.translate("Cette action va extraire / utiliser la ROM sélectionné,"
" préparer les fichiers et installer le mod. Voulez-vous continuer ?")):
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("Tout faire"),
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.button_prepare_file = Button(self.frame_action, text=self.translate("Preparer les fichiers"), relief=RIDGE,
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("Installer le mod"), relief=RIDGE,
self.button_install_mod = Button(self.frame_action, text=self.translate("Install mod"), relief=RIDGE,
command=self.install_mod, width=45)
# Le boutton d'installation du mod n'est affiché qu'après avoir préparer les fichiers
# Install mod button will only appear after prepare file step
self.progressbar = ttk.Progressbar(self.root)
self.progresslabel = Label(self.root)

View file

@ -18,33 +18,32 @@ def check_update(self):
(float(gitversion["version"]) == float(locversion["version"])) and
float(gitversion["subversion"]) > float(locversion["subversion"])):
if messagebox.askyesno(
self.translate("Mise à jour disponible !"),
self.translate("Une mise à jour est disponible, souhaitez-vous l'installer ?") +
f"\n\nVersion : {locversion['version']}.{locversion['subversion']} -> {gitversion['version']}.{gitversion['subversion']}\n"
f"Changelog :\n{gitversion['changelog']}"):
self.translate("Update available !"),
self.translate("An update is available, do you want to install it ?",
f"\n\nVersion : {locversion['version']}.{locversion['subversion']} -> "
f"{gitversion['version']}.{gitversion['subversion']}\n"
f"Changelog :\n{gitversion['changelog']}")):
if not(os.path.exists("./Updater/Updater.exe")):
dl = requests.get(gitversion["updater_bin"], allow_redirects=True)
with open("./download.zip", "wb") as file:
print(self.translate("Téléchargement de Updater en cours..."))
print(self.translate("Downloading the Updater..."))
file.write(dl.content)
print(self.translate("fin du téléchargement, "
"début de l'extraction..."))
print(self.translate("end of the download, extracting..."))
with zipfile.ZipFile("./download.zip") as file:
file.extractall("./Updater/")
print(self.translate("fin de l'extraction"))
print(self.translate("finished extracting"))
os.remove("./download.zip")
print(self.translate("lancement de l'application..."))
print(self.translate("starting application..."))
os.startfile(os.path.realpath("./Updater/Updater.exe"))
sys.exit()
except requests.ConnectionError:
messagebox.showwarning(self.translate("Attention"),
self.translate("Impossible de se connecter à internet. Le téléchargement sera "
"automatiquement désactivé."))
messagebox.showwarning(self.translate("Warning"),
self.translate("Can't connect to internet. Download will be disabled."))
self.option["disable_download"] = True
except:
self.log_error()
except SystemExit: pass
except: self.log_error()

View file

@ -5,29 +5,28 @@ from .definition import *
def create_lecode_config(self):
try:
def get_star_text(track):
if "warning" in track: warning = "!" * track["warning"]
else: warning = ""
if "score" in track:
if track["score"] > 0:
return "" * track["score"] + "" * (3 - track["score"]) + warning + " "
if 0 < track["score"] <= 3:
star_text = "" * track["score"] + "" * (3 - track["score"])
return trackname_color[star_text] + " "
return ""
def get_ctfile_text(track, race=False):
if race:
return f' T {track["music"]}; ' + \
f'{track["special"]}; ' + \
f'{"0x01" if track["new"] else "0x00"}; ' + \
f'"-"; ' + \
f'"{get_star_text(track)}{get_trackctname(track=track)}\\n{track["author"]}"; ' + \
f'"-"\n'
return (f' T {track["music"]}; '
f'{track["special"]}; '
f'{"0x01" if track["new"] else "0x00"}; '
f'"-"; '
f'"{get_star_text(track)}{self.get_trackctname(track=track, color=True)}\\n{track["author"]}"; '
f'"-"\n')
else:
return f' T {track["music"]}; ' + \
f'{track["special"]}; ' + \
f'{"0x01" if track["new"] else "0x00"}; ' + \
f'"{get_trackctname(track=track)}"; ' + \
f'"{get_star_text(track)}{get_trackctname(track=track)}"; ' + \
f'"-"\n'
return (f' T {track["music"]}; '
f'{track["special"]}; '
f'{"0x01" if track["new"] else "0x00"}; '
f'"{self.get_trackctname(track=track)}"; '
f'"{get_star_text(track)}{self.get_trackctname(track=track, color=True)}"; '
f'"-"\n')
with open("./ct_config.json", encoding="utf-8") as f:
ctconfig = json.load(f)
@ -35,17 +34,17 @@ def create_lecode_config(self):
with open("./file/CTFILE.txt", "w", encoding="utf-8") as ctfile, \
open("./file/RCTFILE.txt", "w", encoding="utf-8") as rctfile:
header = "#CT-CODE\n" +\
"[RACING-TRACK-LIST]\n" +\
"%LE-FLAGS=1\n" +\
"%WIIMM-CUP=1\n" +\
"N N$SWAP | N$F_WII\n\n"
header = ("#CT-CODE\n"
"[RACING-TRACK-LIST]\n"
"%LE-FLAGS=1\n"
"%WIIMM-CUP=1\n"
"N N$SWAP | N$F_WII\n\n")
ctfile.write(header)
rctfile.write(header)
for cup in ctconfig["cup"]: # defined cup section
for cup in ctconfig["cup"]: # defined cup section
_cup_config = ctconfig["cup"][cup]
if int(cup) >= 9: # Course qui ne sont ni les originales, ni les courses aléatoires.
if int(cup) >= 9: # Track that are not original and not random selection
cup = f'\nC "{_cup_config["name"]}"\n'
ctfile.write(cup)
rctfile.write(cup)
@ -55,7 +54,16 @@ def create_lecode_config(self):
ctfile.write(get_ctfile_text(_course_config, race=False))
rctfile.write(get_ctfile_text(_course_config, race=True))
for i, _course_config in enumerate(ctconfig["tracks_list"]): # undefined cup section
tracks_list = ctconfig["tracks_list"]
if not self.boolvar_use_1star_track.get(): # if 1 star track are disabled, remove them
tracks_list = list(filter(lambda track: track.get("score") != 1, tracks_list))
if not self.boolvar_use_2star_track.get(): # if 2 stars track are disabled, remove them
tracks_list = list(filter(lambda track: track.get("score") != 2, tracks_list))
if not self.boolvar_use_3star_track.get(): # if 3 stars track are disabled, remove them
tracks_list = list(filter(lambda track: track.get("score") != 3, tracks_list))
# using dict.get allow track that with no "score" attribute to not raise an exception by returning None
for i, _course_config in enumerate(tracks_list): # undefined cup section
if i % 4 == 0:
cup = f'\nC "TL{i//4}"\n'
ctfile.write(cup)
@ -65,8 +73,8 @@ def create_lecode_config(self):
rctfile.write(get_ctfile_text(_course_config, race=True))
for _ in range(1, 4-(i%4)): # Complete cup if track are missing
ctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n')
rctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n')
ctfile.write(EMPTY_TRACK)
rctfile.write(EMPTY_TRACK)
except:
self.log_error()

View file

@ -1,3 +1,5 @@
import json
CREATE_NO_WINDOW = 0x08000000
GITHUB_REPOSITORY = "Faraphel/MKWF-Install"
GITHUB_CONTENT_ROOT = f"https://raw.githubusercontent.com/{GITHUB_REPOSITORY}/master/"
@ -13,23 +15,87 @@ get_track_szs = lambda track: f"./file/Track/{track}.szs"
region_ID = {
"J": "JAP",
"P": "PAL",
"K": "KOR",
"K": "KO",
"E": "USA"
}
EMPTY_TRACK = ' T T44; T44; 0x00; "_"; ""; "-"\n'
def get_trackname(name=None, prefix=None, suffix=None, track=None):
if track:
name = track["name"]
if "prefix" in track: prefix = track["prefix"]
if "suffix" in track: suffix = track["suffix"]
if prefix: name = prefix + " " + name
if suffix: name = name + " (" + suffix + ")"
return name
with open("./translation.json", encoding="utf-8") as f:
translation_dict = json.load(f)
bmgID_track_move = {
"T11": 0x7008, "T12": 0x7001, "T13": 0x7002, "T14": 0x7004,
"T21": 0x7000, "T22": 0x7005, "T23": 0x7006, "T24": 0x7007,
"T31": 0x7009, "T32": 0x700f, "T33": 0x700b, "T34": 0x7003,
"T41": 0x700e, "T42": 0x700a, "T43": 0x700c, "T44": 0x700d,
def get_trackctname(name=None, prefix=None, suffix=None, track=None):
return get_trackname(name=name, prefix=prefix, suffix=suffix, track=track).replace("_", "")
"T51": 0x7010, "T52": 0x7014, "T53": 0x7019, "T54": 0x701a,
"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}",
"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}",
"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}",
}
def filecopy(src, dst):

View file

@ -39,11 +39,11 @@ def install_mod(self):
for ffp in fs[fp][nf]: count_rf(path=f)
###
extracted_file = []
max_step += 4 # PATCH main.dol et PATCH lecode.bin, conversion, changement d'ID
self.Progress(show=True, indeter=False, statut=self.translate("Installation du mod"), max=max_step, step=0)
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("Modification de")+f"\n{get_nodir(path)}", add=1)
self.Progress(statut=self.translate("Editing", "\n", get_nodir(path)), add=1)
extension = get_extension(path)
if extension == "szs":
@ -77,7 +77,7 @@ def install_mod(self):
for ffp in fs[fp][nf]: replace_file(path=f, subpath=nf, file=ffp)
for file in extracted_file:
self.Progress(statut=self.translate("Recompilation de")+f"\n{get_nodir(file)}", add=1)
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)
@ -106,7 +106,7 @@ def install_mod(self):
shutil.rmtree(self.path_mkwf + "/tmp/")
outputformat = self.stringvar_game_format.get()
self.Progress(statut=self.translate("Conversion en")+f" {outputformat}", add=1)
self.Progress(statut=self.translate("Converting to", " ", outputformat), add=1)
if outputformat in ["ISO", "WBFS", "CISO"]:
self.path_mkwf_format = os.path.realpath(self.path_mkwf + "/../MKWFaraphel." + outputformat.lower())
@ -116,14 +116,14 @@ def install_mod(self):
check=True, stdout=subprocess.PIPE)
shutil.rmtree(self.path_mkwf)
self.Progress(statut=self.translate("Changement de l'ID du jeu"), add=1)
self.Progress(statut=self.translate("Changing game's ID"), add=1)
subprocess.run(["./tools/wit/wit", "EDIT", get_nodir(self.path_mkwf_format), "--id",
f"RMC{self.original_region_ID}60", "--name", f"Mario Kart Wii Faraphel {self.VERSION}",
"--modify", "ALL"],
creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path_mkwf_format),
check=True, stdout=subprocess.PIPE)
messagebox.showinfo(self.translate("Fin"), self.translate("L'installation est terminé !"))
messagebox.showinfo(self.translate("End"), self.translate("The mod has been installed !"))
except: self.log_error()
finally: self.Progress(show=False)

View file

@ -5,4 +5,4 @@ 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("Erreur"), self.translate("Une erreur est survenue :") + f"\n{error}\n\n")
messagebox.showerror(self.translate("Error"), self.translate("An error occured", " :", "\n", error, "\n\n"))

View file

@ -7,86 +7,6 @@ from .definition import *
def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /files/Scene/UI/ du jeu
try:
bmgID_track_move = {
"T11": 0x7008, "T12": 0x7001, "T13": 0x7002, "T14": 0x7004,
"T21": 0x7000, "T22": 0x7005, "T23": 0x7006, "T24": 0x7007,
"T31": 0x7009, "T32": 0x700f, "T33": 0x700b, "T34": 0x7003,
"T41": 0x700e, "T42": 0x700a, "T43": 0x700c, "T44": 0x700d,
"T51": 0x7010, "T52": 0x7014, "T53": 0x7019, "T54": 0x701a,
"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} ",
"Aléatoire: ": "\c{white}Aléatoire: ",
"Random: ": "\c{white}Random: ",
"Zufällig: ": "\c{white}Zufällig: ",
"Casuale: ": "\c{white}Casuale: ",
"Aleatorio: ": "\c{white}Aleatorio: ",
"Wii U ": "WiiU ",
"Wii ": "\c{blue}Wii\c{off} ",
"WiiU ": "\c{red4}Wii U\c{off} ", # Permet d'éviter que Wii et Wii U se mélange
"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}",
"★★★ ": "\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} ",
}
NINTENDO_CWF_REPLACE = "Wiimmfi"
MAINMENU_REPLACE = f"MKWFaraphel {self.VERSION}"
menu_replacement = {
@ -106,7 +26,7 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
}
bmglang = gamefile[-len("E.txt"):-len(".txt")] # Langue du fichier
self.Progress(statut=self.translate("Patch des textes ") + bmglang, add=1)
self.Progress(statut=self.translate("Patching text", " ", bmglang), add=1)
subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(gamefile), "-d", get_nodir(gamefile) + ".d",
"--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(gamefile))
@ -126,10 +46,10 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
with open("./file/ExtraCommon.txt", "w", encoding="utf8") as f:
f.write("#BMG\n\n"
f" 703e\t= {self.translate('Aléatoire: Toutes les pistes', lang=bmglang)}\n"
f" 703f\t= {self.translate('Aléatoire: Pistes Originales', lang=bmglang)}\n"
f" 7040\t= {self.translate('Aléatoire: Custom Tracks', lang=bmglang)}\n"
f" 7041\t= {self.translate('Aléatoire: Pistes Nouvelles', lang=bmglang)}\n")
f" 703e\t= \\\\c{{white}}{self.translate('Random: All tracks', lang=bmglang)}\n"
f" 703f\t= \\\\c{{white}}{self.translate('Random: Original tracks', lang=bmglang)}\n"
f" 7040\t= \\\\c{{white}}{self.translate('Random: Custom Tracks', lang=bmglang)}\n"
f" 7041\t= \\\\c{{white}}{self.translate('Random: New tracks', lang=bmglang)}\n")
for bmgtrack in bmgtracks.split("\n"):
if "=" in bmgtrack:
@ -138,7 +58,8 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
if "T" in bmgtrack[:bmgtrack.find("=")]:
sTid = bmgtrack.find("T")
Tid = bmgtrack[sTid:sTid + 3]
if Tid[1] in "1234": prefix = "Wii " # Si la course est original à la wii
if Tid[1] in "1234":
prefix = trackname_color["Wii"] + " " # Si la course est original à la wii
Tid = hex(bmgID_track_move[Tid])[2:]
else: # Arena
@ -165,16 +86,17 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
os.remove("./file/tmp/Common.bmg")
os.remove("./file/ExtraCommon.txt")
def finalise(file, bmgtext, replacement_list):
for text, colored_text in replacement_list.items(): bmgtext = bmgtext.replace(text, colored_text)
def finalise(file, bmgtext, replacement_list=None):
if replacement_list:
for text, colored_text in replacement_list.items(): bmgtext = bmgtext.replace(text, colored_text)
with open(file, "w", encoding="utf-8") as f: f.write(bmgtext)
subprocess.run(["./tools/szs/wbmgt", "ENCODE", get_nodir(file), "--overwrite"],
creationflags=CREATE_NO_WINDOW, cwd=get_dir(file))
os.remove(file)
finalise(f"./file/Menu_{bmglang}.txt", bmgmenu, menu_replacement)
finalise(f"./file/Common_{bmglang}.txt", bmgcommon, trackname_color)
finalise(f"./file/Common_R{bmglang}.txt", rbmgcommon, trackname_color)
finalise(f"./file/Common_{bmglang}.txt", bmgcommon)
finalise(f"./file/Common_R{bmglang}.txt", rbmgcommon)
except:
self.log_error()

View file

@ -30,9 +30,9 @@ def patch_ct_icon(self):
draw.text((4, 4), "CT", (255, 165, 0), font=font)
font = ImageFont.truetype("./file/SuperMario256.ttf", 60)
draw.text((5 - 2, 80 - 2), "%03i" % (i-10), (0, 0, 0), font=font) # i-10 car on ne compte pas les 8 coupes
draw.text((5 + 2, 80 - 2), "%03i" % (i-10), (0, 0, 0), font=font) # de base (0-7), la coupe aléatoire, et
draw.text((5 - 2, 80 + 2), "%03i" % (i-10), (0, 0, 0), font=font) # les icones droite et gauche.
draw.text((5 - 2, 80 - 2), "%03i" % (i-10), (0, 0, 0), font=font) # i-10 because first 8 cup are not
draw.text((5 + 2, 80 - 2), "%03i" % (i-10), (0, 0, 0), font=font) # counted as new, random cup,
draw.text((5 - 2, 80 + 2), "%03i" % (i-10), (0, 0, 0), font=font) # left and right arrow
draw.text((5 + 2, 80 + 2), "%03i" % (i-10), (0, 0, 0), font=font)
draw.text((5, 80), "%03i" % (i-10), (255, 165, 0), font=font)

View file

@ -9,24 +9,23 @@ def patch_file(self):
try:
if not(os.path.exists("./file/Track-WU8/")): os.makedirs("./file/Track-WU8/")
with open("./convert_file.json") as f: fc = json.load(f)
tracks, total_track = self.count_track()
max_step = len(fc["img"]) + total_track + 3 + len("EGFIS")
max_step = len(fc["img"]) + self.TOTAL_TRACK + 3 + len("EGFIS")
self.Progress(show=True, indeter=False, statut=self.translate("Conversion des fichiers"), max=max_step, step=0)
self.Progress(statut=self.translate("Configuration de LE-CODE"), add=1)
self.Progress(show=True, indeter=False, statut=self.translate("Converting files"), max=max_step, step=0)
self.Progress(statut=self.translate("Configurating LE-CODE"), add=1)
self.create_lecode_config()
self.Progress(statut=self.translate("Création de ct_icon.png"), add=1)
self.Progress(statut=self.translate("Creating ct_icon.png"), add=1)
self.patch_ct_icon()
self.Progress(statut=self.translate("Création des images descriptives"), add=1)
self.Progress(statut=self.translate("Creating descriptive images"), add=1)
self.patch_img_desc()
self.patch_image(fc)
for file in glob.glob(self.path_mkwf+"/files/Scene/UI/MenuSingle_?.szs"): self.patch_bmg(file)
# MenuSingle could be any other file, Common and Menu are all the same in all other files.
self.patch_autoadd()
if self.patch_track(tracks, total_track) != 0: return
if self.patch_track() != 0: return
self.button_install_mod.grid(row=2, column=1, columnspan=2, sticky="NEWS")
self.button_install_mod.config(text=f'{self.translate("Installer le mod")} (v{self.VERSION})')
self.button_install_mod.config(text=self.translate("Install mod", " (v", self.VERSION, ")"))
except: self.log_error()
finally: self.Progress(show=False)

View file

@ -4,6 +4,6 @@ import subprocess
def patch_image(self, fc):
for i, file in enumerate(fc["img"]):
self.Progress(statut=self.translate("Conversion des images") + f"\n({i + 1}/{len(fc['img'])}) {file}", add=1)
self.Progress(statut=self.translate("Converting images") + f"\n({i + 1}/{len(fc['img'])}) {file}", add=1)
subprocess.run(["./tools/szs/wimgt", "ENCODE", "./file/" + file, "-x", fc["img"][file], "--overwrite"],
creationflags=CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE)

View file

@ -6,16 +6,54 @@ import json
import os
def count_track(self):
def get_trackname(self, track, color=False):
hl_prefix, hl_suffix = "", ""
if color:
if track.get("since_version") == self.stringvar_mark_track_from_version.get():
hl_prefix, hl_suffix = "\\\\c{blue1}", "\\\\c{off}"
name = track["name"]
name = hl_prefix + name + hl_suffix
if "prefix" in track:
prefix = track["prefix"]
if color:
if prefix in trackname_color:
prefix = trackname_color[prefix]
name = prefix + " " + name
if "suffix" in track:
suffix = track["suffix"]
if color:
if suffix in trackname_color:
suffix = trackname_color[suffix]
name = name + " (" + suffix + ")"
return name
def get_trackctname(self, *args, **kwargs):
return self.get_trackname(*args, **kwargs).replace("_", "")
def load_ct_config(self):
tracks = []
with open("./ct_config.json", encoding="utf-8") as f: ctconfig = json.load(f)
self.VERSION = ctconfig["version"]
for cup in ctconfig["cup"].values():
for cup in ctconfig["cup"].values(): # defined order tracks
if not (cup["locked"]): tracks.extend(cup["courses"].values())
tracks.extend(ctconfig["tracks_list"])
tracks = [dict(t) for t in {tuple(d.items()) for d in tracks}]
total_track = len(tracks)
return tracks, total_track
tracks.extend(ctconfig["tracks_list"]) # unordered tracks
self.TRACKS = [dict(t) for t in {tuple(d.items()) for d in tracks}] # removing duplicate
self.TOTAL_TRACK = len(tracks)
self.VERSION = ctconfig["version"]
self.ALL_VERSION = []
for track in self.TRACKS:
if not track.get("since_version") in self.ALL_VERSION:
self.ALL_VERSION.append(track["since_version"])
self.ALL_VERSION.sort()
def patch_autoadd(self):
@ -29,19 +67,18 @@ def patch_autoadd(self):
shutil.rmtree(self.path_mkwf + "/tmp/")
def patch_track(self, tracks, total_track="?"):
def patch_track(self):
max_process = self.intvar_process_track.get()
process_list = {}
error_count, error_max = 0, 3
def add_process(track):
track_file = get_trackname(track=track)
track_file = self.get_trackname(track=track)
nonlocal error_count, error_max, process_list
process_list[track_file] = None # Used for
self.Progress(statut=self.translate("Conversion des courses") + f"\n({i + 1}/{total_track})\n" +
"\n".join(process_list.keys()), add=1)
self.Progress(statut=self.translate("Converting tracks", f"\n({i + 1}/{self.TOTAL_TRACK})\n",
"\n".join(process_list.keys())), add=1)
for _track in [get_track_szs(track_file), get_track_wu8(track_file)]:
if os.path.exists(_track):
@ -54,14 +91,14 @@ def patch_track(self, tracks, total_track="?"):
error_count += 1
if error_count > error_max: # Too much track wasn't correctly converted
messagebox.showerror(
self.translate("Erreur"),
self.translate("Trop de course ont eu une erreur du téléchargement."))
self.translate("Error"),
self.translate("Too much tracks had a download issue."))
return -1
else:
messagebox.showwarning(self.translate("Attention"),
self.translate("Impossible de télécharger cette course ! (") +
str(error_count) + "/" + str(error_max) + ")")
elif download_returncode == 2: break # Si le téléchargement est désactivé, ne pas checker le sha1
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 "sha1" in track:
if not self.boolvar_dont_check_track_sha1.get():
@ -69,8 +106,8 @@ def patch_track(self, tracks, total_track="?"):
error_count += 1
if error_count > error_max: # Too much track wasn't correctly converted
messagebox.showerror(
self.translate("Erreur"),
self.translate("Trop de course ont eu une erreur de vérification de sha1."))
self.translate("Error"),
self.translate("Too much tracks had an issue during sha1 check."))
return -1
continue
@ -84,9 +121,8 @@ def patch_track(self, tracks, total_track="?"):
"./file/Track/%N.szs", "--szs", "--overwrite", "--autoadd-path",
"./file/auto-add/"], creationflags=CREATE_NO_WINDOW, stderr=subprocess.PIPE)
else:
messagebox.showerror(self.translate("Erreur"),
self.translate("Impossible de convertir la course.\n"
"Réactiver le téléchargement des courses et réessayer."))
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(get_track_wu8(track_file))
return 0
@ -106,16 +142,15 @@ def patch_track(self, tracks, total_track="?"):
error_count += 1
if error_count > error_max: # Too much track wasn't correctly converted
messagebox.showerror(
self.translate("Erreur"),
self.translate("Trop de course ont eu une erreur de conversion."))
self.translate("Error"),
self.translate("Too much track had a conversion issue."))
return -1
else: # if the error max hasn't been reach
messagebox.showwarning(
self.translate("Attention"),
self.translate("La course ") +
get_track_wu8(track_file) +
self.translate(" n'a pas été correctement converti. (") +
str(error_count) + "/" + str(error_max) + ")")
self.translate("Warning"),
self.translate("The track", " ", get_track_wu8(track_file),
"do not have been properly converted.",
f" ({error_count} / {error_max})"))
else:
if self.boolvar_del_track_after_conv.get(): os.remove(get_track_wu8(track_file))
else:
@ -125,7 +160,7 @@ def patch_track(self, tracks, total_track="?"):
if len(process_list): return 1
else: return 0
for i, track in enumerate(tracks):
for i, track in enumerate(self.TRACKS):
while True:
if len(process_list) < max_process:
returncode = add_process(track)

View file

@ -1,20 +1,21 @@
import json
from .definition import translation_dict
def translate(self, text, lang = None):
if lang == None: lang = self.stringvar_language.get()
elif lang == "E": lang = "en"
def translate(self, *texts, lang=None):
if lang is None: lang = self.stringvar_language.get()
elif lang == "F": lang = "fr"
elif lang == "G": lang = "ge"
elif lang == "I": lang = "it"
elif lang == "S": lang = "sp"
with open("./translation.json", encoding="utf-8") as f:
translation = json.load(f)
if lang in translation:
_lang_trad = translation[lang]
if text in _lang_trad: return _lang_trad[text]
else:
print(f"no translation for : \"{text}\"")
return text
if lang in translation_dict:
_lang_trad = translation_dict[lang]
translated_text = ""
for text in texts:
if text in _lang_trad: translated_text += _lang_trad[text]
else: translated_text += text
return translated_text
return "".join(texts) # if no translation language is found

View file

@ -1,87 +1,90 @@
{
"en": {
"Ne pas vérifier le sha1 des courses": "Don't check for track's sha1",
"Impossible de se connecter à internet. Le téléchargement sera automatiquement désactivé.": "Can't connect to internet, download will automatically be disabled.",
"fr": {
"MKWFaraphel Installer": "MKWFaraphel Installateur",
"FST (Directory)": "FST (Dossier)",
"Advanced": "Avancé",
"Language": "Langage",
"Disable downloads": "Désactiver les téléchargements",
"Delete track after wu8 to szs conversion": "Supprimer les courses wu8 après conversion en szs",
"Don't check for update": "Ne pas vérifier les mises à jour",
"Don't check track's sha1": "Ne pas vérifier le sha1 des courses",
"Number of track conversion process": "Nombre de processus de conversion de course",
"process": "processus",
"Original game": "Jeu original",
"Wii game": "Jeu Wii",
"Error": "Erreur",
"The file path in invalid": "Le chemin de fichier est invalide",
"Warning": "Attention",
"This directory will be overwritten if you install the mod !\nAre you sure you want to use it ?": "Ce dossier sera écrasé si vous installer le mod !\nÊtes-vous sûr de vouloir l'utiliser ?",
"Extracting the game...": "Extraction du jeu...",
"This file type is not supported": "Le type de fichier n'est pas reconnu",
"This game is already modded, it is not recommended to use it to install the mod": "Cette ROM est déjà moddé, il est déconseillé de l'utiliser pour installer le mod",
"Can't find game region.\nPAL region will be used.": "Impossible de trouver la région de votre jeu.\nla région PAL sera utilisé par défaut.",
"Extract file": "Extraire le fichier",
"Experimental functionality": "Fonctionnalité expérimentale",
"This will extract the selected ROM, prepare files and install mod. Do you wish to continue ?": "Cette action va extraire / utiliser la ROM sélectionné, préparer les fichiers et installer le mod. Voulez-vous continuer ?",
"Do everything": "Tout faire",
"Action": "Action",
"Prepare files": "Préparer les fichiers",
"Install mod": "Installer le mod",
"Update available !": "Mise à jour disponible !",
"An update is available, do you want to install it ?": "Une mise à jour est disponible, souhaitez-vous l'installer ?",
"Downloading the Updater...": "Téléchargement de Updater en cours...",
"end of the download, extracting...": "fin du téléchargement, début de l'extraction...",
"finished extracting": "fin de l'extraction",
"starting application...": "lancement de l'application...",
"Can't connect to internet. Download will be disabled.": "Impossible de se connecter à internet. Le téléchargement sera désactivé.",
"Installing mod": "Installation du mod",
"Editing": "Modification de",
"Recompilating": "Recompilation de",
"Patch main.dol": "Patch main.dol",
"Patch lecode.bin": "Patch lecode.bin",
"Installation du mod": "Installing mod",
"Impossible de convertir la course.\nRéactiver le téléchargement des courses et réessayer.": "Impossible to convert track.\nEnable track download and retry.",
"Langage": "Language",
"Format": "Format",
"FST (Dossier)": "FST (Directory)",
"Avancé": "Advanced",
"Désactiver les téléchargements": "Disable downloads",
"Supprimer les courses wu8 après conversion en szs": "Delete wu8 track after conversion to szs",
"Ne pas vérifier les mises à jour": "Don't check for update",
"Nombre de processus de conversion de course :": "Number of process for track conversion :",
"1 processus": "1 process",
"2 processus": "2 process",
"4 processus": "4 process",
"8 processus": "8 process",
"La course ": "The track ",
" n'a pas été correctement converti. (": "hasn't been correctly converted. (",
"Trop de course ont eu une erreur de conversion.": "Too much track had a conversion issue.",
"Une erreur est survenue :": "An error occured :",
"Cette action va extraire / utiliser la ROM sélectionné, préparer les fichiers et installer le mod. Voulez-vous continuer ?": "This will extract the selected ROM, prepare files and install mod. Do you wish to continue ?",
"Fonctionnalité expérimentale": "Experimental functionality",
"Tout faire": "Do everything",
"Création des images descriptives": "Creation of descriptive images",
"Création de ct_icon.png": "Creating ct_icon.png",
"Patch des textes ": "Patching text ",
"Aléatoire: Toutes les pistes": "Random: All tracks",
"Aléatoire: Pistes Originales": "Random: Original tracks",
"Aléatoire: Custom Tracks": "Random: Custom Tracks",
"Aléatoire: Pistes Nouvelles": "Random: New tracks",
"MKWFaraphel Installateur": "MKWFaraphel Installer",
"Jeu Wii": "Wii game",
"Jeu original": "Original game",
"Erreur": "Error",
"Le chemin de fichier est invalide": "The file path in invalid",
"Attention": "Warning",
"Ce dossier sera écrasé si vous installer le mod !\nÊtes-vous sûr de vouloir l'utiliser ?": "This directory will be overwritten if you install the mod !\nAre you sure you want to use it ?",
"Extraction du jeu...": "Extracting the game...",
"Le type de fichier n'est pas reconnu": "This file type is not supported",
"Cette ROM est déjà moddé, il est déconseillé de l'utiliser pour installer le mod": "This game is already modded, it is not recommended to use it to install the mod",
"Extraire le fichier": "Extract file",
"Preparer les fichiers": "Prepare files",
"Action": "Action",
"Installer le mod": "Install mod",
"Dossier": "Directory",
"Langage : ": "Language : ",
"Mise à jour disponible !": "Update available !",
"Une mise à jour est disponible, souhaitez-vous l'installer ?": "An update is available, do you want to install it ?",
"Téléchargement de Updater en cours...": "Downloading the Updater...",
"fin du téléchargement, début de l'extraction...": "end of the download, extracting...",
"fin de l'extraction": "finished extracting",
"lancement de l'application...": "starting application...",
"Modification de": "Modifying",
"Recompilation de": "Recompilating",
"Conversion en": "Converting to",
"Changement de l'ID du jeu": "editing game's ID",
"Fin": "End",
"L'installation est terminé !": "The mod has been installed !",
"Conversion des fichiers": "Converting files",
"Conversion des images": "Converting images",
"Conversion des textes": "Converting texts",
"Conversion des courses": "Converting races",
"Configuration de LE-CODE": "Configurating LE-CODE"
"Converting to": "Conversion en",
"Changing game's ID": "Changement de l'ID du jeu",
"End": "Fin",
"The mod has been installed !": "L'installation est terminé !",
"An error occured": "Une erreur est survenue",
"Patching text": "Patch des textes",
"Random: All tracks": "Aléatoire: Toutes les pistes",
"Random: Original tracks": "Aléatoire: Pistes Originales",
"Random: Custom Tracks": "Aléatoire: Custom Tracks",
"Random: New tracks": "Aléatoire: Pistes Nouvelles",
"Converting files": "Conversion des fichiers",
"Configurating LE-CODE": "Configuration de LE-CODE",
"Creating ct_icon.png": "Création de ct_icon.png",
"Creating descriptive images": "Création des images descriptives",
"Converting images": "Conversion des images",
"Converting tracks": "Conversion des courses",
"Too much tracks had a download issue.": "Trop de course ont eu une erreur de téléchargement.",
"Can't download this track !": "Impossible de télécharger cette course !",
"Too much tracks had an issue during sha1 check.": "Trop de course ont eu une erreur de vérification de sha1.",
"Can't convert track.\nEnable track download and retry.": "Impossible de convertir la course.\nRéactiver le téléchargement des courses et réessayer.",
"Too much track had a conversion issue.": "Trop de course ont eu une erreur de conversion.",
"La course": "The track",
"do not have been properly converted.": "n'a pas été correctement converti.",
"Track selection": "Sélection de course",
"Select": "Sélectionner",
"star": "étoile",
"stars": "étoiles",
"Mark all tracks from version": "Marquer toutes les courses de la version",
"None": "Aucune"
},
"ge": {
"Aléatoire: Toutes les pistes": "Zufällig: Alle Spuren",
"Aléatoire: Pistes Originales": "Zufällig: Original-Spuren",
"Aléatoire: Custom Tracks": "Zufällig: Custom Tracks",
"Aléatoire: Pistes Nouvelles": "Zufällig: Neue Spuren"
"Random: All tracks": "Zufällig: Alle Spuren",
"Random: Original tracks": "Zufällig: Original-Spuren",
"Random: Custom Tracks": "Zufällig: Custom Tracks",
"Random: New tracks": "Zufällig: Neue Spuren"
},
"it": {
"Aléatoire: Toutes les pistes": "Casuale: Tutte le tracce",
"Aléatoire: Pistes Originales": "Casuale: Tracce originali",
"Aléatoire: Custom Tracks": "Casuale: Custom Tracks",
"Aléatoire: Pistes Nouvelles": "Casuale: Nuovi brani"
"Random: All tracks": "Casuale: Tutte le tracce",
"Random: Original tracks": "Casuale: Tracce originali",
"Random: Custom Tracks": "Casuale: Custom Tracks",
"Random: New tracks": "Casuale: Nuovi brani"
},
"sp": {
"Aléatoire: Toutes les pistes": "Aleatorio: Todas las pistas",
"Aléatoire: Pistes Originales": "Aleatorio: Pistas originales",
"Aléatoire: Custom Tracks": "Aleatorio: Custom Tracks",
"Aléatoire: Pistes Nouvelles": "Aleatorio: Pistas nuevas"
"Random: All tracks": "Aleatorio: Todas las pistas",
"Random: Original tracks": "Aleatorio: Pistas originales",
"Random: Custom Tracks": "Aleatorio: Custom Tracks",
"Random: New tracks": "Aleatorio: Pistas nuevas"
}
}

View file

@ -1,7 +1,7 @@
{
"version": "0.8",
"version": "0.9",
"subversion": "0",
"changelog": "",
"download_bin": "https://github.com/Faraphel/MKWF-Install/releases/download/0.8/MKWF.v0.8.zip",
"changelog": "- Updated GBA Sky Garden, Quag Beach -> Pokemon Beach, Rainbow Mountain Fortress, Sarasa Kingdom, Sunset Sewer, Torrential Flood Lake, Red Sector B -> Red Sector A.\n- Added 33 new tracks.\n\n- Added a page in the github wiki about forking the project to make your own ISO patcher based on MKWF-Install (https://github.com/Faraphel/MKWF-Install/wiki/Customizing-the-installer)\n- Reworked translation code.\n- English is now used in the program instead of French to make the code easier to read for everyone !\n- Reworked prefix and suffix code, now only them can be colored (the name will no longer be colored if it contains N64 for example)\n\n- You can now color track from a specific version (for example, if you only want to play on new track)\n- Added a \"track selection\" menu allowing you to only patch game for track with a certain amount of stars. (This does not apply for track from other Mario Kart like SNES, GBA, GCN, ...)\n\n- An error occurred with the updater making it unusable. If you had it, please delete ./Updater directory.\n- Fixed an error occurring when trying to update.",
"download_bin": "https://github.com/Faraphel/MKWF-Install/releases/download/0.9/MKWF.v0.9.zip",
"updater_bin": "https://github.com/Faraphel/MKWF-Install/raw/master/Updater/Updater.zip"
}