bethesda_structs.archive

This module contains structures that can read and extract Bethesda’s archive file formats.

bethesda_structs.archive.get_archive(filepath)[source]

Get an instance of the first archive that can handle a given file.

Parameters:filepath (str) – The path of the file to handle
Returns:The base archive
Return type:BaseArchive

Examples

This method simply returns the first encountered archive that can handle a given file.

>>> FILEPATH = ""  # absolute filepath to some BSA
>>> archive = bethesda_structs.archive.get_archve(FILEPATH)
>>> archive
BSAArchive(filepath=PosixPath(...))

Common

Below is a listing of common objects, resources, etc. that can and are probably used throughout the other Archive objects. An example of this is the BaseArchive class which provides an abstract class which all valid archives should extend.

class bethesda_structs.archive._common.ArchiveFile(filepath, data)[source]

A generic archive file object that can be used for extracting.

The purpose of this object is to provide some generic format for iter_files() to yield so that the extract() method can be abstracted away from the archive subclasses.

filepath = None

The relative filepath of the archived file.

Returns:The relative filepath of the archived file
Return type:str
data = None

The raw data of the archived file.

Returns:The raw data of the archived file
Return type:bytes
size

The size of the raw data.

Returns:The size of the raw data
Return type:int
class bethesda_structs.archive._common.BaseArchive(content, filepath=None)[source]

The base class all Archives should subclass.

archive_struct

The base archive structure to use for parsing the full archive.

Raises:NotImplementedError – Subclasses must implement
Returns:The archive structure
Return type:construct.Construct
classmethod parse(content, filepath=None)[source]

Create a BaseArchive from a byte array.

Parameters:
  • content (bytes) – The byte content of the archive
  • filepath (str, optional) – Defaults to None. Sets the filepath attribute for user’s reference
Raises:

ValueError – If the given content is not of bytes

Returns:

An archive instance

Return type:

BaseArchive

iter_files()[source]

Iterates over the available files in the archive.

Yields:ArchiveFile – An archive file
Raises:NotImplementedError – Subclasses must implement
Return type:Generator[ArchiveFile, None, None]
extract(to_dir, progress_hook=None)[source]

Extracts the content of the BaseArchive to the given directory.

Parameters:
  • to_dir (str) – The directory to extract the content to
  • progress_hook (Callable[[int, int, str], None], optional) – Defaults to None. A progress hook that should expect (current, total, current_filepath) as arguments

Example

>>> FILEPATH = ""  # absolute path to BSA/BTDX archive
>>> archive = bethesda_structs.archive.get_archive(FILEPATH)
>>> archive.extract('/home/username/Downloads/extracted')

Example

>>> def progress_hook(current, total, filepath):
...     print((current / total) * 100.0)
>>> FILEPATH = ""  # absolute path to BSA/BTDX archive
>>> archive = bethesda_structs.archive.get_archive(FILEPATH)
>>> archive.extract(
...     '/home/username/Downloads/extracted',
...     progress_hook=progress_hook
... )
0.0
12.2
12.2
12.67
12.67
50.4443
50.4443
70.0
70.0
92.1
92.1
100.0

Note

The provided progress hook is simple and two-stage. It is called once before a file is being written and once after the same file is done being written.

BSA Archives

This module contains all the required structures to extract BSA archives.

class bethesda_structs.archive.bsa.LZ4CompressedAdapter(subcon)[source]

Bases: construct.core.Adapter

An adapter for LZ4 compressed data.

Note

v105 BSA’s utilize LZ4 compression instead of zlib.

class bethesda_structs.archive.bsa.BSAArchive(content, filepath=None)[source]

Bases: bethesda_structs.archive._common.BaseArchive

Archive type for BSA files.

BSA stands for “Bethesda ? Archive”. These archives are compressed meshes, textures and other static resources that can be loaded as a single file instead of a directory of files (loose files).

There are currently 4 versions of BSA:
  • ???: Morrowind
  • 103: Oblivion
  • 104: Fallout 3, Fallout: New Vegas, and Skyrim
  • 105: Skyrim: Special Edition

Note

BSA archives to not read the file data on initialization. Header’s, records and names are read in and files are built during iter_files().

Credit:
header_struct = <Struct>

The structure of BSA headers.

Returns:The structure of BSA headers
Return type:Struct
directory_record_struct = <Struct>

The structure of directory records.

Returns:The structure of directory records
Return type:Struct
file_record_struct = <Struct>

The structure of file records.

Returns:The structure of file records
Return type:Struct
directory_block_struct = <Struct>

The structure of directory blocks.

Returns:The structure of directory blocks
Return type:Struct
archive_struct = <Struct>

The partial structure of BSA archives.

Returns:The partial structure of BSA archives
Return type:Struct
uncompressed_file_struct

The uncompressed file structure for uncompressed files.

Returns:The uncompressed file structure for uncompressed files.
Return type:Struct
compressed_file_struct

The compressed file structure for compressed files.

Returns:The compressed file structure for compressed files.
Return type:Struct
classmethod can_handle(filepath)[source]

Determines if a given file can be handled by the current archive.

Parameters:filepath (str) – The filepath to check if can be handled
Return type:bool
iter_files()[source]

Iterates over the parsed data and yields instances of ArchiveFile.

Yields:ArchiveFile – An file contained within the archive
Return type:Generator[ArchiveFile, None, None]

BTDX Archives

This module (along with dds) contains all the required structures to read and extract BTDX (.ba2) archives.

class bethesda_structs.archive.btdx.BTDXArchive(content, filepath=None)[source]

Bases: bethesda_structs.archive._common.BaseArchive

Archive type for BTDX files (aka. BA2).

BTDX files (utilize the extension .ba2) are Bethesda’s second framework revision for archives. These files have virtually the same goal as BSAArchive but for optimized loading of archived textures directly into the engine instead of simply compressing the files.

This is done by splitting the BTDX archive into 2 different types:
  • GNRL: Storage for general files that are simply compressed
  • DX10: Storage for Microsoft DirectDraw textures in an optimized format

The extraction for GNRL files is simple. But the extraction for DX10 requires rebuliding the DDS headers for each of the texture chunks. For this reason the bethesda_structs.contrib.dds module was added.

Note

BTDX archives to not read the file data on initialization. Header’s, records and names are read in and files are built during iter_files().

Reference:
header_struct = <Struct>

The structure of BTDX headers.

Returns:The structure of BTDX headers
Return type:Struct
file_struct = <Struct>

The structure of GNRL files.

Returns:The structure of GNRL files
Return type:Struct
tex_header_struct = <Struct>

The structure of DX10 file headers.

Returns:The structure of DX10 file headers.
Return type:Struct
tex_chunk_struct = <Struct>

The structure of DX10 chunks.

Returns:The structure of DX10 chunks
Return type:Struct
tex_struct = <Struct>

The structure of DX10 tex files.

Returns:The structure of DX10 tex files
Return type:Struct
archive_struct = <Struct>

The partial structure of BTDX archives.

Returns:The partial structure of BTDX archives
Return type:Struct
classmethod can_handle(filepath)[source]

Determines if a given file can be handled by the current archive.

Parameters:filepath (str) – The filepath to check if can be handled
Return type:bool
iter_files()[source]

Iterates over the parsed data and yields instances of ArchiveFile

Raises:ValueError – If a filename cannot be determined for a specific file record
Yields:ArchiveFile – A file contained within the archive
Return type:Generator[ArchiveFile, None, None]