diff --git a/CDNSP-GUI-Bob.py b/CDNSP-GUI-Bob.py index 15b8435..83e8cf9 100644 --- a/CDNSP-GUI-Bob.py +++ b/CDNSP-GUI-Bob.py @@ -232,11 +232,16 @@ def add_to_installed(tid, ver): tqdmProgBar = True sysver0 = False +sysverUser = sys.maxsize #Global Vars truncateName = False tinfoil = False enxhop = False + +system_version = {'1.0.0': 450, '2.0.0': 65796, '2.1.0': 131162, '2.2.0': 196628, '2.3.0': 262164, '3.0.0': 201327002, '3.0.1': 201392178, '3.0.2': 201457684, + '4.0.0': 268435656, '4.0.1': 268501002, '4.1.0': 269484082, '5.0.0': 335544750, '5.0.1': 335609886, '5.0.2': 335675432, '5.1.0': 336592976, + 'Latest': sys.maxsize} import os, sys import re @@ -1112,6 +1117,48 @@ def download_sysupdate(ver): download_title(dir, title, titles[title][0], n='n') return sysupdateDir + +def get_title_sysver(tid, ver, path_Dir=""): + if path_Dir == "": + path_Dir = os.path.join(os.path.dirname(__file__), "_NSPOUT") + + gameDir = os.path.join(path_Dir, tid) + + if not os.path.exists(gameDir): + os.makedirs(gameDir, exist_ok=True) + + print('\n%s v%s:' % (tid, ver)) + if len(tid) != 16: + tid = (16-len(tid)) * '0' + tid + + url = 'https://atum.hac.%s.d4c.nintendo.net/t/a/%s/%s?device_id=%s' % (env, tid, ver, did) + r = make_request('HEAD', url) + CNMTid = r.headers.get('X-Nintendo-Content-ID') + + print('\tDownloading CNMT (%s.cnmt.nca)...' % CNMTid) + url = 'https://atum.hac.%s.d4c.nintendo.net/c/a/%s?device_id=%s' % (env, CNMTid, did) + fPath = os.path.join(gameDir, CNMTid + '.cnmt.nca') + cnmtNCA = download_file(url, fPath) + + cnmtDir = decrypt_NCA(cnmtNCA) + CNMT = cnmt(os.path.join(cnmtDir, 'section0', os.listdir(os.path.join(cnmtDir, 'section0'))[0]), + os.path.join(cnmtDir, 'Header.bin')) + + outf = os.path.join(gameDir, '%s.xml' % os.path.basename(cnmtNCA).strip('.nca')) + cnmtXML = CNMT.gen_xml(cnmtNCA, outf) + + content_meta = {} + + root = ET.parse(outf).getroot() + for child in root: + if len(list(child)) == 0: # Content + content_meta[child.tag] = child.text + + required_sysver = int(content_meta['RequiredSystemVersion']) % 0x100000000 + + shutil.rmtree(gameDir, ignore_errors=True) + + return required_sysver class cnmt: titleTypes = { @@ -1483,6 +1530,7 @@ def GUI_config(fPath): "Shorten": "False", "Tinfoil": "False", "SysVerZero": "False", + "SysVerUser": "Latest", "Main_win": main_win, "Queue_win": queue_win, "Update_win": "600x400+120+200", @@ -1513,6 +1561,10 @@ def str2bool(v): shorten = str2bool(j['Options']['Shorten']) tinfoil = str2bool(j['Options']['Tinfoil']) sysver0 = str2bool(j['Options']['SysVerZero']) + try: + sysverUser = system_version[j['Options']['SysVerUser']] + except: + sysverUser = sys.maxsize main_win = j['Options']['Main_win'] queue_win = j['Options']['Queue_win'] update_win = j['Options']['Update_win'] @@ -1524,7 +1576,7 @@ def str2bool(v): download_location = "" updateJsonFile("Download_location", download_location) return download_location, game_location, repack, mute, titlekey_check, noaria, \ - disable_game_image, shorten, tinfoil, sysver0, main_win, queue_win, update_win, \ + disable_game_image, shorten, tinfoil, sysver0, sysverUser, main_win, queue_win, update_win, \ scan_win, base64_win, language class Application(): @@ -1540,8 +1592,8 @@ def __init__(self, root, titleID, titleKey, title, dbURL): configGUIPath = os.path.join(os.path.dirname(__file__), 'CDNSP-GUI-config.json') # Load config file self.path, self.game_location, self.repack, self.mute, self.titlekey_check, noaria_temp, \ - self.game_image_disable, shorten_temp, tinfoil_temp, sysver0_temp, main_win, \ - queue_win, update_win, scan_win, \ + self.game_image_disable, shorten_temp, tinfoil_temp, sysver0_temp, sysverUser_temp, \ + main_win, queue_win, update_win, scan_win, \ base64_win, language = GUI_config(configGUIPath) # Get config values @@ -1598,6 +1650,9 @@ def __init__(self, root, titleID, titleKey, title, dbURL): global sysver0 sysver0 = sysver0_temp + global sysverUser + sysverUser = sysverUser_temp + # Top Menu bar self.menubar = Menu(self.root) @@ -1629,6 +1684,28 @@ def __init__(self, root, titleID, titleKey, title, dbURL): self.optionMenu.add_command(label=_("Enable Tinfoil Download"), command=self.tinfoil_change) self.optionMenu.add_command(label=_("Enable SysVer 0 Patch"), command=self.sysver_zero) + self.optionMenu.add_separator() # Add separator to the menu dropdown + + self.sysverMenu = Menu(self.optionMenu, tearoff=0) + self.optionMenu.add_cascade(label=_("System Firmware"), menu=self.sysverMenu) + + self.sysverMenu.add_command(label="1.0.0", command=lambda: self.system_firmware("1.0.0")) + self.sysverMenu.add_command(label="2.0.0", command=lambda: self.system_firmware("2.0.0")) + self.sysverMenu.add_command(label="2.1.0", command=lambda: self.system_firmware("2.1.0")) + self.sysverMenu.add_command(label="2.2.0", command=lambda: self.system_firmware("2.2.0")) + self.sysverMenu.add_command(label="2.3.0", command=lambda: self.system_firmware("2.3.0")) + self.sysverMenu.add_command(label="3.0.0", command=lambda: self.system_firmware("3.0.0")) + self.sysverMenu.add_command(label="3.0.1", command=lambda: self.system_firmware("3.0.1")) + self.sysverMenu.add_command(label="3.0.2", command=lambda: self.system_firmware("3.0.2")) + self.sysverMenu.add_command(label="4.0.0", command=lambda: self.system_firmware("4.0.0")) + self.sysverMenu.add_command(label="4.0.1", command=lambda: self.system_firmware("4.0.1")) + self.sysverMenu.add_command(label="4.1.0", command=lambda: self.system_firmware("4.1.0")) + self.sysverMenu.add_command(label="5.0.0", command=lambda: self.system_firmware("5.0.0")) + self.sysverMenu.add_command(label="5.0.1", command=lambda: self.system_firmware("5.0.1")) + self.sysverMenu.add_command(label="5.0.2", command=lambda: self.system_firmware("5.0.2")) + self.sysverMenu.add_command(label="5.1.0", command=lambda: self.system_firmware("5.1.0")) + self.sysverMenu.add_command(label="Latest", command=lambda: self.system_firmware("Latest")) + self.optionMenu.add_separator() # Add separator to the menu dropdown self.optionMenu.add_command(label=_("Save Windows Location and Size"), command=self.window_save) @@ -1708,6 +1785,13 @@ def __init__(self, root, titleID, titleKey, title, dbURL): else: self.optionMenu.entryconfig(9, label= _("Enable SysVer 0 Patch")) + label = next((firmware for firmware, sysver in system_version.items() if sysver >= sysverUser), "Latest") + try: + index = list(system_version).index(label) + self.sysverMenu.entryconfig(index, label= label + "*") + except Exception as e: + print(e) + # Status Label self.status_label = Label(self.root, text=_("Status:")) self.status_label.grid(row=0, column=0, columnspan=2, sticky=NS) @@ -1899,21 +1983,22 @@ def queue_menu_setup(self): # Queue GUI self.queue_scrollbar = Scrollbar(self.queue_win) - self.queue_scrollbar.grid(row=0, column=3, sticky=N+S+W) + self.queue_scrollbar.grid(row=0, column=4, sticky=N+S+W) if self.sys_name == "Mac": self.queue_width = self.listWidth+28 else: self.queue_width = 100 # Windows self.queue_title_list = Listbox(self.queue_win, yscrollcommand = self.queue_scrollbar.set, width=self.queue_width, selectmode=EXTENDED) - self.queue_title_list.grid(row=0, column=0, sticky=W, columnspan=3) + self.queue_title_list.grid(row=0, column=0, sticky=W, columnspan=4) self.queue_scrollbar.config(command = self.queue_title_list.yview) Button(self.queue_win, text=_("Remove selected game"), command=self.remove_selected_items).grid(row=1, column=0, pady=(30,0)) Button(self.queue_win, text=_("Remove all"), command=self.remove_all_and_dump).grid(row=1, column=1, pady=(30,0)) Button(self.queue_win, text=_("Download all"), command=self.download_all).grid(row=1, column=2, pady=(30,0)) + Button(self.queue_win, text=_("Get required firmware"), command=self.get_required_sysver).grid(row=1, column=3, pady=(30,0)) self.stateLabel = Label(self.queue_win, text=_("Click download all to download all games in queue!")) - self.stateLabel.grid(row=2, column=0, columnspan=3, pady=(20, 0)) + self.stateLabel.grid(row=2, column=0, columnspan=4, pady=(20, 0)) # Sorting function for the treeview widget def sortby(self, tree, col, descending): @@ -2569,8 +2654,17 @@ def threaded_download(self): if option == "U" or self.is_DLC == True: if ver != "none": self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) - download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + + required_sysver = 0 + if sysverUser < sys.maxsize: + required_sysver = get_title_sysver(updateTid, ver, path_Dir=self.path) + + if required_sysver == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver), "Unknown"))): + download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("Download cancelled!")) else: self.messages("", _("No updates available for the game")) @@ -2578,37 +2672,69 @@ def threaded_download(self): base_tid = "{}000".format(tid[0:13]) self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) base_ver = get_versions(base_tid)[-1] - download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) + updateTid = "" if ver != 'none': updateTid = "{}800".format(tid[0:13]) - download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) DLC_titleID = [] tid = "{}".format(tid[0:12]) indices = [i for i, s in enumerate(self.titleID) if tid in s] for index in indices: if not self.titleID[index].endswith("00"): DLC_titleID.append(self.titleID[index]) - for DLC_ID in DLC_titleID: - DLC_ver = get_versions(DLC_ID)[-1] - download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + + required_sysver = [] + if sysverUser < sys.maxsize: + required_sysver.append(get_title_sysver(base_tid, base_ver, path_Dir=self.path)) + if ver != 'none': + required_sysver.append(get_title_sysver(updateTid, ver, path_Dir=self.path)) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path)) + required_sysver.sort(reverse=True) + + if len(required_sysver) == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver[0]), "Unknown"))): + download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) + if ver != 'none': + download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("Download cancelled!")) elif option == "U+D": + self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) + updateTid = "" if ver != "none": updateTid = "{}800".format(tid[0:13]) - self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) - download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) DLC_titleID = [] tid = "{}".format(tid[0:12]) indices = [i for i, s in enumerate(self.titleID) if tid in s] for index in indices: if not self.titleID[index].endswith("00"): DLC_titleID.append(self.titleID[index]) - for DLC_ID in DLC_titleID: - DLC_ver = get_versions(DLC_ID)[-1] - download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + required_sysver = [] + if sysverUser < sys.maxsize: + if ver != "none": + required_sysver.append(get_title_sysver(updateTid, ver, path_Dir=self.path)) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path)) + required_sysver.sort(reverse=True) + + if len(required_sysver) == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver[0]), "Unknown"))): + if ver != "none": + download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("Download cancelled!")) elif option == "D": self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) @@ -2618,30 +2744,64 @@ def threaded_download(self): for index in indices: if not self.titleID[index].endswith("00"): DLC_titleID.append(self.titleID[index]) - for DLC_ID in DLC_titleID: - DLC_ver = get_versions(DLC_ID)[-1] - download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + required_sysver = [] + if sysverUser < sys.maxsize: + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path)) + required_sysver.sort(reverse=True) + + if len(required_sysver) == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver[0]), "Unknown"))): + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + download_game(DLC_ID, DLC_ver, self.titleKey[self.titleID.index(DLC_ID)], nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("Download cancelled!")) elif option == "B": base_tid = "{}000".format(tid[0:13]) self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) base_ver = get_versions(base_tid)[-1] - download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + + required_sysver = 0 + if sysverUser < sys.maxsize: + required_sysver = get_title_sysver(base_tid, base_ver, path_Dir=self.path) + + if required_sysver == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver), "Unknown"))): + download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("Download cancelled!")) elif option == "B+U": base_tid = "{}000".format(tid[0:13]) self.messages("", _("Starting to download! It will take some time, please be patient. You can check the CMD (command prompt) at the back to see your download progress.")) base_ver = get_versions(base_tid)[-1] - download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) + updateTid = "" if ver != 'none': updateTid = "{}800".format(tid[0:13]) - download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) - self.messages("", _("Download finished!")) + + required_sysver = [] + if sysverUser < sys.maxsize: + required_sysver.append(get_title_sysver(base_tid, base_ver, path_Dir=self.path)) + if ver != 'none': + required_sysver.append(get_title_sysver(updateTid, ver, path_Dir=self.path)) + required_sysver.sort(reverse=True) + + if len(required_sysver) == 0 or messagebox.askyesno("", (_("This game requires Firmware version {}.") + " " + _("Do you wish to continue downloading?")). + format(next((firmware for firmware, sysver in system_version.items() if sysver >= required_sysver[0]), "Unknown"))): + download_game(base_tid, base_ver, tkey, nspRepack=self.repack, path_Dir=self.path) + if ver != 'none': + download_game(updateTid, ver, tkey, nspRepack=self.repack, path_Dir=self.path) + self.messages("", _("Download finished!")) + else: + self.messages("", _("No updates available for the game, base game downloaded!")) else: - self.messages("", _("No updates available for the game, base game downloaded!")) + self.messages("", _("Download cancelled!")) ## except: ## print("Error downloading {}, note: if you're downloading a DLC then different versions of DLC may have different titlekeys".format(tid)) return @@ -2712,7 +2872,7 @@ def add_items_to_queue(self, indices): ## messagebox.showerror("Error", "No game selected/entered to add to queue") def process_item_versions(self, tid, ver): - if _("Latest") or "Latest" in ver: + if _("Latest") in ver or "Latest" in ver: if tid.endswith('000'): tid = '%s800' % tid[:-3] ver = get_versions(tid)[-1] @@ -2866,6 +3026,107 @@ def download_all(self): ## else: ## if any(tid_list in tid for tid_list in self.installed): + def threaded_get_required_sysver(self): + selection = self.queue_title_list.curselection() + if len(selection) == 0: + self.messages("", _("No game selected!")) + return + + self.messages("", _("Starting to retrieve required firmware info! It will take some time, please be patient.")) + required_sysver_all = [] + + for item in selection: + try: + tid, ver, tkey, option = self.queue_list[item] + ver = self.process_item_versions(tid, ver)[1] + + required_sysver = [] +## try: + if option == "U" or option == "DLC": + if ver != "none": + if tid.endswith("00"): + tid = "{}800".format(tid[0:13]) + required_sysver.append(("{}{} (v{})".format("[DLC] " if option == "DLC" and not self.persistent_queue[item][0].startswith("[DLC] ") else "[UPD] ", self.persistent_queue[item][0], ver), get_title_sysver(tid, ver, path_Dir=self.path))) + else: + print(_("No updates available for titleID: {}").format(tid)) + + elif option == "B+U+D": + base_tid = "{}000".format(tid[0:13]) + base_ver = get_versions(base_tid)[-1] + required_sysver.append(("{} (v{})".format(self.persistent_queue[item][0], base_ver), get_title_sysver(base_tid, base_ver, path_Dir=self.path))) + if ver != 'none': + updateTid = "{}800".format(tid[0:13]) + required_sysver.append(("[UPD] {} (v{})".format(self.persistent_queue[item][0], ver), get_title_sysver(updateTid, ver, path_Dir=self.path))) + DLC_titleID = [] + tid = "{}".format(tid[0:12]) + indices = [i for i, s in enumerate(self.titleID) if tid in s] + for index in indices: + if not self.titleID[index].endswith("00"): + DLC_titleID.append(self.titleID[index]) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(("{}{} (v{})".format("[DLC] " if not self.persistent_queue[item][0].startswith("[DLC] ") else "", self.persistent_queue[item][0], DLC_ver), get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path))) + + elif option == "U+D": + if ver != "none": + updateTid = "{}800".format(tid[0:13]) + required_sysver.append(("[UPD] {} (v{})".format(self.persistent_queue[item][0], ver), get_title_sysver(updateTid, ver, path_Dir=self.path))) + DLC_titleID = [] + tid = "{}".format(tid[0:12]) + indices = [i for i, s in enumerate(self.titleID) if tid in s] + for index in indices: + if not self.titleID[index].endswith("00"): + DLC_titleID.append(self.titleID[index]) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(("{}{} (v{})".format("[DLC] " if not self.persistent_queue[item][0].startswith("[DLC] ") else "", self.persistent_queue[item][0], DLC_ver), get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path))) + + elif option == "D": + DLC_titleID = [] + tid = "{}".format(tid[0:12]) + indices = [i for i, s in enumerate(self.titleID) if tid in s] + for index in indices: + if not self.titleID[index].endswith("00"): + DLC_titleID.append(self.titleID[index]) + for DLC_ID in DLC_titleID: + DLC_ver = get_versions(DLC_ID)[-1] + required_sysver.append(("{}{} (v{})".format("[DLC] " if not self.persistent_queue[item][0].startswith("[DLC] ") else "", self.persistent_queue[item][0], DLC_ver), get_title_sysver(DLC_ID, DLC_ver, path_Dir=self.path))) + + elif option == "B": + base_tid = "{}000".format(tid[0:13]) + base_ver = get_versions(base_tid)[-1] + required_sysver.append(("{} (v{})".format(self.persistent_queue[item][0], base_ver), get_title_sysver(base_tid, base_ver, path_Dir=self.path))) + + elif option == "B+U": + base_tid = "{}000".format(tid[0:13]) + base_ver = get_versions(base_tid)[-1] + required_sysver.append(("{} (v{})".format(self.persistent_queue[item][0], base_ver), get_title_sysver(base_tid, base_ver, path_Dir=self.path))) + if ver != 'none': + updateTid = "{}800".format(tid[0:13]) + required_sysver.append(("[UPD] {} (v{})".format(self.persistent_queue[item][0], ver), get_title_sysver(updateTid, ver, path_Dir=self.path))) + else: + print(_("No updates available for titleID: {}, base game downloaded!").format(tid)) +## except: +## print("Error downloading {}, note: if you're downloading a DLC then different versions of DLC may have different titlekeys".format(tid)) + + required_sysver_all.extend(required_sysver) + except Exception as e: + print(e) + + if len(required_sysver_all) > 0: + messages = "Required Firmware:" + if len(required_sysver_all) > 1: + messages += "\n" + for sysver in required_sysver_all: + messages += "\n{} {}".format(sysver[0].ljust(50, " "), next((firmware for firmware, version in system_version.items() if version >= sysver[1]), "Unknown")) + self.messages("", messages) + else: + self.messages("", _("No game selected!")) + + def get_required_sysver(self): + thread = threading.Thread(target = self.threaded_get_required_sysver) + thread.start() + def normalize_file_path(self, file_path): if self.sys_name == "Win": return file_path.replace("/", "\\") @@ -3430,6 +3691,27 @@ def sysver_zero(self): sysver0 = False self.optionMenu.entryconfig(9, label= _("Enable SysVer 0 Patch")) updateJsonFile("SysVerZero", str(sysver0)) + + def system_firmware(self, sysver): + global sysverUser + label = next((firmware for firmware, sysver in system_version.items() if sysver >= sysverUser), "Latest") + try: + index = list(system_version).index(label) + self.sysverMenu.entryconfig(index, label= label) + except Exception as e: + print(e) + + try: + sysverUser = system_version[sysver] + except: + sysverUser = sys.maxsize + label = next((firmware for firmware, sysver in system_version.items() if sysver >= sysverUser), "Latest") + try: + index = list(system_version).index(label) + self.sysverMenu.entryconfig(index, label= label + "*") + except Exception as e: + print(e) + updateJsonFile("SysVerUser", label) ## def threaded_preload_desc(self): ## self.status_label.config(text=_("Status: Downloading all game descriptions")) diff --git a/locales/af/LC_MESSAGES/language.mo b/locales/af/LC_MESSAGES/language.mo new file mode 100644 index 0000000..c8c31b9 Binary files /dev/null and b/locales/af/LC_MESSAGES/language.mo differ diff --git a/locales/ar/LC_MESSAGES/language.mo b/locales/ar/LC_MESSAGES/language.mo new file mode 100644 index 0000000..47ad42d Binary files /dev/null and b/locales/ar/LC_MESSAGES/language.mo differ diff --git a/locales/de/LC_MESSAGES/language.mo b/locales/de/LC_MESSAGES/language.mo new file mode 100644 index 0000000..b8e2db5 Binary files /dev/null and b/locales/de/LC_MESSAGES/language.mo differ diff --git a/locales/el/LC_MESSAGES/language.mo b/locales/el/LC_MESSAGES/language.mo new file mode 100644 index 0000000..97a97e0 Binary files /dev/null and b/locales/el/LC_MESSAGES/language.mo differ diff --git a/locales/en/LC_MESSAGES/language.mo b/locales/en/LC_MESSAGES/language.mo new file mode 100644 index 0000000..e9daff5 Binary files /dev/null and b/locales/en/LC_MESSAGES/language.mo differ diff --git a/locales/es/LC_MESSAGES/language.mo b/locales/es/LC_MESSAGES/language.mo new file mode 100644 index 0000000..fea1e62 Binary files /dev/null and b/locales/es/LC_MESSAGES/language.mo differ diff --git a/locales/fa/LC_MESSAGES/language.mo b/locales/fa/LC_MESSAGES/language.mo new file mode 100644 index 0000000..6cec870 Binary files /dev/null and b/locales/fa/LC_MESSAGES/language.mo differ diff --git a/locales/fr/LC_MESSAGES/language.mo b/locales/fr/LC_MESSAGES/language.mo new file mode 100644 index 0000000..6e151b3 Binary files /dev/null and b/locales/fr/LC_MESSAGES/language.mo differ diff --git a/locales/he/LC_MESSAGES/language.mo b/locales/he/LC_MESSAGES/language.mo new file mode 100644 index 0000000..56ec54c Binary files /dev/null and b/locales/he/LC_MESSAGES/language.mo differ diff --git a/locales/hu/LC_MESSAGES/language.mo b/locales/hu/LC_MESSAGES/language.mo new file mode 100644 index 0000000..7e6dc68 Binary files /dev/null and b/locales/hu/LC_MESSAGES/language.mo differ diff --git a/locales/id/LC_MESSAGES/language.mo b/locales/id/LC_MESSAGES/language.mo new file mode 100644 index 0000000..992bcd3 Binary files /dev/null and b/locales/id/LC_MESSAGES/language.mo differ diff --git a/locales/it/LC_MESSAGES/language.mo b/locales/it/LC_MESSAGES/language.mo new file mode 100644 index 0000000..ab1f99b Binary files /dev/null and b/locales/it/LC_MESSAGES/language.mo differ diff --git a/locales/ja/LC_MESSAGES/language.mo b/locales/ja/LC_MESSAGES/language.mo new file mode 100644 index 0000000..db756f7 Binary files /dev/null and b/locales/ja/LC_MESSAGES/language.mo differ diff --git a/locales/ko/LC_MESSAGES/language.mo b/locales/ko/LC_MESSAGES/language.mo new file mode 100644 index 0000000..e3333b9 Binary files /dev/null and b/locales/ko/LC_MESSAGES/language.mo differ diff --git a/locales/ms/LC_MESSAGES/language.mo b/locales/ms/LC_MESSAGES/language.mo new file mode 100644 index 0000000..1f130db Binary files /dev/null and b/locales/ms/LC_MESSAGES/language.mo differ diff --git a/locales/nl/LC_MESSAGES/language.mo b/locales/nl/LC_MESSAGES/language.mo new file mode 100644 index 0000000..50b19a9 Binary files /dev/null and b/locales/nl/LC_MESSAGES/language.mo differ diff --git a/locales/pl/LC_MESSAGES/language.mo b/locales/pl/LC_MESSAGES/language.mo new file mode 100644 index 0000000..c99f87e Binary files /dev/null and b/locales/pl/LC_MESSAGES/language.mo differ diff --git a/locales/pt/LC_MESSAGES/language.mo b/locales/pt/LC_MESSAGES/language.mo new file mode 100644 index 0000000..a94df56 Binary files /dev/null and b/locales/pt/LC_MESSAGES/language.mo differ diff --git a/locales/ru/LC_MESSAGES/language.mo b/locales/ru/LC_MESSAGES/language.mo new file mode 100644 index 0000000..1e4e6f1 Binary files /dev/null and b/locales/ru/LC_MESSAGES/language.mo differ diff --git a/locales/th/LC_MESSAGES/language.mo b/locales/th/LC_MESSAGES/language.mo new file mode 100644 index 0000000..9ea742c Binary files /dev/null and b/locales/th/LC_MESSAGES/language.mo differ diff --git a/locales/tr/LC_MESSAGES/language.mo b/locales/tr/LC_MESSAGES/language.mo new file mode 100644 index 0000000..f5954e6 Binary files /dev/null and b/locales/tr/LC_MESSAGES/language.mo differ diff --git a/locales/vi/LC_MESSAGES/language.mo b/locales/vi/LC_MESSAGES/language.mo new file mode 100644 index 0000000..6c064ae Binary files /dev/null and b/locales/vi/LC_MESSAGES/language.mo differ diff --git a/locales/zh-cn/LC_MESSAGES/language.mo b/locales/zh-cn/LC_MESSAGES/language.mo new file mode 100644 index 0000000..4545345 Binary files /dev/null and b/locales/zh-cn/LC_MESSAGES/language.mo differ diff --git a/locales/zh-tw/LC_MESSAGES/language.mo b/locales/zh-tw/LC_MESSAGES/language.mo new file mode 100644 index 0000000..2bc69cd Binary files /dev/null and b/locales/zh-tw/LC_MESSAGES/language.mo differ