implemented SzsEdit to allow easier track modification (changing laps count, ...)

This commit is contained in:
Faraphel 2022-08-14 16:09:30 +02:00
parent 20a7abadaf
commit 781e564dd2
8 changed files with 81 additions and 2 deletions

View file

@ -1,4 +1,4 @@
{ {
"mode": "match", "mode": "match-copy",
"match_regex": "*/*.thp" "match_regex": "*/*.thp"
} }

View file

@ -0,0 +1,12 @@
{
"mode": "match-edit",
"match_regex": "*.szs",
"operation": {
"szs-edit": {
"scale": {"x": 2, "y": 2, "z": 2},
"speed": 1.5,
"laps": 9
}
}
}

View file

@ -23,6 +23,7 @@ class AbstractLayer(ABC):
""" """
Patch a bmg with the actual layer. Return the new bmg content. Patch a bmg with the actual layer. Return the new bmg content.
""" """
...
@classmethod @classmethod
def get(cls, layer: dict) -> "AbstractLayer": def get(cls, layer: dict) -> "AbstractLayer":

View file

@ -65,6 +65,7 @@ class AbstractLayer(ABC):
""" """
Patch an image with the actual layer. Return the new image. Patch an image with the actual layer. Return the new image.
""" """
...
@classmethod @classmethod
def get(cls, layer: dict) -> "AbstractLayer": def get(cls, layer: dict) -> "AbstractLayer":

View file

@ -0,0 +1,39 @@
from io import BytesIO
from typing import IO, TYPE_CHECKING
from source.mkw.Patch.PatchOperation import AbstractPatchOperation
from source.wt import szs
if TYPE_CHECKING:
from source.mkw.Patch import Patch
class SzsEditor(AbstractPatchOperation):
"""
patch a track szs file
"""
type = "szs-edit"
def __init__(self, scale: dict[str, int] = None, shift: dict[str, int] = None, rotation: dict[str, int] = None,
translate: dict[str, int] = None, speed: str = None, laps: str = None):
self.scale = scale # example : {"x": 1, "y": 1, "z": 1}
self.shift = shift
self.rotation = rotation
self.translate = translate
self.speed = float(speed)
self.laps = int(laps)
def patch(self, patch: "Patch", file_name: str, file_content: IO) -> (str, IO):
patched_content = BytesIO(szs.patch(
file_content.read(),
scale=self.scale,
shift=self.shift,
rotation=self.rotation,
translate=self.translate,
speed=self.speed,
laps=self.laps,
))
return file_name, patched_content

View file

@ -39,5 +39,5 @@ class AbstractPatchOperation(ABC):
# load all the subclass of AbstractPatchOperation to that __subclasses__ can filter them # load all the subclass of AbstractPatchOperation to that __subclasses__ can filter them
from source.mkw.Patch.PatchOperation import ( from source.mkw.Patch.PatchOperation import (
ImageDecoder, ImageEncoder, Rename, Special, StrEditor, ImageDecoder, ImageEncoder, Rename, Special, StrEditor,
BmgTxtEditor, ImageEditor, BmgEncoder, BmgDecoder BmgTxtEditor, ImageEditor, BmgEncoder, BmgDecoder, SzsEditor
) )

View file

@ -6,6 +6,7 @@ tools_path = tools_szs_dir / "wszst"
_tools_run = get_tools_run_function(tools_path) _tools_run = get_tools_run_function(tools_path)
_tools_run_dict = get_tools_run_dict_function(tools_path) _tools_run_dict = get_tools_run_dict_function(tools_path)
_tools_run_popen = get_tools_run_popen_function(tools_path)
@better_wt_error(tools_path) @better_wt_error(tools_path)
@ -40,6 +41,31 @@ def create(extracted_szs: Path | str, dest: Path | str, overwrite: bool = False)
return SZSPath(dest) return SZSPath(dest)
def patch(szs_data: bytes, scale: dict[str, int] = None, shift: dict[str, int] = None, rotation: dict[str, int] = None,
translate: dict[str, int] = None, speed: float = None, laps: int = None):
"""
Patch a szs file (especially track file)
:return: the patched szs file
"""
args = []
if scale is not None: args.append(f"--scale={scale.get('x', 1)},{scale.get('y', 1)},{scale.get('z', 1)}")
if shift is not None: args.append(f"--shift={shift.get('x', 0)},{scale.get('y', 0)},{scale.get('z', 0)}")
if rotation is not None: args.append(f"--rot={rotation.get('x', 0)},{rotation.get('y', 0)},{rotation.get('z', 0)}")
if translate is not None: args.append(
f"--translate={translate.get('x', 0)},{translate.get('y', 0)},{translate.get('z', 0)}"
)
if speed is not None: args.append(f"--speed-mod={speed}")
if laps is not None: args.append(f"--kmp={laps}LAPS")
process = _tools_run_popen("PATCH", "-", *args, "--DEST", "-")
stdout, _ = process.communicate(input=szs_data)
if process.returncode != 0:
raise WTError(tools_path, process.returncode)
return stdout
class SZSPath: class SZSPath:
__slots__ = ("path", "_analyze") __slots__ = ("path", "_analyze")