implemented a very experimental function for packs

This commit is contained in:
Faraphel 2022-01-18 14:04:51 +01:00
parent fd997719b3
commit 6042ca441a
8 changed files with 120 additions and 146 deletions

View file

@ -7,28 +7,6 @@ from source.Cup import Cup
from source.Track import Track, HiddenTrackAttr from source.Track import Track, HiddenTrackAttr
def get_cup_icon(cup_id: [str, int], font_path: str = "./file/SuperMario256.ttf",
cup_icon_dir: str = "./file/cup_icon") -> Image:
"""
:param cup_id: id of the cup
:param cup_icon_dir: directory to cup icon
:param font_path: path to the font used to generate icon
:return: cup icon
"""
if os.path.exists(f"{cup_icon_dir}/{cup_id}.png"):
cup_icon = Image.open(f"{cup_icon_dir}/{cup_id}.png").resize((128, 128))
else:
cup_icon = Image.new("RGBA", (128, 128))
draw = ImageDraw.Draw(cup_icon)
font = ImageFont.truetype(font_path, 90)
draw.text((4, 4), "CT", (255, 165, 0), font=font, stroke_width=2, stroke_fill=(0, 0, 0))
font = ImageFont.truetype(font_path, 60)
draw.text((5, 80), "%03i" % cup_id, (255, 165, 0), font=font, stroke_width=2, stroke_fill=(0, 0, 0))
return cup_icon
class CT_Config: class CT_Config:
def __init__(self, version: str = None, name: str = None, nickname: str = None, def __init__(self, version: str = None, name: str = None, nickname: str = None,
game_variant: str = "01", gui=None, region: int = None, cheat_region: int = None, game_variant: str = "01", gui=None, region: int = None, cheat_region: int = None,
@ -117,6 +95,27 @@ class CT_Config:
ctfile.write(cup.get_ctfile_cup(race=False, **kwargs)) ctfile.write(cup.get_ctfile_cup(race=False, **kwargs))
rctfile.write(cup.get_ctfile_cup(race=True, **kwargs)) rctfile.write(cup.get_ctfile_cup(race=True, **kwargs))
def get_cup_icon(self, cup_id: [str, int], font_path: str = "./assets/SuperMario256.ttf",
cup_icon_dir: str = "./file/cup_icon") -> Image:
"""
:param cup_id: id of the cup
:param cup_icon_dir: directory to cup icon
:param font_path: path to the font used to generate icon
:return: cup icon
"""
if os.path.exists(f"{cup_icon_dir}/{cup_id}.png"):
cup_icon = Image.open(f"{cup_icon_dir}/{cup_id}.png").resize((128, 128))
else:
cup_icon = Image.new("RGBA", (128, 128))
draw = ImageDraw.Draw(cup_icon)
font = ImageFont.truetype(font_path, 90)
draw.text((4, 4), "CT", (255, 165, 0), font=font, stroke_width=2, stroke_fill=(0, 0, 0))
font = ImageFont.truetype(font_path, 60)
draw.text((5, 80), "%03i" % cup_id, (255, 165, 0), font=font, stroke_width=2, stroke_fill=(0, 0, 0))
return cup_icon
def get_cticon(self) -> Image: def get_cticon(self) -> Image:
""" """
get all cup icon into a single image get all cup icon into a single image
@ -133,7 +132,7 @@ class CT_Config:
for index, cup_id in enumerate(icon_files): for index, cup_id in enumerate(icon_files):
# index is a number, id can be string or number ("left", 0, 12, ...) # index is a number, id can be string or number ("left", 0, 12, ...)
cup_icon = get_cup_icon(cup_id) cup_icon = self.get_cup_icon(cup_id, cup_icon_dir=self.pack_path+"/file/cup_icon/")
ct_icon.paste(cup_icon, (0, index * CT_ICON_WIDTH)) ct_icon.paste(cup_icon, (0, index * CT_ICON_WIDTH))
return ct_icon return ct_icon
@ -159,19 +158,20 @@ class CT_Config:
self.unordered_tracks = [] self.unordered_tracks = []
self.all_tracks = [] self.all_tracks = []
self.pack_path = pack_path
# default track # default track
self.default_track = Track() self.default_track = Track(track_wu8_dir=f"{self.pack_path}/file/Track-WU8/")
if "default_track" in ctconfig_json: self.default_track.load_from_json(ctconfig_json["default_track"]) if "default_track" in ctconfig_json: self.default_track.load_from_json(ctconfig_json["default_track"])
for cup_json in ctconfig_json["cup"] if "cup" in ctconfig_json else []: # tracks with defined order for cup_json in ctconfig_json["cup"] if "cup" in ctconfig_json else []: # tracks with defined order
cup = Cup(default_track=self.default_track) cup = Cup(default_track=self.default_track)
cup.load_from_json(cup_json) cup.load_from_json(cup_json)
if not cup.locked: # locked cup are not useful (they are original track or random track) self.ordered_cups.append(cup)
self.ordered_cups.append(cup) self.all_tracks.extend(cup.tracks)
self.all_tracks.extend(cup.tracks)
for track_json in ctconfig_json["tracks_list"] if "tracks_list" in ctconfig_json else []: # unordered tracks for track_json in ctconfig_json["tracks_list"] if "tracks_list" in ctconfig_json else []: # unordered tracks
track = Track() track = Track(track_wu8_dir=f"{self.pack_path}/file/Track-WU8/")
track.load_from_json(track_json) track.load_from_json(track_json)
self.unordered_tracks.append(track) self.unordered_tracks.append(track)
self.all_tracks.append(track) self.all_tracks.append(track)
@ -182,7 +182,7 @@ class CT_Config:
self.nickname = ctconfig_json["nickname"] if "nickname" in ctconfig_json else self.name self.nickname = ctconfig_json["nickname"] if "nickname" in ctconfig_json else self.name
if "game_variant" in ctconfig_json: self.game_variant = ctconfig_json["game_variant"] if "game_variant" in ctconfig_json: self.game_variant = ctconfig_json["game_variant"]
for param in ["region", "cheat_region", "tags_color", "prefix_list", "suffix_list", "tag_retro", "pack_path"]: for param in ["region", "cheat_region", "tags_color", "prefix_list", "suffix_list", "tag_retro"]:
setattr(self, param, ctconfig_json.get(param)) setattr(self, param, ctconfig_json.get(param))
return self return self

View file

@ -9,7 +9,6 @@ class Cup:
track2: Track = None, track2: Track = None,
track3: Track = None, track3: Track = None,
track4: Track = None, track4: Track = None,
locked: bool = False,
*args, **kwargs): *args, **kwargs):
""" """
class of a cup class of a cup
@ -18,13 +17,11 @@ class Cup:
:param track2: second track :param track2: second track
:param track3: third track :param track3: third track
:param track4: fourth track :param track4: fourth track
:param locked: is the track locked (used to load ctconfig in CT_Config)
:param args: other args that I could add in the future :param args: other args that I could add in the future
:param kwargs: other kwargs that I could add in the future :param kwargs: other kwargs that I could add in the future
""" """
self.name = name self.name = name
self.locked = locked
self.tracks = [ self.tracks = [
track1 if track1 else default_track.copy(), track1 if track1 else default_track.copy(),
track2 if track2 else default_track.copy(), track2 if track2 else default_track.copy(),
@ -51,7 +48,7 @@ class Cup:
for key, value in cup.items(): # load all value in the json as class attribute for key, value in cup.items(): # load all value in the json as class attribute
if key == "tracks": # if the key is tracks if key == "tracks": # if the key is tracks
for i, track_json in enumerate(value): # load all tracks from their json for i, track_json in enumerate(value): # load all tracks from their json
self.tracks[int(i)].load_from_json(track_json) self.tracks[i].load_from_json(track_json)
else: else:
setattr(self, key, value) setattr(self, key, value)

View file

@ -213,14 +213,14 @@ class Game:
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] == "/":
shutil.copyfile(f"./file/{file}", szs_extract_path + subpath + file) shutil.copyfile(f"{self.ctconfig.pack_path}/file/{file}", szs_extract_path + subpath + file)
else: else:
shutil.copyfile(f"./file/{file}", szs_extract_path + subpath) shutil.copyfile(f"{self.ctconfig.pack_path}/file/{file}", szs_extract_path + subpath)
elif path[-1] == "/": elif path[-1] == "/":
shutil.copyfile(f"./file/{file}", path + file) shutil.copyfile(f"{self.ctconfig.pack_path}/file/{file}", path + file)
else: else:
shutil.copyfile(f"./file/{file}", path) shutil.copyfile(f"{self.ctconfig.pack_path}/file/{file}", path)
for fp in fs: for fp in fs:
for f in glob.glob(self.path + "/files/" + fp, recursive=True): for f in glob.glob(self.path + "/files/" + fp, recursive=True):
@ -282,10 +282,11 @@ class Game:
""" """
self.gui.progress(statut=self.gui.translate("Patch lecode.bin"), add=1) self.gui.progress(statut=self.gui.translate("Patch lecode.bin"), add=1)
lpar_path = "./file/lpar-debug.txt" if self.gui.boolvar_use_debug_mode.get() else "./file/lpar-default.txt" lpar_path = f"{self.ctconfig.pack_path}/file/lpar-debug.txt" \
if self.gui.boolvar_use_debug_mode.get() else f"{self.ctconfig.pack_path}/file/lpar-default.txt"
lec.patch( lec.patch(
lecode_file=f"./file/lecode-{self.region}.bin", lecode_file=f"{self.ctconfig.pack_path}/file/lecode-{self.region}.bin",
dest_lecode_file=f"{self.path}/files/rel/lecode-{self.region}.bin", dest_lecode_file=f"{self.path}/files/rel/lecode-{self.region}.bin",
game_track_path=f"{self.path}/files/Race/Course/", game_track_path=f"{self.path}/files/Race/Course/",
copy_track_paths=[f"./file/Track/"], copy_track_paths=[f"./file/Track/"],
@ -422,13 +423,12 @@ class Game:
:param bmg_language: language of the bmg file :param bmg_language: language of the bmg file
:return: the replaced bmg file :return: the replaced bmg file
""" """
with open("./file_process.json", encoding="utf8") as fp_file: with open(f"{self.ctconfig.pack_path}/file_process.json", encoding="utf8") as fp_file:
file_process = json.load(fp_file) file_process = json.load(fp_file)
for bmg_process in file_process["bmg"]: for bmg_process in file_process["bmg"]:
if "language" in bmg_process: if "language" in bmg_process and bmg_language not in bmg_process["language"]:
if bmg_language not in bmg_process["language"]: continue
continue
for data, data_replacement in bmg_process["data"].items(): for data, data_replacement in bmg_process["data"].items():
for key, replacement in bmg_replacement.items(): for key, replacement in bmg_replacement.items():
@ -462,17 +462,18 @@ class Game:
bmg.encode(file) bmg.encode(file)
os.remove(file) os.remove(file)
save_bmg(f"./file/Menu_{bmglang}.txt", process_bmg_replacement(bmgmenu, bmglang)) save_bmg(f"{self.ctconfig.pack_path}/file/Menu_{bmglang}.txt", process_bmg_replacement(bmgmenu, bmglang))
save_bmg(f"./file/Common_{bmglang}.txt", process_bmg_replacement(bmgcommon, bmglang)) save_bmg(f"{self.ctconfig.pack_path}/file/Common_{bmglang}.txt", process_bmg_replacement(bmgcommon, bmglang))
save_bmg(f"./file/Common_R{bmglang}.txt", process_bmg_replacement(rbmgcommon, bmglang)) save_bmg(f"{self.ctconfig.pack_path}/file/Common_R{bmglang}.txt", process_bmg_replacement(rbmgcommon, bmglang))
def patch_file(self): def patch_file(self):
""" """
Prepare all files to install the mod (track, bmg text, descriptive image, ...) Prepare all files to install the mod (track, bmg text, descriptive image, ...)
""" """
try: try:
if not (os.path.exists("./file/Track-WU8/")): os.makedirs("./file/Track-WU8/") os.makedirs(f"{self.ctconfig.pack_path}/file/Track-WU8/", exist_ok=True)
with open("./file_process.json", encoding="utf8") as fp_file:
with open(f"{self.ctconfig.pack_path}/file_process.json", encoding="utf8") as fp_file:
file_process = json.load(fp_file) file_process = json.load(fp_file)
max_step = len(file_process["img"]) + len(self.ctconfig.all_tracks) + 3 + len("EGFIS") max_step = len(file_process["img"]) + len(self.ctconfig.all_tracks) + 3 + len("EGFIS")
@ -486,10 +487,13 @@ class Game:
self.gui.progress(statut=self.gui.translate("Creating ct_icon.png"), add=1) self.gui.progress(statut=self.gui.translate("Creating ct_icon.png"), add=1)
ct_icon = self.ctconfig.get_cticon() ct_icon = self.ctconfig.get_cticon()
ct_icon.save("./file/ct_icons.tpl.png") ct_icon.save(f"{self.ctconfig.pack_path}/file/ct_icons.tpl.png")
self.gui.progress(statut=self.gui.translate("Creating descriptive images"), add=1) self.gui.progress(statut=self.gui.translate("Creating descriptive images"), add=1)
self.patch_img_desc() self.patch_img_desc(
img_desc_path=self.ctconfig.pack_path+"/file/img_desc/",
dest_dir=self.ctconfig.pack_path+"/file/"
)
self.patch_image(file_process["img"]) self.patch_image(file_process["img"])
for file in glob.glob(self.path + "/files/Scene/UI/MenuSingle_?.szs"): self.patch_bmg(file) for file in glob.glob(self.path + "/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.
@ -511,7 +515,12 @@ class Game:
for i, file in enumerate(fp_img): for i, file in enumerate(fp_img):
self.gui.progress(statut=self.gui.translate("Converting images") + f"\n({i + 1}/{len(fp_img)}) {file}", self.gui.progress(statut=self.gui.translate("Converting images") + f"\n({i + 1}/{len(fp_img)}) {file}",
add=1) add=1)
img.encode(file="./file/" + file, format=fp_img[file]) # TODO: IMG DESC AND THIS PART REALLY NEED A REWRITE !
img.encode(
file=f"{self.ctconfig.pack_path}/file/{file}",
format=fp_img[file]
)
def patch_img_desc(self, img_desc_path: str = "./file/img_desc/", dest_dir: str = "./file/") -> None: def patch_img_desc(self, img_desc_path: str = "./file/img_desc/", dest_dir: str = "./file/") -> None:
""" """

View file

@ -7,7 +7,6 @@ import requests
import zipfile import zipfile
import glob import glob
import json import json
import os
from source.Game import Game, RomAlreadyPatched, InvalidGamePath, InvalidFormat from source.Game import Game, RomAlreadyPatched, InvalidGamePath, InvalidFormat
from source.Option import Option from source.Option import Option
@ -25,9 +24,10 @@ class Gui:
Initialize program Gui Initialize program Gui
""" """
self.root = Tk() self.root = Tk()
self.root.resizable(False, False)
self.root.iconbitmap(bitmap="./icon.ico")
self.option = Option() self.option = Option().load_from_file("./option.json")
self.option.load_from_file("./option.json")
self.game = Game(gui=self) self.game = Game(gui=self)
self.menu_bar = None self.menu_bar = None
@ -47,42 +47,35 @@ class Gui:
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.intvar_process_track = IntVar(value=self.option.process_track) self.intvar_process_track = IntVar(value=self.option.process_track)
self.root.title(self.translate("MKWFaraphel Installer"))
self.boolvar_use_1star_track = BooleanVar(value=True) self.boolvar_use_1star_track = BooleanVar(value=True)
self.boolvar_use_2star_track = BooleanVar(value=True) self.boolvar_use_2star_track = BooleanVar(value=True)
self.boolvar_use_3star_track = BooleanVar(value=True) self.boolvar_use_3star_track = BooleanVar(value=True)
self.stringvar_mark_track_from_version = StringVar(value="None") self.stringvar_mark_track_from_version = StringVar(value="None")
self.stringvar_sort_track_by = StringVar(value="name") self.stringvar_sort_track_by = StringVar(value="name")
self.boolvar_use_debug_mode = BooleanVar(value=False) self.boolvar_use_debug_mode = BooleanVar(value=False)
self.boolvar_force_unofficial_mode = BooleanVar(value=False) self.boolvar_force_unofficial_mode = BooleanVar(value=False)
self.stringvar_mystuff_folder = StringVar(value=None) self.stringvar_mystuff_folder = StringVar(value=None)
self.stringvar_mystuff_music_folder = StringVar(value=None)
self.stringvar_mystuff_vehicle_folder = StringVar(value=None)
self.stringvar_mystuff_character_folder = StringVar(value=None)
self.stringvar_mystuff_original_track_folder = StringVar(value=None)
self.root.title(self.translate("MKWFaraphel Installer"))
self.root.resizable(False, False)
self.root.iconbitmap(bitmap="./icon.ico")
if not self.boolvar_dont_check_for_update.get(): self.check_update() if not self.boolvar_dont_check_for_update.get(): self.check_update()
self.init_gui() # GUI
self.init_menu() # Mod selector
def init_gui(self) -> None:
self.frame_ctconfig = LabelFrame(self.root, text=self.translate("Mod")) self.frame_ctconfig = LabelFrame(self.root, text=self.translate("Mod"))
self.frame_ctconfig.grid(row=1, column=1, sticky="NWS") self.frame_ctconfig.grid(row=1, column=1, sticky="NWS")
self.combobox_ctconfig_path = ttk.Combobox( self.combobox_ctconfig_path = ttk.Combobox(
self.frame_ctconfig, self.frame_ctconfig,
values=self.available_packs, values=self.available_packs,
textvariable=self.stringvar_ctconfig textvariable=self.stringvar_ctconfig,
width=30
) )
self.combobox_ctconfig_path.grid(row=1, column=1, sticky="NEWS", columnspan=2) self.combobox_ctconfig_path.grid(row=1, column=1, sticky="NEWS", columnspan=2)
self.combobox_ctconfig_path.bind("<<ComboboxSelected>>", lambda x=None: self.init_menu()) self.combobox_ctconfig_path.bind("<<ComboboxSelected>>", lambda x=None: self.reload_ctconfig())
self.reload_ctconfig()
# Jeu # Jeu
self.frame_game_path = LabelFrame(self.root, text=self.translate("Original game")) self.frame_game_path = LabelFrame(self.root, text=self.translate("Original game"))
@ -136,21 +129,22 @@ class Gui:
self.game.patch_file() self.game.patch_file()
self.game.install_mod() self.game.install_mod()
self.button_do_everything = Button(self.frame_game_path_action, text=self.translate("Install mod"), self.button_do_everything = Button(
relief=RIDGE, command=do_everything) self.frame_game_path_action,
text=self.translate("Install mod"),
relief=RIDGE,
command=do_everything
)
self.button_do_everything.grid(row=1, column=1, columnspan=2, sticky="NEWS") self.button_do_everything.grid(row=1, column=1, columnspan=2, sticky="NEWS")
self.progressbar = ttk.Progressbar(self.root) self.progressbar = ttk.Progressbar(self.root)
self.progresslabel = Label(self.root) self.progresslabel = Label(self.root)
def init_menu(self) -> None:
if self.menu_bar: self.menu_bar.destroy() if self.menu_bar: self.menu_bar.destroy()
self.menu_bar = Menu(self.root) self.menu_bar = Menu(self.root)
self.root.config(menu=self.menu_bar) self.root.config(menu=self.menu_bar)
self.game.ctconfig.load_ctconfig_file(ctconfig_file=self.get_ctconfig_path_pack(self.stringvar_ctconfig.get()))
track_attr_possibilities = self.game.ctconfig.get_all_track_possibilities()
# LANGUAGE MENU # LANGUAGE MENU
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("Language"), menu=self.menu_language) self.menu_bar.add_cascade(label=self.translate("Language"), menu=self.menu_language)
@ -195,50 +189,6 @@ class Gui:
command=lambda: self.option.edit("format", "WBFS") command=lambda: self.option.edit("format", "WBFS")
) )
# TRACK CONFIGURATION MENU
self.menu_trackconfiguration = Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label=self.translate("Track configuration"), menu=self.menu_trackconfiguration)
# sort track
self.menu_sort_track_by = Menu(self.menu_trackconfiguration, tearoff=0)
self.menu_trackconfiguration.add_cascade(label=self.translate("Sort track"), menu=self.menu_sort_track_by)
for param in track_attr_possibilities:
self.menu_sort_track_by.add_radiobutton(
label=param.title(),
variable=self.stringvar_sort_track_by,
value=param
)
# select track
self.menu_trackselection = Menu(self.menu_trackconfiguration, tearoff=0)
self.menu_trackconfiguration.add_cascade(label=self.translate("Select track"), menu=self.menu_trackselection)
self.menu_trackselection_param = {}
self.menu_trackhighlight = Menu(self.menu_trackconfiguration, tearoff=0)
self.menu_trackconfiguration.add_cascade(label=self.translate("Highlight track"), menu=self.menu_trackhighlight)
self.menu_trackhighlight_param = {}
for param, values in track_attr_possibilities.items():
for menu_param, menu in [
(self.menu_trackselection_param, self.menu_trackselection),
(self.menu_trackhighlight_param, self.menu_trackhighlight)
]:
menu_param[param] = {
"Menu": Menu(menu, tearoff=0),
"Var": []
}
menu.add_cascade(
label=param.title(),
menu=menu_param[param]["Menu"]
)
for value in values:
menu_param[param]["Var"].append(BooleanVar(value=True))
menu_param[param]["Menu"].add_checkbutton(
label=value,
variable=menu_param[param]["Var"][-1],
)
# ADVANCED MENU # ADVANCED MENU
## INSTALLER PARAMETER ## INSTALLER PARAMETER
self.menu_advanced = Menu(self.menu_bar, tearoff=0) self.menu_advanced = Menu(self.menu_bar, tearoff=0)
@ -286,7 +236,8 @@ class Gui:
## GAME PARAMETER ## GAME PARAMETER
self.menu_advanced.add_separator() self.menu_advanced.add_separator()
self.menu_advanced.add_checkbutton(label=self.translate("Use debug mode"), variable=self.boolvar_use_debug_mode) self.menu_advanced.add_checkbutton(label=self.translate("Use debug mode"),
variable=self.boolvar_use_debug_mode)
self.menu_mystuff = Menu(self.menu_advanced, tearoff=0) self.menu_mystuff = Menu(self.menu_advanced, tearoff=0)
self.menu_advanced.add_cascade(label=self.translate("MyStuff"), menu=self.menu_mystuff) self.menu_advanced.add_cascade(label=self.translate("MyStuff"), menu=self.menu_mystuff)
@ -303,7 +254,7 @@ class Gui:
self.menu_mystuff.entryconfig(index, label=self.translate( self.menu_mystuff.entryconfig(index, label=self.translate(
"Apply", " ", label, f" ({stringvar.get()!r} ", "selected", ")") "Apply", " ", label, f" ({stringvar.get()!r} ", "selected", ")")
) )
_func(init=True) _func(init=True)
self.menu_mystuff.entryconfig(index, command=_func) self.menu_mystuff.entryconfig(index, command=_func)
@ -318,6 +269,11 @@ class Gui:
self.menu_help.add_command(label="Github Wiki", command=lambda: webbrowser.open(GITHUB_HELP_PAGE_URL)) self.menu_help.add_command(label="Github Wiki", command=lambda: webbrowser.open(GITHUB_HELP_PAGE_URL))
self.menu_help.add_command(label="Discord", command=lambda: webbrowser.open(DISCORD_URL)) self.menu_help.add_command(label="Discord", command=lambda: webbrowser.open(DISCORD_URL))
def reload_ctconfig(self) -> None:
self.game.ctconfig.load_ctconfig_file(
ctconfig_file=self.get_ctconfig_path_pack(self.stringvar_ctconfig.get())
)
def get_available_packs(self) -> list: def get_available_packs(self) -> list:
available_packs = [] available_packs = []
@ -335,13 +291,13 @@ class Gui:
Check if an update is available Check if an update is available
""" """
try: try:
github_version_data = requests.get(VERSION_FILE_URL, allow_redirects=True).json() github_version_data = requests.get(VERSION_FILE_URL, allow_redirects=True, timeout=3).json()
with open("./version", "rb") as f: local_version_data = json.load(f) with open("./version", "rb") as f: local_version_data = json.load(f)
local_version = StrictVersion(f"{local_version_data['version']}.{local_version_data['subversion']}") local_version = StrictVersion(f"{local_version_data['version']}.{local_version_data['subversion']}")
github_version = StrictVersion(f"{github_version_data['version']}.{github_version_data['subversion']}") github_version = StrictVersion(f"{github_version_data['version']}.{github_version_data['subversion']}")
if github_version > local_version: # if github version is newer than local version if github_version > local_version: # if github version is newer than local version
if messagebox.askyesno( if messagebox.askyesno(
self.translate("Update available !"), self.translate("Update available !"),
self.translate("An update is available, do you want to install it ?", self.translate("An update is available, do you want to install it ?",
@ -360,8 +316,9 @@ class Gui:
print(self.translate("finished extracting")) print(self.translate("finished extracting"))
os.remove("./download.zip") os.remove("./download.zip")
print(self.translate("starting application..."))
os.startfile(os.path.realpath("./Updater/Updater.exe")) print(self.translate("starting application..."))
os.startfile(os.path.realpath("./Updater/Updater.exe"))
elif local_version > github_version: elif local_version > github_version:
self.is_dev_version = True self.is_dev_version = True
@ -380,13 +337,18 @@ class Gui:
""" """
error = traceback.format_exc() error = traceback.format_exc()
with open("./error.log", "a") as f: with open("./error.log", "a") as f:
f.write(f"---\n" f.write(
f"For game version : {self.game.ctconfig.version}\n" f"---\n"
f"./file/ directory : {os.listdir('./file/')}\n" f"For game version : {self.game.ctconfig.version}\n"
f"GAME/files/ information : {self.game.path, self.game.region}\n" f"./file/ directory : {os.listdir('./file/')}\n"
f"{error}\n" f"ctconfig directory : {os.listdir(self.game.ctconfig.pack_path)}\n"
f"GAME/files/ information : {self.game.path, self.game.region}\n"
f"{error}\n"
) )
messagebox.showerror(self.translate("Error"), self.translate("An error occured", " :", "\n", error, "\n\n")) messagebox.showerror(
self.translate("Error"),
self.translate("An error occured", " :", "\n", error, "\n\n")
)
def progress(self, show: bool = None, indeter: bool = None, step: int = None, def progress(self, show: bool = None, indeter: bool = None, step: int = None,
statut: str = None, max: int = None, add: int = None) -> None: statut: str = None, max: int = None, add: int = None) -> None:

View file

@ -30,7 +30,7 @@ class Option:
self.save_to_file() self.save_to_file()
if need_restart: restart() if need_restart: restart()
def load_from_file(self, option_file: str = "./option.json") -> None: def load_from_file(self, option_file: str = "./option.json"):
""" """
Load all options from a json file Load all options from a json file
:param option_file: the file where to load option :param option_file: the file where to load option
@ -40,6 +40,8 @@ class Option:
file_json = json.load(file) file_json = json.load(file)
self.load_from_json(file_json) self.load_from_json(file_json)
return self
def load_from_json(self, option_json: dict) -> None: def load_from_json(self, option_json: dict) -> None:
""" """
Load all options from a dictionnary Load all options from a dictionnary

View file

@ -5,8 +5,8 @@ from source.wszst import *
HiddenTrackAttr = [ HiddenTrackAttr = [
"file_wu8", "file_wu8",
"file_szs", "file_szs",
"track_wu8_dir", "_track_wu8_dir",
"track_szs_dir" "_track_szs_dir"
] # These attribute shouldn't be used to reference all the possibilities of values ] # These attribute shouldn't be used to reference all the possibilities of values
@ -48,7 +48,6 @@ class Track:
:param since_version: since when version did the track got added to the mod :param since_version: since when version did the track got added to the mod
:param score: what it the score of the track :param score: what it the score of the track
:param warning: what is the warn level of the track (0 = none, 1 = minor bug, 2 = major bug) :param warning: what is the warn level of the track (0 = none, 1 = minor bug, 2 = major bug)
:param note: note about the track
:param track_wu8_dir: where is stored the track wu8 :param track_wu8_dir: where is stored the track wu8
:param track_szs_dir: where is stored the track szs :param track_szs_dir: where is stored the track szs
:param track_version: version of the track :param track_version: version of the track
@ -66,12 +65,11 @@ class Track:
self.since_version = since_version # Since which version is this track available self.since_version = since_version # Since which version is this track available
self.score = score # Track score between 1 and 3 stars self.score = score # Track score between 1 and 3 stars
self.warning = warning # Track bug level (1 = minor, 2 = major) self.warning = warning # Track bug level (1 = minor, 2 = major)
self.note = note # Note about the track
self.version = version self.version = version
self.tags = tags self.tags = tags
self.track_wu8_dir = track_wu8_dir self._track_wu8_dir = track_wu8_dir
self.track_szs_dir = track_szs_dir self._track_szs_dir = track_szs_dir
self.file_wu8 = f"{track_wu8_dir}/{self.sha1}.wu8" self.file_wu8 = f"{track_wu8_dir}/{self.sha1}.wu8"
self.file_szs = f"{track_szs_dir}/{self.sha1}.szs" self.file_szs = f"{track_szs_dir}/{self.sha1}.szs"
@ -100,7 +98,10 @@ class Track:
""" """
convert track to szs convert track to szs
""" """
szs.normalize(src_file=self.file_wu8) szs.normalize(
src_file=self.file_wu8,
dest_dir="./file/Track/"
)
def get_author_str(self) -> str: def get_author_str(self) -> str:
""" """
@ -128,7 +129,8 @@ class Track:
else: else:
ctfile_text += ( ctfile_text += (
f'"-"; ' # track path, not used in Race_*.szs, save a bit of space f'"-"; ' # track path, not used in Race_*.szs, save a bit of space
f'"{self.get_track_formatted_name(ct_config, *args, **kwargs)}\\n{self.get_author_str()}"; ' # only in race show author's name f'"{self.get_track_formatted_name(ct_config, *args, **kwargs)}\\n{self.get_author_str()}"; '
# only in race show author's name
f'"-"\n' # sha1, not used in Race_*.szs, save a bit of space f'"-"\n' # sha1, not used in Race_*.szs, save a bit of space
) )
@ -185,8 +187,8 @@ class Track:
for key, value in track_json.items(): # load all value in the json as class attribute for key, value in track_json.items(): # load all value in the json as class attribute
setattr(self, key, value) setattr(self, key, value)
self.file_wu8 = f"{self.track_wu8_dir}/{self.sha1}.wu8" self.file_wu8 = f"{self._track_wu8_dir}/{self.sha1}.wu8"
self.file_szs = f"{self.track_szs_dir}/{self.sha1}.szs" self.file_szs = f"{self._track_szs_dir}/{self.sha1}.szs"
return self return self

View file

@ -5,11 +5,13 @@ WIMGT_PATH = "./tools/szs/wimgt"
@error.better_wszst_error(wszst_tools=WIMGT_PATH) @error.better_wszst_error(wszst_tools=WIMGT_PATH)
def encode(file: str, format: str) -> None: def encode(file: str, format: str, dest_file: str = None) -> None:
""" """
Encode an .png image into a new format Encode an .png image into a new format
:param dest_file: destination
:param file: .png image :param file: .png image
:param format: new image format :param format: new image format
""" """
subprocess.run([WIMGT_PATH, "ENCODE", file, "-x", format, "--overwrite"], cmd = [WIMGT_PATH, "ENCODE", file, "-x", format, "--overwrite"]
creationflags=subprocess.CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE) if dest_file: cmd.extend(["--dest", dest_file])
subprocess.run(cmd, creationflags=subprocess.CREATE_NO_WINDOW, check=True, stdout=subprocess.PIPE)