mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-03 03:08:29 +02:00
cleaned Riivolution generation
This commit is contained in:
parent
6e032d4d1a
commit
6fe1223c8b
4 changed files with 90 additions and 67 deletions
|
@ -108,6 +108,11 @@
|
||||||
"TESTING_MOD_SETTINGS": "Test mod settings",
|
"TESTING_MOD_SETTINGS": "Test mod settings",
|
||||||
"SETTINGS_FILE": "Settings file",
|
"SETTINGS_FILE": "Settings file",
|
||||||
"EXPORT_SETTINGS": "Export settings",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -109,6 +109,11 @@
|
||||||
"TESTING_MOD_SETTINGS": "Paramètre de test",
|
"TESTING_MOD_SETTINGS": "Paramètre de test",
|
||||||
"SETTINGS_FILE": "Fichier de paramètres",
|
"SETTINGS_FILE": "Fichier de paramètres",
|
||||||
"EXPORT_SETTINGS": "Exporter les 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"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ from source.mkw.ModConfig import ModConfig
|
||||||
from source.mkw.Patch.Patch import Patch
|
from source.mkw.Patch.Patch import Patch
|
||||||
from source.mkw.collection.Extension import Extension
|
from source.mkw.collection.Extension import Extension
|
||||||
from source.progress import Progress
|
from source.progress import Progress
|
||||||
|
from source.utils import comp_dict_changes
|
||||||
from source.wt import szs, lec, wit
|
from source.wt import szs, lec, wit
|
||||||
from source.wt.wstrt import StrPath
|
from source.wt.wstrt import StrPath
|
||||||
from source.translation import translate as _
|
from source.translation import translate as _
|
||||||
|
@ -17,6 +18,9 @@ if TYPE_CHECKING:
|
||||||
from source.mkw.Game import Game
|
from source.mkw.Game import Game
|
||||||
|
|
||||||
|
|
||||||
|
RIIVOLUTION_FOLDER_NAME: str = "riivolution"
|
||||||
|
|
||||||
|
|
||||||
class PathOutsideMod(Exception):
|
class PathOutsideMod(Exception):
|
||||||
def __init__(self, forbidden_path: Path, allowed_range: Path):
|
def __init__(self, forbidden_path: Path, allowed_range: Path):
|
||||||
super().__init__(_("PATH", ' "', forbidden_path, '" ', "OUTSIDE_ALLOWED_RANGE", ' "', allowed_range, '" '))
|
super().__init__(_("PATH", ' "', forbidden_path, '" ', "OUTSIDE_ALLOWED_RANGE", ' "', allowed_range, '" '))
|
||||||
|
@ -166,7 +170,7 @@ class ExtractedGame:
|
||||||
Used before the lecode patch is applied
|
Used before the lecode patch is applied
|
||||||
:param mod_config: the mod to install
|
: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/")
|
yield from self._install_all_patch(mod_config, "_PREPATCH/")
|
||||||
|
|
||||||
def install_all_patch(self, mod_config: ModConfig) -> Generator[Progress, None, None]:
|
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
|
Used after the lecode patch is applied
|
||||||
:param mod_config: the mod to install
|
: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/")
|
yield from self._install_all_patch(mod_config, "_PATCH/")
|
||||||
|
|
||||||
def convert_to(self, output_type: Extension) -> Generator[Progress, None, wit.WITPath | None]:
|
def convert_to(self, output_type: Extension) -> Generator[Progress, None, wit.WITPath | None]:
|
||||||
|
@ -205,7 +209,67 @@ class ExtractedGame:
|
||||||
|
|
||||||
return converted_game
|
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
|
||||||
: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("*")):
|
for fp in filter(lambda fp: fp.is_file(), self.path.rglob("*")):
|
||||||
hasher = hashlib.md5()
|
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:
|
with open(fp, "rb") as file:
|
||||||
while block := file.read(file_block_size):
|
while block := file.read(file_block_size):
|
||||||
hasher.update(block)
|
hasher.update(block)
|
||||||
md5_map[str(fp.relative_to(self.path))] = hasher.hexdigest()
|
md5_map[rel_path] = hasher.hexdigest()
|
||||||
|
|
||||||
return md5_map
|
return md5_map
|
||||||
|
|
|
@ -7,7 +7,6 @@ from source.mkw.collection.Extension import Extension
|
||||||
from source.mkw.collection.Region import Region
|
from source.mkw.collection.Region import Region
|
||||||
from source.option import Options
|
from source.option import Options
|
||||||
from source.progress import Progress
|
from source.progress import Progress
|
||||||
from source.utils import comp_dict_changes
|
|
||||||
from source.wt.wit import WITPath
|
from source.wt.wit import WITPath
|
||||||
from source.translation import translate as _
|
from source.translation import translate as _
|
||||||
|
|
||||||
|
@ -124,10 +123,11 @@ class Game:
|
||||||
yield Progress(title=_("EXTRACTION"), set_part=1)
|
yield Progress(title=_("EXTRACTION"), set_part=1)
|
||||||
yield from self.extract(extracted_game.path)
|
yield from self.extract(extracted_game.path)
|
||||||
|
|
||||||
# Riivolution hash map for the final comparaison
|
# Get the original file hash map for comparaison with the post-patched game
|
||||||
yield Progress(title=_("PREPARING_RIIVOLUTION"), set_part=2,
|
yield Progress(title=_("PREPARING_RIIVOLUTION"), set_part=2)
|
||||||
description=_("PREPARING_RIIVOLUTION"), determinate=False)
|
riivolution_original_hash_map: dict[str, str] | None = None
|
||||||
if output_type.is_riivolution(): riivolution_original_hash_map = extracted_game.get_hash_map()
|
if output_type.is_riivolution():
|
||||||
|
riivolution_original_hash_map = yield from extracted_game.get_hash_map()
|
||||||
|
|
||||||
# install mystuff
|
# install mystuff
|
||||||
yield Progress(title=_("MYSTUFF"), set_part=3)
|
yield Progress(title=_("MYSTUFF"), set_part=3)
|
||||||
|
@ -165,62 +165,8 @@ class Game:
|
||||||
yield from extracted_game.recreate_all_szs()
|
yield from extracted_game.recreate_all_szs()
|
||||||
|
|
||||||
if output_type.is_riivolution():
|
if output_type.is_riivolution():
|
||||||
# Riivolution comparaison
|
yield Progress(title=_("CONVERTING_TO_RIIVOLUTION"), set_part=8)
|
||||||
riivolution_patched_hash_map = extracted_game.get_hash_map()
|
yield from extracted_game.convert_to_riivolution(mod_config, riivolution_original_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")
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# convert the extracted game into a file
|
# convert the extracted game into a file
|
||||||
|
|
Loading…
Reference in a new issue