diff --git a/assets/language/en.json b/assets/language/en.json index 4fa30ba..59e78eb 100644 --- a/assets/language/en.json +++ b/assets/language/en.json @@ -108,6 +108,11 @@ "TESTING_MOD_SETTINGS": "Test mod settings", "SETTINGS_FILE": "Settings file", "EXPORT_SETTINGS": "Export settings", - "IMPORT_SETTINGS": "Import settings" + "IMPORT_SETTINGS": "Import settings", + "PREPARING_RIIVOLUTION": "Preparing for riivolution", + "CONVERTING_TO_RIIVOLUTION": "Converting to Riivolution patch", + "PATCHS": "patchs", + "PRE-PATCHS": "pre-patchs", + "CALCULATING_HASH_FOR": "Calculating hash for" } } \ No newline at end of file diff --git a/assets/language/fr.json b/assets/language/fr.json index 89c4e12..1f8679e 100644 --- a/assets/language/fr.json +++ b/assets/language/fr.json @@ -109,6 +109,11 @@ "TESTING_MOD_SETTINGS": "Paramètre de test", "SETTINGS_FILE": "Fichier de paramètres", "EXPORT_SETTINGS": "Exporter les paramètres", - "IMPORT_SETTINGS": "Importer les paramètres" + "IMPORT_SETTINGS": "Importer les paramètres", + "PREPARING_RIIVOLUTION": "Préparation pour Riivolution", + "CONVERTING_TO_RIIVOLUTION": "Conversion en patch Riivolution", + "PATCHS": "patchs", + "PRE-PATCHS": "pre-patchs", + "CALCULATING_HASH_FOR": "Calcule du hash pour" } } \ No newline at end of file diff --git a/source/mkw/ExtractedGame.py b/source/mkw/ExtractedGame.py index 5d3eb17..097d891 100644 --- a/source/mkw/ExtractedGame.py +++ b/source/mkw/ExtractedGame.py @@ -9,6 +9,7 @@ from source.mkw.ModConfig import ModConfig from source.mkw.Patch.Patch import Patch from source.mkw.collection.Extension import Extension from source.progress import Progress +from source.utils import comp_dict_changes from source.wt import szs, lec, wit from source.wt.wstrt import StrPath from source.translation import translate as _ @@ -17,6 +18,9 @@ if TYPE_CHECKING: from source.mkw.Game import Game +RIIVOLUTION_FOLDER_NAME: str = "riivolution" + + class PathOutsideMod(Exception): def __init__(self, forbidden_path: Path, allowed_range: Path): super().__init__(_("PATH", ' "', forbidden_path, '" ', "OUTSIDE_ALLOWED_RANGE", ' "', allowed_range, '" ')) @@ -166,7 +170,7 @@ class ExtractedGame: Used before the lecode patch is applied :param mod_config: the mod to install """ - yield Progress(description=_("INSTALLING_ALL", " Pre-Patchs..."), determinate=False) + yield Progress(description=_("INSTALLING_ALL", " ", "PRE-PATCHS", "..."), determinate=False) yield from self._install_all_patch(mod_config, "_PREPATCH/") def install_all_patch(self, mod_config: ModConfig) -> Generator[Progress, None, None]: @@ -175,7 +179,7 @@ class ExtractedGame: Used after the lecode patch is applied :param mod_config: the mod to install """ - yield Progress(description=_("INSTALLING_ALL", " Patchs..."), determinate=False) + yield Progress(description=_("INSTALLING_ALL", " ", "PATCHS", "..."), determinate=False) yield from self._install_all_patch(mod_config, "_PATCH/") def convert_to(self, output_type: Extension) -> Generator[Progress, None, wit.WITPath | None]: @@ -205,7 +209,67 @@ class ExtractedGame: return converted_game - def get_hash_map(self) -> dict[str, str]: + def convert_to_riivolution(self, mod_config: ModConfig, old_hash_map: dict[str, str] + ) -> Generator[Progress, None, None]: + """ + Convert the extracted game into a riivolution patch + :param mod_config: the mod configuration + :param old_hash_map: hash map of all the games files created before all the modifications + """ + new_hash_map = yield from self.get_hash_map() + + yield Progress(description=_("CONVERTING_TO_RIIVOLUTION"), determinate=False) + + # get the files difference between the original game and the patched game + diff_hash_map: dict[str, Path] = comp_dict_changes(old_hash_map, new_hash_map) + + for file in filter(lambda file: file.is_file(), self.path.rglob("*")): + # if the file have not being patched, delete it + if str(file.relative_to(self.path)) not in diff_hash_map: + file.unlink() + + # get riivolution configuration content + riivolution_config_content = "\n".join(( + '', + ' ', + '', + ' ', + f'
', + ' ', + ' ', + ' ', + '
', + '
', + '', + ' ', + f' ', + f' ', + ' ', + '', + ' ', + f' ', + f' ', + ' ', + '', + ' ', + ' ', + ' ', + '
', + )) + + # get riivolution configuration path + riivolution_config_path: Path = self.path.parent / f"{RIIVOLUTION_FOLDER_NAME}/{str(mod_config)}.xml" + riivolution_config_path.parent.mkdir(parents=True, exist_ok=True) + riivolution_config_path.write_text(riivolution_config_content, encoding="utf-8") + + def get_hash_map(self) -> Generator[Progress, None, dict[str, str]]: """ Return a dictionary associating all the game subfiles to a hash :return: a dictionary associating all the game subfiles to a hash @@ -214,10 +278,13 @@ class ExtractedGame: for fp in filter(lambda fp: fp.is_file(), self.path.rglob("*")): hasher = hashlib.md5() + rel_path: str = str(fp.relative_to(self.path)) + + yield Progress(description=_(f"CALCULATING_HASH_FOR", ' "', rel_path, '"')) with open(fp, "rb") as file: while block := file.read(file_block_size): hasher.update(block) - md5_map[str(fp.relative_to(self.path))] = hasher.hexdigest() + md5_map[rel_path] = hasher.hexdigest() return md5_map diff --git a/source/mkw/Game.py b/source/mkw/Game.py index 2eb5459..23c85e2 100644 --- a/source/mkw/Game.py +++ b/source/mkw/Game.py @@ -7,7 +7,6 @@ from source.mkw.collection.Extension import Extension from source.mkw.collection.Region import Region from source.option import Options from source.progress import Progress -from source.utils import comp_dict_changes from source.wt.wit import WITPath from source.translation import translate as _ @@ -124,10 +123,11 @@ class Game: yield Progress(title=_("EXTRACTION"), set_part=1) yield from self.extract(extracted_game.path) - # Riivolution hash map for the final comparaison - yield Progress(title=_("PREPARING_RIIVOLUTION"), set_part=2, - description=_("PREPARING_RIIVOLUTION"), determinate=False) - if output_type.is_riivolution(): riivolution_original_hash_map = extracted_game.get_hash_map() + # Get the original file hash map for comparaison with the post-patched game + yield Progress(title=_("PREPARING_RIIVOLUTION"), set_part=2) + riivolution_original_hash_map: dict[str, str] | None = None + if output_type.is_riivolution(): + riivolution_original_hash_map = yield from extracted_game.get_hash_map() # install mystuff yield Progress(title=_("MYSTUFF"), set_part=3) @@ -165,62 +165,8 @@ class Game: yield from extracted_game.recreate_all_szs() if output_type.is_riivolution(): - # Riivolution comparaison - riivolution_patched_hash_map = extracted_game.get_hash_map() - riivolution_diff: dict[str, Path] = comp_dict_changes( - riivolution_original_hash_map, - riivolution_patched_hash_map - ) - - for file in filter(lambda file: file.is_file(), extracted_game.path.rglob("*")): - # if the file have not being patched, delete it - if str(file.relative_to(extracted_game.path)) not in riivolution_diff: - file.unlink() - - # get riivolution configuration content - riivolution_config_content = f""" - - - - - - - - - -
- - - -
-
- - - - - - - - - - - - - - -
- """ - - # get riivolution configuration path - riivolution_config_path = extracted_game.path.parent / f"riivolution/{str(mod_config)}.xml" - riivolution_config_path.parent.mkdir(parents=True, exist_ok=True) - riivolution_config_path.write_text(riivolution_config_content, encoding="utf8") + yield Progress(title=_("CONVERTING_TO_RIIVOLUTION"), set_part=8) + yield from extracted_game.convert_to_riivolution(mod_config, riivolution_original_hash_map) else: # convert the extracted game into a file