mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-01 18:28:27 +02:00
61 lines
2.7 KiB
Python
61 lines
2.7 KiB
Python
from pathlib import Path
|
|
from typing import Generator, TYPE_CHECKING
|
|
|
|
from source.mkw.Patch import PathOutsidePatch, InvalidPatchMode
|
|
from source.mkw.Patch.PatchObject import PatchObject
|
|
from source.progress import Progress
|
|
|
|
if TYPE_CHECKING:
|
|
from source.mkw.ExtractedGame import ExtractedGame
|
|
|
|
|
|
class PatchDirectory(PatchObject):
|
|
"""
|
|
Represent a directory from a patch
|
|
"""
|
|
|
|
@property
|
|
def subpatchs(self) -> Generator["PatchObject", None, None]:
|
|
"""
|
|
return all the subpatchs inside the PatchDirectory
|
|
"""
|
|
for subpath in self.full_path.iterdir():
|
|
if subpath.suffix == ".json": continue
|
|
yield self.subfile_from_path(subpath)
|
|
|
|
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[Progress, None, None]:
|
|
"""
|
|
patch a subdirectory of the game with the PatchDirectory
|
|
"""
|
|
yield Progress(description=f"Patching {game_subpath}")
|
|
|
|
# check if the directory should be patched
|
|
if not self.is_enabled(extracted_game): return
|
|
|
|
match self.configuration["mode"]:
|
|
# if the mode is copy, then simply patch the subfile into the game with the same path
|
|
case "copy":
|
|
for subpatch in self.subpatchs:
|
|
# install the subfile in the directory with the same name as the PatchDirectory
|
|
yield from subpatch.install(extracted_game, game_subpath / subpatch.full_path.name)
|
|
|
|
# if the mode is replace, patch all the files that match the replace_regex
|
|
case "match":
|
|
for subpatch in self.subpatchs:
|
|
# install the subfile in all the directory that match the match_regex of the configuration
|
|
for game_subfile in game_subpath.parent.glob(self.configuration["match_regex"]):
|
|
# disallow patching files outside of the game
|
|
if not game_subfile.relative_to(extracted_game.path):
|
|
raise PathOutsidePatch(game_subfile, extracted_game.path)
|
|
|
|
# patch the game with the subpatch
|
|
# if the subfile is a szs archive, replace it with a .d extension
|
|
if game_subfile.suffix == ".szs": game_subfile = game_subfile.with_suffix(".d")
|
|
yield from subpatch.install(extracted_game, game_subfile / subpatch.full_path.name)
|
|
|
|
# ignore if mode is "ignore", useful if the file is used as a resource for an operation
|
|
case "ignore": pass
|
|
|
|
# else raise an error
|
|
case _:
|
|
raise InvalidPatchMode(self, self.configuration["mode"])
|