cpk¶
Support for CRI CPK archives, used by many CRI Middleware based games.
A CPK archive is a container indexed by one or more tables (TOC, ETOC, ITOC, GTOC) serialized in the CRI @UTF table format. Files can optionally be compressed with the CRILAYLA scheme and the @UTF packets themselves can be encrypted with a simple XOR scheme. Based on CriPakTools.
- class hacktools.cpk.CPK[source]¶
Structure of a CPK archive.
- filetable¶
List of file and header entries in the archive.
- data¶
Extra data associated with the archive, not used by this module.
- align¶
Alignment of file data in the archive.
- getFileEntry(filename, filetype='', tocname='')[source]¶
Search the file table for an entry with the given filename.
- Parameters:
- Returns:
The first matching entry, or None if not found.
- Return type:
CPKFileEntry | None
- getIDEntry(id, filetype='', tocname='')[source]¶
Search the file table for an entry with the given ID.
- Parameters:
- Returns:
The first matching entry, or None if not found.
- Return type:
CPKFileEntry | None
- getEntries(filetype)[source]¶
Get all the file table entries with the given filetype.
- Parameters:
filetype (str) – Filetype to search for, usually “FILE”.
- Returns:
The list of matching entries.
- Return type:
list[CPKFileEntry]
- class hacktools.cpk.CPKFileEntry[source]¶
Structure of a single entry in a CPK file table.
Both actual files and internal headers (CPK, TOC, ETOC, ITOC, GTOC) are represented as entries, distinguished by their filetype.
- dirname¶
Directory name of the file.
- filename¶
Name of the file.
- filesize¶
Size of the file as stored in the archive.
- filesizepos¶
Position of the filesize value in the @UTF packet.
- filesizetype¶
Data type of the filesize value, as a
UTFStructTypes.
- fileoffset¶
Absolute offset of the file data in the archive.
- fileoffsetpos¶
Position of the fileoffset value in the @UTF packet.
- fileoffsettype¶
Data type of the fileoffset value, as a
UTFStructTypes.
- extractsize¶
Size of the file after decompression, equal to filesize if the file is not compressed.
- extractsizepos¶
Position of the extractsize value in the @UTF packet.
- extractsizetype¶
Data type of the extractsize value, as a
UTFStructTypes.
- offset¶
Base offset that was added to fileoffset when reading the entry.
- id¶
Numeric ID of the file.
- userstring¶
Optional user string attached to the file.
- updatetime¶
Update timestamp read from the ETOC.
- localdir¶
Local directory read from the ETOC.
- tocname¶
Name of the TOC the entry belongs to (“TOC”, “ITOC” or “CPK”).
- encrypted¶
Whether the @UTF packet of this entry is encrypted.
- filetype¶
Type of the entry (“FILE”, “CPK”, “HDR” or “CONTENT”).
- utf¶
Parsed @UTF table for header entries, None otherwise.
- classmethod createEntry(filename, fileoffset, fileoffsettype, fileoffsetpos, tocname, filetype, encrypted)[source]¶
Create an entry with the given attributes.
- Parameters:
filename (str) – Name of the file.
fileoffset (int) – Absolute offset of the file data in the archive.
fileoffsettype (int) – Data type of the fileoffset value, as a
UTFStructTypes.fileoffsetpos (int) – Position of the fileoffset value in the @UTF packet.
tocname (str) – Name of the TOC the entry belongs to.
filetype (str) – Type of the entry.
encrypted (bool) – Whether the @UTF packet of this entry is encrypted.
- Returns:
The new entry.
- Return type:
- class hacktools.cpk.UTFStructTypes(*values)[source]¶
Data types of the values stored in a @UTF table.
- class hacktools.cpk.UTF[source]¶
Structure of a @UTF table, a set of typed columns and rows.
- columns¶
List of columns in the table.
- tablesize¶
Size of the table.
- rowsoffset¶
Absolute offset of the rows data.
- stringsoffset¶
Absolute offset of the strings data.
- dataoffset¶
Absolute offset of the binary data.
- tablename¶
Offset of the table name in the strings data.
- numcolumns¶
Number of columns in the table.
- rowlength¶
Length in bytes of a single row.
- numrows¶
Number of rows in the table.
- columnlookup¶
Lookup dictionary from column name to column index.
- rawpacket¶
Stream holding the decrypted @UTF packet, only set when requested with storeraw.
- datalpos¶
Position of the DataL value in the packet, used by ITOC tables.
- datahpos¶
Position of the DataH value in the packet, used by ITOC tables.
- utfdatal¶
Nested table parsed from the DataL value, used by ITOC tables.
- utfdatah¶
Nested table parsed from the DataH value, used by ITOC tables.
- getColumnData(row, name, type)[source]¶
Get the value of a column, with a default if it’s missing.
Like
getColumnDataType()but if the column is missing or empty, a default is returned instead of None: the maximum unsigned value for integer types, or 0 for the other types.- Parameters:
row (int) – Index of the row to read from.
name (str) – Name of the column.
type (int) – Expected data type, as a
UTFStructTypes, used to pick the default value.
- Returns:
A (data, position) tuple.
- Return type:
tuple[int | float | str | bytes, int]
- getColumnDataType(row, name)[source]¶
Get the value, position and type of a column.
Constant column values are shared by all rows, otherwise the value is read from the given row.
- Parameters:
row (int) – Index of the row to read from.
name (str) – Name of the column.
- Returns:
A (data, position, type) tuple with the type as a
UTFStructTypes, or (None, 0, DATA_TYPE_NONE) if the column is missing or holds no data.- Return type:
tuple[int | float | str | bytes | None, int, int]
- updateColumnDataType(data, pos, type)[source]¶
Write a new integer value in the raw packet of this table.
The position and type are usually the ones previously returned by
getColumnDataType(). Only integer types are supported.- Parameters:
data (int) – New value to write.
pos (int) – Position to write the value at.
type (int) – Data type of the value, as a
UTFStructTypes.
- Return type:
None
- class hacktools.cpk.UTFColumnFlags(*values)[source]¶
Flags of a @UTF column, holding the storage type and data type.
- class hacktools.cpk.UTFColumn[source]¶
Structure of a single column in a @UTF table.
- flags¶
Raw flags of the column, as a
UTFColumnFlagsmask.
- name¶
Name of the column.
- data¶
Value of the column if it’s a constant one, None otherwise.
- storagetype¶
Storage type of the column, as a
UTFColumnFlags.
- type¶
Data type of the column if it’s a constant one, as a
UTFStructTypes, DATA_TYPE_NONE otherwise.
- position¶
Position of the column value if it’s a constant one.
- class hacktools.cpk.UTFRow[source]¶
Structure of a single row value in a @UTF table.
- data¶
Value of the row, None if the column stores no data.
- type¶
Data type of the value, as a
UTFStructTypes.
- position¶
Position of the value in the packet, for per-row storage.
- hacktools.cpk.extract(file, outfolder, guessextension=None)[source]¶
Extract all the files of a CPK archive to a folder.
Files compressed with CRILAYLA are decompressed. Files without a name are extracted with a generated “ID” name.
- Parameters:
file (str) – Path of the CPK archive.
outfolder (str) – Path of the folder to extract to.
guessextension (Callable[[bytes, CPKFileEntry, str], str] | None) – Optional function receiving the file data, the
CPKFileEntryand the current filename, returning the filename to use.
- Return type:
None
- hacktools.cpk.repack(file, outfile, infolder, outfolder, nocmp=False)[source]¶
Repack a CPK archive, replacing the files found in a folder.
Files that exist in outfolder are read from there and compressed if they were compressed in the original archive, while the others are copied from the original archive. Since CRILAYLA compression is slow, compressed data is cached next to the input file in a .cache file tagged with the input CRC, and reused as long as the input doesn’t change. The TOC and ITOC tables are updated with the new offsets and sizes.
- Parameters:
file (str) – Path of the original CPK archive.
outfile (str) – Path of the output CPK archive.
infolder (str) – Path of the folder the archive was extracted to, used to look up the original filenames and extensions.
outfolder (str) – Path of the folder containing the replacement files.
nocmp (bool) – Whether to store the replacement files uncompressed.
- Return type:
None
- hacktools.cpk.readCPK(file)[source]¶
Read the header and file table of a CPK archive.
All the TOC tables present in the archive (TOC, ETOC, ITOC, GTOC) are parsed, adding their header and file entries to the archive filetable.
- hacktools.cpk.readTOC(f, cpk, tocoffset, contentoffset)[source]¶
Read a TOC table, adding a file entry for each row.
- hacktools.cpk.readETOC(f, cpk, tocoffset)[source]¶
Read an ETOC table, updating the file entries with their local directory and update time.
- hacktools.cpk.readITOC(f, cpk, tocoffset, contentoffset, align)[source]¶
Read an ITOC table, holding files indexed by ID instead of name.
File sizes are read from the nested DataL and DataH tables, and a file entry is added for each ID found. If the table has no nested data, the IDs are assigned to the file entries already in the archive filetable.
- Parameters:
f (Stream) – Stream opened on the CPK archive.
cpk (CPK) – Archive structure holding an ITOC_HDR entry, updated in place.
tocoffset (int) – Offset of the ITOC table.
contentoffset (int) – Offset of the archive content, where file data starts.
align (int) – Alignment of the file data, used to compute the file offsets.
- Return type:
None
- hacktools.cpk.readGTOC(f, cpk, tocoffset)[source]¶
Read a GTOC table, only checking the header and updating the GTOC_HDR entry, since the table content is currently ignored.
- hacktools.cpk.readUTFData(f)[source]¶
Read a @UTF packet from the current stream position.
The packet is decrypted if needed and returned as a new big endian stream. The stream endianness is restored to little endian afterwards.
- hacktools.cpk.decryptUTF(input)[source]¶
Decrypt a @UTF packet with the standard XOR scheme.
Since this is a simple XOR, calling it on a decrypted packet encrypts it again.
- Parameters:
input (bytes) – Encrypted packet data.
- Returns:
The decrypted packet data.
- Return type:
bytes
- hacktools.cpk.readUTF(f, baseoffset, storeraw=False)[source]¶
Read a @UTF table with all its columns and rows.
- Parameters:
f (Stream) – Stream holding the decrypted @UTF packet, usually returned by
readUTFData().baseoffset (int) – Offset of the packet in the archive, stored in the table for later use.
storeraw (bool) – Whether to store the packet stream in the rawpacket attribute of the table, so it can be edited later with
UTF.updateColumnDataType().
- Returns:
The parsed table, or None if the packet has a wrong header.
- Return type:
UTF | None
- hacktools.cpk.readUTFTypedData(f, utf, flags)[source]¶
Read a single value from a @UTF table.
String and bytearray values are read from the strings and data sections of the table, following the offset at the current position.
- Parameters:
- Returns:
A (data, type) tuple with the type as a
UTFStructTypes.- Return type:
tuple[int | float | str | bytes, int]