mirror of
https://github.com/NinjaCheetah/WiiPy.git
synced 2025-04-26 21:31:02 -04:00
Added wad edit command to change properties of a WAD file
Info command also now shows the 4 character ASCII version of the Title ID when applicable
This commit is contained in:
parent
42fc37de65
commit
554bbfb7cb
@ -10,7 +10,10 @@ from modules.core import fatal_error
|
|||||||
def _print_tmd_info(tmd: libWiiPy.title.TMD):
|
def _print_tmd_info(tmd: libWiiPy.title.TMD):
|
||||||
# Get all important keys from the TMD and print them out nicely.
|
# Get all important keys from the TMD and print them out nicely.
|
||||||
print("Title Info")
|
print("Title Info")
|
||||||
print(f" Title ID: {tmd.title_id}")
|
try:
|
||||||
|
print(f" Title ID: {tmd.title_id.upper()} ({str(bytes.fromhex(tmd.title_id[8:]).decode()).upper()})")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print(f" Title ID: {tmd.title_id.upper()}")
|
||||||
# This type of version number really only applies to the System Menu and IOS.
|
# This type of version number really only applies to the System Menu and IOS.
|
||||||
if tmd.title_id[:8] == "00000001":
|
if tmd.title_id[:8] == "00000001":
|
||||||
print(f" Title Version: {tmd.title_version} ({tmd.title_version_converted})")
|
print(f" Title Version: {tmd.title_version} ({tmd.title_version_converted})")
|
||||||
@ -21,7 +24,7 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD):
|
|||||||
if tmd.ios_tid == "0000000000000000":
|
if tmd.ios_tid == "0000000000000000":
|
||||||
print(f" Required IOS: N/A")
|
print(f" Required IOS: N/A")
|
||||||
else:
|
else:
|
||||||
print(f" Required IOS: IOS{int(tmd.ios_tid[-2:], 16)} ({tmd.ios_tid})")
|
print(f" Required IOS: IOS{int(tmd.ios_tid[-2:], 16)} ({tmd.ios_tid.upper()})")
|
||||||
if tmd.signature_issuer.find("CP00000004") != -1:
|
if tmd.signature_issuer.find("CP00000004") != -1:
|
||||||
print(f" Certificate: CP00000004 (Retail)")
|
print(f" Certificate: CP00000004 (Retail)")
|
||||||
print(f" Certificate Issuer: Root-CA00000001 (Retail)")
|
print(f" Certificate Issuer: Root-CA00000001 (Retail)")
|
||||||
@ -45,7 +48,7 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD):
|
|||||||
region = "KOR"
|
region = "KOR"
|
||||||
case _:
|
case _:
|
||||||
region = "None"
|
region = "None"
|
||||||
elif tmd.title_id[:8] == "00000001":
|
elif tmd.get_title_type() == "System":
|
||||||
region = "None"
|
region = "None"
|
||||||
else:
|
else:
|
||||||
region = tmd.get_title_region()
|
region = tmd.get_title_region()
|
||||||
@ -71,7 +74,11 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD):
|
|||||||
def _print_ticket_info(ticket: libWiiPy.title.Ticket):
|
def _print_ticket_info(ticket: libWiiPy.title.Ticket):
|
||||||
# Get all important keys from the TMD and print them out nicely.
|
# Get all important keys from the TMD and print them out nicely.
|
||||||
print(f"Ticket Info")
|
print(f"Ticket Info")
|
||||||
print(f" Title ID: {ticket.title_id.decode()}")
|
try:
|
||||||
|
print(f" Title ID: {ticket.title_id.decode().upper()} "
|
||||||
|
f"({str(bytes.fromhex(ticket.title_id.decode()[8:]).decode()).upper()})")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print(f" Title ID: {ticket.title_id.decode().upper()}")
|
||||||
# This type of version number really only applies to the System Menu and IOS.
|
# This type of version number really only applies to the System Menu and IOS.
|
||||||
if ticket.title_id.decode()[:8] == "00000001":
|
if ticket.title_id.decode()[:8] == "00000001":
|
||||||
print(f" Title Version: {ticket.title_version} "
|
print(f" Title Version: {ticket.title_version} "
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
# "commands/title/wad.py" from WiiPy by NinjaCheetah
|
# "commands/title/wad.py" from WiiPy by NinjaCheetah
|
||||||
# https://github.com/NinjaCheetah/WiiPy
|
# https://github.com/NinjaCheetah/WiiPy
|
||||||
|
|
||||||
|
import binascii
|
||||||
import pathlib
|
import pathlib
|
||||||
from random import randint
|
from random import randint
|
||||||
import libWiiPy
|
import libWiiPy
|
||||||
|
|
||||||
from modules.core import fatal_error
|
from modules.core import fatal_error
|
||||||
|
|
||||||
|
|
||||||
@ -366,3 +368,75 @@ def handle_wad_unpack(args):
|
|||||||
output_path.joinpath(content_file_name).write_bytes(title.get_content_by_index(content_file, skip_hash))
|
output_path.joinpath(content_file_name).write_bytes(title.get_content_by_index(content_file, skip_hash))
|
||||||
|
|
||||||
print("WAD file unpacked!")
|
print("WAD file unpacked!")
|
||||||
|
|
||||||
|
|
||||||
|
def handle_wad_edit(args):
|
||||||
|
input_path = pathlib.Path(args.input)
|
||||||
|
if args.output is not None:
|
||||||
|
output_path = pathlib.Path(args.output)
|
||||||
|
else:
|
||||||
|
output_path = pathlib.Path(args.input)
|
||||||
|
|
||||||
|
title = libWiiPy.title.Title()
|
||||||
|
title.load_wad(input_path.read_bytes())
|
||||||
|
|
||||||
|
# State variable to make sure that changes are made.
|
||||||
|
edits_made = False
|
||||||
|
# Go over every possible change, and apply them if they were specified.
|
||||||
|
if args.tid is not None:
|
||||||
|
# Setting a new TID, only changing TID low since this expects a 4 character ASCII input.
|
||||||
|
new_tid = args.tid
|
||||||
|
if len(new_tid) != 4:
|
||||||
|
fatal_error(f"The specified Title ID is not valid! The new Title ID should be 4 characters long.")
|
||||||
|
if not new_tid.isalnum():
|
||||||
|
fatal_error(f"The specified Title ID is not valid! The new Title ID should be alphanumeric.")
|
||||||
|
# Get the current TID high, because we want to preserve the title type while only changing the TID low.
|
||||||
|
tid_high = title.tmd.title_id[:8]
|
||||||
|
new_tid = f"{tid_high}{str(binascii.hexlify(new_tid.encode()), 'ascii')}"
|
||||||
|
title.set_title_id(new_tid)
|
||||||
|
edits_made = True
|
||||||
|
if args.ios is not None:
|
||||||
|
# Setting a new required IOS.
|
||||||
|
new_ios = None
|
||||||
|
try:
|
||||||
|
new_ios = int(args.ios)
|
||||||
|
except ValueError:
|
||||||
|
fatal_error("The specified IOS is not valid! The new IOS should be a valid integer.")
|
||||||
|
if new_ios < 3 or new_ios > 255:
|
||||||
|
fatal_error("The specified IOS is not valid! The new IOS version should be between 3 and 255.")
|
||||||
|
new_ios_tid = f"00000001{new_ios:08X}"
|
||||||
|
title.tmd.ios_tid = new_ios_tid
|
||||||
|
edits_made = True
|
||||||
|
if args.type is not None:
|
||||||
|
# Setting a new title type.
|
||||||
|
new_type = args.type
|
||||||
|
new_tid_high = None
|
||||||
|
match new_type:
|
||||||
|
case "System":
|
||||||
|
new_tid_high = "00000001"
|
||||||
|
case "Channel":
|
||||||
|
new_tid_high = "00010001"
|
||||||
|
case "SystemChannel":
|
||||||
|
new_tid_high = "00010002"
|
||||||
|
case "GameChannel":
|
||||||
|
new_tid_high = "00010004"
|
||||||
|
case "DLC":
|
||||||
|
new_tid_high = "00010005"
|
||||||
|
case "HiddenChannel":
|
||||||
|
new_tid_high = "00010008"
|
||||||
|
case _:
|
||||||
|
fatal_error("The specified type is not valid! The new type must be one of: System, Channel, "
|
||||||
|
"SystemChannel, GameChannel, DLC, HiddenChannel.")
|
||||||
|
tid_low = title.tmd.title_id[8:]
|
||||||
|
new_tid = f"{new_tid_high}{tid_low}"
|
||||||
|
title.set_title_id(new_tid)
|
||||||
|
edits_made = True
|
||||||
|
|
||||||
|
if not edits_made:
|
||||||
|
fatal_error("You must specify at least one change to make!")
|
||||||
|
|
||||||
|
# Fakesign the title since any changes have already invalidated the signature.
|
||||||
|
title.fakesign()
|
||||||
|
output_path.write_bytes(title.dump_wad())
|
||||||
|
|
||||||
|
print("Successfully edited WAD file!")
|
||||||
|
15
wiipy.py
15
wiipy.py
@ -286,6 +286,21 @@ if __name__ == "__main__":
|
|||||||
"installed from Wii U mode if a Wii U mode WAD installer is created")
|
"installed from Wii U mode if a Wii U mode WAD installer is created")
|
||||||
wad_convert_parser.add_argument("-o", "--output", metavar="OUT", type=str,
|
wad_convert_parser.add_argument("-o", "--output", metavar="OUT", type=str,
|
||||||
help="file to output the new WAD to (optional, defaults to '<old_name>_<key>.wad')")
|
help="file to output the new WAD to (optional, defaults to '<old_name>_<key>.wad')")
|
||||||
|
# Edit WAD subcommand.
|
||||||
|
wad_edit_parser = wad_subparsers.add_parser("edit", help="edit the properties of a WAD file",
|
||||||
|
description="edit the properties of a WAD file; by default, this will "
|
||||||
|
"overwrite the input file unless an output is specified")
|
||||||
|
wad_edit_parser.set_defaults(func=handle_wad_edit)
|
||||||
|
wad_edit_parser.add_argument("input", metavar="IN", type=str, help="WAD file to edit")
|
||||||
|
wad_edit_parser.add_argument("--tid", metavar="TID", type=str,
|
||||||
|
help="a new Title ID for this WAD (formatted as 4 ASCII characters)")
|
||||||
|
wad_edit_parser.add_argument("--ios", metavar="IOS", type=str,
|
||||||
|
help="a new IOS version for this WAD (formatted as the decimal IOS version, eg. 58)")
|
||||||
|
wad_edit_parser.add_argument("--type", metavar="TYPE", type=str,
|
||||||
|
help="a new title type for this WAD (valid options: System, Channel, SystemChannel, "
|
||||||
|
"GameChannel, DLC, HiddenChannel)")
|
||||||
|
wad_edit_parser.add_argument("-o", "--output", metavar="OUT", type=str,
|
||||||
|
help="file to output the updated WAD to (optional)")
|
||||||
# Pack WAD subcommand.
|
# Pack WAD subcommand.
|
||||||
wad_pack_parser = wad_subparsers.add_parser("pack", help="pack a directory to a WAD file",
|
wad_pack_parser = wad_subparsers.add_parser("pack", help="pack a directory to a WAD file",
|
||||||
description="pack a directory to a WAD file")
|
description="pack a directory to a WAD file")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user