diff --git a/filereader.py b/filereader.py index ea1691b..aa43720 100644 --- a/filereader.py +++ b/filereader.py @@ -1,3 +1,5 @@ +import io +import os import struct @@ -60,3 +62,18 @@ class FileReader: def SetBufferPos(self, pos:int): self.stream.seek(pos) + + def GetStreamLength(self) -> int: + if isinstance(self.stream, io.BytesIO): + return self.stream.getbuffer().nbytes + elif isinstance(self.stream, io.BufferedReader): + pos = self.GetBufferPos() + self.stream.seek(0, os.SEEK_END) + length = self.GetBufferPos() + self.SetBufferPos(pos) + return length + else: + raise Exception("unknown buffer type") + + def GetRemainingLength(self) -> int: + return self.GetStreamLength() - self.GetBufferPos() diff --git a/mapper.py b/mapper.py index bbfa006..b4cc759 100644 --- a/mapper.py +++ b/mapper.py @@ -31,8 +31,10 @@ class Mapper: reader = self.reader # utils - val = lambda length: int.from_bytes(reader.ReadBytes(length), "little") - raw = lambda length: reader.ReadBytes(length).rstrip(b"\x00").decode("utf-8") + val = lambda length: vl2(reader.ReadBytes(length)) + vl2 = lambda data: int.from_bytes(data, "little") + raw = lambda length: rw2(reader.ReadBytes(length)) + rw2 = lambda data: data.rstrip(b"\x00").decode("utf-8") n2p = lambda val: [e[0] for e in enumerate(list(bin(val)[2:][::-1])) if e[1] == "1"] # get map meta @@ -54,11 +56,14 @@ class Mapper: "sfx" ] - reader.ReadBytes(1) # header size + header_size = val(1) # header size + block_size = 4 + header_blocks = [reader.ReadBytes(block_size) for _ in range(header_size // block_size)] + infos = { - "game": games[raw(4)], - "version": list(raw(4)), - "coverage": int(raw(4)) + "game": games[rw2(header_blocks[0])], + "version": list(rw2(header_blocks[1])), + "coverage": int(rw2(header_blocks[2])), # more later } @@ -83,6 +88,8 @@ class Mapper: offset = reader.GetBufferPos() langs_offsets[offset] = raw(l_langs) + self.langs_offsets = langs_offsets + # read folders folder_offsets = {} n_folders = reader.ReadUInt8() @@ -120,17 +127,16 @@ class Mapper: files_offsets[offset] = path + self.files_offsets = files_offsets + # read keys + # GI 3649050 keys_data = {} n_keys = val(3) - for i in range(n_keys): - key = raw(16) - - lang_offset = val(2) - file_offset = val(3) - - keys_data[key] = [files_offsets[file_offset], langs_offsets[lang_offset]] + left = reader.GetRemainingLength() + data = bytearray(reader.ReadBytes(left)) + keys_data = {rw2(data[i:i+16]): bytes(data[i+16:i+21]) for i in range(0, len(data), 21)} self.keys_data = keys_data @@ -154,9 +160,9 @@ class Mapper: return None key_data = keys_data[key] - data = [key_data[0]] + data = [self.files_offsets[int.from_bytes(key_data[2:], "little")]] if lang: - data.append(key_data[1]) + data.append(self.langs_offsets[int.from_bytes(key_data[:1], "little")]) return data