diff --git a/modules/title/emunand.py b/modules/title/emunand.py index c10ab59..1ed9236 100644 --- a/modules/title/emunand.py +++ b/modules/title/emunand.py @@ -55,3 +55,61 @@ def handle_emunand_title(args): emunand.uninstall_title(target_tid) print("Title uninstalled from EmuNAND!") + + +def handle_emunand_gensetting(args): + # Validate the provided SN. It should be 2 or 3 letters followed by 9 numbers. + if len(args.serno) != 11 and len(args.serno) != 12: + raise ValueError("The provided Serial Number is not valid!") + try: + int(args.serno[-9:]) + except ValueError: + raise ValueError("The provided Serial Number is not valid!") + prefix = args.serno[:-9] + # Detect the console revision based on the SN. + match prefix[0].upper(): + case "L": + revision = "RVL-001" + case "K": + revision = "RVL-101" + case "H": + revision = "RVL-201" + case _: + revision = "RVL-001" + # Validate the region, and then validate the SN based on the region. USA has a two-letter prefix for a total length + # of 11 characters, while other regions have a three-letter prefix for a total length of 12 characters. + valid_regions = ["USA", "EUR", "JPN", "KOR"] + if args.region not in valid_regions: + raise ValueError("The provided region is not valid!") + if len(prefix) == 2 and args.region != "USA": + raise ValueError("The provided region does not match the provided Serial Number!") + elif len(prefix) == 3 and args.region == "USA": + raise ValueError("The provided region does not match the provided Serial Number!") + # Get the values for VIDEO and GAME. + video = "" + game = "" + match args.region: + case "USA": + video = "NTSC" + game = "US" + case "EUR": + video = "PAL" + game = "EU" + case "JPN": + video = "NTSC" + game = "JP" + case "KOR": + video = "NTSC" + game = "KR" + # Create a new SettingTxt object and load the settings into it. + setting = libWiiPy.nand.SettingTxt() + setting.area = args.region + setting.model = f"{revision}({args.region})" + setting.dvd = 0 + setting.mpch = "0x7FFE" + setting.code = prefix + setting.serial_number = args.serno[-9:] + setting.video = video + setting.game = game + # Write out the setting.txt file. + open("setting.txt", "wb").write(setting.dump()) diff --git a/wiipy.py b/wiipy.py index d727292..2981253 100644 --- a/wiipy.py +++ b/wiipy.py @@ -71,6 +71,15 @@ if __name__ == "__main__": "accepts a WAD file to read the TID from)") emunand_title_parser.add_argument("-s", "--skip-hash", help="skips validating the hashes of decrypted " "content (install only)", action="store_true") + # Setting generation EmuNAND command. + emunand_gensetting_parser = emunand_subparsers.add_parser("gen-setting", + help="generate a new setting.txt based on the provided values", + description="generate a new setting.txt based on the provided values") + emunand_gensetting_parser.set_defaults(func=handle_emunand_gensetting) + emunand_gensetting_parser.add_argument("serno", metavar="SERNO", type=str, + help="serial number of the console these settings are for") + emunand_gensetting_parser.add_argument("region", metavar="REGION", type=str, + help="region of the console these settings are for (USA, EUR, JPN, or KOR)") # Argument parser for the fakesign subcommand. fakesign_parser = subparsers.add_parser("fakesign", help="fakesign a TMD, Ticket, or WAD (trucha bug)",