求助.dmxpkg文件解包

from io import BytesIO
from pathlib import Path
from zipfile import ZipFile
from io import BufferedReader

def parse(r: BufferedReader, r2: BufferedReader, outPath: Path):
    count = int.from_bytes(r.read(4), 'little')
    for _ in range(count):
        nameLen = r.read(1)[0]
        name = bytes(i ^ nameLen for i in r.read(nameLen))
        start = int.from_bytes(r.read(4), 'little') - name[-6] - nameLen
        size = int.from_bytes(r.read(4), 'little') - name[-7] - nameLen
        new = outPath.joinpath(name.decode())
        new.parent.mkdir(parents=True, exist_ok=True)
        r2.seek(start)
        if new.is_file():
            print(f'存在重名文件 --- {new.as_posix()}')
        with open(new, 'wb') as w: w.write(r2.read(size))

def batch(datPath: str = '', outPath: str = '', subfolder: bool = False):
    path = Path(datPath) if datPath else Path.cwd()
    move = (Path(outPath) if outPath else path).joinpath('Extract')
    need = [i for i in (path.rglob('*.dmxpkg') if subfolder else path.glob('*.dmxpkg'))]
    for i in need:
        with ZipFile(i) as z:
            names = {j.lower():j for j in z.namelist() if j.lower().endswith(('.dat', '.dic'))}
            files: dict[str, str] = {}
            for i in names:
                if i.endswith('.dat'): continue
                v = f'{i[:-3]}dat'
                if v not in names:
                    print(f'缺少dat文件 --- {i}')
                    continue
                files[i] = v
            if not files:
                print(f'没有dat和dic文件 --- {i}')
            for k, v in files.items():
                with z.open(names[k]) as z1, z.open(names[v]) as z2:
                    f = BytesIO(z1.read())
                    f2 = BytesIO(z2.read())
                parse(f, f2, move)

if __name__ == '__main__':
    path = r'' # 游戏文件所在的路径
    outPath = r'' # 导出文件的路径
    subfolder = False # 是否查找字文件夹内的.dmxpkg文件
    batch(path, outPath, subfolder)

批量解压dmxpkg

2 个赞