Files
ark-stronghold-protocol/tools/local-extract/aklz4.py
T

35 lines
1.3 KiB
Python

# LZ4AK decompressor for Arknights bundles (algorithm from isHarryh/Ark-Unpacker, BSD-3, via MooncellWiki/UnityPy)
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022, Harry Huang (isHarryh/Ark-Unpacker). Unlike the rest of this project (GPL-3.0-or-later), this
# file is distributed under the BSD 3-Clause License of Ark-Unpacker: tools/local-extract/LICENSE-Ark-Unpacker.txt
# (UnityPy, which it plugs into, is MIT; see THIRD-PARTY-NOTICES.md).
import lz4.block
from UnityPy.helpers import CompressionHelper
from UnityPy.enums.BundleFile import CompressionFlags
def _xlen(d, p, m):
l = 0
while p < m:
b = d[p]; l += b; p += 1
if b != 0xFF: break
return l, p
def decompress_lz4ak(data, usize):
ip = op = 0
d = bytearray(data); n = len(d)
while ip < n:
lit = d[ip] & 0xF; mat = (d[ip] >> 4) & 0xF
d[ip] = (lit << 4) | mat; ip += 1
if lit == 0xF:
l, ip = _xlen(d, ip, n); lit += l
ip += lit; op += lit
if op >= usize: break
off = (d[ip] << 8) | d[ip + 1]
d[ip] = off & 0xFF; d[ip + 1] = (off >> 8) & 0xFF; ip += 2
if mat == 0xF:
l, ip = _xlen(d, ip, n); mat += l
op += mat + 4
return lz4.block.decompress(bytes(d), usize)
CompressionHelper.DECOMPRESSION_MAP[CompressionFlags.LZHAM] = decompress_lz4ak