Added command to get info about an EmuNAND

This commit is contained in:
Campbell 2024-12-12 20:07:51 -05:00
parent 3e9f452885
commit ceff61930b
Signed by: NinjaCheetah
GPG Key ID: 670C282B3291D63D
2 changed files with 127 additions and 1 deletions

View File

@ -1,11 +1,131 @@
# "commands/nand/emunand.py" from WiiPy by NinjaCheetah
# https://github.com/NinjaCheetah/WiiPy
import math
import pathlib
import libWiiPy
from modules.core import fatal_error
def handle_emunand_info(args):
emunand = libWiiPy.nand.EmuNAND(args.emunand)
# Basic info.
print(f"EmuNAND Info")
print(f" Path: {str(emunand.emunand_root.absolute())}")
is_vwii = False
try:
tmd = emunand.get_title_tmd("0000000100000002")
is_vwii = bool(tmd.vwii)
print(f" System Menu Version: {libWiiPy.title.title_ver_dec_to_standard(tmd.title_version, '0000000100000002',
vwii=is_vwii)}")
except FileNotFoundError:
print(f" System Menu Version: None")
settings_path = emunand.title_dir.joinpath("00000001", "00000002", "data", "setting.txt")
if settings_path.exists():
settings = libWiiPy.nand.SettingTxt()
settings.load(settings_path.read_bytes())
print(f" System Region: {settings.area}")
else:
print(f" System Region: N/A")
if is_vwii:
print(f" Type: vWii")
else:
print(f" Type: Wii")
categories = emunand.get_installed_titles()
installed_count = 0
for category in categories:
if category.type != "00010000":
for _ in category.titles:
installed_count += 1
print(f" Installed Titles: {installed_count}")
total_size = sum(file.stat().st_size for file in emunand.emunand_root.rglob('*'))
total_size_blocks = math.ceil(total_size / 131072)
print(f" Space Used: {total_size_blocks} blocks ({round(total_size / 1048576, 2)} MB)")
print("")
installed_ioses = []
installed_titles = []
disc_titles = []
for category in categories:
if category.type == "00000001":
ioses = []
for title in category.titles:
if title != "00000002":
ioses.append(int(title, 16))
ioses.sort()
installed_ioses = [f"00000001{i:08X}".upper() for i in ioses]
elif category.type != "00010000":
for title in category.titles:
installed_titles.append(f"{category.type}{title}".upper())
elif category.type == "00010000":
for title in category.titles:
if title != "48415A41":
disc_titles.append(f"{category.type}{title}".upper())
print(f"System Titles:")
for ios in installed_ioses:
if ios[8:] in ["00000100", "00000101", "00000200", "00000201"]:
if ios[8:] == "00000100":
print(f" BC ({ios.upper()})")
elif ios[8:] == "00000101":
print(f" MIOS ({ios.upper()})")
elif ios[8:] == "00000200":
print(f" BC-NAND ({ios.upper()})")
elif ios[8:] == "00000201":
print(f" BC-WFS ({ios.upper()})")
tmd = emunand.get_title_tmd(f"{ios}")
print(f" Version: {tmd.title_version}")
else:
print(f" IOS{int(ios[-2:], 16)} ({ios.upper()})")
tmd = emunand.get_title_tmd(f"{ios}")
print(f" Version: {tmd.title_version} ({tmd.title_version_converted})")
print("")
print(f"Installed Titles:")
missing_ioses = []
for title in installed_titles:
ascii_tid = ""
try:
ascii_tid = (bytes.fromhex(title[8:].replace("00", "30"))).decode("ascii")
except UnicodeDecodeError:
pass
if ascii_tid.isalnum():
print(f" {title.upper()} ({ascii_tid})")
else:
print(f" {title.upper()}")
tmd = emunand.get_title_tmd(f"{title}")
print(f" Version: {tmd.title_version}")
print(f" Required IOS: IOS{int(tmd.ios_tid[-2:], 16)} ({tmd.ios_tid.upper()})", end="", flush=True)
if tmd.ios_tid.upper() not in installed_ioses:
print(" *")
if tmd.ios_tid not in missing_ioses:
missing_ioses.append(tmd.ios_tid)
else:
print("")
print("")
if disc_titles:
print(f"Save data was found for the following disc titles:")
for disc in disc_titles:
ascii_tid = ""
try:
ascii_tid = (bytes.fromhex(disc[8:].replace("00", "30"))).decode("ascii")
except UnicodeDecodeError:
pass
if ascii_tid.isalnum():
print(f" {disc.upper()} ({ascii_tid})")
else:
print(f" {disc.upper()}")
print("")
if missing_ioses:
print(f"Some titles installed are missing their required IOS. These missing IOSes are marked with a * in the "
f"title list above. If these IOSes are not installed, the titles requiring them will not launch. The "
f"IOSes required but not installed are:")
for missing in missing_ioses:
print(f" IOS{int(missing[-2:], 16)} ({missing.upper()})")
print("")
def handle_emunand_title(args):
emunand = libWiiPy.nand.EmuNAND(args.emunand)
if args.skip_hash:

View File

@ -76,12 +76,18 @@ if __name__ == "__main__":
emunand_parser = subparsers.add_parser("emunand", help="manage Wii EmuNAND directories",
description="manage Wii EmuNAND directories")
emunand_subparsers = emunand_parser.add_subparsers(title="emunand", dest="emunand", required=True)
# Info EmuNAND subcommand.
emunand_info_parser = emunand_subparsers.add_parser("info", help="show info about an EmuNAND",
description="show info about an EmuNAND")
emunand_info_parser.set_defaults(func=handle_emunand_info)
emunand_info_parser.add_argument("emunand", metavar="EMUNAND", type=str,
help="path of the EmuNAND directory")
# Title EmuNAND subcommand.
emunand_title_parser = emunand_subparsers.add_parser("title", help="manage titles on an EmuNAND",
description="manage titles on an EmuNAND")
emunand_title_parser.set_defaults(func=handle_emunand_title)
emunand_title_parser.add_argument("emunand", metavar="EMUNAND", type=str,
help="path to the target EmuNAND directory")
help="path of the target EmuNAND directory")
emunand_title_install_group = emunand_title_parser.add_mutually_exclusive_group(required=True)
emunand_title_install_group.add_argument("--install", metavar="WAD", type=str,
help="install the target WAD(s) to an EmuNAND (can be a single file or a "