mirror of
https://github.com/NinjaCheetah/libWiiPy.git
synced 2025-04-26 05:11:02 -04:00
Improved docstrings and made them all much more consistent across the project
This commit is contained in:
parent
7c631454a1
commit
e85eae567a
@ -1,5 +1,7 @@
|
||||
# "__init__.py" from libWiiPy by NinjaCheetah & Contributors
|
||||
# https://github.com/NinjaCheetah/libWiiPy
|
||||
#
|
||||
# These are the essential modules from libWiiPy that you'd probably want imported by default.
|
||||
|
||||
from .commonkeys import *
|
||||
from .content import *
|
||||
|
@ -8,8 +8,9 @@ korean_key = '63b82bb4f4614e2e13f2fefbba4c9b7e'
|
||||
vwii_key = '30bfc76e7c19afbb23163330ced7c28d'
|
||||
|
||||
|
||||
def get_common_key(common_key_index):
|
||||
"""Gets the specified Wii Common Key based on the index provided.
|
||||
def get_common_key(common_key_index) -> bytes:
|
||||
"""
|
||||
Gets the specified Wii Common Key based on the index provided.
|
||||
|
||||
Possible values for common_key_index: 0: Common Key, 1: Korean Key, 2: vWii Key
|
||||
|
||||
|
@ -12,7 +12,16 @@ from .crypto import decrypt_content, encrypt_content
|
||||
|
||||
|
||||
class ContentRegion:
|
||||
"""Creates a ContentRegion object to parse the continuous content region of a WAD.
|
||||
"""
|
||||
A ContentRegion object to parse the continuous content region of a WAD. Allows for retrieving content from the
|
||||
region in both encrypted or decrypted form, and setting new content.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
content_records : List[ContentRecord]
|
||||
The content records for the content stored in the region.
|
||||
num_contents : int
|
||||
The total number of contents stored in the region.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@ -23,7 +32,8 @@ class ContentRegion:
|
||||
self.content_list: List[bytes] = []
|
||||
|
||||
def load(self, content_region: bytes, content_records: List[ContentRecord]) -> None:
|
||||
"""Loads the raw content region and builds a list of all the contents.
|
||||
"""
|
||||
Loads the raw content region and builds a list of all the contents.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -59,7 +69,8 @@ class ContentRegion:
|
||||
self.content_list.append(content_enc)
|
||||
|
||||
def dump(self) -> bytes:
|
||||
"""Takes the list of contents and assembles them back into one content region. Returns this content region as a
|
||||
"""
|
||||
Takes the list of contents and assembles them back into one content region. Returns this content region as a
|
||||
bytes object and sets the raw content region variable to this result, then calls load() again to make sure the
|
||||
content list matches the raw data.
|
||||
|
||||
@ -85,7 +96,8 @@ class ContentRegion:
|
||||
return content_region_raw
|
||||
|
||||
def get_enc_content_by_index(self, index: int) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided index, in encrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided index, in encrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -101,7 +113,8 @@ class ContentRegion:
|
||||
return content_enc
|
||||
|
||||
def get_enc_content_by_cid(self, cid: int) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided Content ID, in encrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided Content ID, in encrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -127,7 +140,8 @@ class ContentRegion:
|
||||
return content_enc
|
||||
|
||||
def get_enc_contents(self) -> List[bytes]:
|
||||
"""Gets a list of all encrypted contents from the content region.
|
||||
"""
|
||||
Gets a list of all encrypted contents from the content region.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -137,7 +151,8 @@ class ContentRegion:
|
||||
return self.content_list
|
||||
|
||||
def get_content_by_index(self, index: int, title_key: bytes) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided index, in decrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided index, in decrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -168,7 +183,8 @@ class ContentRegion:
|
||||
return content_dec
|
||||
|
||||
def get_content_by_cid(self, cid: int, title_key: bytes) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided Content ID, in decrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided Content ID, in decrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -196,7 +212,8 @@ class ContentRegion:
|
||||
return content_dec
|
||||
|
||||
def get_contents(self, title_key: bytes) -> List[bytes]:
|
||||
"""Gets a list of all contents from the content region, in decrypted form.
|
||||
"""
|
||||
Gets a list of all contents from the content region, in decrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -216,7 +233,8 @@ class ContentRegion:
|
||||
|
||||
def set_enc_content(self, enc_content: bytes, cid: int, index: int, content_type: int, content_size: int,
|
||||
content_hash: bytes) -> None:
|
||||
"""Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
"""
|
||||
Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
set in the content record, with a new record being added if necessary.
|
||||
|
||||
Parameters
|
||||
@ -257,8 +275,9 @@ class ContentRegion:
|
||||
self.content_list[index] = enc_content
|
||||
|
||||
def set_content(self, dec_content: bytes, cid: int, index: int, content_type: int, title_key: bytes) -> None:
|
||||
"""Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
set in the content record, with a new record being added if necessary.
|
||||
"""
|
||||
Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
set in the content record, with a new record being added if necessary.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -283,7 +302,8 @@ class ContentRegion:
|
||||
self.set_enc_content(enc_content, cid, index, content_type, dec_content_size, dec_content_hash)
|
||||
|
||||
def load_enc_content(self, enc_content: bytes, index: int) -> None:
|
||||
"""Loads the provided encrypted content into the content region at the specified index, with the assumption that
|
||||
"""
|
||||
Loads the provided encrypted content into the content region at the specified index, with the assumption that
|
||||
it matches the record at that index. Not recommended for most use cases, use decrypted content and
|
||||
load_content() instead.
|
||||
|
||||
@ -303,7 +323,8 @@ class ContentRegion:
|
||||
self.content_list[index] = enc_content
|
||||
|
||||
def load_content(self, dec_content: bytes, index: int, title_key: bytes) -> None:
|
||||
"""Loads the provided decrypted content into the content region at the specified index, but first checks to make
|
||||
"""
|
||||
Loads the provided decrypted content into the content region at the specified index, but first checks to make
|
||||
sure it matches the record at that index before loading. This content will be encrypted when loaded.
|
||||
|
||||
Parameters
|
||||
|
@ -7,7 +7,8 @@ from Crypto.Cipher import AES
|
||||
|
||||
|
||||
def decrypt_title_key(title_key_enc, common_key_index, title_id) -> bytes:
|
||||
"""Gets the decrypted version of the encrypted Title Key provided.
|
||||
"""
|
||||
Gets the decrypted version of the encrypted Title Key provided.
|
||||
|
||||
Requires the index of the common key to use, and the Title ID of the title that the Title Key is for.
|
||||
|
||||
@ -37,7 +38,8 @@ def decrypt_title_key(title_key_enc, common_key_index, title_id) -> bytes:
|
||||
|
||||
|
||||
def decrypt_content(content_enc, title_key, content_index, content_length) -> bytes:
|
||||
"""Gets the decrypted version of the encrypted content.
|
||||
"""
|
||||
Gets the decrypted version of the encrypted content.
|
||||
|
||||
This requires the index of the content to decrypt as it is used as the IV, as well as the content length to adjust
|
||||
padding as necessary.
|
||||
@ -76,7 +78,8 @@ def decrypt_content(content_enc, title_key, content_index, content_length) -> by
|
||||
|
||||
|
||||
def encrypt_content(content_dec, title_key, content_index) -> bytes:
|
||||
"""Gets the encrypted version of the decrypted content.
|
||||
"""
|
||||
Gets the encrypted version of the decrypted content.
|
||||
|
||||
This requires the index of the content to encrypt as it is used as the IV, as well as the content length to adjust
|
||||
padding as necessary.
|
||||
|
@ -1,8 +1,12 @@
|
||||
# "shared.py" from libWiiPy by NinjaCheetah & Contributors
|
||||
# https://github.com/NinjaCheetah/libWiiPy
|
||||
#
|
||||
# This file defines general functions that may be useful in other modules of libWiiPy. Putting them here cuts down on
|
||||
# clutter in other files.
|
||||
|
||||
def align_value(value, alignment=64):
|
||||
"""Aligns the provided value to the set alignment (defaults to 64).
|
||||
def align_value(value, alignment=64) -> int:
|
||||
"""
|
||||
Aligns the provided value to the set alignment (defaults to 64).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -22,8 +26,9 @@ def align_value(value, alignment=64):
|
||||
return value
|
||||
|
||||
|
||||
def pad_bytes_stream(data, alignment=64):
|
||||
"""Pads the provided bytes stream to the provided alignment (defaults to 64).
|
||||
def pad_bytes_stream(data, alignment=64) -> bytes:
|
||||
"""
|
||||
Pads the provided bytes stream to the provided alignment (defaults to 64).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -12,8 +12,7 @@ from typing import List
|
||||
|
||||
class Ticket:
|
||||
"""
|
||||
Creates a Ticket object that allows for either loading and editing an existing Ticket or creating one manually if
|
||||
desired.
|
||||
A Ticket object that allows for either loading and editing an existing Ticket or creating one manually if desired.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
@ -58,7 +57,8 @@ class Ticket:
|
||||
# TODO: Write in v1 ticket attributes here. This code can currently only handle v0 tickets, and will reject v1.
|
||||
|
||||
def load(self, ticket: bytes) -> None:
|
||||
"""Loads raw Ticket data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
"""
|
||||
Loads raw Ticket data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
existing Ticket.
|
||||
|
||||
Parameters
|
||||
@ -138,7 +138,8 @@ class Ticket:
|
||||
self.title_limits_list.append(TitleLimit(limit_type, limit_value))
|
||||
|
||||
def dump(self) -> bytes:
|
||||
"""Dumps the Ticket object back into bytes. This also sets the raw Ticket attribute of Ticket object to the
|
||||
"""
|
||||
Dumps the Ticket object back into bytes. This also sets the raw Ticket attribute of Ticket object to the
|
||||
dumped data, and triggers load() again to ensure that the raw data and object match.
|
||||
|
||||
Returns
|
||||
@ -209,8 +210,9 @@ class Ticket:
|
||||
# Return the raw TMD for the data contained in the object.
|
||||
return ticket_data_raw
|
||||
|
||||
def get_title_id(self):
|
||||
"""Gets the Title ID of the ticket's associated title.
|
||||
def get_title_id(self) -> str:
|
||||
"""
|
||||
Gets the Title ID of the ticket's associated title.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -220,8 +222,9 @@ class Ticket:
|
||||
title_id_str = str(self.title_id.decode())
|
||||
return title_id_str
|
||||
|
||||
def get_common_key_type(self):
|
||||
"""Gets the name of the common key used to encrypt the Title Key contained in the ticket.
|
||||
def get_common_key_type(self) -> str:
|
||||
"""
|
||||
Gets the name of the common key used to encrypt the Title Key contained in the ticket.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -240,8 +243,9 @@ class Ticket:
|
||||
case 2:
|
||||
return "vWii"
|
||||
|
||||
def get_title_key(self):
|
||||
"""Gets the decrypted title key contained in the ticket.
|
||||
def get_title_key(self) -> bytes:
|
||||
"""
|
||||
Gets the decrypted title key contained in the ticket.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -251,8 +255,9 @@ class Ticket:
|
||||
title_key = decrypt_title_key(self.title_key_enc, self.common_key_index, self.title_id)
|
||||
return title_key
|
||||
|
||||
def set_title_id(self, title_id):
|
||||
"""Sets the Title ID of the title in the Ticket.
|
||||
def set_title_id(self, title_id) -> None:
|
||||
"""
|
||||
Sets the Title ID of the title in the Ticket.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -10,10 +10,15 @@ from .wad import WAD
|
||||
|
||||
|
||||
class Title:
|
||||
"""Creates a Title object that contains all components of a title, and allows altering them.
|
||||
"""
|
||||
A Title object that contains all components of a title, and allows altering them. Provides higher-level access
|
||||
than manually creating WAD, TMD, Ticket, and ContentRegion objects and ensures that any data that needs to match
|
||||
between files matches.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
wad : WAD
|
||||
A WAD object of a WAD containing the title's data.
|
||||
tmd : TMD
|
||||
A TMD object of the title's TMD.
|
||||
ticket : Ticket
|
||||
@ -28,7 +33,8 @@ class Title:
|
||||
self.content: ContentRegion = ContentRegion()
|
||||
|
||||
def load_wad(self, wad: bytes) -> None:
|
||||
"""Load existing WAD data into the title and create WAD, TMD, Ticket, and ContentRegion objects based off of it
|
||||
"""
|
||||
Load existing WAD data into the title and create WAD, TMD, Ticket, and ContentRegion objects based off of it
|
||||
to allow you to modify that data. Note that this will overwrite any existing data for this title.
|
||||
|
||||
Parameters
|
||||
@ -55,7 +61,8 @@ class Title:
|
||||
"invalid.")
|
||||
|
||||
def dump_wad(self) -> bytes:
|
||||
"""Dumps all title components (TMD, Ticket, and contents) back into the WAD object, and then dumps the WAD back
|
||||
"""
|
||||
Dumps all title components (TMD, Ticket, and contents) back into the WAD object, and then dumps the WAD back
|
||||
into raw data and returns it.
|
||||
|
||||
Returns
|
||||
@ -74,7 +81,8 @@ class Title:
|
||||
return wad_data
|
||||
|
||||
def load_tmd(self, tmd: bytes) -> None:
|
||||
"""Load existing TMD data into the title. Note that this will overwrite any existing TMD data for this title.
|
||||
"""
|
||||
Load existing TMD data into the title. Note that this will overwrite any existing TMD data for this title.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -85,7 +93,8 @@ class Title:
|
||||
self.tmd.load(tmd)
|
||||
|
||||
def load_ticket(self, ticket: bytes) -> None:
|
||||
"""Load existing Ticket data into the title. Note that this will overwrite any existing Ticket data for this
|
||||
"""
|
||||
Load existing Ticket data into the title. Note that this will overwrite any existing Ticket data for this
|
||||
title.
|
||||
|
||||
Parameters
|
||||
@ -97,7 +106,8 @@ class Title:
|
||||
self.ticket.load(ticket)
|
||||
|
||||
def load_content_records(self) -> None:
|
||||
"""Load content records from the TMD into the ContentRegion to allow loading content files based on the records.
|
||||
"""
|
||||
Load content records from the TMD into the ContentRegion to allow loading content files based on the records.
|
||||
This requires that a TMD has already been loaded and will throw an exception if it isn't.
|
||||
"""
|
||||
if not self.tmd.content_records:
|
||||
@ -106,7 +116,8 @@ class Title:
|
||||
self.content.content_records = self.tmd.content_records
|
||||
|
||||
def set_title_id(self, title_id: str) -> None:
|
||||
"""Sets the Title ID of the title in both the TMD and Ticket.
|
||||
"""
|
||||
Sets the Title ID of the title in both the TMD and Ticket.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -119,7 +130,8 @@ class Title:
|
||||
self.ticket.set_title_id(title_id)
|
||||
|
||||
def get_content_by_index(self, index: id) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided index, in decrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided index, in decrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -138,7 +150,8 @@ class Title:
|
||||
return dec_content
|
||||
|
||||
def get_content_by_cid(self, cid: int) -> bytes:
|
||||
"""Gets an individual content from the content region based on the provided Content ID, in decrypted form.
|
||||
"""
|
||||
Gets an individual content from the content region based on the provided Content ID, in decrypted form.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -158,7 +171,8 @@ class Title:
|
||||
|
||||
def set_enc_content(self, enc_content: bytes, cid: int, index: int, content_type: int, content_size: int,
|
||||
content_hash: bytes) -> None:
|
||||
"""Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
"""
|
||||
Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
set in the content record, with a new record being added if necessary. The TMD is also updated to match the new
|
||||
records.
|
||||
|
||||
@ -183,7 +197,8 @@ class Title:
|
||||
self.tmd.content_records = self.content.content_records
|
||||
|
||||
def set_content(self, dec_content: bytes, cid: int, index: int, content_type: int) -> None:
|
||||
"""Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
"""
|
||||
Sets the provided index to a new content with the provided Content ID. Hashes and size of the content are
|
||||
set in the content record, with a new record being added if necessary. The Title Key is sourced from this
|
||||
title's loaded ticket. The TMD is also updated to match the new records.
|
||||
|
||||
@ -204,7 +219,8 @@ class Title:
|
||||
self.tmd.content_records = self.content.content_records
|
||||
|
||||
def load_content(self, dec_content: bytes, index: int) -> None:
|
||||
"""Loads the provided decrypted content into the content region at the specified index, but first checks to make
|
||||
"""
|
||||
Loads the provided decrypted content into the content region at the specified index, but first checks to make
|
||||
sure it matches the record at that index before loading. This content will be encrypted when loaded.
|
||||
|
||||
Parameters
|
||||
|
@ -12,7 +12,7 @@ from .types import ContentRecord
|
||||
|
||||
class TMD:
|
||||
"""
|
||||
Creates a TMD object that allows for either loading and editing an existing TMD or creating one manually if desired.
|
||||
A TMD object that allows for either loading and editing an existing TMD or creating one manually if desired.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
@ -53,7 +53,8 @@ class TMD:
|
||||
self.content_records: List[ContentRecord] = []
|
||||
|
||||
def load(self, tmd: bytes) -> None:
|
||||
"""Loads raw TMD data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
"""
|
||||
Loads raw TMD data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
existing TMD.
|
||||
|
||||
Parameters
|
||||
@ -138,7 +139,8 @@ class TMD:
|
||||
binascii.hexlify(content_record_hdr[4])))
|
||||
|
||||
def dump(self) -> bytes:
|
||||
"""Dumps the TMD object back into bytes. This also sets the raw TMD attribute of TMD object to the dumped data,
|
||||
"""
|
||||
Dumps the TMD object back into bytes. This also sets the raw TMD attribute of TMD object to the dumped data,
|
||||
and triggers load() again to ensure that the raw data and object match.
|
||||
|
||||
Returns
|
||||
@ -212,8 +214,9 @@ class TMD:
|
||||
# Return the raw TMD for the data contained in the object.
|
||||
return tmd_data_raw
|
||||
|
||||
def get_title_region(self):
|
||||
"""Gets the region of the TMD's associated title.
|
||||
def get_title_region(self) -> str:
|
||||
"""
|
||||
Gets the region of the TMD's associated title.
|
||||
|
||||
Can be one of several possible values:
|
||||
'JAP', 'USA', 'EUR', 'NONE', or 'KOR'.
|
||||
@ -235,8 +238,9 @@ class TMD:
|
||||
case 4:
|
||||
return "KOR"
|
||||
|
||||
def get_is_vwii_title(self):
|
||||
"""Gets whether the TMD is designed for the vWii or not.
|
||||
def get_is_vwii_title(self) -> bool:
|
||||
"""
|
||||
Gets whether the TMD is designed for the vWii or not.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -248,8 +252,9 @@ class TMD:
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_title_type(self):
|
||||
"""Gets the type of the TMD's associated title.
|
||||
def get_title_type(self) -> str:
|
||||
"""
|
||||
Gets the type of the TMD's associated title.
|
||||
|
||||
Can be one of several possible values:
|
||||
'System', 'Game', 'Channel', 'SystemChannel', 'GameWithChannel', or 'HiddenChannel'
|
||||
@ -279,7 +284,8 @@ class TMD:
|
||||
return "Unknown"
|
||||
|
||||
def get_content_type(self):
|
||||
"""Gets the type of content contained in the TMD's associated title.
|
||||
"""
|
||||
Gets the type of content contained in the TMD's associated title.
|
||||
|
||||
Can be one of several possible values:
|
||||
'Normal', 'Development/Unknown', 'Hash Tree', 'DLC', or 'Shared'
|
||||
@ -303,8 +309,9 @@ class TMD:
|
||||
case _:
|
||||
return "Unknown"
|
||||
|
||||
def get_content_record(self, record):
|
||||
"""Gets the content record at the specified index.
|
||||
def get_content_record(self, record) -> ContentRecord:
|
||||
"""
|
||||
Gets the content record at the specified index.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -322,8 +329,9 @@ class TMD:
|
||||
raise IndexError("Invalid content record! TMD lists '" + str(self.num_contents - 1) +
|
||||
"' contents but index was '" + str(record) + "'!")
|
||||
|
||||
def set_title_id(self, title_id):
|
||||
"""Sets the Title ID of the title in the ticket.
|
||||
def set_title_id(self, title_id) -> None:
|
||||
"""
|
||||
Sets the Title ID of the title in the ticket.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -7,7 +7,9 @@ from dataclasses import dataclass
|
||||
@dataclass
|
||||
class ContentRecord:
|
||||
"""
|
||||
Creates a content record object that contains the details of a content contained in a title.
|
||||
A content record object that contains the details of a content contained in a title. This information must match
|
||||
the content stored at the index in the record, or else the content will not decrypt properly, as the hash of the
|
||||
decrypted data will not match the hash in the content record.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
@ -31,7 +33,10 @@ class ContentRecord:
|
||||
|
||||
@dataclass
|
||||
class TitleLimit:
|
||||
"""Creates a TitleLimit object that contains the type of restriction and the limit.
|
||||
"""
|
||||
A TitleLimit object that contains the type of restriction and the limit. The limit type can be one of the following:
|
||||
0 = None, 1 = Time Limit, 3 = None, or 4 = Launch Count. The maximum usage is then either the time in minutes the
|
||||
title can be played or the maximum number of launches allowed for that title, based on the type of limit applied.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
@ -40,9 +45,8 @@ class TitleLimit:
|
||||
maximum_usage : int
|
||||
The maximum value for the type of play limit applied.
|
||||
"""
|
||||
# The type of play limit applied. The following types exist:
|
||||
# The type of play limit applied.
|
||||
# 0 = None, 1 = Time Limit, 3 = None, 4 = Launch Count
|
||||
limit_type: int
|
||||
# The maximum value of the limit applied.
|
||||
# This is either the number of minutes for a time limit, or the number of launches for a launch limit.
|
||||
maximum_usage: int
|
||||
|
@ -10,7 +10,24 @@ from .shared import align_value, pad_bytes_stream
|
||||
|
||||
class WAD:
|
||||
"""
|
||||
Creates a WAD object that allows for either loading and editing an existing WAD or creating a new WAD from raw data.
|
||||
A WAD object that allows for either loading and editing an existing WAD or creating a new WAD from raw data.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
wad_type : str
|
||||
The type of WAD, either ib for boot2 or Is for normal installable WADs. libWiiPy only supports Is currently.
|
||||
wad_cert_size : int
|
||||
The size of the WAD's certificate.
|
||||
wad_crl_size : int
|
||||
The size of the WAD's crl.
|
||||
wad_tik_size : int
|
||||
The size of the WAD's Ticket.
|
||||
wad_tmd_size : int
|
||||
The size of the WAD's TMD.
|
||||
wad_content_size : int
|
||||
The size of WAD's total content region.
|
||||
wad_meta_size : int
|
||||
The size of the WAD's meta/footer.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.wad_hdr_size: int = 64
|
||||
@ -33,7 +50,8 @@ class WAD:
|
||||
self.wad_meta_data: bytes = b''
|
||||
|
||||
def load(self, wad_data) -> None:
|
||||
"""Loads raw WAD data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
"""
|
||||
Loads raw WAD data and sets all attributes of the WAD object. This allows for manipulating an already
|
||||
existing WAD file.
|
||||
|
||||
Parameters
|
||||
@ -114,7 +132,8 @@ class WAD:
|
||||
self.wad_meta_data = wad_data.read(self.wad_meta_size)
|
||||
|
||||
def dump(self) -> bytes:
|
||||
"""Dumps the WAD object into the raw WAD file. This allows for creating a WAD file from the data contained in
|
||||
"""
|
||||
Dumps the WAD object into the raw WAD file. This allows for creating a WAD file from the data contained in
|
||||
the WAD object.
|
||||
|
||||
Returns
|
||||
@ -167,8 +186,9 @@ class WAD:
|
||||
# Return the raw WAD file for the data contained in the object.
|
||||
return wad_data_raw
|
||||
|
||||
def get_wad_type(self):
|
||||
"""Gets the type of the WAD.
|
||||
def get_wad_type(self) -> str:
|
||||
"""
|
||||
Gets the type of the WAD.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -178,7 +198,8 @@ class WAD:
|
||||
return self.wad_type
|
||||
|
||||
def get_cert_data(self) -> bytes:
|
||||
"""Gets the certificate data from the WAD.
|
||||
"""
|
||||
Gets the certificate data from the WAD.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -188,7 +209,8 @@ class WAD:
|
||||
return self.wad_cert_data
|
||||
|
||||
def get_crl_data(self) -> bytes:
|
||||
"""Gets the crl data from the WAD, if it exists.
|
||||
"""
|
||||
Gets the crl data from the WAD, if it exists.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -198,7 +220,8 @@ class WAD:
|
||||
return self.wad_crl_data
|
||||
|
||||
def get_ticket_data(self) -> bytes:
|
||||
"""Gets the ticket data from the WAD.
|
||||
"""
|
||||
Gets the ticket data from the WAD.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -208,7 +231,8 @@ class WAD:
|
||||
return self.wad_tik_data
|
||||
|
||||
def get_tmd_data(self) -> bytes:
|
||||
"""Returns the TMD data from the WAD.
|
||||
"""
|
||||
Returns the TMD data from the WAD.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -218,7 +242,8 @@ class WAD:
|
||||
return self.wad_tmd_data
|
||||
|
||||
def get_content_data(self) -> bytes:
|
||||
"""Gets the content of the WAD.
|
||||
"""
|
||||
Gets the content of the WAD.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -228,7 +253,8 @@ class WAD:
|
||||
return self.wad_content_data
|
||||
|
||||
def get_meta_data(self) -> bytes:
|
||||
"""Gets the meta region of the WAD, which is typically unused.
|
||||
"""
|
||||
Gets the meta region of the WAD, which is typically unused.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@ -238,7 +264,8 @@ class WAD:
|
||||
return self.wad_meta_data
|
||||
|
||||
def set_cert_data(self, cert_data) -> None:
|
||||
"""Sets the certificate data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the certificate data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -250,7 +277,8 @@ class WAD:
|
||||
self.wad_cert_size = len(cert_data)
|
||||
|
||||
def set_crl_data(self, crl_data) -> None:
|
||||
"""Sets the crl data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the crl data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -262,7 +290,8 @@ class WAD:
|
||||
self.wad_crl_size = len(crl_data)
|
||||
|
||||
def set_tmd_data(self, tmd_data) -> None:
|
||||
"""Sets the TMD data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the TMD data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -274,7 +303,8 @@ class WAD:
|
||||
self.wad_tmd_size = len(tmd_data)
|
||||
|
||||
def set_ticket_data(self, tik_data) -> None:
|
||||
"""Sets the Ticket data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the Ticket data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -286,7 +316,8 @@ class WAD:
|
||||
self.wad_tik_size = len(tik_data)
|
||||
|
||||
def set_content_data(self, content_data) -> None:
|
||||
"""Sets the content data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the content data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -298,7 +329,8 @@ class WAD:
|
||||
self.wad_content_size = len(content_data)
|
||||
|
||||
def set_meta_data(self, meta_data) -> None:
|
||||
"""Sets the meta data of the WAD. Also calculates the new size.
|
||||
"""
|
||||
Sets the meta data of the WAD. Also calculates the new size.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
Loading…
x
Reference in New Issue
Block a user