Add WIP nus subcommand for downloading a specific content

This commit is contained in:
Campbell 2024-07-10 21:34:28 +10:00
parent 09631d509e
commit 1b603e94fc
Signed by: NinjaCheetah
GPG Key ID: 670C282B3291D63D
2 changed files with 62 additions and 0 deletions

View File

@ -2,6 +2,7 @@
# https://github.com/NinjaCheetah/WiiPy
import os
import hashlib
import pathlib
import libWiiPy
@ -134,3 +135,55 @@ def handle_nus_title(args):
file.close()
print("Downloaded title with Title ID \"" + args.tid + "\"!")
def handle_nus_content(args):
tid = args.tid
cid = args.cid
version = args.version
if args.decrypt:
decrypt_content = True
else:
decrypt_content = False
content_file_name = hex(cid)[2:]
while len(content_file_name) < 8:
content_file_name = "0" + content_file_name
content_data = libWiiPy.title.download_content(tid, cid)
if decrypt_content is True:
content_file_name = content_file_name + ".app"
tmd = libWiiPy.title.TMD()
tmd.load(libWiiPy.title.download_tmd(tid, version))
try:
ticket = libWiiPy.title.Ticket()
ticket.load(libWiiPy.title.download_ticket(tid))
except ValueError:
print(" - No Ticket is available!")
return
content_hash = 'gggggggggggggggggggggggggggggggggggggggg'
content_size = 0
content_index = 0
for record in tmd.content_records:
if record.content_id == cid:
content_hash = record.content_hash.decode()
content_size = record.content_size
content_index = record.index
content_dec = libWiiPy.title.decrypt_content(content_data, ticket.get_title_key(), content_index, content_size)
content_dec_hash = hashlib.sha1(content_dec).hexdigest()
if content_hash != content_dec_hash:
raise ValueError("The decrypted content provided does not match the record at the provided index. \n"
"Expected hash is: {}\n".format(content_hash) +
"Actual hash is: {}".format(content_dec_hash))
file = open(content_file_name, "wb")
file.write(content_dec)
file.close()
else:
file = open(content_file_name, "wb")
file.write(content_data)
file.close()
print("Downloaded content with Content ID \"" + str(cid) + "\"!")

View File

@ -48,6 +48,15 @@ if __name__ == "__main__":
help="pack a wad with the provided name")
nus_title_parser.add_argument("--wii", help="use original Wii NUS instead of the Wii U servers",
action="store_true")
# Content NUS subcommand.
nus_content_parser = nus_subparsers.add_parser("content", help="download a specific content from the NUS",
description="download a specific content from the NUS")
nus_content_parser.set_defaults(func=handle_nus_content)
nus_content_parser.add_argument("tid", metavar="TID", type=str, help="Title ID the content belongs to")
nus_content_parser.add_argument("cid", metavar="CID", type=int, help="Content ID to download")
nus_content_parser.add_argument("-v", "--version", metavar="VERSION", type=int,
help="version this content belongs to (required for decryption)")
nus_content_parser.add_argument("-d", "--decrypt", action="store_true", help="decrypt this content")
# Argument parser for the U8 subcommand.
u8_parser = subparsers.add_parser("u8", help="pack/unpack a U8 archive",