mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-04 19:58:26 +02:00
commit
f3a62f8188
60 changed files with 13675 additions and 333 deletions
|
@ -5,7 +5,7 @@ import sys
|
||||||
|
|
||||||
Dir, ext = os.path.splitext(sys.argv[0])
|
Dir, ext = os.path.splitext(sys.argv[0])
|
||||||
if ext == ".py":
|
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()
|
exit()
|
||||||
|
|
||||||
VERSION_FILE_URL = "https://raw.githubusercontent.com/Faraphel/MKWF-Install/master/version"
|
VERSION_FILE_URL = "https://raw.githubusercontent.com/Faraphel/MKWF-Install/master/version"
|
||||||
|
@ -18,28 +18,26 @@ try:
|
||||||
dl_size = int(dl.headers["Content-Length"])
|
dl_size = int(dl.headers["Content-Length"])
|
||||||
|
|
||||||
with open("./download.zip", "wb") as file:
|
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
|
chunk_size = 1024
|
||||||
for i, chunk in enumerate(dl.iter_content(chunk_size=chunk_size)):
|
for i, chunk in enumerate(dl.iter_content(chunk_size=chunk_size)):
|
||||||
progress = int((i * chunk_size * 100) / dl_size)
|
progress = int((i * chunk_size * 100) / dl_size)
|
||||||
print("("+str(progress)+"%) | " + "#" * (progress//5) + "_" * (20 - (progress//5)) + " | " +
|
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")
|
str(round(i*chunk_size/1000000,1)) + "Mo/" + str(round(dl_size/1000000,1)) + "Mo" + " " * 10,
|
||||||
|
end="\r")
|
||||||
file.write(chunk)
|
file.write(chunk)
|
||||||
file.flush()
|
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:
|
with zipfile.ZipFile("./download.zip") as file:
|
||||||
file.extractall("./")
|
file.extractall("./")
|
||||||
print("fin de l'extraction")
|
print("end of extraction")
|
||||||
|
|
||||||
os.remove("./download.zip")
|
os.remove("./download.zip")
|
||||||
print("lancement de l'application...")
|
print("restarting application...")
|
||||||
os.startfile(os.path.realpath("./MKWF-Install.exe"))
|
os.startfile(os.path.realpath("./MKWF-Install.exe"))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Impossible d'effectuer la mise à jour :\n\n{str(e)}")
|
print(f"Can't update :\n\n{str(e)}")
|
||||||
input("Appuyez pour continuer...")
|
input("Press to close...")
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
Binary file not shown.
|
@ -16,7 +16,7 @@ setup(
|
||||||
license='GPL-3.0',
|
license='GPL-3.0',
|
||||||
author='Faraphel',
|
author='Faraphel',
|
||||||
author_email='rc60650@hotmail.com',
|
author_email='rc60650@hotmail.com',
|
||||||
description='Logiciel de mise à jour pour MKWF-Install.',
|
description='MKWF-Install Updater.',
|
||||||
executables = [Executable("./Updater.py",
|
executables = [Executable("./Updater.py",
|
||||||
target_name = "Updater.exe",
|
target_name = "Updater.exe",
|
||||||
shortcut_name = "MKWF-Install Updater",
|
shortcut_name = "MKWF-Install Updater",
|
||||||
|
|
13296
ct_config.json
13296
ct_config.json
File diff suppressed because one or more lines are too long
BIN
file/Track-WU8/Battle-Race Resort.wu8
Normal file
BIN
file/Track-WU8/Battle-Race Resort.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Blowy Breezeway.wu8
Normal file
BIN
file/Track-WU8/Blowy Breezeway.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Bowsers Challenge.wu8
Normal file
BIN
file/Track-WU8/Bowsers Challenge.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Coco Park.wu8
Normal file
BIN
file/Track-WU8/Coco Park.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Desert Canyon Wasteland.wu8
Normal file
BIN
file/Track-WU8/Desert Canyon Wasteland.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Desert Resort.wu8
Normal file
BIN
file/Track-WU8/Desert Resort.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Electro Raceway.wu8
Normal file
BIN
file/Track-WU8/Electro Raceway.wu8
Normal file
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Golf Getaway.wu8
Normal file
BIN
file/Track-WU8/Golf Getaway.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Greenway Circuit.wu8
Normal file
BIN
file/Track-WU8/Greenway Circuit.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Haunted Library.wu8
Normal file
BIN
file/Track-WU8/Haunted Library.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Hole-In-One.wu8
Normal file
BIN
file/Track-WU8/Hole-In-One.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Lake Bridge.wu8
Normal file
BIN
file/Track-WU8/Lake Bridge.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Lava Falls.wu8
Normal file
BIN
file/Track-WU8/Lava Falls.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Maple Treeway - Route 2.wu8
Normal file
BIN
file/Track-WU8/Maple Treeway - Route 2.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Miniature Paradise.wu8
Normal file
BIN
file/Track-WU8/Miniature Paradise.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Mount Morton.wu8
Normal file
BIN
file/Track-WU8/Mount Morton.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Nexuz Road.wu8
Normal file
BIN
file/Track-WU8/Nexuz Road.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Ocean Islands.wu8
Normal file
BIN
file/Track-WU8/Ocean Islands.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Penguin's Ice Mine.wu8
Normal file
BIN
file/Track-WU8/Penguin's Ice Mine.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Pokemon Beach.wu8
Normal file
BIN
file/Track-WU8/Pokemon Beach.wu8
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Rainy Rainbow Raceway.wu8
Normal file
BIN
file/Track-WU8/Rainy Rainbow Raceway.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Red Sector A.wu8
Normal file
BIN
file/Track-WU8/Red Sector A.wu8
Normal file
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Ring of Fire.wu8
Normal file
BIN
file/Track-WU8/Ring of Fire.wu8
Normal file
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Shipyard.wu8
Normal file
BIN
file/Track-WU8/Shipyard.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Speedwagon Speedway.wu8
Normal file
BIN
file/Track-WU8/Speedwagon Speedway.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Spyro The Dragon Toasty.wu8
Normal file
BIN
file/Track-WU8/Spyro The Dragon Toasty.wu8
Normal file
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Super Bell Circuit.wu8
Normal file
BIN
file/Track-WU8/Super Bell Circuit.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Sweet Galaxy Canyon.wu8
Normal file
BIN
file/Track-WU8/Sweet Galaxy Canyon.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Swine Canyon.wu8
Normal file
BIN
file/Track-WU8/Swine Canyon.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/The Grand Oak.wu8
Normal file
BIN
file/Track-WU8/The Grand Oak.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/The Nether Fortress.wu8
Normal file
BIN
file/Track-WU8/The Nether Fortress.wu8
Normal file
Binary file not shown.
Binary file not shown.
BIN
file/Track-WU8/Town.wu8
Normal file
BIN
file/Track-WU8/Town.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Track and Field.wu8
Normal file
BIN
file/Track-WU8/Track and Field.wu8
Normal file
Binary file not shown.
BIN
file/Track-WU8/Wacker's Rainbow Road.wu8
Normal file
BIN
file/Track-WU8/Wacker's Rainbow Road.wu8
Normal file
Binary file not shown.
2
main.pyw
2
main.pyw
|
@ -29,7 +29,7 @@ class ClassApp():
|
||||||
from source.patch_ct_icon import patch_ct_icon
|
from source.patch_ct_icon import patch_ct_icon
|
||||||
from source.log_error import log_error
|
from source.log_error import log_error
|
||||||
from source.get_github_file import get_github_file, check_track_sha1
|
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.patch_image import patch_image
|
||||||
from source.option import load_option, change_option
|
from source.option import load_option, change_option
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ def __init__(self):
|
||||||
self.root = Tk()
|
self.root = Tk()
|
||||||
|
|
||||||
self.load_option()
|
self.load_option()
|
||||||
|
self.load_ct_config()
|
||||||
|
|
||||||
self.stringvar_language = StringVar(value=self.option["language"])
|
self.stringvar_language = StringVar(value=self.option["language"])
|
||||||
self.stringvar_game_format = StringVar(value=self.option["format"])
|
self.stringvar_game_format = StringVar(value=self.option["format"])
|
||||||
self.boolvar_disable_download = BooleanVar(value=self.option["disable_download"])
|
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_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.boolvar_dont_check_track_sha1 = BooleanVar(value=self.option["dont_check_track_sha1"])
|
||||||
self.intvar_process_track = IntVar(value=self.option["process_track"])
|
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.resizable(False, False)
|
||||||
self.root.iconbitmap(bitmap="./icon.ico")
|
self.root.iconbitmap(bitmap="./icon.ico")
|
||||||
|
|
||||||
|
@ -35,43 +41,55 @@ def __init__(self):
|
||||||
self.root.config(menu=self.menu_bar)
|
self.root.config(menu=self.menu_bar)
|
||||||
|
|
||||||
self.menu_language = Menu(self.menu_bar, tearoff=0)
|
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="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.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_format = Menu(self.menu_bar, tearoff=0)
|
||||||
self.menu_bar.add_cascade(label=self.translate("Format"), menu=self.menu_format)
|
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="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="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.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_advanced = Menu(self.menu_bar, tearoff=0)
|
||||||
self.menu_bar.add_cascade(label=self.translate("Avancé"), menu=self.menu_advanced)
|
self.menu_bar.add_cascade(label=self.translate("Advanced"), 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("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("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("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("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("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("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_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_separator()
|
||||||
self.menu_advanced.add_command(label=self.translate("Nombre de processus de conversion de course :"))
|
self.menu_advanced.add_command(label=self.translate("Number of track conversion process", " :"))
|
||||||
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("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 processus"), variable=self.intvar_process_track, value=2, command=lambda: self.change_option("process_track", 2))
|
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 processus"), variable=self.intvar_process_track, value=4, command=lambda: self.change_option("process_track", 4))
|
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 processus"), variable=self.intvar_process_track, value=8, command=lambda: self.change_option("process_track", 8))
|
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 = Frame(self.root)
|
||||||
self.frame_language.grid(row=1, column=1, sticky="E")
|
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)
|
self.frame_game_path.grid(row=2, column=1)
|
||||||
|
|
||||||
entry_game_path = Entry(self.frame_game_path, width=50)
|
entry_game_path = Entry(self.frame_game_path, width=50)
|
||||||
entry_game_path.grid(row=1, column=1, sticky="NEWS")
|
entry_game_path.grid(row=1, column=1, sticky="NEWS")
|
||||||
|
|
||||||
def select_path():
|
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"),))
|
r"*.iso *.wbfs main.dol *.wia *.ciso"),))
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
entry_game_path.delete(0, END)
|
entry_game_path.delete(0, END)
|
||||||
|
@ -89,14 +107,14 @@ def __init__(self):
|
||||||
self.frame_action.grid_forget()
|
self.frame_action.grid_forget()
|
||||||
path = entry_game_path.get()
|
path = entry_game_path.get()
|
||||||
if not (os.path.exists(path)):
|
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
|
return
|
||||||
|
|
||||||
extension = get_extension(path)
|
extension = get_extension(path)
|
||||||
if extension.upper() == "DOL":
|
if extension.upper() == "DOL":
|
||||||
if messagebox.askyesno(self.translate("Attention"),
|
if messagebox.askyesno(self.translate("Warning"),
|
||||||
self.translate("Ce dossier sera écrasé si vous installer le mod !\n" +
|
self.translate("This directory will be overwritten if you install the "
|
||||||
"Êtes-vous sûr de vouloir l'utiliser ?")):
|
"mod !\n Are you sure you want to use it ?")):
|
||||||
self.path_mkwf = os.path.realpath(path + "/../../")
|
self.path_mkwf = os.path.realpath(path + "/../../")
|
||||||
else: return
|
else: return
|
||||||
elif extension.upper() in ["ISO", "WBFS", "CSIO"]:
|
elif extension.upper() in ["ISO", "WBFS", "CSIO"]:
|
||||||
|
@ -107,7 +125,7 @@ def __init__(self):
|
||||||
if not(os.path.exists(self.path_mkwf)): break
|
if not(os.path.exists(self.path_mkwf)): break
|
||||||
directory_name, i = f"MKWiiFaraphel ({i})", i + 1
|
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]
|
subprocess.call(["./tools/wit/wit", "EXTRACT", get_nodir(path), "--DEST", directory_name]
|
||||||
, creationflags=CREATE_NO_WINDOW, cwd=get_dir(path))
|
, creationflags=CREATE_NO_WINDOW, cwd=get_dir(path))
|
||||||
|
|
||||||
|
@ -116,23 +134,22 @@ def __init__(self):
|
||||||
self.Progress(show=False)
|
self.Progress(show=False)
|
||||||
|
|
||||||
else:
|
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)
|
self.Progress(show=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
if glob.glob(self.path_mkwf + "/files/rel/lecode-???.bin"): # if a LECODE file is already here
|
if glob.glob(self.path_mkwf + "/files/rel/lecode-???.bin"): # if a LECODE file is already here
|
||||||
messagebox.showwarning(self.translate("Attention"),
|
messagebox.showwarning(self.translate("Warning"),
|
||||||
self.translate("Cette ROM est déjà moddé, " +
|
self.translate("This game is already modded, it is not recommended to "
|
||||||
"il est déconseillé de l'utiliser pour installer le mod"))
|
"use it to install the mod"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.path_mkwf + "/setup.txt") as f: setup = f.read()
|
with open(self.path_mkwf + "/setup.txt") as f: setup = f.read()
|
||||||
setup = setup[setup.find("!part-id = ")+len("!part-id = "):]
|
setup = setup[setup.find("!part-id = ")+len("!part-id = "):]
|
||||||
self.original_game_ID = setup[:setup.find("\n")]
|
self.original_game_ID = setup[:setup.find("\n")]
|
||||||
except:
|
except:
|
||||||
messagebox.showwarning(self.translate("Attention"),
|
messagebox.showwarning(self.translate("Warning"),
|
||||||
self.transate("Impossible de trouver la région de votre jeu.\n"
|
self.transate("Can't find game region.\nPAL region will be used."))
|
||||||
"la région PAL sera utilisé par défaut."))
|
|
||||||
self.original_game_ID = "RMCP01"
|
self.original_game_ID = "RMCP01"
|
||||||
try:
|
try:
|
||||||
self.original_region_ID = self.original_game_ID[3]
|
self.original_region_ID = self.original_game_ID[3]
|
||||||
|
@ -150,7 +167,7 @@ def __init__(self):
|
||||||
t.start()
|
t.start()
|
||||||
return t
|
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)
|
relief=RIDGE, command=use_path)
|
||||||
self.button_game_extract.grid(row=1, column=1, sticky="NEWS")
|
self.button_game_extract.grid(row=1, column=1, sticky="NEWS")
|
||||||
|
|
||||||
|
@ -160,26 +177,26 @@ def __init__(self):
|
||||||
self.patch_file().join()
|
self.patch_file().join()
|
||||||
self.install_mod().join()
|
self.install_mod().join()
|
||||||
|
|
||||||
if messagebox.askyesno(self.translate("Fonctionnalité expérimentale"),
|
if messagebox.askyesno(self.translate("Experimental functionality"),
|
||||||
self.translate("Cette action va extraire / utiliser la ROM sélectionné,"
|
self.translate("This will extract the selected ROM, prepare files and install mod. "
|
||||||
" préparer les fichiers et installer le mod. Voulez-vous continuer ?")):
|
"Do you wish to continue ?")):
|
||||||
t = Thread(target=func)
|
t = Thread(target=func)
|
||||||
t.setDaemon(True)
|
t.setDaemon(True)
|
||||||
t.start()
|
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)
|
relief=RIDGE, command=do_everything)
|
||||||
self.button_do_everything.grid(row=1, column=2, sticky="NEWS")
|
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("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)
|
command=self.patch_file, width=45)
|
||||||
self.button_prepare_file.grid(row=1, column=1, columnspan=2, sticky="NEWS")
|
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)
|
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.progressbar = ttk.Progressbar(self.root)
|
||||||
self.progresslabel = Label(self.root)
|
self.progresslabel = Label(self.root)
|
||||||
|
|
|
@ -18,33 +18,32 @@ def check_update(self):
|
||||||
(float(gitversion["version"]) == float(locversion["version"])) and
|
(float(gitversion["version"]) == float(locversion["version"])) and
|
||||||
float(gitversion["subversion"]) > float(locversion["subversion"])):
|
float(gitversion["subversion"]) > float(locversion["subversion"])):
|
||||||
if messagebox.askyesno(
|
if messagebox.askyesno(
|
||||||
self.translate("Mise à jour disponible !"),
|
self.translate("Update available !"),
|
||||||
self.translate("Une mise à jour est disponible, souhaitez-vous l'installer ?") +
|
self.translate("An update is available, do you want to install it ?",
|
||||||
f"\n\nVersion : {locversion['version']}.{locversion['subversion']} -> {gitversion['version']}.{gitversion['subversion']}\n"
|
f"\n\nVersion : {locversion['version']}.{locversion['subversion']} -> "
|
||||||
f"Changelog :\n{gitversion['changelog']}"):
|
f"{gitversion['version']}.{gitversion['subversion']}\n"
|
||||||
|
f"Changelog :\n{gitversion['changelog']}")):
|
||||||
|
|
||||||
if not(os.path.exists("./Updater/Updater.exe")):
|
if not(os.path.exists("./Updater/Updater.exe")):
|
||||||
dl = requests.get(gitversion["updater_bin"], allow_redirects=True)
|
dl = requests.get(gitversion["updater_bin"], allow_redirects=True)
|
||||||
with open("./download.zip", "wb") as file:
|
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)
|
file.write(dl.content)
|
||||||
print(self.translate("fin du téléchargement, "
|
print(self.translate("end of the download, extracting..."))
|
||||||
"début de l'extraction..."))
|
|
||||||
|
|
||||||
with zipfile.ZipFile("./download.zip") as file:
|
with zipfile.ZipFile("./download.zip") as file:
|
||||||
file.extractall("./Updater/")
|
file.extractall("./Updater/")
|
||||||
print(self.translate("fin de l'extraction"))
|
print(self.translate("finished extracting"))
|
||||||
|
|
||||||
os.remove("./download.zip")
|
os.remove("./download.zip")
|
||||||
print(self.translate("lancement de l'application..."))
|
print(self.translate("starting application..."))
|
||||||
os.startfile(os.path.realpath("./Updater/Updater.exe"))
|
os.startfile(os.path.realpath("./Updater/Updater.exe"))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
messagebox.showwarning(self.translate("Attention"),
|
messagebox.showwarning(self.translate("Warning"),
|
||||||
self.translate("Impossible de se connecter à internet. Le téléchargement sera "
|
self.translate("Can't connect to internet. Download will be disabled."))
|
||||||
"automatiquement désactivé."))
|
|
||||||
self.option["disable_download"] = True
|
self.option["disable_download"] = True
|
||||||
|
|
||||||
except:
|
except SystemExit: pass
|
||||||
self.log_error()
|
except: self.log_error()
|
||||||
|
|
|
@ -5,29 +5,28 @@ from .definition import *
|
||||||
def create_lecode_config(self):
|
def create_lecode_config(self):
|
||||||
try:
|
try:
|
||||||
def get_star_text(track):
|
def get_star_text(track):
|
||||||
if "warning" in track: warning = "!" * track["warning"]
|
|
||||||
else: warning = ""
|
|
||||||
|
|
||||||
if "score" in track:
|
if "score" in track:
|
||||||
if track["score"] > 0:
|
if 0 < track["score"] <= 3:
|
||||||
return "★" * track["score"] + "☆" * (3 - track["score"]) + warning + " "
|
star_text = "★" * track["score"] + "☆" * (3 - track["score"])
|
||||||
|
return trackname_color[star_text] + " "
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def get_ctfile_text(track, race=False):
|
def get_ctfile_text(track, race=False):
|
||||||
if race:
|
if race:
|
||||||
return f' T {track["music"]}; ' + \
|
return (f' T {track["music"]}; '
|
||||||
f'{track["special"]}; ' + \
|
f'{track["special"]}; '
|
||||||
f'{"0x01" if track["new"] else "0x00"}; ' + \
|
f'{"0x01" if track["new"] else "0x00"}; '
|
||||||
f'"-"; ' + \
|
f'"-"; '
|
||||||
f'"{get_star_text(track)}{get_trackctname(track=track)}\\n{track["author"]}"; ' + \
|
f'"{get_star_text(track)}{self.get_trackctname(track=track, color=True)}\\n{track["author"]}"; '
|
||||||
f'"-"\n'
|
f'"-"\n')
|
||||||
else:
|
else:
|
||||||
return f' T {track["music"]}; ' + \
|
return (f' T {track["music"]}; '
|
||||||
f'{track["special"]}; ' + \
|
f'{track["special"]}; '
|
||||||
f'{"0x01" if track["new"] else "0x00"}; ' + \
|
f'{"0x01" if track["new"] else "0x00"}; '
|
||||||
f'"{get_trackctname(track=track)}"; ' + \
|
f'"{self.get_trackctname(track=track)}"; '
|
||||||
f'"{get_star_text(track)}{get_trackctname(track=track)}"; ' + \
|
f'"{get_star_text(track)}{self.get_trackctname(track=track, color=True)}"; '
|
||||||
f'"-"\n'
|
f'"-"\n')
|
||||||
|
|
||||||
with open("./ct_config.json", encoding="utf-8") as f:
|
with open("./ct_config.json", encoding="utf-8") as f:
|
||||||
ctconfig = json.load(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, \
|
with open("./file/CTFILE.txt", "w", encoding="utf-8") as ctfile, \
|
||||||
open("./file/RCTFILE.txt", "w", encoding="utf-8") as rctfile:
|
open("./file/RCTFILE.txt", "w", encoding="utf-8") as rctfile:
|
||||||
|
|
||||||
header = "#CT-CODE\n" +\
|
header = ("#CT-CODE\n"
|
||||||
"[RACING-TRACK-LIST]\n" +\
|
"[RACING-TRACK-LIST]\n"
|
||||||
"%LE-FLAGS=1\n" +\
|
"%LE-FLAGS=1\n"
|
||||||
"%WIIMM-CUP=1\n" +\
|
"%WIIMM-CUP=1\n"
|
||||||
"N N$SWAP | N$F_WII\n\n"
|
"N N$SWAP | N$F_WII\n\n")
|
||||||
ctfile.write(header)
|
ctfile.write(header)
|
||||||
rctfile.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]
|
_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'
|
cup = f'\nC "{_cup_config["name"]}"\n'
|
||||||
ctfile.write(cup)
|
ctfile.write(cup)
|
||||||
rctfile.write(cup)
|
rctfile.write(cup)
|
||||||
|
@ -55,7 +54,16 @@ def create_lecode_config(self):
|
||||||
ctfile.write(get_ctfile_text(_course_config, race=False))
|
ctfile.write(get_ctfile_text(_course_config, race=False))
|
||||||
rctfile.write(get_ctfile_text(_course_config, race=True))
|
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:
|
if i % 4 == 0:
|
||||||
cup = f'\nC "TL{i//4}"\n'
|
cup = f'\nC "TL{i//4}"\n'
|
||||||
ctfile.write(cup)
|
ctfile.write(cup)
|
||||||
|
@ -65,8 +73,8 @@ def create_lecode_config(self):
|
||||||
rctfile.write(get_ctfile_text(_course_config, race=True))
|
rctfile.write(get_ctfile_text(_course_config, race=True))
|
||||||
|
|
||||||
for _ in range(1, 4-(i%4)): # Complete cup if track are missing
|
for _ in range(1, 4-(i%4)): # Complete cup if track are missing
|
||||||
ctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n')
|
ctfile.write(EMPTY_TRACK)
|
||||||
rctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n')
|
rctfile.write(EMPTY_TRACK)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
self.log_error()
|
self.log_error()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import json
|
||||||
|
|
||||||
CREATE_NO_WINDOW = 0x08000000
|
CREATE_NO_WINDOW = 0x08000000
|
||||||
GITHUB_REPOSITORY = "Faraphel/MKWF-Install"
|
GITHUB_REPOSITORY = "Faraphel/MKWF-Install"
|
||||||
GITHUB_CONTENT_ROOT = f"https://raw.githubusercontent.com/{GITHUB_REPOSITORY}/master/"
|
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 = {
|
region_ID = {
|
||||||
"J": "JAP",
|
"J": "JAP",
|
||||||
"P": "PAL",
|
"P": "PAL",
|
||||||
"K": "KOR",
|
"K": "KO",
|
||||||
"E": "USA"
|
"E": "USA"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMPTY_TRACK = ' T T44; T44; 0x00; "_"; ""; "-"\n'
|
||||||
|
|
||||||
def get_trackname(name=None, prefix=None, suffix=None, track=None):
|
with open("./translation.json", encoding="utf-8") as f:
|
||||||
if track:
|
translation_dict = json.load(f)
|
||||||
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
|
|
||||||
|
|
||||||
|
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):
|
"T51": 0x7010, "T52": 0x7014, "T53": 0x7019, "T54": 0x701a,
|
||||||
return get_trackname(name=name, prefix=prefix, suffix=suffix, track=track).replace("_", "")
|
"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):
|
def filecopy(src, dst):
|
||||||
|
|
|
@ -39,11 +39,11 @@ def install_mod(self):
|
||||||
for ffp in fs[fp][nf]: count_rf(path=f)
|
for ffp in fs[fp][nf]: count_rf(path=f)
|
||||||
###
|
###
|
||||||
extracted_file = []
|
extracted_file = []
|
||||||
max_step += 4 # PATCH main.dol et PATCH lecode.bin, conversion, changement d'ID
|
max_step += 4 # PATCH main.dol and PATCH lecode.bin, converting, changing ID
|
||||||
self.Progress(show=True, indeter=False, statut=self.translate("Installation du mod"), max=max_step, step=0)
|
self.Progress(show=True, indeter=False, statut=self.translate("Installing mod"), max=max_step, step=0)
|
||||||
|
|
||||||
def replace_file(path, file, subpath="/"):
|
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)
|
extension = get_extension(path)
|
||||||
|
|
||||||
if extension == "szs":
|
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 ffp in fs[fp][nf]: replace_file(path=f, subpath=nf, file=ffp)
|
||||||
|
|
||||||
for file in extracted_file:
|
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),
|
subprocess.run(["./tools/szs/wszst", "CREATE", get_nodir(file) + ".d", "-d", get_nodir(file),
|
||||||
"--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file),
|
"--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file),
|
||||||
check=True, stdout=subprocess.PIPE)
|
check=True, stdout=subprocess.PIPE)
|
||||||
|
@ -106,7 +106,7 @@ def install_mod(self):
|
||||||
shutil.rmtree(self.path_mkwf + "/tmp/")
|
shutil.rmtree(self.path_mkwf + "/tmp/")
|
||||||
|
|
||||||
outputformat = self.stringvar_game_format.get()
|
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"]:
|
if outputformat in ["ISO", "WBFS", "CISO"]:
|
||||||
self.path_mkwf_format = os.path.realpath(self.path_mkwf + "/../MKWFaraphel." + outputformat.lower())
|
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)
|
check=True, stdout=subprocess.PIPE)
|
||||||
shutil.rmtree(self.path_mkwf)
|
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",
|
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}",
|
f"RMC{self.original_region_ID}60", "--name", f"Mario Kart Wii Faraphel {self.VERSION}",
|
||||||
"--modify", "ALL"],
|
"--modify", "ALL"],
|
||||||
creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path_mkwf_format),
|
creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path_mkwf_format),
|
||||||
check=True, stdout=subprocess.PIPE)
|
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()
|
except: self.log_error()
|
||||||
finally: self.Progress(show=False)
|
finally: self.Progress(show=False)
|
||||||
|
|
|
@ -5,4 +5,4 @@ from tkinter import messagebox
|
||||||
def log_error(self):
|
def log_error(self):
|
||||||
error = traceback.format_exc()
|
error = traceback.format_exc()
|
||||||
with open("./error.log", "a") as f: f.write(f"---\n{error}\n")
|
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"))
|
|
@ -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
|
def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /files/Scene/UI/ du jeu
|
||||||
try:
|
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"
|
NINTENDO_CWF_REPLACE = "Wiimmfi"
|
||||||
MAINMENU_REPLACE = f"MKWFaraphel {self.VERSION}"
|
MAINMENU_REPLACE = f"MKWFaraphel {self.VERSION}"
|
||||||
menu_replacement = {
|
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
|
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",
|
subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(gamefile), "-d", get_nodir(gamefile) + ".d",
|
||||||
"--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(gamefile))
|
"--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:
|
with open("./file/ExtraCommon.txt", "w", encoding="utf8") as f:
|
||||||
f.write("#BMG\n\n"
|
f.write("#BMG\n\n"
|
||||||
f" 703e\t= {self.translate('Aléatoire: Toutes les pistes', lang=bmglang)}\n"
|
f" 703e\t= \\\\c{{white}}{self.translate('Random: All tracks', lang=bmglang)}\n"
|
||||||
f" 703f\t= {self.translate('Aléatoire: Pistes Originales', lang=bmglang)}\n"
|
f" 703f\t= \\\\c{{white}}{self.translate('Random: Original tracks', lang=bmglang)}\n"
|
||||||
f" 7040\t= {self.translate('Aléatoire: Custom Tracks', lang=bmglang)}\n"
|
f" 7040\t= \\\\c{{white}}{self.translate('Random: Custom Tracks', lang=bmglang)}\n"
|
||||||
f" 7041\t= {self.translate('Aléatoire: Pistes Nouvelles', lang=bmglang)}\n")
|
f" 7041\t= \\\\c{{white}}{self.translate('Random: New tracks', lang=bmglang)}\n")
|
||||||
|
|
||||||
for bmgtrack in bmgtracks.split("\n"):
|
for bmgtrack in bmgtracks.split("\n"):
|
||||||
if "=" in bmgtrack:
|
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("=")]:
|
if "T" in bmgtrack[:bmgtrack.find("=")]:
|
||||||
sTid = bmgtrack.find("T")
|
sTid = bmgtrack.find("T")
|
||||||
Tid = bmgtrack[sTid:sTid + 3]
|
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:]
|
Tid = hex(bmgID_track_move[Tid])[2:]
|
||||||
|
|
||||||
else: # Arena
|
else: # Arena
|
||||||
|
@ -165,7 +86,8 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
|
||||||
os.remove("./file/tmp/Common.bmg")
|
os.remove("./file/tmp/Common.bmg")
|
||||||
os.remove("./file/ExtraCommon.txt")
|
os.remove("./file/ExtraCommon.txt")
|
||||||
|
|
||||||
def finalise(file, bmgtext, replacement_list):
|
def finalise(file, bmgtext, replacement_list=None):
|
||||||
|
if replacement_list:
|
||||||
for text, colored_text in replacement_list.items(): bmgtext = bmgtext.replace(text, colored_text)
|
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)
|
with open(file, "w", encoding="utf-8") as f: f.write(bmgtext)
|
||||||
subprocess.run(["./tools/szs/wbmgt", "ENCODE", get_nodir(file), "--overwrite"],
|
subprocess.run(["./tools/szs/wbmgt", "ENCODE", get_nodir(file), "--overwrite"],
|
||||||
|
@ -173,8 +95,8 @@ def patch_bmg(self, gamefile): # gamefile est le fichier .szs trouvé dans le /
|
||||||
os.remove(file)
|
os.remove(file)
|
||||||
|
|
||||||
finalise(f"./file/Menu_{bmglang}.txt", bmgmenu, menu_replacement)
|
finalise(f"./file/Menu_{bmglang}.txt", bmgmenu, menu_replacement)
|
||||||
finalise(f"./file/Common_{bmglang}.txt", bmgcommon, trackname_color)
|
finalise(f"./file/Common_{bmglang}.txt", bmgcommon)
|
||||||
finalise(f"./file/Common_R{bmglang}.txt", rbmgcommon, trackname_color)
|
finalise(f"./file/Common_R{bmglang}.txt", rbmgcommon)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
self.log_error()
|
self.log_error()
|
||||||
|
|
|
@ -30,9 +30,9 @@ def patch_ct_icon(self):
|
||||||
draw.text((4, 4), "CT", (255, 165, 0), font=font)
|
draw.text((4, 4), "CT", (255, 165, 0), font=font)
|
||||||
|
|
||||||
font = ImageFont.truetype("./file/SuperMario256.ttf", 60)
|
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) # i-10 because first 8 cup are not
|
||||||
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) # counted as new, random cup,
|
||||||
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) # left and right arrow
|
||||||
draw.text((5 + 2, 80 + 2), "%03i" % (i-10), (0, 0, 0), font=font)
|
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)
|
draw.text((5, 80), "%03i" % (i-10), (255, 165, 0), font=font)
|
||||||
|
|
|
@ -9,24 +9,23 @@ def patch_file(self):
|
||||||
try:
|
try:
|
||||||
if not(os.path.exists("./file/Track-WU8/")): os.makedirs("./file/Track-WU8/")
|
if not(os.path.exists("./file/Track-WU8/")): os.makedirs("./file/Track-WU8/")
|
||||||
with open("./convert_file.json") as f: fc = json.load(f)
|
with open("./convert_file.json") as f: fc = json.load(f)
|
||||||
tracks, total_track = self.count_track()
|
max_step = len(fc["img"]) + self.TOTAL_TRACK + 3 + len("EGFIS")
|
||||||
max_step = len(fc["img"]) + total_track + 3 + len("EGFIS")
|
|
||||||
|
|
||||||
self.Progress(show=True, indeter=False, statut=self.translate("Conversion des fichiers"), max=max_step, step=0)
|
self.Progress(show=True, indeter=False, statut=self.translate("Converting files"), max=max_step, step=0)
|
||||||
self.Progress(statut=self.translate("Configuration de LE-CODE"), add=1)
|
self.Progress(statut=self.translate("Configurating LE-CODE"), add=1)
|
||||||
self.create_lecode_config()
|
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.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_img_desc()
|
||||||
self.patch_image(fc)
|
self.patch_image(fc)
|
||||||
for file in glob.glob(self.path_mkwf+"/files/Scene/UI/MenuSingle_?.szs"): self.patch_bmg(file)
|
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.
|
# MenuSingle could be any other file, Common and Menu are all the same in all other files.
|
||||||
self.patch_autoadd()
|
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.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()
|
except: self.log_error()
|
||||||
finally: self.Progress(show=False)
|
finally: self.Progress(show=False)
|
||||||
|
|
|
@ -4,6 +4,6 @@ import subprocess
|
||||||
|
|
||||||
def patch_image(self, fc):
|
def patch_image(self, fc):
|
||||||
for i, file in enumerate(fc["img"]):
|
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"],
|
subprocess.run(["./tools/szs/wimgt", "ENCODE", "./file/" + file, "-x", fc["img"][file], "--overwrite"],
|
||||||
creationflags=CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE)
|
creationflags=CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE)
|
||||||
|
|
|
@ -6,16 +6,54 @@ import json
|
||||||
import os
|
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 = []
|
tracks = []
|
||||||
with open("./ct_config.json", encoding="utf-8") as f: ctconfig = json.load(f)
|
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())
|
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}]
|
tracks.extend(ctconfig["tracks_list"]) # unordered tracks
|
||||||
total_track = len(tracks)
|
|
||||||
return tracks, total_track
|
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):
|
def patch_autoadd(self):
|
||||||
|
@ -29,19 +67,18 @@ def patch_autoadd(self):
|
||||||
shutil.rmtree(self.path_mkwf + "/tmp/")
|
shutil.rmtree(self.path_mkwf + "/tmp/")
|
||||||
|
|
||||||
|
|
||||||
def patch_track(self, tracks, total_track="?"):
|
def patch_track(self):
|
||||||
max_process = self.intvar_process_track.get()
|
max_process = self.intvar_process_track.get()
|
||||||
process_list = {}
|
process_list = {}
|
||||||
error_count, error_max = 0, 3
|
error_count, error_max = 0, 3
|
||||||
|
|
||||||
|
|
||||||
def add_process(track):
|
def add_process(track):
|
||||||
track_file = get_trackname(track=track)
|
track_file = self.get_trackname(track=track)
|
||||||
nonlocal error_count, error_max, process_list
|
nonlocal error_count, error_max, process_list
|
||||||
|
|
||||||
process_list[track_file] = None # Used for
|
process_list[track_file] = None # Used for
|
||||||
self.Progress(statut=self.translate("Conversion des courses") + f"\n({i + 1}/{total_track})\n" +
|
self.Progress(statut=self.translate("Converting tracks", f"\n({i + 1}/{self.TOTAL_TRACK})\n",
|
||||||
"\n".join(process_list.keys()), add=1)
|
"\n".join(process_list.keys())), add=1)
|
||||||
|
|
||||||
for _track in [get_track_szs(track_file), get_track_wu8(track_file)]:
|
for _track in [get_track_szs(track_file), get_track_wu8(track_file)]:
|
||||||
if os.path.exists(_track):
|
if os.path.exists(_track):
|
||||||
|
@ -54,14 +91,14 @@ def patch_track(self, tracks, total_track="?"):
|
||||||
error_count += 1
|
error_count += 1
|
||||||
if error_count > error_max: # Too much track wasn't correctly converted
|
if error_count > error_max: # Too much track wasn't correctly converted
|
||||||
messagebox.showerror(
|
messagebox.showerror(
|
||||||
self.translate("Erreur"),
|
self.translate("Error"),
|
||||||
self.translate("Trop de course ont eu une erreur du téléchargement."))
|
self.translate("Too much tracks had a download issue."))
|
||||||
return -1
|
return -1
|
||||||
else:
|
else:
|
||||||
messagebox.showwarning(self.translate("Attention"),
|
messagebox.showwarning(self.translate("Warning"),
|
||||||
self.translate("Impossible de télécharger cette course ! (") +
|
self.translate("Can't download this track !",
|
||||||
str(error_count) + "/" + str(error_max) + ")")
|
f" ({error_count} / {error_max})"))
|
||||||
elif download_returncode == 2: break # Si le téléchargement est désactivé, ne pas checker le sha1
|
elif download_returncode == 2: break # if download is disabled, don't check sha1
|
||||||
|
|
||||||
if "sha1" in track:
|
if "sha1" in track:
|
||||||
if not self.boolvar_dont_check_track_sha1.get():
|
if not self.boolvar_dont_check_track_sha1.get():
|
||||||
|
@ -69,8 +106,8 @@ def patch_track(self, tracks, total_track="?"):
|
||||||
error_count += 1
|
error_count += 1
|
||||||
if error_count > error_max: # Too much track wasn't correctly converted
|
if error_count > error_max: # Too much track wasn't correctly converted
|
||||||
messagebox.showerror(
|
messagebox.showerror(
|
||||||
self.translate("Erreur"),
|
self.translate("Error"),
|
||||||
self.translate("Trop de course ont eu une erreur de vérification de sha1."))
|
self.translate("Too much tracks had an issue during sha1 check."))
|
||||||
return -1
|
return -1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -84,9 +121,8 @@ def patch_track(self, tracks, total_track="?"):
|
||||||
"./file/Track/%N.szs", "--szs", "--overwrite", "--autoadd-path",
|
"./file/Track/%N.szs", "--szs", "--overwrite", "--autoadd-path",
|
||||||
"./file/auto-add/"], creationflags=CREATE_NO_WINDOW, stderr=subprocess.PIPE)
|
"./file/auto-add/"], creationflags=CREATE_NO_WINDOW, stderr=subprocess.PIPE)
|
||||||
else:
|
else:
|
||||||
messagebox.showerror(self.translate("Erreur"),
|
messagebox.showerror(self.translate("Error"),
|
||||||
self.translate("Impossible de convertir la course.\n"
|
self.translate("Can't convert track.\nEnable track download and retry."))
|
||||||
"Réactiver le téléchargement des courses et réessayer."))
|
|
||||||
return -1
|
return -1
|
||||||
elif self.boolvar_del_track_after_conv.get(): os.remove(get_track_wu8(track_file))
|
elif self.boolvar_del_track_after_conv.get(): os.remove(get_track_wu8(track_file))
|
||||||
return 0
|
return 0
|
||||||
|
@ -106,16 +142,15 @@ def patch_track(self, tracks, total_track="?"):
|
||||||
error_count += 1
|
error_count += 1
|
||||||
if error_count > error_max: # Too much track wasn't correctly converted
|
if error_count > error_max: # Too much track wasn't correctly converted
|
||||||
messagebox.showerror(
|
messagebox.showerror(
|
||||||
self.translate("Erreur"),
|
self.translate("Error"),
|
||||||
self.translate("Trop de course ont eu une erreur de conversion."))
|
self.translate("Too much track had a conversion issue."))
|
||||||
return -1
|
return -1
|
||||||
else: # if the error max hasn't been reach
|
else: # if the error max hasn't been reach
|
||||||
messagebox.showwarning(
|
messagebox.showwarning(
|
||||||
self.translate("Attention"),
|
self.translate("Warning"),
|
||||||
self.translate("La course ") +
|
self.translate("The track", " ", get_track_wu8(track_file),
|
||||||
get_track_wu8(track_file) +
|
"do not have been properly converted.",
|
||||||
self.translate(" n'a pas été correctement converti. (") +
|
f" ({error_count} / {error_max})"))
|
||||||
str(error_count) + "/" + str(error_max) + ")")
|
|
||||||
else:
|
else:
|
||||||
if self.boolvar_del_track_after_conv.get(): os.remove(get_track_wu8(track_file))
|
if self.boolvar_del_track_after_conv.get(): os.remove(get_track_wu8(track_file))
|
||||||
else:
|
else:
|
||||||
|
@ -125,7 +160,7 @@ def patch_track(self, tracks, total_track="?"):
|
||||||
if len(process_list): return 1
|
if len(process_list): return 1
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
for i, track in enumerate(tracks):
|
for i, track in enumerate(self.TRACKS):
|
||||||
while True:
|
while True:
|
||||||
if len(process_list) < max_process:
|
if len(process_list) < max_process:
|
||||||
returncode = add_process(track)
|
returncode = add_process(track)
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import json
|
from .definition import translation_dict
|
||||||
|
|
||||||
|
|
||||||
def translate(self, text, lang = None):
|
def translate(self, *texts, lang=None):
|
||||||
if lang == None: lang = self.stringvar_language.get()
|
if lang is None: lang = self.stringvar_language.get()
|
||||||
elif lang == "E": lang = "en"
|
elif lang == "F": lang = "fr"
|
||||||
elif lang == "G": lang = "ge"
|
elif lang == "G": lang = "ge"
|
||||||
elif lang == "I": lang = "it"
|
elif lang == "I": lang = "it"
|
||||||
elif lang == "S": lang = "sp"
|
elif lang == "S": lang = "sp"
|
||||||
|
|
||||||
with open("./translation.json", encoding="utf-8") as f:
|
if lang in translation_dict:
|
||||||
translation = json.load(f)
|
_lang_trad = translation_dict[lang]
|
||||||
if lang in translation:
|
translated_text = ""
|
||||||
_lang_trad = translation[lang]
|
for text in texts:
|
||||||
if text in _lang_trad: return _lang_trad[text]
|
if text in _lang_trad: translated_text += _lang_trad[text]
|
||||||
else:
|
else: translated_text += text
|
||||||
print(f"no translation for : \"{text}\"")
|
return translated_text
|
||||||
return text
|
|
||||||
|
return "".join(texts) # if no translation language is found
|
||||||
|
|
||||||
|
|
||||||
|
|
153
translation.json
153
translation.json
|
@ -1,87 +1,90 @@
|
||||||
{
|
{
|
||||||
"en": {
|
"fr": {
|
||||||
"Ne pas vérifier le sha1 des courses": "Don't check for track's sha1",
|
"MKWFaraphel Installer": "MKWFaraphel Installateur",
|
||||||
"Impossible de se connecter à internet. Le téléchargement sera automatiquement désactivé.": "Can't connect to internet, download will automatically be disabled.",
|
"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 main.dol": "Patch main.dol",
|
||||||
"Patch lecode.bin": "Patch lecode.bin",
|
"Patch lecode.bin": "Patch lecode.bin",
|
||||||
"Installation du mod": "Installing mod",
|
"Converting to": "Conversion en",
|
||||||
"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.",
|
"Changing game's ID": "Changement de l'ID du jeu",
|
||||||
"Langage": "Language",
|
"End": "Fin",
|
||||||
"Format": "Format",
|
"The mod has been installed !": "L'installation est terminé !",
|
||||||
"FST (Dossier)": "FST (Directory)",
|
"An error occured": "Une erreur est survenue",
|
||||||
"Avancé": "Advanced",
|
"Patching text": "Patch des textes",
|
||||||
"Désactiver les téléchargements": "Disable downloads",
|
"Random: All tracks": "Aléatoire: Toutes les pistes",
|
||||||
"Supprimer les courses wu8 après conversion en szs": "Delete wu8 track after conversion to szs",
|
"Random: Original tracks": "Aléatoire: Pistes Originales",
|
||||||
"Ne pas vérifier les mises à jour": "Don't check for update",
|
"Random: Custom Tracks": "Aléatoire: Custom Tracks",
|
||||||
"Nombre de processus de conversion de course :": "Number of process for track conversion :",
|
"Random: New tracks": "Aléatoire: Pistes Nouvelles",
|
||||||
"1 processus": "1 process",
|
"Converting files": "Conversion des fichiers",
|
||||||
"2 processus": "2 process",
|
"Configurating LE-CODE": "Configuration de LE-CODE",
|
||||||
"4 processus": "4 process",
|
"Creating ct_icon.png": "Création de ct_icon.png",
|
||||||
"8 processus": "8 process",
|
"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",
|
"La course": "The track",
|
||||||
" n'a pas été correctement converti. (": "hasn't been correctly converted. (",
|
"do not have been properly converted.": "n'a pas été correctement converti.",
|
||||||
"Trop de course ont eu une erreur de conversion.": "Too much track had a conversion issue.",
|
"Track selection": "Sélection de course",
|
||||||
"Une erreur est survenue :": "An error occured :",
|
"Select": "Sélectionner",
|
||||||
"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 ?",
|
"star": "étoile",
|
||||||
"Fonctionnalité expérimentale": "Experimental functionality",
|
"stars": "étoiles",
|
||||||
"Tout faire": "Do everything",
|
"Mark all tracks from version": "Marquer toutes les courses de la version",
|
||||||
"Création des images descriptives": "Creation of descriptive images",
|
"None": "Aucune"
|
||||||
"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"
|
|
||||||
},
|
},
|
||||||
"ge": {
|
"ge": {
|
||||||
"Aléatoire: Toutes les pistes": "Zufällig: Alle Spuren",
|
"Random: All tracks": "Zufällig: Alle Spuren",
|
||||||
"Aléatoire: Pistes Originales": "Zufällig: Original-Spuren",
|
"Random: Original tracks": "Zufällig: Original-Spuren",
|
||||||
"Aléatoire: Custom Tracks": "Zufällig: Custom Tracks",
|
"Random: Custom Tracks": "Zufällig: Custom Tracks",
|
||||||
"Aléatoire: Pistes Nouvelles": "Zufällig: Neue Spuren"
|
"Random: New tracks": "Zufällig: Neue Spuren"
|
||||||
},
|
},
|
||||||
"it": {
|
"it": {
|
||||||
"Aléatoire: Toutes les pistes": "Casuale: Tutte le tracce",
|
"Random: All tracks": "Casuale: Tutte le tracce",
|
||||||
"Aléatoire: Pistes Originales": "Casuale: Tracce originali",
|
"Random: Original tracks": "Casuale: Tracce originali",
|
||||||
"Aléatoire: Custom Tracks": "Casuale: Custom Tracks",
|
"Random: Custom Tracks": "Casuale: Custom Tracks",
|
||||||
"Aléatoire: Pistes Nouvelles": "Casuale: Nuovi brani"
|
"Random: New tracks": "Casuale: Nuovi brani"
|
||||||
},
|
},
|
||||||
"sp": {
|
"sp": {
|
||||||
"Aléatoire: Toutes les pistes": "Aleatorio: Todas las pistas",
|
"Random: All tracks": "Aleatorio: Todas las pistas",
|
||||||
"Aléatoire: Pistes Originales": "Aleatorio: Pistas originales",
|
"Random: Original tracks": "Aleatorio: Pistas originales",
|
||||||
"Aléatoire: Custom Tracks": "Aleatorio: Custom Tracks",
|
"Random: Custom Tracks": "Aleatorio: Custom Tracks",
|
||||||
"Aléatoire: Pistes Nouvelles": "Aleatorio: Pistas nuevas"
|
"Random: New tracks": "Aleatorio: Pistas nuevas"
|
||||||
}
|
}
|
||||||
}
|
}
|
6
version
6
version
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"version": "0.8",
|
"version": "0.9",
|
||||||
"subversion": "0",
|
"subversion": "0",
|
||||||
"changelog": "",
|
"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.8/MKWF.v0.8.zip",
|
"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"
|
"updater_bin": "https://github.com/Faraphel/MKWF-Install/raw/master/Updater/Updater.zip"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue