added special operation, allowing for replacing a file_content with a precalculated file, useful for ct_icons.tpl for example

This commit is contained in:
Faraphel 2022-07-14 15:47:35 +02:00
parent cab9b7745d
commit fbdd207c52
6 changed files with 45 additions and 11 deletions

View file

@ -0,0 +1,6 @@
{
"operation": {
"special": {"name": "ct_icon"},
"img-encode": {"encoding": "TPL.CMPR"}
}
}

View file

@ -1,5 +1,6 @@
from io import BytesIO
from pathlib import Path from pathlib import Path
from typing import Generator from typing import Generator, IO
from source.mkw.ModConfig import ModConfig from source.mkw.ModConfig import ModConfig
from source.mkw.Patch.Patch import Patch from source.mkw.Patch.Patch import Patch
@ -14,6 +15,7 @@ class ExtractedGame:
def __init__(self, path: Path | str, original_game: "Game" = None): def __init__(self, path: Path | str, original_game: "Game" = None):
self.path = Path(path) self.path = Path(path)
self.original_game = original_game self.original_game = original_game
self._special_file: dict[str, IO] = {}
def extract_autoadd(self, destination_path: Path | str) -> Generator[dict, None, None]: def extract_autoadd(self, destination_path: Path | str) -> Generator[dict, None, None]:
""" """
@ -30,18 +32,33 @@ class ExtractedGame:
:return: :return:
""" """
yield {"description": "Installing MyStuff directory...", "determinate": False} yield {"description": "Installing MyStuff directory...", "determinate": False}
... # TODO: implement mystuff
def prepare_special_file(self, mod_config: ModConfig) -> Generator[dict, None, None]:
"""
Prepare special files for the patch
:return: the special files dict
"""
yield {"description": "Preparing ct_icon special file...", "determinate": False}
ct_icons = BytesIO()
mod_config.get_full_cticon().save(ct_icons, format="PNG")
ct_icons.seek(0)
self._special_file["ct_icon"] = ct_icons
def install_all_patch(self, mod_config: ModConfig) -> Generator[dict, None, None]: def install_all_patch(self, mod_config: ModConfig) -> Generator[dict, None, None]:
""" """
Install all patchs of the mod_config into the game Install all patchs of the mod_config into the game
:param special_file: special file that can be used to patch the game
:param mod_config: the mod to install :param mod_config: the mod to install
:return: :return:
""" """
yield {"description": "Installing all Patch...", "determinate": False} yield {"description": "Installing all Patch...", "determinate": False}
# prepare special files data
yield from self.prepare_special_file(mod_config)
# for all directory that are in the root of the mod, and don't start with an underscore, # for all directory that are in the root of the mod, and don't start with an underscore,
# for all the subdirectory named "_PATCH", apply the patch # for all the subdirectory named "_PATCH", apply the patch
for part_directory in mod_config.get_mod_directory().glob("[!_]*"): for part_directory in mod_config.get_mod_directory().glob("[!_]*"):
for patch_directory in part_directory.glob("_PATCH/"): for patch_directory in part_directory.glob("_PATCH/"):
yield from Patch(patch_directory, mod_config).install(self) yield from Patch(patch_directory, mod_config, self._special_file).install(self)

View file

@ -1,4 +1,4 @@
from typing import Generator from typing import Generator, IO
from source.mkw.Patch import * from source.mkw.Patch import *
from source.safe_eval import safe_eval, multiple_safe_eval from source.safe_eval import safe_eval, multiple_safe_eval
@ -9,9 +9,10 @@ class Patch:
Represent a patch object Represent a patch object
""" """
def __init__(self, path: Path | str, mod_config: "ModConfig"): def __init__(self, path: Path | str, mod_config: "ModConfig", special_file: dict[str, IO] = None):
self.path = Path(path) self.path = Path(path)
self.mod_config = mod_config self.mod_config = mod_config
self.special_file = special_file if special_file is not None else {}
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<{self.__class__.__name__} {self.path}>" return f"<{self.__class__.__name__} {self.path}>"

View file

@ -1,5 +1,5 @@
from io import BytesIO from io import BytesIO
from typing import Generator, IO from typing import Generator
from source.mkw.Patch import * from source.mkw.Patch import *
from source.mkw.Patch.PatchOperation import PatchOperation from source.mkw.Patch.PatchOperation import PatchOperation
@ -44,11 +44,6 @@ class PatchFile(PatchObject):
if szs_path.with_suffix(".szs").exists(): if szs_path.with_suffix(".szs").exists():
SZSPath(szs_path.with_suffix(".szs")).extract_all(szs_path) SZSPath(szs_path.with_suffix(".szs")).extract_all(szs_path)
# if the file is a special file
if self.full_path.name.startswith("#"):
# print(f"special file : {self} [install to {game_subpath}]")
return
# apply operation on the file # apply operation on the file
patch_source: Path = self.get_source_path(game_subpath) patch_source: Path = self.get_source_path(game_subpath)
patch_name: str = game_subpath.name patch_name: str = game_subpath.name

View file

@ -31,6 +31,21 @@ class PatchOperation:
patch a file and return the new file_path (if changed) and the new content of the file patch a file and return the new file_path (if changed) and the new content of the file
""" """
class Special(Operation):
"""
use a file defined as special in the patch to replate the current file content
"""
type = "special"
def __init__(self, name: str):
self.name = name
def patch(self, patch: "Patch", file_name: str, file_content: IO) -> (str, IO):
patch_content = patch.special_file[self.name]
patch_content.seek(0)
return file_name, patch_content
class ImageGenerator(Operation): class ImageGenerator(Operation):
""" """
generate a new image based on a file and apply a generator on it generate a new image based on a file and apply a generator on it