From 9d97326f4b7f8f4a7d79879a5cf1c51fed8292d9 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Thu, 9 Jun 2022 22:47:13 +0200 Subject: [PATCH] started implementing Game and wit for the game file manipulation, and modifying ModConfig syntax --- .../{ct_config.json => mod_config.json} | 189 +++++++----------- source/mkw/Cup.py | 4 + source/mkw/Game.py | 73 +++++++ source/mkw/ModConfig.py | 35 ++-- source/wt/szs.py | 2 +- source/wt/wit.py | 36 ++++ 6 files changed, 205 insertions(+), 134 deletions(-) rename Pack/MKWFaraphel/{ct_config.json => mod_config.json} (99%) create mode 100644 source/wt/wit.py diff --git a/Pack/MKWFaraphel/ct_config.json b/Pack/MKWFaraphel/mod_config.json similarity index 99% rename from Pack/MKWFaraphel/ct_config.json rename to Pack/MKWFaraphel/mod_config.json index fae4403..9085e4d 100644 --- a/Pack/MKWFaraphel/ct_config.json +++ b/Pack/MKWFaraphel/mod_config.json @@ -2,121 +2,68 @@ "version":"0.11", "name":"Mario Kart Wii Faraphel", "nickname":"MKWF", - "game_variant":"60", - "region":5500, - "cheat_region":20061, - "tags_prefix":[ - "Wii U", - "3DS", - "DS", - "GCN", - "GBA", - "SNES", - "N64", - "MKT", - "RMX", - "GP", - "MSRDS", - "CTR", - "CTTR", - "CNR", - "DKR", - "LCP", - "LEGO-R", - "MP9", - "MSUSA", - "FZMV", - "KAR", - "KO", - "FZ", - "RV", - "SADX", - "SCR", - "SH", - "SM64", - "SMB1", - "SMB2", - "SSBB", - "SMS", - "SMO", - "VVVVVV", - "WF", - "WP", - "Zelda OoT", - "Zelda TP", - "Zelda WW", - "PMWR", - "SHR", - "SK64", - "SMG", - "Spyro 1", - "Wii Shop", - "UT", - "GK2", - "GK3", - "GK7", - "FGKR" - ], - "tags_suffix":[ - "Boost" - ], - "tags_color":{ - "MSRDS":"green", - "CTR":"YOR4", - "CTTR":"YOR5", - "CNR":"YOR5", - "DKR":"YOR6", - "LCP":"green", - "LEGO-R":"red2", - "MP9":"YOR0", - "MSUSA":"green", - "FZMV":"YOR2", - "KAR":"green", - "KO":"YOR5", - "FZ":"YOR2", - "RV":"white", - "SADX":"blue2", - "SCR":"YOR2", - "SH":"red", - "SM64":"red1", - "SMB1":"red2", - "SMB2":"red3", - "SSBB":"red4", - "SMS":"YOR6", - "SMO":"YOR7", - "VVVVVV":"blue", - "WF":"green", - "WP":"yellow", - "Zelda OoT":"green", - "Zelda TP":"green", - "Zelda WW":"green", - "PMWR":"yellow", - "SHR":"green", - "SK64":"green", - "SMG":"red2", - "Spyro 1":"blue", - "Wii U":"red4", - "Wii":"blue", - "3DS":"YOR3", - "DS":"white", - "GCN":"blue2", - "GBA":"blue1", - "N64":"red", - "SNES":"green", - "RMX":"YOR4", - "MKT":"YOR5", - "GP":"YOR6", - "Boost":"YOR3", - "Wii Shop":"blue1", - "UT":"red3", - "FGKR":"YOR5", - "GK2":"green", - "GK3":"green", - "GK7":"green" + "variant":"60", + "region":{ + "default": 5500, + "cheat": 20061 }, - - "tag_retro":"Retro", - + "tags_prefix":{ + "MSRDS": "green", + "CTR": "YOR4", + "CTTR": "YOR5", + "CNR": "YOR5", + "DKR": "YOR6", + "LCP": "green", + "LEGO-R": "red2", + "MP9": "YOR0", + "MSUSA": "green", + "FZMV": "YOR2", + "KAR": "green", + "KO": "YOR5", + "FZ": "YOR2", + "RV": "white", + "SADX": "blue2", + "SCR": "YOR2", + "SH": "red", + "SM64": "red1", + "SMB1": "red2", + "SMB2": "red3", + "SSBB": "red4", + "SMS": "YOR6", + "SMO": "YOR7", + "VVVVVV": "blue", + "WF": "green", + "WP": "yellow", + "Zelda OoT": "green", + "Zelda TP": "green", + "Zelda WW": "green", + "PMWR": "yellow", + "SHR": "green", + "SK64": "green", + "SMG": "red2", + "Spyro 1": "blue", + "Wii U": "red4", + "Wii": "blue", + "3DS": "YOR3", + "DS": "white", + "GCN": "blue2", + "GBA": "blue1", + "N64": "red", + "SNES": "green", + "RMX": "YOR4", + "MKT": "YOR5", + "GP": "YOR6", + "Wii Shop": "blue1", + "UT": "red3", + "GK2": "green", + "GK3": "green", + "GK7": "green", + "FGKR": "YOR5" + }, + "tags_suffix": { + "Boost": "orange" + }, + "tags_cups": ["Switch", "3DS", "DS", "GCN", "GBA", "N64", "SNES", "MKT", "DX"], "default_track":{ "music":"T32", "special":"T32", @@ -219,6 +166,7 @@ "since_version":"0.11", "score":4, "tags":[ + "Retro", "Wii U" ] }, @@ -232,6 +180,7 @@ "since_version":"0.11", "score":3, "tags":[ + "Retro", "Wii U" ], "note":"some collision (like the plane) are buggy, and the texture feel a bit too dark" @@ -265,6 +214,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "Wii U" ] }, @@ -278,6 +228,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "Wii U" ] }, @@ -291,6 +242,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "Wii U" ] }, @@ -839,6 +791,7 @@ "since_version":"0.11", "score":2, "tags":[ + "Retro", "GCN" ] }, @@ -952,6 +905,7 @@ "since_version":"0.11", "score":4, "tags":[ + "Retro", "GCN" ] } @@ -1399,6 +1353,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "N64" ] }, @@ -1440,6 +1395,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "N64" ] } @@ -1812,6 +1768,7 @@ "since_version":"0.11", "score":4, "tags":[ + "Retro", "RMX" ] }, @@ -1825,6 +1782,7 @@ "since_version":"0.11", "score":3, "tags":[ + "Retro", "RMX" ] }, @@ -1874,6 +1832,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "MKT" ] }, @@ -1887,6 +1846,7 @@ "since_version":"0.11", "score":5, "tags":[ + "Retro", "MKT" ] } @@ -1955,7 +1915,6 @@ ] } ], - "tracks":[ { "name":"4IT Clown's Road", diff --git a/source/mkw/Cup.py b/source/mkw/Cup.py index e69de29..4820acc 100644 --- a/source/mkw/Cup.py +++ b/source/mkw/Cup.py @@ -0,0 +1,4 @@ +# class that represent a mario kart wii cup +class Cup: + def __init__(self, track1: "Track" = None, track2: "Track" = None, track3: "Track" = None, track4: "Track" = None): + self._tracks = [track1, track2, track3, track4] \ No newline at end of file diff --git a/source/mkw/Game.py b/source/mkw/Game.py index e69de29..ed617e4 100644 --- a/source/mkw/Game.py +++ b/source/mkw/Game.py @@ -0,0 +1,73 @@ +import enum +from pathlib import Path + +from source.wt.wit import WITPath + + +class Extension(enum.Enum): + """ + Enum for game extension + """ + FST = ".dol" + WBFS = ".wbfs" + ISO = ".iso" + + @classmethod + def _missing_(cls, value: str) -> "Extension | None": + """ + if not found, search for the same value with lower case + :param value: value to search for + :return: None if nothing found, otherwise the found value + """ + value = value.lower() + for member in filter(lambda m: m.value == value, cls): return member + return None + + +class Region(enum.Enum): + """ + Enum for game region + """ + PAL = "PAL" + USA = "USA" + EUR = "EUR" + KOR = "KOR" + + +class Game: + def __init__(self, path: Path | str): + self.path = Path(path) if isinstance(path, str) else path + + @property + def extension(self) -> Extension: + """ + Returns the extension of the game + :return: the extension of the game + """ + return Extension(self.path.suffix) + + @property + def id(self) -> str: + """ + Return the id of the game (RMCP01, RMCK01, ...) + :return: the id of the game + """ + return WITPath(self.path).analyze()["id6"] + + @property + def region(self) -> Region: + """ + Return the region of the game (PAL, USA, EUR, ...) + :return: the region of the game + """ + return Region(WITPath(self.path).analyze()["dol_region"]) + + def is_mkw(self) -> bool: + """ + Return True if the game is Mario Kart Wii, else otherwise + :return: is the game a MKW game + """ + return WITPath(self.path).analyze()["dol_is_mkw"] == 1 + + def is_vanilla(self) -> bool: + ... diff --git a/source/mkw/ModConfig.py b/source/mkw/ModConfig.py index 0e3a9ba..1045db9 100644 --- a/source/mkw/ModConfig.py +++ b/source/mkw/ModConfig.py @@ -8,15 +8,16 @@ import json # representation of the configuration of a mod class ModConfig: - __slots__ = ("name", "nickname", "variant", "region", "tags_prefix", "tags_suffix", "tag_retro", + __slots__ = ("name", "nickname", "variant", "region", "tags_prefix", "tags_suffix", "default_track", "_tracks", "version", "original_track_prefix", "swap_original_order", - "keep_original_track", "enable_random_cup") + "keep_original_track", "enable_random_cup", "tags_cups") def __init__(self, name: str, nickname: str = None, version: str = None, variant: str = None, tags_prefix: dict[Tag, Color] = None, tags_suffix: dict[Tag, Color] = None, - region: dict[int] | int = None, tag_retro: Tag = None, default_track: "Track | TrackGroup" = None, - tracks: list["Track | TrackGroup"] = None, original_track_prefix: bool = None, - swap_original_order: bool = None, keep_original_track: bool = None, enable_random_cup: bool = None): + tags_cups: list[Tag] = None, region: dict[int] | int = None, + default_track: "Track | TrackGroup" = None, tracks: list["Track | TrackGroup"] = None, + original_track_prefix: bool = None, swap_original_order: bool = None, + keep_original_track: bool = None, enable_random_cup: bool = None): self.name: str = name self.nickname: str = nickname if nickname is not None else name @@ -24,9 +25,9 @@ class ModConfig: self.variant: str = variant if variant is not None else "01" self.region: dict[int] | int = region if region is not None else 0 - self.tags_prefix: dict[str] = tags_prefix if tags_prefix is not None else {} - self.tags_suffix: dict[str] = tags_suffix if tags_suffix is not None else {} - self.tag_retro: str = tag_retro if tag_retro is None else "Retro" + self.tags_prefix: dict[Tag] = tags_prefix if tags_prefix is not None else {} + self.tags_suffix: dict[Tag] = tags_suffix if tags_suffix is not None else {} + self.tags_cups: dict[Tag] = tags_cups if tags_cups is not None else {} self.default_track: "Track | TrackGroup" = default_track if default_track is not None else None self._tracks: list["Track | TrackGroup"] = tracks if tracks is not None else [] @@ -44,18 +45,16 @@ class ModConfig: :return: ModConfig """ + kwargs = { + attr: config_dict.get(attr) + for attr in ["nickname", "version", "variant", "tags_prefix", "tags_suffix", "tags_cups", + "original_track_prefix", "swap_original_order", "keep_original_track", "enable_random_cup"] + } + return cls( name=config_dict["name"], - nickname=config_dict.get("nickname"), - version=config_dict.get("version"), - variant=config_dict.get("variant"), - tags_prefix=config_dict.get("tags_prefix"), - tags_suffix=config_dict.get("tags_suffix"), - tag_retro=config_dict.get("tag_retro"), - original_track_prefix=config_dict.get("original_track_prefix"), - swap_original_order=config_dict.get("swap_original_order"), - keep_original_track=config_dict.get("keep_original_track"), - enable_random_cup=config_dict.get("enable_random_cup"), + + **kwargs, default_track=Track.from_dict(config_dict.get("default_track", {})), tracks=[Track.from_dict(track) for track in config_dict.get("tracks", [])], diff --git a/source/wt/szs.py b/source/wt/szs.py index 089522b..673fe9b 100644 --- a/source/wt/szs.py +++ b/source/wt/szs.py @@ -1,7 +1,7 @@ from source.wt import * from source.wt import _run, _run_dict -tools_path = tools_szs_dir / "wszst.exe" +tools_path = tools_szs_dir / ("wszst.exe" if system == "win64" else "wszst") class SZSPath: diff --git a/source/wt/wit.py b/source/wt/wit.py new file mode 100644 index 0000000..feb527f --- /dev/null +++ b/source/wt/wit.py @@ -0,0 +1,36 @@ +from source.wt import * +from source.wt import _run, _run_dict + +tools_path = tools_wit_dir / ("wit.exe" if system == "win64" else "wit") + + +class WITPath: + __slots__ = ("path",) + + def __init__(self, path: Path): + self.path = path + + @better_error(tools_path) + def _run(self, *args) -> bytes: + """ + Return a command with wit and return the output + :param args: command arguments + :return: the output of the command + """ + return _run(tools_path, *args) + + @better_error(tools_path) + def _run_dict(self, *args) -> dict: + """ + Return a dictionary of a command that return value associated to a key with a equal sign + :param args: others arguments + :return: the dictionary + """ + return _run_dict(tools_path, *args) + + def analyze(self) -> dict: + """ + Return the analyze of the file + :return: dictionnary of key and value of the analyze + """ + return self._run_dict("ANALYZE", self.path)