Merge pull request #13 from Faraphel/dev

v0.6
This commit is contained in:
Faraphel 2021-06-16 01:14:37 +02:00 committed by GitHub
commit 4f57e99508
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 448 additions and 381 deletions

1
.gitignore vendored
View file

@ -87,3 +87,4 @@
/build/ /build/
/test/ /test/
/distribution.txt /distribution.txt
/error.log

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 88 KiB

BIN
file/lecode-JAP.bin Normal file

Binary file not shown.

BIN
file/lecode-KOR.bin Normal file

Binary file not shown.

BIN
file/lecode-USA.bin Normal file

Binary file not shown.

View file

@ -3,6 +3,7 @@ from PIL import Image, ImageFont, ImageDraw
from tkinter import messagebox, filedialog, ttk from tkinter import messagebox, filedialog, ttk
from threading import Thread from threading import Thread
import subprocess import subprocess
import traceback
import requests import requests
import zipfile import zipfile
import shutil import shutil
@ -26,6 +27,7 @@ class ClassApp():
from source.restart import restart from source.restart import restart
from source.patch_img_desc import patch_img_desc from source.patch_img_desc import patch_img_desc
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
App = ClassApp() App = ClassApp()

View file

@ -49,8 +49,9 @@ options = {
"build_exe": { "build_exe": {
"include_files": include_files, "include_files": include_files,
"includes": ["tkinter", "requests"], "includes": ["tkinter", "requests"],
"include_msvcr": True,
"packages": [], "packages": [],
"excludes": [] "excludes": [],
} }
} }

View file

@ -9,123 +9,133 @@ from .check_update import check_update
from .translate import translate from .translate import translate
def __init__(self): def __init__(self):
self.language = self.get_language() try:
self.language = self.get_language()
self.root = Tk() self.root = Tk()
self.root.title(self.translate("MKWFaraphel Installateur")) self.root.title(self.translate("MKWFaraphel Installateur"))
self.root.resizable(False, False) self.root.resizable(False, False)
self.root.iconbitmap(bitmap="./icon.ico") self.root.iconbitmap(bitmap="./icon.ico")
self.check_update() self.check_update()
self.path_mkwf = None self.path_mkwf = None
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")
Label(self.frame_language, text=self.translate("Langage : ")).grid(row=1, column=1) Label(self.frame_language, text=self.translate("Langage : ")).grid(row=1, column=1)
self.listbox_language = ttk.Combobox(self.frame_language, values=["fr", "en"], width=5) self.listbox_language = ttk.Combobox(self.frame_language, values=["fr", "en"], width=5)
self.listbox_language.set(self.language) self.listbox_language.set(self.language)
self.listbox_language.grid(row=1, column=2) self.listbox_language.grid(row=1, column=2)
self.listbox_language.bind("<<ComboboxSelected>>", lambda x: self.change_language()) self.listbox_language.bind("<<ComboboxSelected>>", lambda x: self.change_language())
self.frame_game_path = LabelFrame(self.root, text=self.translate("Jeu original")) self.frame_game_path = LabelFrame(self.root, text=self.translate("Jeu original"))
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("Jeu Wii"),
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)
entry_game_path.insert(0, path) entry_game_path.insert(0, path)
Button(self.frame_game_path, text="...", relief=RIDGE, command=select_path).grid(row=1, column=2, sticky="NEWS") Button(self.frame_game_path, text="...", relief=RIDGE, command=select_path).grid(row=1, column=2, sticky="NEWS")
self.frame_game_path_action = Frame(self.frame_game_path) # Action Extraire & Tout faire self.frame_game_path_action = Frame(self.frame_game_path) # Action Extraire & Tout faire
self.frame_game_path_action.grid(row=2, column=1, columnspan=2, sticky="NEWS") self.frame_game_path_action.grid(row=2, column=1, columnspan=2, sticky="NEWS")
self.frame_game_path_action.columnconfigure(1, weight=1) self.frame_game_path_action.columnconfigure(1, weight=1)
def use_path(): def use_path():
def func(): def func():
self.frame_action.grid_forget() try:
path = entry_game_path.get() self.frame_action.grid_forget()
if not (os.path.exists(path)): path = entry_game_path.get()
messagebox.showerror(self.translate("Erreur"), self.translate("Le chemin de fichier est invalide")) if not (os.path.exists(path)):
return messagebox.showerror(self.translate("Erreur"), self.translate("Le chemin de fichier est invalide"))
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("Attention"),
self.translate("Ce dossier sera écrasé si vous installer le mod !\n" + self.translate("Ce dossier sera écrasé si vous installer le mod !\n" +
"Êtes-vous sûr de vouloir l'utiliser ?")): "Êtes-vous sûr de vouloir l'utiliser ?")):
self.path_mkwf = os.path.realpath(path + "/../../") self.path_mkwf = os.path.realpath(path + "/../../")
elif extension.upper() in ["ISO", "WBFS", "WIA", "CSIO"]: elif extension.upper() in ["ISO", "WBFS", "WIA", "CSIO"]:
self.path_mkwf, i = os.path.realpath(path + "/../MKWiiFaraphel"), 1 # Fiding a directory name that dosen't already exist
directory_name, i = "MKWiiFaraphel", 1
while True:
self.path_mkwf = os.path.realpath(path + f"/../{directory_name}")
if not(os.path.exists(self.path_mkwf)): break
directory_name, i = f"MKWiiFaraphel ({i})", i + 1
while True: if os.path.exists(self.path_mkwf + "/DATA/"): self.path_mkwf += "/DATA/"
if not (os.path.exists(self.path_mkwf)): break
self.path_mkwf, i = os.path.realpath(path + 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("Extraction du jeu..."))
subprocess.call(["./tools/wit/wit", "EXTRACT", path, "--DEST", self.path_mkwf] subprocess.call(["./tools/wit/wit", "EXTRACT", get_nodir(path), "--DEST", directory_name]
, creationflags=CREATE_NO_WINDOW) , creationflags=CREATE_NO_WINDOW, cwd=get_dir(path))
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("Erreur"), self.translate("Le type de fichier n'est pas reconnu"))
self.Progress(show=False) self.Progress(show=False)
return return
if os.path.exists(self.path_mkwf + "/files/rel/lecode-PAL.bin"): if os.path.exists(self.path_mkwf + "/files/rel/lecode-PAL.bin"):
messagebox.showwarning(self.translate("Attention"), messagebox.showwarning(self.translate("Attention"),
self.translate("Cette ROM est déjà moddé, " + self.translate("Cette ROM est déjà moddé, " +
"il est déconseillé de l'utiliser pour installer le mod")) "il est déconseillé de l'utiliser pour installer le mod"))
self.frame_action.grid(row=3, column=1, sticky="NEWS") except: self.log_error()
self.Progress(show=False) finally:
self.frame_action.grid(row=3, column=1, sticky="NEWS")
self.Progress(show=False)
t = Thread(target=func)
t.setDaemon(True)
t.start()
return t
self.button_game_extract = Button(self.frame_game_path_action, text=self.translate("Extraire le fichier"),
relief=RIDGE, command=use_path)
self.button_game_extract.grid(row=1, column=1, sticky="NEWS")
def do_everything():
def func():
use_path().join()
self.patch_file().join()
self.install_mod().join()
if messagebox.askyesno(self.translate("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 ?")):
t = Thread(target=func) t = Thread(target=func)
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()
return t
self.button_do_everything = Button(self.frame_game_path_action, text=self.translate("Tout faire"), self.button_game_extract = Button(self.frame_game_path_action, text=self.translate("Extraire le fichier"),
relief=RIDGE, command=do_everything) relief=RIDGE, command=use_path)
self.button_do_everything.grid(row=1, column=2, sticky="NEWS") self.button_game_extract.grid(row=1, column=1, sticky="NEWS")
def do_everything():
def func():
use_path().join()
self.patch_file().join()
self.install_mod().join()
if messagebox.askyesno(self.translate("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 ?")):
t = Thread(target=func)
t.setDaemon(True)
t.start()
self.button_do_everything = Button(self.frame_game_path_action, text=self.translate("Tout faire"),
relief=RIDGE, command=do_everything)
self.button_do_everything.grid(row=1, column=2, sticky="NEWS")
self.frame_action = LabelFrame(self.root, text=self.translate("Action")) self.frame_action = LabelFrame(self.root, text=self.translate("Action"))
self.button_prepare_file = Button(self.frame_action, text=self.translate("Preparer les fichiers"), relief=RIDGE, self.button_prepare_file = Button(self.frame_action, text=self.translate("Preparer les fichiers"), 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("Installer le mod"), relief=RIDGE,
command=self.install_mod, width=35) command=self.install_mod, width=35)
self.listbox_outputformat = ttk.Combobox(self.frame_action, values=[self.translate("Dossier"), self.listbox_outputformat = ttk.Combobox(self.frame_action, values=[self.translate("Dossier"),
"ISO", "WBFS", "CISO"], width=5) "ISO", "WBFS", "CISO"], width=5)
self.listbox_outputformat.set(self.translate("Dossier")) self.listbox_outputformat.set(self.translate("Dossier"))
# Le boutton d'installation du mod n'est affiché qu'après avoir préparer les fichiers # Le boutton d'installation du mod n'est affiché qu'après avoir préparer les fichiers
self.progressbar = ttk.Progressbar(self.root) self.progressbar = ttk.Progressbar(self.root)
self.progresslabel = Label(self.root) self.progresslabel = Label(self.root)
except:
self.log_error()

View file

@ -6,13 +6,17 @@ import sys
import os import os
VERSION_FILE_URL = "https://raw.githubusercontent.com/Faraphel/MKWF-Install/master/version" VERSION_FILE_URL = "https://raw.githubusercontent.com/Faraphel/MKWF-Install/master/version"
def check_update(self): def check_update(self):
try: try:
gitversion = requests.get(VERSION_FILE_URL, allow_redirects=True).json() gitversion = requests.get(VERSION_FILE_URL, allow_redirects=True).json()
with open("version", "rb") as f: with open("./version", "rb") as f:
locversion = json.load(f) locversion = json.load(f)
if float(gitversion["version"]) > float(locversion["version"]): if ((float(gitversion["version"]) > float(locversion["version"])) or
(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 ?") + 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"\n\nVersion : {locversion['version']}.{locversion['subversion']} -> {gitversion['version']}.{gitversion['subversion']}\n"+\
f"Changelog :\n{gitversion['changelog']}"): f"Changelog :\n{gitversion['changelog']}"):
@ -34,5 +38,5 @@ def check_update(self):
os.startfile(os.path.realpath("./Updater/Updater.exe")) os.startfile(os.path.realpath("./Updater/Updater.exe"))
sys.exit() sys.exit()
except Exception as e: except:
print(e) self.log_error()

View file

@ -2,73 +2,77 @@ import json
def create_lecode_config(self): def create_lecode_config(self):
def get_star_text(track): try:
if "warning" in track: warning = "!" * track["warning"] def get_star_text(track):
else: warning = "" if "warning" in track: warning = "!" * track["warning"]
else: warning = ""
if "score" in track: if "score" in track:
if track["score"] > 0: if track["score"] > 0:
return "" * track["score"] + "" * (3 - track["score"]) + warning + " " return "" * track["score"] + "" * (3 - track["score"]) + warning + " "
return "" return ""
def get_ctfile_text(track, race=False): def get_ctfile_text(track, race=False):
track_name = track["name"].replace("_", "") track_name = track["name"].replace("_", "")
if "prefix" in track: prefix = f"{track['prefix']} " if "prefix" in track: prefix = f"{track['prefix']} "
else: prefix = "" else: prefix = ""
if "suffix" in track: suffix = f" ({track['suffix']})" if "suffix" in track: suffix = f" ({track['suffix']})"
else: suffix = "" else: suffix = ""
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)}{prefix}{track_name}{suffix}\\n{track["author"]}"; ' + \ f'"{get_star_text(track)}{prefix}{track_name}{suffix}\\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'"{prefix}{track["name"]}{suffix}"; ' + \ f'"{prefix}{track["name"]}{suffix}"; ' + \
f'"{get_star_text(track)}{prefix}{track_name}{suffix}"; ' + \ f'"{get_star_text(track)}{prefix}{track_name}{suffix}"; ' + \
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)
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: # Course qui ne sont ni les originales, ni les courses aléatoires.
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)
for course in _cup_config["courses"]: for course in _cup_config["courses"]:
_course_config = _cup_config["courses"][course] _course_config = _cup_config["courses"][course]
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 for i, _course_config in enumerate(ctconfig["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)
rctfile.write(cup) rctfile.write(cup)
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 _ 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(f' T T44; T44; 0x00; "_"; ""; "-"\n')
rctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n') rctfile.write(f' T T44; T44; 0x00; "_"; ""; "-"\n')
except:
self.log_error()

View file

@ -1,9 +1,10 @@
get_filename = lambda file: ".".join(file.split(".")[:-1]) get_filename = lambda file: ".".join(file.split(".")[:-1])
get_nodir = lambda file: file.split("/")[-1].split("\\")[-1] get_nodir = lambda file: file.replace("\\", "/").split("/")[-1]
get_dir = lambda file: "/".join(file.replace("\\", "/").split("/")[:-1])
get_extension = lambda file: file.split(".")[-1] get_extension = lambda file: file.split(".")[-1]
CREATE_NO_WINDOW = 0x08000000 CREATE_NO_WINDOW = 0x08000000
VERSION = "0.8" VERSION = "0.8.1"
def filecopy(src, dst): def filecopy(src, dst):
with open(src, "rb") as f1: with open(src, "rb") as f1:

View file

@ -11,104 +11,120 @@ from .definition import *
def install_mod(self): def install_mod(self):
def func(): def func():
with open("./fs.json") as f: try:
fs = json.load(f) with open("./fs.json") as f:
fs = json.load(f)
# This part is used to estimate the max_step # This part is used to estimate the max_step
extracted_file = [] extracted_file = []
max_step, step = 1, 0 max_step, step = 1, 0
def count_rf(path): def count_rf(path):
nonlocal max_step nonlocal max_step
max_step += 1 max_step += 1
extension = get_extension(path) extension = get_extension(path)
if extension == "szs": if extension == "szs":
if not (os.path.realpath(path) in extracted_file): if not (os.path.realpath(path) in extracted_file):
extracted_file.append(os.path.realpath(path)) extracted_file.append(os.path.realpath(path))
max_step += 1 max_step += 1
for fp in fs: for fp in fs:
for f in glob.glob(self.path_mkwf + "/files/" + fp, recursive=True): for f in glob.glob(self.path_mkwf + "/files/" + fp, recursive=True):
if type(fs[fp]) == str: if type(fs[fp]) == str:
count_rf(path=f) count_rf(path=f)
elif type(fs[fp]) == dict: elif type(fs[fp]) == dict:
for nf in fs[fp]: for nf in fs[fp]:
if type(fs[fp][nf]) == str: if type(fs[fp][nf]) == str:
count_rf(path=f) count_rf(path=f)
elif type(fs[fp][nf]) == list: elif type(fs[fp][nf]) == list:
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 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) self.Progress(show=True, indeter=False, statut=self.translate("Installation du 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("Modification de")+f"\n{get_nodir(path)}", add=1)
extension = get_extension(path) extension = get_extension(path)
if extension == "szs": if extension == "szs":
if not (os.path.realpath(path) in extracted_file): if not (os.path.realpath(path) in extracted_file):
subprocess.call(["./tools/szs/wszst", "EXTRACT", path, "-d", path + ".d", "--overwrite"] subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(path), "-d", get_nodir(path) + ".d",
, creationflags=CREATE_NO_WINDOW) "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(path),
extracted_file.append(os.path.realpath(path)) check=True, stdout=subprocess.PIPE)
extracted_file.append(os.path.realpath(path))
szs_extract_path = path + ".d" szs_extract_path = path + ".d"
if os.path.exists(szs_extract_path + subpath): if os.path.exists(szs_extract_path + subpath):
if subpath[-1] == "/": if subpath[-1] == "/":
filecopy(f"./file/{file}", szs_extract_path + subpath + file) filecopy(f"./file/{file}", szs_extract_path + subpath + file)
else: else:
filecopy(f"./file/{file}", szs_extract_path + subpath) filecopy(f"./file/{file}", szs_extract_path + subpath)
elif path[-1] == "/": elif path[-1] == "/":
filecopy(f"./file/{file}", path + file) filecopy(f"./file/{file}", path + file)
else: else:
filecopy(f"./file/{file}", path) filecopy(f"./file/{file}", path)
for fp in fs: for fp in fs:
for f in glob.glob(self.path_mkwf + "/files/" + fp, recursive=True): for f in glob.glob(self.path_mkwf + "/files/" + fp, recursive=True):
if type(fs[fp]) == str: if type(fs[fp]) == str:
replace_file(path=f, file=fs[fp]) replace_file(path=f, file=fs[fp])
elif type(fs[fp]) == dict: elif type(fs[fp]) == dict:
for nf in fs[fp]: for nf in fs[fp]:
if type(fs[fp][nf]) == str: if type(fs[fp][nf]) == str:
replace_file(path=f, subpath=nf, file=fs[fp][nf]) replace_file(path=f, subpath=nf, file=fs[fp][nf])
elif type(fs[fp][nf]) == list: elif type(fs[fp][nf]) == list:
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("Recompilation de")+f"\n{get_nodir(file)}", add=1)
subprocess.call(["./tools/szs/wszst", "CREATE", file + ".d", "-d", file, subprocess.run(["./tools/szs/wszst", "CREATE", get_nodir(file) + ".d", "-d", get_nodir(file),
"--overwrite"], creationflags=CREATE_NO_WINDOW) "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(file),
if os.path.exists(file + ".d"): shutil.rmtree(file + ".d") check=True, stdout=subprocess.PIPE)
if os.path.exists(file + ".d"): shutil.rmtree(file + ".d")
self.Progress(statut=self.translate("Patch main.dol"), add=1) self.Progress(statut=self.translate("Patch main.dol"), add=1)
subprocess.call(["./tools/szs/wstrt", "patch", self.path_mkwf + "/sys/main.dol", "--clean-dol", subprocess.run(["./tools/szs/wstrt", "patch", get_nodir(self.path_mkwf) + "/sys/main.dol", "--clean-dol",
"--add-lecode"], creationflags=CREATE_NO_WINDOW) "--add-lecode"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(self.path_mkwf),
check=True, stdout=subprocess.PIPE)
self.Progress(statut=self.translate("Patch lecode-PAL.bin"), add=1) self.Progress(statut=self.translate("Patch lecode-PAL.bin"), add=1)
subprocess.call( shutil.copytree("./file/Track/", self.path_mkwf+"/files/Race/Course/", dirs_exist_ok=True)
["./tools/szs/wlect", "patch", "./file/lecode-PAL.bin", "-od", self.path_mkwf + "/files/rel/lecode-PAL.bin", if not(os.path.exists(self.path_mkwf+"/tmp/")): os.makedirs(self.path_mkwf+"/tmp/")
"--track-dir", self.path_mkwf + "/files/Race/Course/", "--copy-tracks", "./file/Track/", filecopy("./file/CTFILE.txt", self.path_mkwf+"/tmp/CTFILE.txt")
"--move-tracks", self.path_mkwf + "/files/Race/Course/", "--le-define", filecopy("./file/lpar-default.txt", self.path_mkwf + "/tmp/lpar-default.txt")
"./file/CTFILE.txt", "--lpar", "./file/lpar-default.txt", "--overwrite"], creationflags=CREATE_NO_WINDOW) filecopy("./file/lecode-PAL.bin", self.path_mkwf + "/tmp/lecode-PAL.bin")
outputformat = self.listbox_outputformat.get() subprocess.run(
self.Progress(statut=self.translate("Conversion en")+f" {outputformat}", add=1) ["./tools/szs/wlect", "patch", "./tmp/lecode-PAL.bin", "-od", "./files/rel/lecode-PAL.bin",
"--track-dir", "./files/Race/Course/", "--move-tracks", "./files/Race/Course/", "--le-define",
"./tmp/CTFILE.txt", "--lpar", "./tmp/lpar-default.txt", "--overwrite"],
creationflags=CREATE_NO_WINDOW, cwd=self.path_mkwf, check=True, stdout=subprocess.PIPE)
if outputformat in ["ISO", "WBFS", "CISO"]: shutil.rmtree(self.path_mkwf + "/tmp/")
self.path_mkwf_format = os.path.realpath(self.path_mkwf + "/../MKWFaraphel." + outputformat.lower())
subprocess.call(["./tools/wit/wit", "COPY", self.path_mkwf, "--DEST",
self.path_mkwf_format, f"--{outputformat.lower()}", "--overwrite"]
, creationflags=CREATE_NO_WINDOW)
shutil.rmtree(self.path_mkwf)
self.Progress(statut=self.translate("Changement de l'ID du jeu"), add=1) outputformat = self.listbox_outputformat.get()
subprocess.call(["./tools/wit/wit", "EDIT", self.path_mkwf_format, "--id", "RMCP60"] self.Progress(statut=self.translate("Conversion en")+f" {outputformat}", add=1)
, creationflags=CREATE_NO_WINDOW)
self.Progress(show=False) if outputformat in ["ISO", "WBFS", "CISO"]:
messagebox.showinfo(self.translate("Fin"), self.translate("L'installation est terminé !")) self.path_mkwf_format = os.path.realpath(self.path_mkwf + "/../MKWFaraphel." + outputformat.lower())
subprocess.run(["./tools/wit/wit", "COPY", get_nodir(self.path_mkwf), "--DEST",
get_nodir(self.path_mkwf_format), f"--{outputformat.lower()}", "--overwrite"],
CREATE_NO_WINDOW, cwd=get_dir(self.path_mkwf),
check=True, stdout=subprocess.PIPE)
shutil.rmtree(self.path_mkwf)
self.Progress(statut=self.translate("Changement de l'ID du jeu"), add=1)
subprocess.run(["./tools/wit/wit", "EDIT", get_dir(self.path_mkwf_format), "--id", "RMCP60"],
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é !"))
except: self.log_error()
finally: self.Progress(show=False)
t = Thread(target=func) t = Thread(target=func)
t.setDaemon(True) t.setDaemon(True)

7
source/log_error.py Normal file
View file

@ -0,0 +1,7 @@
import traceback
from tkinter import messagebox
def log_error(self):
error = traceback.format_exc()
with open("./error.log", "a") as f: f.write(f"---\n{error}\n")
messagebox.showerror(self.translate("Erreur"), self.translate("Une erreur est survenue :") + f"\n{error}\n\n")

View file

@ -84,63 +84,72 @@ trackname_color = {
"★☆☆!! ": "\c{YOR6}★☆☆\c{off} ", "★☆☆!! ": "\c{YOR6}★☆☆\c{off} ",
} }
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
bmglang = gamefile[-len("E.txt"):-len(".txt")] # Langue du fichier try:
self.Progress(statut=self.translate("Patch des textes " + bmglang), add=1) bmglang = gamefile[-len("E.txt"):-len(".txt")] # Langue du fichier
self.Progress(statut=self.translate("Patch des textes " + bmglang), add=1)
subprocess.call(["./tools/szs/wszst", "EXTRACT", gamefile, "-d", gamefile + ".d", "--overwrite"] subprocess.run(["./tools/szs/wszst", "EXTRACT", get_nodir(gamefile), "-d", get_nodir(gamefile) + ".d",
, creationflags=CREATE_NO_WINDOW) "--overwrite"], creationflags=CREATE_NO_WINDOW, cwd=get_dir(gamefile))
# Common.bmg # Common.bmg
bmgtracks = subprocess.check_output(["./tools/szs/wbmgt", "CAT", gamefile + ".d/message/Common.bmg"], bmgtracks = subprocess.run(["./tools/szs/wbmgt", "CAT", get_nodir(gamefile) + ".d/message/Common.bmg"],
creationflags=CREATE_NO_WINDOW) creationflags=CREATE_NO_WINDOW, cwd=get_dir(gamefile),
bmgtracks = bmgtracks.decode() check=True, stdout=subprocess.PIPE).stdout
trackheader = "#--- standard track names" bmgtracks = bmgtracks.decode()
trackend = "2328" trackheader = "#--- standard track names"
bmgtracks = bmgtracks[bmgtracks.find(trackheader) + len(trackheader):bmgtracks.find(trackend)] trackend = "2328"
bmgtracks = bmgtracks[bmgtracks.find(trackheader) + len(trackheader):bmgtracks.find(trackend)]
with open("./file/ExtraCommon.txt", "w") as f: with open("./file/ExtraCommon.txt", "w") 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= {self.translate('Aléatoire: Toutes les pistes', lang=bmglang)}\n"
f" 703f\t= {self.translate('Aléatoire: Pistes Originales', 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" 7040\t= {self.translate('Aléatoire: Custom Tracks', lang=bmglang)}\n"
f" 7041\t= {self.translate('Aléatoire: Pistes Nouvelles', lang=bmglang)}\n") f" 7041\t= {self.translate('Aléatoire: Pistes Nouvelles', lang=bmglang)}\n")
for bmgtrack in bmgtracks.split("\n"): for bmgtrack in bmgtracks.split("\n"):
if "=" in bmgtrack: if "=" in bmgtrack:
prefix = "" prefix = ""
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 = "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
sTid = bmgtrack.find("U") + 1 sTid = bmgtrack.find("U") + 1
Tid = bmgtrack[sTid:sTid + 2] Tid = bmgtrack[sTid:sTid + 2]
Tid = hex((int(Tid[0]) - 1) * 5 + (int(Tid[1]) - 1) + 0x7020)[2:] Tid = hex((int(Tid[0]) - 1) * 5 + (int(Tid[1]) - 1) + 0x7020)[2:]
Tname = bmgtrack[bmgtrack.find("= ") + 2:] Tname = bmgtrack[bmgtrack.find("= ") + 2:]
f.write(f" {Tid}\t= {prefix}{Tname}\n") f.write(f" {Tid}\t= {prefix}{Tname}\n")
bmgtext = subprocess.check_output(["tools/szs/wctct", "bmg", "--le-code", "--long", "./file/CTFILE.txt", if not(os.path.exists("./file/tmp/")): os.makedirs("./file/tmp/")
"--patch-bmg", "OVERWRITE=" + gamefile + ".d/message/Common.bmg",
"--patch-bmg", "OVERWRITE=./file/ExtraCommon.txt"],
creationflags=CREATE_NO_WINDOW).decode()
rbmgtext = subprocess.check_output(["tools/szs/wctct", "bmg", "--le-code", "--long", "./file/RCTFILE.txt",
"--patch-bmg", "OVERWRITE=" + gamefile + ".d/message/Common.bmg",
"--patch-bmg", "OVERWRITE=./file/ExtraCommon.txt"],
creationflags=CREATE_NO_WINDOW).decode()
shutil.rmtree(gamefile + ".d") filecopy(gamefile+".d/message/Common.bmg", "./file/tmp/Common.bmg")
os.remove("./file/ExtraCommon.txt") bmgtext = subprocess.run(["tools/szs/wctct", "bmg", "--le-code", "--long", "./file/CTFILE.txt", "--patch-bmg",
"OVERWRITE=./file/tmp/Common.bmg", "--patch-bmg", "OVERWRITE=./file/ExtraCommon.txt"],
creationflags=CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE).stdout.decode()
rbmgtext = subprocess.run(["tools/szs/wctct", "bmg", "--le-code", "--long", "./file/RCTFILE.txt", "--patch-bmg",
"OVERWRITE=./file/tmp/Common.bmg", "--patch-bmg", "OVERWRITE=./file/ExtraCommon.txt"],
creationflags=CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE).stdout.decode()
def finalise(common_file, bmgtext): shutil.rmtree(gamefile + ".d")
for console in trackname_color: bmgtext = bmgtext.replace(console, trackname_color[console]) os.remove("./file/tmp/Common.bmg")
with open(common_file, "w", encoding="utf-8") as f: f.write(bmgtext) os.remove("./file/ExtraCommon.txt")
subprocess.call(["./tools/szs/wbmgt", "ENCODE", common_file, "--overwrite"], creationflags=CREATE_NO_WINDOW)
os.remove(common_file)
finalise(f"./file/Common_{bmglang}.txt", bmgtext) def finalise(common_file, bmgtext):
finalise(f"./file/Common_R{bmglang}.txt", rbmgtext) for console in trackname_color: bmgtext = bmgtext.replace(console, trackname_color[console])
with open(common_file, "w", encoding="utf-8") as f: f.write(bmgtext)
subprocess.run(["./tools/szs/wbmgt", "ENCODE", get_nodir(common_file), "--overwrite"],
creationflags=CREATE_NO_WINDOW, cwd=get_dir(common_file))
os.remove(common_file)
finalise(f"./file/Common_{bmglang}.txt", bmgtext)
finalise(f"./file/Common_R{bmglang}.txt", rbmgtext)
except:
self.log_error()

View file

@ -5,37 +5,41 @@ import os
def patch_ct_icon(self): def patch_ct_icon(self):
with open("./ct_config.json", encoding="utf8") as f: config = json.load(f) try:
with open("./ct_config.json", encoding="utf8") as f: config = json.load(f)
cup_number = len(config["cup"]) + math.ceil(len(config["tracks_list"]) / 4) cup_number = len(config["cup"]) + math.ceil(len(config["tracks_list"]) / 4)
ct_icon = Image.new("RGBA", (128, 128 * (cup_number + 2))) ct_icon = Image.new("RGBA", (128, 128 * (cup_number + 2)))
files = ["left", "right"] files = ["left", "right"]
files.extend(config["cup"].keys()) files.extend(config["cup"].keys())
files.extend(["_"] * ((len(config["tracks_list"]) // 4) + 1)) files.extend(["_"] * ((len(config["tracks_list"]) // 4) + 1))
for i, id in enumerate(files): for i, id in enumerate(files):
if os.path.exists(f"./file/cup_icon/{id}.png"): if os.path.exists(f"./file/cup_icon/{id}.png"):
cup_icon = Image.open(f"./file/cup_icon/{id}.png").resize((128, 128)) cup_icon = Image.open(f"./file/cup_icon/{id}.png").resize((128, 128))
else: else:
cup_icon = Image.new("RGBA", (128, 128)) cup_icon = Image.new("RGBA", (128, 128))
draw = ImageDraw.Draw(cup_icon) draw = ImageDraw.Draw(cup_icon)
font = ImageFont.truetype("./file/SuperMario256.ttf", 90) font = ImageFont.truetype("./file/SuperMario256.ttf", 90)
draw.text((4 - 2, 4 - 2), "CT", (0, 0, 0), font=font) draw.text((4 - 2, 4 - 2), "CT", (0, 0, 0), font=font)
draw.text((4 + 2, 4 - 2), "CT", (0, 0, 0), font=font) draw.text((4 + 2, 4 - 2), "CT", (0, 0, 0), font=font)
draw.text((4 - 2, 4 + 2), "CT", (0, 0, 0), font=font) draw.text((4 - 2, 4 + 2), "CT", (0, 0, 0), font=font)
draw.text((4 + 2, 4 + 2), "CT", (0, 0, 0), font=font) draw.text((4 + 2, 4 + 2), "CT", (0, 0, 0), font=font)
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 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) # 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) # les icones droite et gauche.
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)
ct_icon.paste(cup_icon, (0, i * 128)) ct_icon.paste(cup_icon, (0, i * 128))
ct_icon.save("./file/ct_icons.tpl.png") ct_icon.save("./file/ct_icons.tpl.png")
except:
self.log_error()

View file

@ -9,65 +9,69 @@ from .definition import *
def patch_file(self): def patch_file(self):
def func(): def func():
if os.path.exists("./file/Track-WU8/"): try:
total_track = len(os.listdir("./file/Track-WU8/")) if os.path.exists("./file/Track-WU8/"):
else: total_track = len(os.listdir("./file/Track-WU8/"))
total_track = 0 else:
with open("./convert_file.json") as f: total_track = 0
fc = json.load(f) with open("./convert_file.json") as f:
max_step = len(fc["img"]) + total_track + 3 + len("EGFIS") fc = json.load(f)
self.Progress(show=True, indeter=False, statut=self.translate("Conversion des fichiers"), max=max_step, step=0) 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(statut=self.translate("Configuration de LE-CODE"), add=1) self.Progress(statut=self.translate("Configuration de 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("Création de 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("Création des images descriptives"), add=1)
self.patch_img_desc() self.patch_img_desc()
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("Conversion des images")+f"\n({i + 1}/{len(fc['img'])}) {file}", add=1)
subprocess.call(["./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) creationflags=CREATE_NO_WINDOW)
for file in glob.glob(self.path_mkwf+"/files/Scene/UI/MenuSingle_?.szs"): for file in glob.glob(self.path_mkwf+"/files/Scene/UI/MenuSingle_?.szs"):
self.patch_bmg(file) self.patch_bmg(file)
if not (os.path.exists("./file/auto-add/")): if not(os.path.exists("./file/auto-add/")):
subprocess.call(["./tools/szs/wszst", "AUTOADD", self.path_mkwf + "/files/Race/Course/", "--DEST", subprocess.run(["./tools/szs/wszst", "AUTOADD", self.path_mkwf + "/files/Race/Course/", "--DEST",
"./file/auto-add/"], creationflags=CREATE_NO_WINDOW) "./file/auto-add/"], creationflags=CREATE_NO_WINDOW)
max_process = 8 max_process = 8
process_list = {} process_list = {}
for i, file in enumerate(os.listdir("./file/Track-WU8/")): for i, file in enumerate(os.listdir("./file/Track-WU8/")):
while True: while True:
if len(process_list) < max_process: if len(process_list) < max_process:
process_list[file] = None process_list[file] = None
self.Progress(statut=self.translate("Conversion des courses")+f"\n({i + 1}/{total_track})\n" + self.Progress(statut=self.translate("Conversion des courses")+f"\n({i + 1}/{total_track})\n" +
"\n".join(process_list.keys()), add=1) "\n".join(process_list.keys()), add=1)
if not (os.path.exists("./file/Track/" + get_filename(file) + ".szs")): if not (os.path.exists("./file/Track/" + get_filename(file) + ".szs")):
process_list[file] = subprocess.Popen([ process_list[file] = subprocess.Popen([
"./tools/szs/wszst", "NORMALIZE", "./file/Track-WU8/" + file, "--DEST", "./tools/szs/wszst", "NORMALIZE", "./file/Track-WU8/" + file, "--DEST",
"./file/Track/%N.szs", "--szs", "--overwrite", "--autoadd-path", "./file/Track/%N.szs", "--szs", "--overwrite", "--autoadd-path",
"./file/auto-add/"], creationflags=CREATE_NO_WINDOW) "./file/auto-add/"], creationflags=CREATE_NO_WINDOW)
break break
else: else:
for process in process_list: for process in process_list:
if process_list[process] is not None: if process_list[process] is not None:
if not (process_list[process].poll() is None): if not (process_list[process].poll() is None):
process_list.pop(process)
break
else:
process_list.pop(process) process_list.pop(process)
break break
else:
process_list.pop(process)
break
self.Progress(show=False) self.Progress(show=False)
self.button_install_mod.grid(row=2, column=1, sticky="NEWS") self.button_install_mod.grid(row=2, column=1, sticky="NEWS")
self.listbox_outputformat.grid(row=2, column=2, sticky="NEWS") self.listbox_outputformat.grid(row=2, column=2, sticky="NEWS")
except:
self.log_error()
t = Thread(target=func) t = Thread(target=func)
t.setDaemon(True) t.setDaemon(True)

View file

@ -5,21 +5,25 @@ from .definition import *
def patch_img_desc(self): def patch_img_desc(self):
il = Image.open("./file/img_desc/illustration.png") try:
il_16_9 = il.resize((832, 456)) il = Image.open("./file/img_desc/illustration.png")
il_4_3 = il.resize((608, 456)) il_16_9 = il.resize((832, 456))
il_4_3 = il.resize((608, 456))
for file_lang in glob.glob("./file/img_desc/??.png"): for file_lang in glob.glob("./file/img_desc/??.png"):
img_lang = Image.open(file_lang) img_lang = Image.open(file_lang)
img_lang_16_9 = img_lang.resize((832, 456)) img_lang_16_9 = img_lang.resize((832, 456))
img_lang_4_3 = img_lang.resize((608, 456)) img_lang_4_3 = img_lang.resize((608, 456))
new_16_9 = Image.new("RGBA", (832, 456), (0, 0, 0, 255)) new_16_9 = Image.new("RGBA", (832, 456), (0, 0, 0, 255))
new_16_9.paste(il_16_9, (0, 0), il_16_9) new_16_9.paste(il_16_9, (0, 0), il_16_9)
new_16_9.paste(img_lang_16_9, (0, 0), img_lang_16_9) new_16_9.paste(img_lang_16_9, (0, 0), img_lang_16_9)
new_16_9.save(f"./file/strapA_16_9_832x456{get_filename(get_nodir(file_lang))}.png") new_16_9.save(f"./file/strapA_16_9_832x456{get_filename(get_nodir(file_lang))}.png")
new_4_3 = Image.new("RGBA", (608, 456), (0, 0, 0, 255)) new_4_3 = Image.new("RGBA", (608, 456), (0, 0, 0, 255))
new_4_3.paste(il_4_3, (0, 0), il_4_3) new_4_3.paste(il_4_3, (0, 0), il_4_3)
new_4_3.paste(img_lang_4_3, (0, 0), img_lang_4_3) new_4_3.paste(img_lang_4_3, (0, 0), img_lang_4_3)
new_4_3.save(f"./file/strapA_608x456{get_filename(get_nodir(file_lang))}.png") new_4_3.save(f"./file/strapA_608x456{get_filename(get_nodir(file_lang))}.png")
except:
self.log_error()

View file

@ -1 +1 @@
{"en": {"Cette action va extraire / utiliser la ROM s\u00e9lectionn\u00e9, pr\u00e9parer 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\u00e9 exp\u00e9rimentale": "Experimental functionality", "Tout faire": "Do everything", "Cr\u00e9ation des images descriptives": "Creation of descriptive images", "Cr\u00e9ation de ct_icon.png": "Creating ct_icon.png", "Patch des textes ": "Patching text ", "Al\u00e9atoire: Toutes les pistes": "Random: All tracks", "Al\u00e9atoire: Pistes Originales": "Random: Original tracks", "Al\u00e9atoire: Custom Tracks": "Random: Custom Tracks", "Al\u00e9atoire: 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 \u00e9cras\u00e9 si vous installer le mod !\n\u00cates-vous s\u00fbr 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\u00e9j\u00e0 modd\u00e9, il est d\u00e9conseill\u00e9 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 \u00e0 jour disponible !": "Update available !", "Une mise \u00e0 jour est disponible, souhaitez-vous l'installer ?": "An update is available, do you want to install it ?", "T\u00e9l\u00e9chargement de Updater en cours...": "Downloading the Updater...", "fin du t\u00e9l\u00e9chargement, d\u00e9but 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\u00e9 !": "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": {"Al\u00e9atoire: Toutes les pistes": "Zuf\u00e4llig: Alle Spuren", "Al\u00e9atoire: Pistes Originales": "Zuf\u00e4llig: Original-Spuren", "Al\u00e9atoire: Custom Tracks": "Zuf\u00e4llig: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Zuf\u00e4llig: Neue Spuren"}, "it": {"Al\u00e9atoire: Toutes les pistes": "Casuale: Tutte le tracce", "Al\u00e9atoire: Pistes Originales": "Casuale: Tracce originali", "Al\u00e9atoire: Custom Tracks": "Casuale: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Casuale: Nuovi brani"}, "sp": {"Al\u00e9atoire: Toutes les pistes": "Aleatorio: Todas las pistas", "Al\u00e9atoire: Pistes Originales": "Aleatorio: Pistas originales", "Al\u00e9atoire: Custom Tracks": "Aleatorio: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Aleatorio: Pistas nuevas"}, "selected": "fr"} {"en": {"Une erreur est survenue :": "An error occured :", "Cette action va extraire / utiliser la ROM s\u00e9lectionn\u00e9, pr\u00e9parer 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\u00e9 exp\u00e9rimentale": "Experimental functionality", "Tout faire": "Do everything", "Cr\u00e9ation des images descriptives": "Creation of descriptive images", "Cr\u00e9ation de ct_icon.png": "Creating ct_icon.png", "Patch des textes ": "Patching text ", "Al\u00e9atoire: Toutes les pistes": "Random: All tracks", "Al\u00e9atoire: Pistes Originales": "Random: Original tracks", "Al\u00e9atoire: Custom Tracks": "Random: Custom Tracks", "Al\u00e9atoire: 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 \u00e9cras\u00e9 si vous installer le mod !\n\u00cates-vous s\u00fbr 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\u00e9j\u00e0 modd\u00e9, il est d\u00e9conseill\u00e9 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 \u00e0 jour disponible !": "Update available !", "Une mise \u00e0 jour est disponible, souhaitez-vous l'installer ?": "An update is available, do you want to install it ?", "T\u00e9l\u00e9chargement de Updater en cours...": "Downloading the Updater...", "fin du t\u00e9l\u00e9chargement, d\u00e9but 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\u00e9 !": "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": {"Al\u00e9atoire: Toutes les pistes": "Zuf\u00e4llig: Alle Spuren", "Al\u00e9atoire: Pistes Originales": "Zuf\u00e4llig: Original-Spuren", "Al\u00e9atoire: Custom Tracks": "Zuf\u00e4llig: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Zuf\u00e4llig: Neue Spuren"}, "it": {"Al\u00e9atoire: Toutes les pistes": "Casuale: Tutte le tracce", "Al\u00e9atoire: Pistes Originales": "Casuale: Tracce originali", "Al\u00e9atoire: Custom Tracks": "Casuale: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Casuale: Nuovi brani"}, "sp": {"Al\u00e9atoire: Toutes les pistes": "Aleatorio: Todas las pistas", "Al\u00e9atoire: Pistes Originales": "Aleatorio: Pistas originales", "Al\u00e9atoire: Custom Tracks": "Aleatorio: Custom Tracks", "Al\u00e9atoire: Pistes Nouvelles": "Aleatorio: Pistas nuevas"}, "selected": "fr"}

View file

@ -1,7 +1,7 @@
{ {
"version": "0.5", "version": "0.6",
"subversion": "1", "subversion": "0",
"changelog": "- les courses Mario Kart Tour ne fonctionnaient pas", "changelog": "- The image of the score system explanation now have explain the star's color\n- Microsoft Visual C++ should now be included with the installer, avoiding an error with vcruntime140.dll\n- Update will now be detected by the installer when changing subversion (0.5.1 -> 0.5.2 will be detected)\n- A new file named \"error.log\" can now be generated when an error is occurring, helping debugging\n- Updated cx_freeze so that having special character in path don't cause issue (.exe version)\n- Fixed an issue where having a dump with a DATA directory would cause the installer to not work",
"download_bin": "https://github.com/Faraphel/MKWF-Install/releases/download/0.5.1/MKWF.v0.5.1.zip", "download_bin": "https://github.com/Faraphel/MKWF-Install/releases/download/0.6/MKWF.v0.6.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"
} }