Beispiel #1
0
 def get_sarc_tree(parent_sarc: Sarc) -> Tuple[dict, list]:
     tree = {}
     modded = set()
     for file in sorted(parent_sarc.get_files(), key=lambda f: f.name):
         path_parts = Path(file.name).parts
         magic = file.data[0:4]
         nest_tree = {}
         if magic == b"SARC" or (magic == b"Yaz0"
                                 and file.data[0x11:0x15] == b"SARC"):
             nest_sarc = Sarc(file.data if not magic == b"Yaz0" else
                              decompress(file.data))
             nest_tree, mods = get_sarc_tree(nest_sarc)
             modded.update(mods)
             del nest_sarc
         _dict_merge(
             tree,
             reduce(lambda res, cur: {cur: res}, reversed(path_parts),
                    nest_tree),
         )
         if util.get_hashtable(parent_sarc.get_endianness() ==
                               Endianness.Big).is_file_modded(
                                   file.name.replace(".s", "."),
                                   bytes(file.data)):
             modded.add(file.name)
     return tree, modded
def _unbuild_file(
    f: Path, out: Path, content: str, mod: Path, verbose: bool, skip_texts: bool = False
) -> set:
    of = out / f.relative_to(mod)
    if not of.parent.exists():
        of.parent.mkdir(parents=True, exist_ok=True)
    names = set()
    canon = get_canon_name(f.relative_to(mod))
    if canon:
        names.add(canon)
    if f.name in HANDLED:
        pass
    elif f.suffix in AAMP_EXTS:
        of.with_suffix(f"{f.suffix}.yml").write_bytes(_aamp_to_yml(f.read_bytes()))
    elif f.suffix in BYML_EXTS:
        of.with_suffix(f"{f.suffix}.yml").write_bytes(_byml_to_yml(f.read_bytes()))
    elif f.suffix in SARC_EXTS:
        with f.open("rb") as file:
            data = file.read()
            if data[0:4] == b"Yaz0":
                data = decompress(data)
            if data[0:4] != b"SARC":
                return names
            s = oead.Sarc(data)
        if "bactorpack" in f.suffix:
            names.update(_unbuild_actorpack(s, out / content))
        else:
            names.update(_unbuild_sarc(s, of, skip_texts=skip_texts))
        del s
    else:
        of.write_bytes(f.read_bytes())
    if verbose:
        print(f"Unbuilt {f.relative_to(mod).as_posix()}")
    return names
def _unbuild_actorinfo(mod: Path, content: str, out: Path):
    file = mod / content / "Actor" / "ActorInfo.product.sbyml"
    actor_info = oead.byml.from_binary(decompress(file.read_bytes()))
    actor_info_dir = out / content / "Actor" / "ActorInfo"
    actor_info_dir.mkdir(parents=True, exist_ok=True)
    for actor in actor_info["Actors"]:
        output = actor_info_dir / f"{actor['name']}.info.yml"
        output.write_text(oead.byml.to_text(actor), encoding="utf-8")
Beispiel #4
0
def open_rstb(file: Path) -> ResourceSizeTable:
    data = file.read_bytes()
    if data[0:4] == b"Yaz0":
        data = decompress(data)
    be = True
    rstb = ResourceSizeTable(data, be=True)
    random_tests = {
        "EventFlow/PictureMemory.bfevfl",
        "Camera/Demo648_0/C04-0.bcamanim",
        "Effect/FldObj_ScaffoldIronParts_A_01.esetlist",
        "Physics/TeraMeshRigidBody/MainField/9-8.hktmrb",
    }
    if not any(rstb.is_in_table(f) for f in random_tests):
        del rstb
        rstb = ResourceSizeTable(data, be=False)
        be = False
        if not any(rstb.is_in_table(f) for f in random_tests):
            raise ValueError("File does not appeat to be a valid BOTW RSTB")
    return rstb, be
Beispiel #5
0
    def from_bytes(cls, b: bytes, path: Path = None):
        inst = cls()

        if path:
            inst.path = path

        if b[0:4] == b"Yaz0":
            b = yaz0.decompress(b)

        br = BinaryReader(initial_bytes=b)

        while br.tell() != br.length():
            br = BinaryReader(initial_bytes=br.read())

            file = HKFile()
            file.read(br)

            inst.files.append(file)

        return inst
Beispiel #6
0
    def is_file_modded(
        self, file_name: str, data: Union[ByteString, int], flag_new: bool = True
    ) -> bool:
        """Checks a file to see if it has been modified. Automatically decompresses yaz0 data.

        Args:
            file_name (str): The canonical resource path of the file to check
            data (Union[ByteString, int]): Either the file data (as a byteslike object) or an xxh32
                hash as an int
            flag_new (bool, optional): Whether to flag new files (not in vanilla BOTW) as modified.
                Defaults to True.

        Returns:
            bool: Returns whether the file's hash matches a known version of the hash for the
                original version.
        """
        if file_name not in self._table:
            return flag_new
        else:
            if isinstance(data, int):
                return data not in self._table[file_name]
            if data[0:4] == b"Yaz0":
                data = decompress(data)
            return xxh32_intdigest(data) not in self._table[file_name]
def _if_unyaz(data: bytes) -> bytes:
    return data if data[0:4] != b"Yaz0" else decompress(data)
def _aamp_to_yml(file_bytes: bytes) -> bytes:
    if file_bytes[0:4] == b"Yaz0":
        file_bytes = decompress(file_bytes)
    return aamp.ParameterIO.from_binary(file_bytes).to_text().encode("utf8")
def _byml_to_yml(file_bytes: bytes) -> bytes:
    if file_bytes[0:4] == b"Yaz0":
        file_bytes = decompress(file_bytes)
    return oead.byml.to_text(oead.byml.from_binary(file_bytes)).encode("utf8")
Beispiel #10
0
def unyaz_if_yazd(data: ByteString) -> ByteString:
    return data if data[0:4] != b"Yaz0" else memoryview(decompress(data))
 def init(self):
     with open(self.file + '', 'rb') as f:
         data = yaz0.decompress(f.read())
     data_dec = Sarc(data)
     return data_dec