Edit subtitles and menu text
This commit is contained in:
42
ackit/upk.py
42
ackit/upk.py
@@ -8,7 +8,7 @@ Patching rewrites only the blocks that contain changed bytes (stored as one LZO
|
||||
lzo.compress_stored) and moves the chunks after them; every other byte of the file stays identical.
|
||||
"""
|
||||
import struct
|
||||
from collections import OrderedDict
|
||||
from collections import OrderedDict, namedtuple
|
||||
|
||||
from . import lzo
|
||||
|
||||
@@ -20,6 +20,9 @@ class PackageError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
Export = namedtuple("Export", "index cls outer name size offset entry") # entry: table position (uncompressed)
|
||||
|
||||
|
||||
class Block:
|
||||
__slots__ = ("chunk", "uoff", "usize", "coff", "csize")
|
||||
|
||||
@@ -52,6 +55,7 @@ class Package:
|
||||
f12 = struct.unpack_from("<12i", b, o)
|
||||
self.name_count, self.name_offset = f12[1], f12[2]
|
||||
self.export_count, self.export_offset = f12[3], f12[4]
|
||||
self.import_count, self.import_offset = f12[5], f12[6]
|
||||
o += 48
|
||||
self.guid = b[o:o + 16]
|
||||
o += 16
|
||||
@@ -106,6 +110,42 @@ class Package:
|
||||
return self.file_size
|
||||
return self.chunks[-1][0] + self.chunks[-1][1]
|
||||
|
||||
# tables (need the uncompressed data: `read_all`) ---------------------------------------------
|
||||
def tables(self, data=None, start=None):
|
||||
"""(names, imports, exports) of the package. imports: [(class name, object name, outer)],
|
||||
exports: [Export]. Layouts: docs/formats/upk.md (licensee 101 adds one u32 to each export)."""
|
||||
if data is None:
|
||||
start, data = self.read_all()
|
||||
buf = memoryview(data)
|
||||
names = []
|
||||
o = self.name_offset - start
|
||||
for _ in range(self.name_count):
|
||||
n = struct.unpack_from("<i", buf, o)[0]
|
||||
o += 4
|
||||
if n >= 0:
|
||||
names.append(bytes(buf[o:o + n - 1]).decode("latin-1"))
|
||||
o += n
|
||||
else:
|
||||
names.append(bytes(buf[o:o - 2 * n - 2]).decode("utf-16-le", "replace"))
|
||||
o += -2 * n
|
||||
o += 8 # name flags
|
||||
imports = []
|
||||
o = self.import_offset - start
|
||||
for _ in range(self.import_count):
|
||||
_pkg, _pn, cls, _cn, outer, nm, nn = struct.unpack_from("<7i", buf, o)
|
||||
imports.append((names[cls], names[nm], outer))
|
||||
o += 28
|
||||
exports = []
|
||||
o = self.export_offset - start
|
||||
for i in range(self.export_count):
|
||||
cls, sup, outer, nm, nn, arch, _x = struct.unpack_from("<7i", buf, o)
|
||||
size, off = struct.unpack_from("<ii", buf, o + 36)
|
||||
ngen = struct.unpack_from("<i", buf, o + 48)[0]
|
||||
exports.append(Export(i + 1, cls, outer, names[nm] + ("_%d" % (nn - 1) if nn else ""), size, off,
|
||||
o + start))
|
||||
o += 72 + 4 * ngen
|
||||
return names, imports, exports
|
||||
|
||||
def fingerprint(self):
|
||||
"""Cheap identity of the package contents: guid + chunk table (changes with any re-cook/patch)."""
|
||||
import hashlib
|
||||
|
||||
Reference in New Issue
Block a user