import struct from typing import Dict, List, Tuple from bemani.protocol.lz77 import Lz77 class ARC: """ Class representing an `.arc` file. These are found in DDR Ace, and possibly other games that use ESS. Given a serires of bytes, this will allow you to query included filenames as well as read the contents of any file inside the archive. """ def __init__(self, data: bytes) -> None: self.__files: Dict[str, Tuple[int, int, int]] = {} self.__data = data self.__parse_file(data) def __parse_file(self, data: bytes) -> None: # Check file header if data[0:4] != bytes([0x20, 0x11, 0x75, 0x19]): raise Exception("Unknown file format!") # Grab header offsets (_, numfiles, _) = struct.unpack(" List[str]: return [f for f in self.__files] def read_file(self, filename: str) -> bytes: (fileoffset, uncompressedsize, compressedsize) = self.__files[filename] if compressedsize == uncompressedsize: # Just stored return self.__data[fileoffset : (fileoffset + compressedsize)] else: # Compressed lz77 = Lz77() return lz77.decompress( self.__data[fileoffset : (fileoffset + compressedsize)] )