diff --git a/bnk.py b/bnk.py index ab48c84..520e3ce 100644 --- a/bnk.py +++ b/bnk.py @@ -2,24 +2,27 @@ import io from filereader import FileReader -def bnk2wem(data): +def bnk2wem(data, name): # gets raw data from object - reader = FileReader(io.BytesIO(data), "little") + reader = FileReader(io.BytesIO(data), "little", name=name) bkhd_signature = reader.ReadBytes(4) if bkhd_signature != b"\x42\x4B\x48\x44": - raise Exception("not a valid bnk") + print(f"[WARNING] invalid bkhd signature at {reader.GetName()}") + return [] bkhd_size = reader.ReadUInt32() reader.ReadBytes(bkhd_size) if reader.GetBufferPos() == reader.GetStreamLength(): + print(f"[WARNING] empty bnk file at {reader.GetName()}") return [] # empty bnk didx_signature = reader.ReadBytes(4) if didx_signature != b"\x44\x49\x44\x58": + print(f"[WARNING] invalid didx signature at {reader.GetName()}") return [] # invalid index signature (hirc block instead ?) didx_size = reader.ReadUInt32() @@ -35,6 +38,7 @@ def bnk2wem(data): data_signature = reader.ReadBytes(4) if data_signature != b"\x44\x41\x54\x41": + print(f"[WARNING] invalid data signature at {reader.GetName()}") return [] # invalid data signature (missing sector ?) data_size = reader.ReadUInt32() diff --git a/extract.py b/extract.py index 2b4d3c7..6e8c551 100644 --- a/extract.py +++ b/extract.py @@ -11,7 +11,12 @@ from filereader import FileReader cwd = os.getcwd() path = lambda *args: os.path.join(*args) -call = lambda args: subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) + +def call(args): + try: + subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) + except Exception as e: + print(f"[WARNING] failed to extract, {e}") class WwiseExtract: def __init__(self): @@ -170,6 +175,9 @@ class WwiseExtract: wem_data = data[file_data["offset"]:file_data["offset"]+file_data["size"]] parsed_wem = wwise.parse_wwise(FileReader(io.BytesIO(wem_data), "little", name=f"{file[3]}:{file[0]}:{file[1]}")) + if not parsed_wem: + continue + file_data["metadata"] = parsed_wem if key is not None: diff --git a/filereader.py b/filereader.py index 507a8ff..905bf69 100644 --- a/filereader.py +++ b/filereader.py @@ -11,8 +11,7 @@ class FileReader: def __init__(self, file, endianness:str, name:str=None): self.stream = file self.endianness = endianness - if name: - self.name = name + self.name = name def _read(self, mode:str, bufferLength:int, endianness:str=None, pos:int=None) -> bytes: # endianness override diff --git a/wavescan.py b/wavescan.py index 55e1fa8..af33961 100644 --- a/wavescan.py +++ b/wavescan.py @@ -220,7 +220,7 @@ def extract_sector(section_size, is_sounds, is_externals, ext, endianness, lang_ bnk_data = reader.ReadBytes(size) reader.SetBufferPos(pos) - wems = bnk2wem(bnk_data) + wems = bnk2wem(bnk_data, f"{filename}@{pos}.{size}") for wem in wems: wwise_data.append([f"{os.path.basename(name).split('.')[0]}_{wem[0]}.wem", offset+wem[1], wem[2], filename]) diff --git a/wwise.py b/wwise.py index 0a0dd4b..1501a08 100644 --- a/wwise.py +++ b/wwise.py @@ -23,7 +23,7 @@ def parse_wwise(reader): if reader.GetStreamLength() == 0: print(f"[WARNING] null stream size at {reader.GetName()}, unreadable block") - return metadata + return None header = reader.ReadBytes(4) @@ -34,7 +34,7 @@ def parse_wwise(reader): reader.endianness = "little" else: print(f"[WARNING] invalid header {header} at {reader.GetName()}, assuming unreadable") - return metadata + return None # additional check reader.SetBufferPos(0x08) @@ -42,7 +42,7 @@ def parse_wwise(reader): if check != b"WAVE" and check != "XWMA": print(f"[WARNING] invalid check mark {check}, assuming unreadable") - return metadata + return None # read chunks reader.SetBufferPos(0x0C) @@ -71,7 +71,7 @@ def parse_wwise(reader): fmt_length = chunks["fmt"]["length"] if fmt_length < 0x10: print(f"[WARNING] invalid fmt chunk length {fmt_length} at {reader.GetName()}, skipping") - return metadata + return None reader.SetBufferPos(chunks["fmt"]["offset"]) @@ -94,7 +94,7 @@ def parse_wwise(reader): if metadata["format"] == 0x0166: print(f"[WARNING] XMA2WAVEFORMATEX in fmt at {reader.GetName()}") - return metadata + return None # parse codec codecs = { @@ -122,7 +122,7 @@ def parse_wwise(reader): if metadata["format"] not in codecs: print(f'[WARNING] unknown codec {metadata["format"]} at {reader.GetName()}') - return metadata + return None codec = codecs[metadata["format"]] @@ -153,18 +153,18 @@ def parse_wwise(reader): elif metadata["codec"] == "VORBIS": if (metadata["blockSize"] != 0 or metadata["bitsPerSample"] != 0): print(f"[WARNING] worbis type at {reader.GetName()}, skipping") - return metadata + return None if "vorb" in chunks: # vorb chunk only in wwise earlier to 2012, therefore impossible for mihoyo games print(f"[WARNING] found vorb chunk at {reader.GetName()}, is this the correct game ?") - return metadata + return None extra_offset = chunks["fmt"]["offset"] + 0x18 if metadata["extraSize"] != 0x30: print(f"[WARNING] unknown extra wwise size at {reader.GetName()}, skipping") - return metadata + return None data_offset = 0x10 blocks_offset = 0x28