livemaker package¶
Subpackages¶
Submodules¶
livemaker.archive module¶
LiveMaker archive/exe file module.
The archive module makes it possible to read and write LiveMaker archives (and executables).
The API for archive behaves similary to Python’s zipfile
module,
with the exception that archives cannot be modified in-place (i.e. mode 'a'
is unavailable).
-
class
livemaker.archive.
LMCompressType
[source]¶ Bases:
enum.IntEnum
An enumeration.
-
ZLIB
= 0¶
-
NONE
= 1¶
-
ENCRYPTED
= 2¶
-
ENCRYPTED_ZLIB
= 3¶
-
-
class
livemaker.archive.
LMObfuscator
(seed=1977019961)[source]¶ Bases:
object
Class for (de)obfuscating LiveMaker directory fields.
Note
RE’d from TTpRandom class in LiveMaker code.
-
class
livemaker.archive.
LMArchiveDirectory
[source]¶ Bases:
object
Class for handling parsing and writing archive directories.
LiveMaker archive format is:
Directory Header: 16-bit "vf" signature 32-bit uint version 32-bit uint count Filenames (list with length <count> entries): 32-bit uint prefixed pascal strings (CP932 (MS Shift-JIS) encoded) Offsets (list with length <file_count> + 1): 32-bit uint offset_low 32-bit uint offset_high Compression flags (list with length <file_count>) 8-bit uint compression method Unknown list (list length <file_count>) 32-bit uint unk1 Checksums - (list length <file_count>) 32-bit uint checksum Encryption flags 0 if not encrypted (list length <file_count>) 8-bit uint encrypt_flag File data ...
Note
LiveMaker3 mangles filenames and offsets by XOR’ing them with a fixed keystream. Individual files may also be encrypted/obfuscated, this is specified by the compression flags.
Offsets are actually 64-bit long long, but they are stored as two separate 32-bit integers.
The extra offset entry is used to calculate the (compressed) size of the final file.
- If
encrypt_flag
is zero,checksum
is the checksum of the compressed file data. - If
encrypt_flag
is nonzerochecksum
is the checksum of the uncompressed and decrypted file data.
RE’d from TVrFileCollection classes in LiveMaker code.
-
classmethod
split_offset
(offset)[source]¶ Split an offset into the expected components for writing to an archive.
- If
-
class
livemaker.archive.
LMArchive
(name=None, mode='r', fp=None, exe=None, split=False, version=102)[source]¶ Bases:
object
Provide interface to a LiveMaker archive (or exe).
Behaves in the same manner as Python
tarfile.TarFile
orzipfile.ZipFile
. Can be used inside a Pythonwith
statement (in the same way as zip/tar files).Parameters: - name – Pathname for the archive. name can be a string or path-like object. If omitted, fp must be specified.
- mode – Either
'r'
to read from an existing archive or'w'
to create a new file (overwriting an existing one). Defaults to'r'
. - fp – If fileobj is given, it will be used for reading and writing data. If it can be determined, mode will be overridden by fp’s mode. fileobj will be used from position 0.
- exe – Pathname for LiveMaker executable (
.exe
) file. If exe is given and mode isw
, the output file will be an executable with the archive appended to the end (i.e. a LiveMaker.exe
file). If exe is not given, the output file will be a standalone archive (i.e. a LiveMaker.dat
file). exe does nothing when opening a file for reading. - split – If opening in write mode and split is
True
, the archive data will be split into smaller files across 1GB boundaries. split has no effect in read mode or when writing an executable archive. - version – Archive version, only applies to write mode.
Note
fp is not closed when LiveMakerArchive is closed.
'a'
is an invalid mode for LiveMakerArchive. Archives cannot be modified in place, to patch an existing archive, you must write to a new file.When opened in write mode, the output archive file will not be written until LMArchive.close() is called. As entries are added to the archive, they will be written to a temporary file. Upon calling close(), the exe (if it exists) and archive header will be written to the output file, then the temporary file will be copied to the end of the output file.
-
close
()[source]¶ Close the archive file.
When an archive is opened in write mode, close() must be called before exiting your program or else the archive will not actually be written.
-
getinfo
(name)[source]¶ Return a LMArchiveInfo object for the entry with the specified name.
Raises: KeyError
– If name is not an entry in the archive.
-
extract
(name, path=None)[source]¶ Extract the specified entry from the archive to the current working directory.
Parameters: - name (str,
LMArchiveInfo
) – The entry to extract, can be either it’s full name or a LMArchiveInfo object. - path – If given, the path will be used instead of the current working directory.
Raises: UnsupportedLiveMakerCompression
– If the specified entry uses an unsupported compression method.- name (str,
-
extractall
(path=None, entries=None, allow_unsupported=False)[source]¶ Extract all entries in this archive to the current working directory.
Parameters: - path – If path is given, it will be used instead of the current working directory.
- entries – Optional value that must be a subset of the list returned by namelist() or infolist().
- allow_unsupported – If True, any files which are compressed with an unsupported method will be silently ignored. If False, an exception will be raised when trying to extract any files which use unsupported compression methods.
Raises: UnsupportedLiveMakerCompression
-
read
(name, decompress=True, skip_checksum=True)[source]¶ Return the bytes of the specified file in the archive.
The archive must be open for reading.
Parameters: - name – Either the name of a file in the archive or a LMArchiveInfo object.
- decompress – If
True
the returned bytes will be decompressed. IfFalse
the original compressed entry data will be returned. - skip_checksum – If
True
the file checksum will not be verified. IfFalse
the checksum will be verified. If the checksum does not match, the file will still be extracted, but a warning will be logged.
Raises: UnsupportedLiveMakerCompression
– If decompress isTrue
and the specified entry uses an unsupported compression method.
-
read_exe
()[source]¶ Return the exe bytes for this archive.
Raises: ValueError
– If this archive is not part of a LiveMaker executable (i.e. it is a.dat
file).
-
write
(filename, arcname=None, compress_type=None, unk1=None)[source]¶ Write the file named filename into the archive.
Parameters: - filename – File to write into archive.
- arcname – If given, the archive file entry will be named arcname. By default, arcname will be the same as filename, but with any drive letter and leading path separators removed. Posix paths will be replaced with equivalent Windows paths.
- compress_type (LMCompressType) – If given, the file will be compressed with the specified method (defaults to uncompressed for files < 5MB in size, and zlib compressed for files >= 5MB).
Returns: The number of (compressed) bytes written.
Raises: FileExistsError
– If an entry matching arcname already exists in this archive.UnsupportedLiveMakerCompression
– If the compress_type is unsupported.
-
writebytes
(arcname, data, compress_type=None, skip_checksum=True)[source]¶ Write a raw (already compressed) file into the archive.
This method can be used to copy compressed data from an old archive into a new one without needing to do any intermediate extraction. This may be useful for copying encrypted files from one archive into another.
Parameters: - arcname – The archive entry name (or LMArchiveInfo object).
- data (bytes) – The contents of arcname. data must be a bytes instance, not a str instance. data must be compressed using the compression type specified in compress_type or the arcname LMArchiveInfo object.
- compress_type – The compression type for the newly created archive entry will be set to this value. If arcname is a string, compress_type must be explicitly set. compress_type can be omitted if arcname is an LMArchiveInfo object, in which case compression type will be read from the info object.
- skip_checksum – If
True
and arcname is a LMArchiveInfo object, checksum for data will not be calculated, and will be copied from arcname.
Returns: The number of bytes written.
Raises: FileExistsError
– If an entry matching arcname already exists in this archive.
-
class
livemaker.archive.
LMArchiveInfo
(name='')[source]¶ Bases:
object
An entry (file) contained in a LiveMaker archive.
-
name
¶ Filename.
Type: str
-
compress_type
¶ Compression type.
Type: LMCompressType
-
compressed_size
¶ Compressed file size in bytes.
Type: int
-
checksum
¶ VF checksum for the compressed data. See LMArchiveDirectory.checksum() for how checksum is calculated.
-
encrypt_flag
¶ Only used for LiveMaker Pro encrypted files.
-
path
¶
-
livemaker.exceptions module¶
pylivemaker exceptions.
-
exception
livemaker.exceptions.
LiveMakerException
[source]¶ Bases:
Exception
Base pylivemaker exception.
-
exception
livemaker.exceptions.
BadLiveMakerArchive
[source]¶ Bases:
livemaker.exceptions.LiveMakerException
Error raised for bad/invalid archive files.
-
exception
livemaker.exceptions.
BadLsbError
[source]¶ Bases:
livemaker.exceptions.LiveMakerException
Error raised for bad/invalid LSB script files.
-
exception
livemaker.exceptions.
BadLpbError
[source]¶ Bases:
livemaker.exceptions.LiveMakerException
Error raised for bad/invalid LPB project settings files.
-
exception
livemaker.exceptions.
BadLnsError
[source]¶ Bases:
livemaker.exceptions.LiveMakerException
Error raised for bad/invalid LNS novel scripts.
-
exception
livemaker.exceptions.
BadTextIdentifierError
[source]¶ Bases:
livemaker.exceptions.LiveMakerException
Error raised for bad/invalid translatable text IDs.
livemaker.lpb module¶
LiveMaker project settings file (LPB) module.
-
class
livemaker.lpb.
LMProject
(version=117, project_name='', unk1=0, unk2=0, init_lsb='', exit_lsb='', project_dir='', unk3=0, bool1=0, bool2=0, audio_formats='.wav.wma.ogg.mid.mp3', bool3=0, bool4=0, bool5=1, insert_disk_prompt='', exit_prompt='', system_settings=[], **kwargs)[source]¶ Bases:
object
Class for handling project settings files.
RE’d from TProject, TProjectSettings classes in LiveMaker code.
-
lm_version
¶
-
livemaker.lpm module¶
LiveMaker preview menu file (LPM) module.
-
class
livemaker.lpm.
LMLivePrevMenu
(version=106, unk1=0, buttons=[], **kwargs)[source]¶ Bases:
object
Class for handling preview menu files.
RE’d from TLivePrevMenu, TLivePrevImages classes in LiveMaker code.
livemaker.project module¶
pylivemaker project management module.
livemaker.scramble module¶
LiveMaker scramble (encryption) module.
Module contents¶
Top-level package for pylivemaker.
-
class
livemaker.
LMArchive
(name=None, mode='r', fp=None, exe=None, split=False, version=102)[source]¶ Bases:
object
Provide interface to a LiveMaker archive (or exe).
Behaves in the same manner as Python
tarfile.TarFile
orzipfile.ZipFile
. Can be used inside a Pythonwith
statement (in the same way as zip/tar files).Parameters: - name – Pathname for the archive. name can be a string or path-like object. If omitted, fp must be specified.
- mode – Either
'r'
to read from an existing archive or'w'
to create a new file (overwriting an existing one). Defaults to'r'
. - fp – If fileobj is given, it will be used for reading and writing data. If it can be determined, mode will be overridden by fp’s mode. fileobj will be used from position 0.
- exe – Pathname for LiveMaker executable (
.exe
) file. If exe is given and mode isw
, the output file will be an executable with the archive appended to the end (i.e. a LiveMaker.exe
file). If exe is not given, the output file will be a standalone archive (i.e. a LiveMaker.dat
file). exe does nothing when opening a file for reading. - split – If opening in write mode and split is
True
, the archive data will be split into smaller files across 1GB boundaries. split has no effect in read mode or when writing an executable archive. - version – Archive version, only applies to write mode.
Note
fp is not closed when LiveMakerArchive is closed.
'a'
is an invalid mode for LiveMakerArchive. Archives cannot be modified in place, to patch an existing archive, you must write to a new file.When opened in write mode, the output archive file will not be written until LMArchive.close() is called. As entries are added to the archive, they will be written to a temporary file. Upon calling close(), the exe (if it exists) and archive header will be written to the output file, then the temporary file will be copied to the end of the output file.
-
close
()[source]¶ Close the archive file.
When an archive is opened in write mode, close() must be called before exiting your program or else the archive will not actually be written.
-
getinfo
(name)[source]¶ Return a LMArchiveInfo object for the entry with the specified name.
Raises: KeyError
– If name is not an entry in the archive.
-
extract
(name, path=None)[source]¶ Extract the specified entry from the archive to the current working directory.
Parameters: - name (str,
LMArchiveInfo
) – The entry to extract, can be either it’s full name or a LMArchiveInfo object. - path – If given, the path will be used instead of the current working directory.
Raises: UnsupportedLiveMakerCompression
– If the specified entry uses an unsupported compression method.- name (str,
-
extractall
(path=None, entries=None, allow_unsupported=False)[source]¶ Extract all entries in this archive to the current working directory.
Parameters: - path – If path is given, it will be used instead of the current working directory.
- entries – Optional value that must be a subset of the list returned by namelist() or infolist().
- allow_unsupported – If True, any files which are compressed with an unsupported method will be silently ignored. If False, an exception will be raised when trying to extract any files which use unsupported compression methods.
Raises: UnsupportedLiveMakerCompression
-
read
(name, decompress=True, skip_checksum=True)[source]¶ Return the bytes of the specified file in the archive.
The archive must be open for reading.
Parameters: - name – Either the name of a file in the archive or a LMArchiveInfo object.
- decompress – If
True
the returned bytes will be decompressed. IfFalse
the original compressed entry data will be returned. - skip_checksum – If
True
the file checksum will not be verified. IfFalse
the checksum will be verified. If the checksum does not match, the file will still be extracted, but a warning will be logged.
Raises: UnsupportedLiveMakerCompression
– If decompress isTrue
and the specified entry uses an unsupported compression method.
-
read_exe
()[source]¶ Return the exe bytes for this archive.
Raises: ValueError
– If this archive is not part of a LiveMaker executable (i.e. it is a.dat
file).
-
write
(filename, arcname=None, compress_type=None, unk1=None)[source]¶ Write the file named filename into the archive.
Parameters: - filename – File to write into archive.
- arcname – If given, the archive file entry will be named arcname. By default, arcname will be the same as filename, but with any drive letter and leading path separators removed. Posix paths will be replaced with equivalent Windows paths.
- compress_type (LMCompressType) – If given, the file will be compressed with the specified method (defaults to uncompressed for files < 5MB in size, and zlib compressed for files >= 5MB).
Returns: The number of (compressed) bytes written.
Raises: FileExistsError
– If an entry matching arcname already exists in this archive.UnsupportedLiveMakerCompression
– If the compress_type is unsupported.
-
writebytes
(arcname, data, compress_type=None, skip_checksum=True)[source]¶ Write a raw (already compressed) file into the archive.
This method can be used to copy compressed data from an old archive into a new one without needing to do any intermediate extraction. This may be useful for copying encrypted files from one archive into another.
Parameters: - arcname – The archive entry name (or LMArchiveInfo object).
- data (bytes) – The contents of arcname. data must be a bytes instance, not a str instance. data must be compressed using the compression type specified in compress_type or the arcname LMArchiveInfo object.
- compress_type – The compression type for the newly created archive entry will be set to this value. If arcname is a string, compress_type must be explicitly set. compress_type can be omitted if arcname is an LMArchiveInfo object, in which case compression type will be read from the info object.
- skip_checksum – If
True
and arcname is a LMArchiveInfo object, checksum for data will not be calculated, and will be copied from arcname.
Returns: The number of bytes written.
Raises: FileExistsError
– If an entry matching arcname already exists in this archive.
-
class
livemaker.
LMArchiveInfo
(name='')[source]¶ Bases:
object
An entry (file) contained in a LiveMaker archive.
-
name
¶ Filename.
Type: str
-
compress_type
¶ Compression type.
Type: LMCompressType
-
compressed_size
¶ Compressed file size in bytes.
Type: int
-
checksum
¶ VF checksum for the compressed data. See LMArchiveDirectory.checksum() for how checksum is calculated.
-
encrypt_flag
¶ Only used for LiveMaker Pro encrypted files.
-
path
¶
-
-
class
livemaker.
LMCompressType
[source]¶ Bases:
enum.IntEnum
An enumeration.
-
ZLIB
= 0¶
-
NONE
= 1¶
-
ENCRYPTED
= 2¶
-
ENCRYPTED_ZLIB
= 3¶
-
-
class
livemaker.
LMScript
(version=117, param_type=1, flags=0, call_name='', novel_params=[], command_params=[[]], commands=[], **kwargs)[source]¶ Bases:
livemaker.lsb.core.BaseSerializable
LiveMaker script class.
A LiveMaker script is a collection of LiveMaker novel commands. One LiveMaker/LiveNovel “Chart” will be serialized as one script file.
Parameters: - version (int) – Version number. If version is not in the range [MIN_LSB_VERSION, MAX_LSB_VERSION], this LMScript cannot be compiled into a binary LSB.
- param_type – Unknown type flag (always 1?).
- flags (int) – Unknown (always 0?).
- call_name (str) – String name for calling this script (only used for documentation).
- novel_params (iterable) – Iterable containing string descriptions for parameters that this script accepts (only used for documentation).
- command_params (iterable(iterable(bool))) – Two dimensional array of booleans specifying the command parameters are for Component type commands. (i.e. command_params[CommandType.BoxNew][PropertyType.PR_NAME] == True means that BoxNew takes a PR_NAME parameter.)
- commands (iterable) – Iterable containing this script’s Command objects.
Raises: BadLsbError
– If the specified LMScript would be invalid or unsupported.-
commands
¶
-
command_count
¶ Return the number of command types supported by this script.
-
param_stream_size
¶ Return the length of this script’s param flag bytestream.
-
lm_version
¶ Return LiveMaker app version based on an LSB version.
-
classmethod
from_lsc
(s)[source]¶ Create an LMScript from the specified string.
Parameters: s – String containing text .lsc format data. Raises: BadLsbError if the string could not be parsed. Note
Currently only supports reading version information.
-
classmethod
from_xml
(root, **kwargs)[source]¶ Create an LMScript from the specified XML element.
Parameters: root – The root tree element. Raises: BadLsbError
– If the XML tree could not be parsed.Note
Currently only supports reading header information.
-
classmethod
from_file
(infile, **kwargs)[source]¶ Parse the specified file into an LMScript.
Parameters: infile – Input .lsc or .lsb file. Can be a string, path-like, or file-like object. Raises: BadLsbError
– If the input file could not be parsed.
-
classmethod
from_lsb
(data, **kwargs)[source]¶ Parse the specified compiled .lsb data into an LMScript.
Parameters: data – Input .lsb data. Raises: BadLsbError
– If the input data could not be parsed.
-
get_command
(line_no)[source]¶ Get specified command by line number.
Returns: tuple(cmd_index, cmd) Raises: KeyError
– the specified line_no does not exist in this LSB.
-
walk
(start=0, unreachable=False)[source]¶ Iterate over LSB commands in approximate execution order.
All conditional branches will be followed (positive condition will be evaluated first), but external jumps and calls will not be followed.
Parameters: - start (int) – Command index to start from.
- unreachable (bool) – If True, unreachable commands will be included.
Yields: 3-tuple in the form
(index, command, last_calc)
-
text_scenarios
(run_order=True)[source]¶ Return a list of LiveNovel text scenarios contained in this script.
Parameters: run_order (bool) – If True, scenarios will be returned in approximately the order they would be run in-game (via walk(). If False, text blocks will be returned in the order they occur in the LSB file. Returns: (line_num, name, scenario) Return type: tuple(int, str, TpWord
)
-
get_text_blocks
(run_order=False)[source]¶ Return LiveNovel scenario text blocks contained in this script.
Parameters: run_order (bool) – If True, text blocks will be returned in approximately the order they would be run in-game (via walk(). If False, text blocks will be returned in the order they occur in the LSB file. Returns: list of (identifier, block) tuples
-
replace_text
(text_objects)[source]¶ Replace the specified translatable text objects in this LSB.
Parameters: text_objects – Iterable containing (identifier, text) tuples
-
replace_text_blocks
(text_objects)[source]¶ Replace the specified LiveNovel scenario text blocks in this LSB.
Parameters: text_objects – Iterable containing (identifier, text) tuples
Return a list of LiveNovel text selection menus contained in this script.
Parameters: run_order (bool) – If True, menus will be returned in approximately the order they would be run in-game (via walk(). If False, text blocks will be returned in the order they occur in the LSB file. Returns: (line_num, menu) Return type: tuple(int, BaseSelectionMenu
)
Return selection menu choices contained in this script.
Parameters: run_order (bool) – If True, menus will be returned in approximately the order they would be run in-game (via walk(). If False, menus will be returned in the order they occur in the LSB file. Returns: list of (identifier, choice) tuples
Replace the specified text selection menu choices in this LSB.
Parameters: text_objects – Iterable containing (identifier, text) tuples
-
class
livemaker.
LNSCompiler
[source]¶ Bases:
_markupbase.ParserBase
Attempt to compile a LiveNovel LNS script into a TpWord block.
Based on Python3 html.parser.HTMLParser.
Note
This is only intended to be used to compile scripts which have been decompiled by pylivemaker and then translated/edited for patching. Attempting to compile a script which was not initially generated by pylivemaker may not work as intended.
-
END_TAGS
= ('a', 'style', 'div')¶
-
compile
(script)[source]¶ Compile a [decompiled] script into a TpWord block.
Parameters: script (str) – Script data
-
-
class
livemaker.
LNSDecompiler
(sep='n', include_comments=True, text_only=False)[source]¶ Bases:
object
Attempt to decompile a TpWord text block into something that resembles LiveMaker’s LiveNovel scenario script format.
Parameters: - sep (str) – Output line separator (defaults to
os.linesep
). - include_comments (bool) – Include comment lines in output.
- text_only (bool) – Output text only (all tags will be removed except for variable names).
Raises: ValueError
– If tpword is not aTpWord
instance.- sep (str) – Output line separator (defaults to