cleaned Riivolution generation

This commit is contained in:
Faraphel 2022-08-27 18:58:09 +02:00
parent 6e032d4d1a
commit 6fe1223c8b
4 changed files with 90 additions and 67 deletions

View file

@ -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"
}
}

View file

@ -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"
}
}

View file

@ -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((
'<wiidisc version="1">',
' <id game="RMC" disc="0" version="0"> </id>',
'',
' <options>',
f' <section name="{str(mod_config)}">',
' <option id="CT" name="Custom Tracks" default="1">',
' <choice name="Enabled"> <patch id="mod"/> </choice>',
' </option>',
' <option id="save_SD" name="Save on SD" default="1">',
' <choice name="Enabled"> <patch id="save_SD"/> </choice>',
' </option>',
' <option id="my_stuff" name="My Stuff" default="1">',
' <choice name="Enabled"> <patch id="my_stuff"/> </choice>',
' </option>',
' </section>',
' </options>',
'',
' <patch id="mod">',
f' <folder disc="/" external="/{self.path.name}/files/" recursive="true" create="true"/>',
f' <folder disc="" external="/{self.path.name}/sys/" recursive="true" create="true"/>',
' </patch>',
'',
' <patch id="my_stuff">',
f' <folder external="/{RIIVOLUTION_FOLDER_NAME}/MyStuff/" recursive="false"/>',
f' <folder external="/{RIIVOLUTION_FOLDER_NAME}/MyStuff/" disc="/"/>',
' </patch>',
'',
' <patch id="save_SD">',
' <savegame clone="false"',
f' external="/{RIIVOLUTION_FOLDER_NAME}/save/{"{$__gameid}{$__region}"}{mod_config.variant}"/>',
' </patch>',
'</wiidisc>',
))
# 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

View file

@ -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"""
<wiidisc version="1">
<id game="RMC" disc="0" version="0">
<region type="P"/>
<region type="J"/>
<region type="E"/>
<region type="K"/>
</id>
<options>
<section name="{str(mod_config)}">
<option id="CT" name="Custom Tracks" default="1">
<choice name="Enabled"> <patch id="mod"/> </choice>
</option>
<option id="save_SD" name="Save on SD" default="1">
<choice name="Enabled"> <patch id="save_SD"/> </choice>
</option>
<option id="my_stuff" name="My Stuff" default="1">
<choice name="Enabled"> <patch id="my_stuff"/> </choice>
</option>
</section>
</options>
<patch id="mod">
<folder disc="/" external="/{extracted_game.path.name}/files/" recursive="true" create="true"/>
<folder disc="" external="/{extracted_game.path.name}/sys/" recursive="true" create="true"/>
</patch>
<patch id="my_stuff">
<folder external="/riivolution/MyStuff/" recursive="false"/>
<folder external="/riivolution/MyStuff/" disc="/"/>
</patch>
<patch id="save_SD">
<savegame clone="false" external="/riivolution/save/{'{$__gameid}{$__region}'}{mod_config.variant}"/>
</patch>
</wiidisc>
"""
# 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