diff --git a/source/mkw/ModConfig.py b/source/mkw/ModConfig.py index f4a48bc..6fa7d84 100644 --- a/source/mkw/ModConfig.py +++ b/source/mkw/ModConfig.py @@ -11,7 +11,7 @@ from source.mkw.Track import Track import json from source.mkw.OriginalTrack import OriginalTrack -from source.safe_eval import safe_eval +from source.safe_eval import safe_eval, multiple_safe_eval from source.wt.szs import SZSPath CT_ICON_SIZE: int = 128 @@ -106,6 +106,20 @@ class ModConfig: macros=json.loads(macros_file.read_text(encoding="utf8")) if macros_file.exists() else None, ) + def safe_eval(self, template: str, multiple: bool = False, env: dict[str, any] = None) -> str: + """ + Safe eval with a patch environment + :param multiple: should the expression be a multiple safe eval or a single safe eval + :param env: other variable that are allowed in the safe_eval + :param template: template to evaluate + :return: the result of the evaluation + """ + return (multiple_safe_eval if multiple else safe_eval)( + template, + env={"mod_config": self} | (env if env is not None else {}), + macros=self.macros, + ) + def get_mod_directory(self) -> Path: """ Get the directory of the mod diff --git a/source/mkw/Patch/Patch.py b/source/mkw/Patch/Patch.py index 1e91847..77258da 100644 --- a/source/mkw/Patch/Patch.py +++ b/source/mkw/Patch/Patch.py @@ -1,7 +1,6 @@ from typing import Generator, IO from source.mkw.Patch import * -from source.safe_eval import safe_eval, multiple_safe_eval class Patch: @@ -17,20 +16,6 @@ class Patch: def __repr__(self) -> str: return f"<{self.__class__.__name__} {self.path}>" - def safe_eval(self, template: str, multiple: bool = False, env: dict[str, any] = None) -> str: - """ - Safe eval with a patch environment - :param multiple: should the expression be a multiple safe eval or a single safe eval - :param env: other variable that are allowed in the safe_eval - :param template: template to evaluate - :return: the result of the evaluation - """ - return (multiple_safe_eval if multiple else safe_eval)( - template, - env={"mod_config": self.mod_config} | (env if env is not None else {}), - macros=self.mod_config.macros, - ) - def install(self, extracted_game: "ExtractedGame") -> Generator[dict, None, None]: """ patch a game with this Patch diff --git a/source/mkw/Patch/PatchDirectory.py b/source/mkw/Patch/PatchDirectory.py index 1717f2f..d04c21b 100644 --- a/source/mkw/Patch/PatchDirectory.py +++ b/source/mkw/Patch/PatchDirectory.py @@ -24,7 +24,8 @@ class PatchDirectory(PatchObject): """ yield {"description": f"Patching {self}"} - if self.patch.safe_eval(self.configuration["if"], env={"extracted_game": extracted_game}) != "True": return + if self.patch.mod_config.safe_eval(self.configuration["if"], env={"extracted_game": extracted_game}) != "True": + return match self.configuration["mode"]: # if the mode is copy, then simply patch the subfile into the game with the same path diff --git a/source/mkw/Patch/PatchFile.py b/source/mkw/Patch/PatchFile.py index e071c40..cd967d6 100644 --- a/source/mkw/Patch/PatchFile.py +++ b/source/mkw/Patch/PatchFile.py @@ -31,7 +31,8 @@ class PatchFile(PatchObject): yield {"description": f"Patching {self}"} # check if the file should be patched considering the "if" configuration - if self.patch.safe_eval(self.configuration["if"], env={"extracted_game": extracted_game}) != "True": return + if self.patch.mod_config.safe_eval(self.configuration["if"], env={"extracted_game": extracted_game}) != "True": + return # check if the path to the game_subpath is inside a szs, and if yes extract it for szs_subpath in filter(lambda path: path.suffix == ".d", diff --git a/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/IDLayer.py b/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/IDLayer.py index c331a08..41cdd36 100644 --- a/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/IDLayer.py +++ b/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/IDLayer.py @@ -16,6 +16,6 @@ class IDLayer(AbstractLayer): def patch_bmg(self, patch: "Patch", decoded_content: str) -> str: return decoded_content + "\n" + ("\n".join( - [f" {id}\t= {patch.safe_eval(repl, multiple=True)}" for id, repl in self.template.items()] + [f" {id}\t= {patch.mod_config.safe_eval(repl, multiple=True)}" for id, repl in self.template.items()] )) + "\n" # add new bmg definition at the end of the bmg file, overwritting old id. diff --git a/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/RegexLayer.py b/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/RegexLayer.py index f9f8f34..d57f897 100644 --- a/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/RegexLayer.py +++ b/source/mkw/Patch/PatchOperation/Operation/BmgTxtEditor/Layer/RegexLayer.py @@ -28,7 +28,7 @@ class RegexLayer(AbstractLayer): for pattern, repl in self.template.items(): value = re.sub( pattern, - patch.safe_eval(repl, multiple=True), + patch.mod_config.safe_eval(repl, multiple=True), value, flags=re.DOTALL ) diff --git a/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/ColorLayer.py b/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/ColorLayer.py index ae506a2..37d28f0 100644 --- a/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/ColorLayer.py +++ b/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/ColorLayer.py @@ -3,6 +3,9 @@ from PIL import ImageDraw, Image from source.mkw.Patch.PatchOperation.Operation.ImageEditor.Layer import * +Patch: any + + class ColorLayer(AbstractLayer): """ Represent a layer that fill a rectangle with a certain color on the image diff --git a/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/TextLayer.py b/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/TextLayer.py index f8584f8..ac8f2e8 100644 --- a/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/TextLayer.py +++ b/source/mkw/Patch/PatchOperation/Operation/ImageEditor/Layer/TextLayer.py @@ -38,7 +38,7 @@ class TextLayer(AbstractLayer): ) draw.text( self.get_layer_position(image), - text=patch.safe_eval(self.text, multiple=True), + text=patch.mod_config.safe_eval(self.text, multiple=True), fill=self.color, font=font ) diff --git a/source/mkw/Track.py b/source/mkw/Track.py index e068e3f..02cc839 100644 --- a/source/mkw/Track.py +++ b/source/mkw/Track.py @@ -4,7 +4,6 @@ from source.mkw import Tag, Slot from source.mkw.MKWColor import bmg_color_text from source.safe_eval import multiple_safe_eval - ModConfig: any @@ -53,13 +52,14 @@ class Track: :return: formatted representation of the track """ - return multiple_safe_eval( + return mod_config.safe_eval( template, env={ "track": self, "prefix": self.get_prefix(mod_config, ""), "suffix": self.get_suffix(mod_config, "") - } + }, + multiple=True ) def get_tag_template(self, templates: dict[str, str], default: any = None) -> any: @@ -71,6 +71,7 @@ class Track: """ for tag in filter(lambda tag: tag in templates, self.tags): template: str = templates[tag] + # TODO: this should try to use mod_config for save_eval return multiple_safe_eval(template, env={"TAG": tag, "bmg_color_text": bmg_color_text}) return default