def gen_sx_autoloader_sd_files(): retrieve_xci_paths() gamelist = get_gamelist(file=sd_xci_cache) SD_folder = os.path.join(sx_autoloader_db, 'sd') if not os.path.exists(sx_autoloader_db): os.makedirs(sx_autoloader_db) if not os.path.exists(SD_folder): os.makedirs(SD_folder) for f in os.listdir(SD_folder): fp = os.path.join(SD_folder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) print(' * Genereting autoloader files') for g in gamelist: fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags( g) tfile = os.path.join(SD_folder, fileid) new_path = g.replace('\\1: External SD Card\\', 'sdmc:/') new_path = new_path.replace('\\', '/') with open(tfile, 'w') as text_file: text_file.write(new_path) print(' * Pushing autoloader files') destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\sd" process = subprocess.Popen([ nscb_mtp, "TransferFolder", "-ori", SD_folder, "-dst", destiny, "-fbf", "true" ]) while process.poll() == None: if process.poll() != None: process.terminate()
def delete_archived(): retrieve_installed() installed = get_gamelist() registered = retrieve_registered() for game in installed: fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags( game) try: del registered[fileid] except: pass games = [] # Name [version][title] for k in registered.keys(): games.append( f"{(registered[k])[2]} [{(registered[k])[0]}][{(registered[k])[1]}]" ) print(" * Entering File Picker") if not games: sys.exit("There isn't any archived games or placeholder on the device") title = 'Select registries to delete: \n + Press space or right to select entries \n + Press E to finish selection \n + Press A to select all entries' options = games picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False, -1 def select_all(picker): return "ALL", -1 picker.register_custom_handler(ord('e'), end_selection) picker.register_custom_handler(ord('E'), end_selection) picker.register_custom_handler(ord('a'), select_all) picker.register_custom_handler(ord('A'), select_all) selected = picker.start() if selected[0] == False: print(" User didn't select any files") return False print(" * Starting uninstalling process...") arch2delete = [] if selected[0] == "ALL": for k in registered: g0 = (registered[k])[2] arch2delete.append(g0) else: for game in selected: g = game[0] g0 = [pos for pos, char in enumerate(g) if char == '['] g0 = (g[0:g0[0]]).strip() arch2delete.append(g0) counter = len(arch2delete) for file in arch2delete: process = subprocess.Popen([nscb_mtp, "DeleteRegistry", "-ID", file]) while process.poll() == None: if process.poll() != None: process.terminate() counter -= 1 print('...................................................') print('STILL ' + str(counter) + ' FILES TO PROCESS') print('...................................................')
def gen_sx_autoloader_files(folder, type='hdd', push=False, no_colide=False): gamelist = folder_to_list(folder, ['xci', 'xc0']) if type == 'hdd': SD_folder = os.path.join(sx_autoloader_db, 'hdd') else: SD_folder = os.path.join(sx_autoloader_db, 'sd') if not os.path.exists(sx_autoloader_db): os.makedirs(sx_autoloader_db) if not os.path.exists(SD_folder): os.makedirs(SD_folder) for f in os.listdir(SD_folder): fp = os.path.join(SD_folder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) print(' * Generating autoloader files') try: for g in gamelist: try: fileid, fileversion, cctag, nG, nU, nD, baseid = parsetags(g) if fileid == 'unknown': continue tfile = os.path.join(SD_folder, fileid) fileparts = Path(g).parts if type == 'hdd': new_path = g.replace(fileparts[0], '"usbhdd:/') else: new_path = g.replace(fileparts[0], '"sdmc:/') new_path = new_path.replace('\\', '/') with open(tfile, 'w') as text_file: text_file.write(new_path) except: pass print(' DONE') if push == True: if not is_switch_connected(): sys.exit( "Can't push files. Switch device isn't connected.\nCheck if mtp responder is running!!!" ) print(' * Pushing autoloader files') if type == 'hdd': destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\hdd" else: destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\sd" process = subprocess.Popen([ nscb_mtp, "TransferFolder", "-ori", SD_folder, "-dst", destiny, "-fbf", "true" ]) while process.poll() == None: if process.poll() != None: process.terminate() if no_colide == True: cleanup_sx_autoloader_files() except BaseException as e: Print.error('Exception: ' + str(e)) pass
def parsedinstalled(): installed={} if os.path.exists(games_installed_cache): gamelist=listmanager.read_lines_to_list(games_installed_cache,all=True) for g in gamelist: entry=listmanager.parsetags(g) entry=list(entry) entry.append(g) installed[entry[0]]=entry return installed
def cleanup_sx_autoloader_files(): from mtp_game_manager import retrieve_xci_paths from mtp_game_manager import get_gamelist try: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) except: pass if not is_switch_connected(): sys.exit( "Can't push files. Switch device isn't connected.\nCheck if mtp responder is running!!!" ) retrieve_xci_paths() print(" * Retriving autoloader files in device. Please Wait...") process = subprocess.Popen([ nscb_mtp, "Retrieve_autoloader_files", "-tfile", autoloader_files_cache, "-show", "false" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) while process.poll() == None: if process.poll() != None: process.terminate() if os.path.exists(autoloader_files_cache): print(" Success") else: sys.exit("Autoloader files weren't retrieved properly") gamelist = get_gamelist(file=sd_xci_cache) autoloader_list = get_gamelist(file=autoloader_files_cache) sd_xci_ids = [] for g in gamelist: try: fileid, fileversion, cctag, nG, nU, nD, baseid = parsetags(g) sd_xci_ids.append(fileid) except: pass files_to_remove = [] for f in autoloader_list: fileparts = Path(f).parts if 'sdd' in fileparts and not (fileparts[-1] in sd_xci_ids): files_to_remove.append(f) elif 'hdd' in fileparts and (fileparts[-1] in sd_xci_ids): files_to_remove.append(f) print(" * The following files will be removed") for f in files_to_remove: print(" - " + f) for f in files_to_remove: process = subprocess.Popen([nscb_mtp, "DeleteFile", "-fp", f]) while process.poll() == None: if process.poll() != None: process.terminate()
def loop_install(tfile,destiny="SD",verification=True,outfolder=None,ch_medium=True,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,install_mode="spec1",st_crypto=False,checked=False): check_connection() if not os.path.exists(tfile): sys.exit(f"Couldn't find {tfile}") if ch_base==True or ch_other==True: if checked==False: print("Content check activated") retrieve_installed() installed=parsedinstalled() elif checked==True: print("Content check activated. Games are preparsed") installed=parsedinstalled() file_list=listmanager.read_lines_to_list(tfile,all=True) for item in file_list: try: if ch_base==True or ch_other==True: fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(item) if fileid.endswith('000') and fileversion==0 and fileid in installed.keys() and ch_base==True: print("Base game already installed. Skipping...") listmanager.striplines(tfile,counter=True) continue elif fileid.endswith('000') and fileid in installed.keys() and ch_other==True: updid=fileid[:-3]+'800' if fileversion>((installed[fileid])[2]): print("Asking DBI to delete previous content") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) continue elif ch_other==True and fileid in installed.keys(): if fileversion>((installed[fileid])[2]): print("Asking DBI to delete previous update") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) continue except:pass install(filepath=item,destiny=destiny,verification=verification,outfolder=outfolder,ch_medium=ch_medium,check_fw=check_fw,patch_keygen=patch_keygen,install_mode=install_mode,st_crypto=st_crypto) print("") listmanager.striplines(tfile,counter=True)
def parsedinstalled(exclude_xci=True): installed = {} if os.path.exists(games_installed_cache): gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True) for g in gamelist: if exclude_xci == True: if g.endswith('xci') or g.endswith('xc0'): continue entry = listmanager.parsetags(g) entry = list(entry) entry.append(g) installed[entry[0]] = entry return installed
def update_console(libraries="all", destiny="SD", exclude_xci=True, prioritize_nsz=True, tfile=None, verification=True, ch_medium=True, ch_other=False, autoupd_aut=True): if tfile == None: tfile = os.path.join(NSCB_dir, 'MTP1.txt') if os.path.exists(tfile): try: os.remove(tfile) except: pass libdict = get_libs("source") pths = {} if libraries == "all": for entry in libdict.keys(): pths[entry] = ((libdict[entry])[0]) else: for entry in libdict.keys(): if (libdict[entry])[1] == True: pths[entry] = ((libdict[entry])[0]) if not os.path.exists(cachefolder): os.makedirs(cachefolder) for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) print("1. Parsing games in device. Please Wait...") process = subprocess.Popen([ nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache, "-show", "false" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) while process.poll() == None: if process.poll() != None: process.terminate() if os.path.exists(games_installed_cache): print(" Success") gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True) installed = {} for g in gamelist: if exclude_xci == True: if g.endswith('xci') or g.endswith('xc0'): continue entry = listmanager.parsetags(g) entry = list(entry) entry.append(g) installed[entry[0]] = entry print("2. Parsing local libraries. Please Wait...") locallist = [] for p in pths.keys(): locallist += listmanager.folder_to_list(pths[p], ['nsp', 'nsz']) print(f' Parsed Library: "{str(p).upper()}"') if prioritize_nsz == True: locallist = sorted(locallist, key=lambda x: x[-1]) locallist.reverse() localgames = {} for g in locallist: entry = listmanager.parsetags(g) entry = list(entry) entry.append(g) if not entry[0] in localgames: localgames[entry[0]] = entry else: v = (localgames[entry[0]])[1] if int(entry[1]) > int(v): localgames[entry[0]] = entry print("3. Searching new updates. Please Wait...") gamestosend = {} for g in installed.keys(): if g.endswith('000') or g.endswith('800'): try: updid = g[:-3] + '800' if updid in localgames: if updid in installed: if ((installed[updid])[1]) < ((localgames[updid])[1]): if not updid in gamestosend: gamestosend[updid] = localgames[updid] else: if ((gamestosend[updid])[1]) < ( (localgames[updid])[1]): gamestosend[updid] = localgames[updid] else: if not updid in gamestosend: gamestosend[updid] = localgames[updid] else: if ((gamestosend[updid])[1]) < ( (localgames[updid])[1]): gamestosend[updid] = localgames[updid] except: pass else: try: if g in localgames: if ((installed[g])[1]) < ((localgames[g])[1]): if not g in gamestosend: gamestosend[g] = localgames[g] else: if ((gamestosend[g])[1]) < ((localgames[g])[1]): gamestosend[g] = localgames[g] except: pass print("4. Searching new dlcs. Please Wait...") for g in installed.keys(): try: if g.endswith('000') or g.endswith('800'): baseid = g[:-3] + '000' else: baseid = (installed[g])[6] for k in localgames.keys(): try: if not (k.endswith('000') or k.endswith('800')) and not k in installed: test = get_dlc_baseid(k) if baseid == test: if not k in gamestosend: gamestosend[k] = localgames[k] else: if ((gamestosend[k])[1]) < ( (localgames[k])[1]): gamestosend[k] = localgames[k] except BaseException as e: # Print.error('Exception: ' + str(e)) pass except BaseException as e: # Print.error('Exception: ' + str(e)) pass print("5. List of content that will get installed...") gamepaths = [] if len(gamestosend.keys()) > 0: if autoupd_aut == True: for i in sorted(gamestosend.keys()): fileid, fileversion, cctag, nG, nU, nD, baseid, path = gamestosend[ i] bname = os.path.basename(path) gamepaths.append(path) g0 = [pos for pos, char in enumerate(bname) if char == '['] g0 = (bname[0:g0[0]]).strip() print( f" * {g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}" ) else: options = [] for i in sorted(gamestosend.keys()): fileid, fileversion, cctag, nG, nU, nD, baseid, path = gamestosend[ i] bname = os.path.basename(path) gamepaths.append(path) g0 = [pos for pos, char in enumerate(bname) if char == '['] g0 = (bname[0:g0[0]]).strip() cstring = f"{g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}" options.append(cstring) if options: title = 'Select content to install: \n + Press space or right to select entries \n + Press E to finish selection \n + Press A to select all entries' picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False, -1 def select_all(picker): return "ALL", -1 picker.register_custom_handler(ord('e'), end_selection) picker.register_custom_handler(ord('E'), end_selection) picker.register_custom_handler(ord('a'), select_all) picker.register_custom_handler(ord('A'), select_all) selected = picker.start() if selected[0] == False: print(" User didn't select any files") return False if selected[0] == "ALL": pass else: newgpaths = [] for game in selected: g = game[1] g0 = gamepaths[g] newgpaths.append(g0) gamepaths = newgpaths print("6. Generating text file...") with open(tfile, 'w', encoding='utf8') as textfile: for i in gamepaths: textfile.write((i).strip() + "\n") print("7. Triggering installer on loop mode.") print( " Note:If you interrupt the list use normal install mode to continue list" ) loop_install(tfile, destiny=destiny, verification=verification, ch_medium=ch_medium, ch_other=ch_other, checked=True) else: print("\n --- DEVICE IS UP TO DATE ---")
def get_archived_info(search_new=True, excludehb=True): forecombo = Style.BRIGHT + Back.GREEN + Fore.WHITE if not os.path.exists(cachefolder): os.makedirs(cachefolder) for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) print("1. Retrieving registered...") dbicsv = os.path.join(cachefolder, "registered.csv") process = subprocess.Popen([ nscb_mtp, "Download", "-ori", "4: Installed games\\InstalledApplications.csv", "-dst", dbicsv ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) while process.poll() == None: if process.poll() != None: process.terminate() if os.path.exists(dbicsv): print(" Success") print("2. Checking Installed...") process = subprocess.Popen([ nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache, "-show", "false" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) while process.poll() == None: if process.poll() != None: process.terminate() if os.path.exists(games_installed_cache): print(" Success") gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True) dbi_dict = {} with open(dbicsv, 'rt', encoding='utf8') as csvfile: readCSV = csv.reader(csvfile, delimiter=',') id = 0 ver = 1 tname = 2 for row in readCSV: try: tid = (str(row[id]).upper())[2:] version = int(row[ver]) name = str(row[tname]) dbi_dict[tid] = [tid, version, name] except: pass installed = {} for g in gamelist: entry = listmanager.parsetags(g) installed[entry[0]] = entry print("..........................................................") print("ARCHIVED|REGISTERED GAMES") print("..........................................................") for g in dbi_dict.keys(): if not g in installed.keys(): tid, version, name = dbi_dict[g] if len(name) > 33: name = name[0:30] + '...' print(f"{name} [{tid}][{version}]") if search_new == True: import nutdb nutdb.check_other_file(urlconfig, 'versions_txt') f = 'nutdb_' + 'versions' + '.txt' DATABASE_folder = nutdb.get_DBfolder() _dbfile_ = os.path.join(DATABASE_folder, f) versiondict = {} with open(_dbfile_, 'rt', encoding='utf8') as csvfile: readCSV = csv.reader(csvfile, delimiter='|') i = 0 for row in readCSV: if i == 0: csvheader = row i = 1 if 'id' and 'version' in csvheader: id = csvheader.index('id') ver = csvheader.index('version') else: break else: try: tid = str(row[id]).upper() version = str(row[ver]).upper() if tid.endswith('800'): baseid = tid[:-3] + '000' if baseid in versiondict.keys(): v = versiondict[baseid] if v < int(version): versiondict[baseid] = int(version) else: versiondict[tid] = int(version) except: pass print("..........................................................") print("NEW UPDATES") print("..........................................................") for k in dbi_dict.keys(): fileid, fileversion, g0 = dbi_dict[k] if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + (33 - len(g0)) * ' ' v = 0 updateid = fileid[:-3] + '800' if updateid in dbi_dict.keys() and fileid.endswith('000'): continue if fileid.endswith('800'): try: v = versiondict[baseid] except: pass else: try: v = versiondict[fileid] except: pass if int(v) > int(fileversion): if fileid.endswith('000') or fileid.endswith('800'): updid = fileid[:-3] + '800' print(f"{g0} [{baseid}][{fileversion}] -> " + forecombo + f"[{updid}] [v{v}]" + Style.RESET_ALL) else: print(f"{g0} [{fileid}][{fileversion}] -> " + forecombo + f"[{fileid}] [v{v}]" + Style.RESET_ALL) print("..........................................................") print("NEW DLCS") print("..........................................................") for k in versiondict.keys(): if k in dbi_dict.keys() or k.endswith('000') or k.endswith('800'): continue else: baseid = get_dlc_baseid(k) updid = baseid[:-3] + '800' if baseid in dbi_dict.keys() or updid in dbi_dict.keys(): fileid, fileversion, g0 = dbi_dict[baseid] if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + ((33 - len(g0)) * ' ') print(f"{g0} [{baseid}] -> " + forecombo + f"[{k}] [v{versiondict[k]}]" + Style.RESET_ALL)
def get_installed_info(tfile=None, search_new=True, excludehb=True): if not os.path.exists(cachefolder): os.makedirs(cachefolder) forecombo = Style.BRIGHT + Back.GREEN + Fore.WHITE if tfile == "": tfile = None if os.path.exists(games_installed_cache): try: os.remove(games_installed_cache) except: pass if tfile == None: for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) process = subprocess.Popen([ nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache, "-show", "false" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("Parsing games in device. Please Wait...") while process.poll() == None: if process.poll() != None: process.terminate() if os.path.exists(games_installed_cache): gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True) gamelist.sort() print("..........................................................") print("CONTENT FOUND ON DEVICE") print("..........................................................") installed = {} for g in gamelist: fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags( g) g0 = [pos for pos, char in enumerate(g) if char == '['] g0 = (g[0:g0[0]]).strip() installed[fileid] = [ fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g ] if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + ((33 - len(g0)) * ' ') verprint = str(fileversion) if len(verprint) < 9: verprint = verprint + ((9 - len(verprint)) * ' ') if excludehb == True: if not fileid.startswith('05') and not fileid.startswith( '04') and not str(fileid).lower() == 'unknown': if g.endswith('.xci') or g.endswith('.xc0'): print( f"{g0}|{fileid}|{verprint}|XCI|{nG}G|{nU}U|{nD}D") else: print(f"{g0}|{fileid}|{verprint}|{cctag}") else: if g.endswith('.xci') or g.endswith('.xc0'): print(f"{g0}|{fileid}|{verprint}|XCI|{nG}G|{nU}U|{nD}D") else: print(f"{g0}|{fileid}|{verprint}|{cctag}") if search_new == True: import nutdb nutdb.check_other_file(urlconfig, 'versions_txt') f = 'nutdb_' + 'versions' + '.txt' DATABASE_folder = nutdb.get_DBfolder() _dbfile_ = os.path.join(DATABASE_folder, f) versiondict = {} with open(_dbfile_, 'rt', encoding='utf8') as csvfile: readCSV = csv.reader(csvfile, delimiter='|') i = 0 for row in readCSV: if i == 0: csvheader = row i = 1 if 'id' and 'version' in csvheader: id = csvheader.index('id') ver = csvheader.index('version') else: break else: try: tid = str(row[id]).upper() version = str(row[ver]).upper() if tid.endswith('800'): baseid = tid[:-3] + '000' if baseid in versiondict.keys(): v = versiondict[baseid] if v < int(version): versiondict[baseid] = int(version) else: versiondict[tid] = int(version) except: pass print("..........................................................") print("NEW UPDATES") print("..........................................................") for k in installed.keys(): fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[ k] if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + ((33 - len(g0)) * ' ') verprint = str(fileversion) fillver = '' if len(verprint) < 6: fillver = (6 - len(verprint)) * ' ' v = 0 updateid = fileid[:-3] + '800' if updateid in installed.keys() and fileid.endswith('000'): continue if fileid.endswith('800'): try: v = versiondict[baseid] except: pass else: try: v = versiondict[fileid] except: pass if int(v) > int(fileversion): if fileid.endswith('000') or fileid.endswith('800'): updid = fileid[:-3] + '800' print(f"{g0} [{baseid}][{verprint}]{fillver} -> " + forecombo + f"[{updid}] [v{v}]" + Style.RESET_ALL) else: print(f"{g0} [{fileid}][{verprint}]{fillver} -> " + forecombo + f"[{fileid}] [v{v}]" + Style.RESET_ALL) check_xcis = False xci_dlcs = {} print("..........................................................") print("NEW DLCS") print("..........................................................") for k in versiondict.keys(): if k in installed.keys() or k.endswith('000') or k.endswith( '800'): continue else: baseid = get_dlc_baseid(k) updid = baseid[:-3] + '800' if baseid in installed.keys() or updid in installed.keys(): fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[ baseid] if nD > 0: if check_xcis == False: check_xcis = True if not baseid in xci_dlcs.keys(): entry = list() entry.append(k) xci_dlcs[baseid] = entry else: entry = xci_dlcs[baseid] entry.append(k) xci_dlcs[baseid] = entry continue if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + ((33 - len(g0)) * ' ') print(f"{g0} [{baseid}] -> " + forecombo + f"[{k}] [v{versiondict[k]}]" + Style.RESET_ALL) t = 0 if check_xcis == True: for bid in xci_dlcs.keys(): fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[ bid] entry = xci_dlcs[bid] test = len(entry) if test > nD: if t == 0: print( ".........................................................." ) print("XCI MAY HAVE NEW DLCS. LISTING AVAILABLE") print( ".........................................................." ) t += 1 if len(g0) > 33: g0 = g0[0:30] + '...' else: g0 = g0 + ((33 - len(g0)) * ' ') for k in xci_dlcs[baseid]: print(f"{g0} [{baseid}] -> " + forecombo + f"[{k}] [v{versiondict[k]}]" + Style.RESET_ALL)
def update_console_from_gd(libraries="all",destiny="SD",exclude_xci=True,prioritize_nsz=True,tfile=None,verification=True,ch_medium=True,ch_other=False,autoupd_aut=True,use_archived=False): check_connection() if use_archived==True: autoupd_aut=False if tfile==None: tfile=os.path.join(NSCB_dir, 'MTP1.txt') if os.path.exists(tfile): try: os.remove(tfile) except: pass libdict=get_libs_remote_source(remote_lib_file); if libdict==False: sys.exit("No libraries set up") pths={};TDs={}; if libraries=="all": for entry in libdict.keys(): pths[entry]=((libdict[entry])[0]) TDs[entry]=((libdict[entry])[1]) else: for entry in libdict.keys(): if (libdict[entry])[2]==True: pths[entry]=((libdict[entry])[0]) TDs[entry]=((libdict[entry])[1]) # print(pths);print(TDs); if not os.path.exists(cachefolder): os.makedirs(cachefolder) for f in os.listdir(cachefolder): fp = os.path.join(cachefolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) if use_archived!=True: print("1. Parsing games in device. Please Wait...") if exclude_xci==True: process=subprocess.Popen([nscb_mtp,"ShowInstalled","-tfile",games_installed_cache,"-show","false","-exci","true"],stdout=subprocess.PIPE,stderr=subprocess.PIPE) else: process=subprocess.Popen([nscb_mtp,"ShowInstalled","-tfile",games_installed_cache,"-show","false","-exci","false","-xci_lc",xci_locations],stdout=subprocess.PIPE,stderr=subprocess.PIPE) while process.poll()==None: if process.poll()!=None: process.terminate(); if os.path.exists(games_installed_cache): print(" Success") gamelist=listmanager.read_lines_to_list(games_installed_cache,all=True) installed={} for g in gamelist: try: if exclude_xci==True: if g.endswith('xci') or g.endswith('xc0'): continue entry=listmanager.parsetags(g) entry=list(entry) entry.append(g) installed[entry[0]]=entry except:pass # for i in pths: # print(i) else: print("1. Retrieving registered...") dbicsv=os.path.join(cachefolder,"registered.csv") process=subprocess.Popen([nscb_mtp,"Download","-ori","4: Installed games\\InstalledApplications.csv","-dst",dbicsv],stdout=subprocess.PIPE,stderr=subprocess.PIPE) while process.poll()==None: if process.poll()!=None: process.terminate(); if os.path.exists(dbicsv): print(" Success") installed={} with open(dbicsv,'rt',encoding='utf8') as csvfile: readCSV = csv.reader(csvfile, delimiter=',') id=0;ver=1;tname=2; for row in readCSV: try: tid=(str(row[id]).upper())[2:] version=int(row[ver]) if version>0 and tid.endswith('000'): tid=tid[:-3]+'800' name=str(row[tname]) g=f"{name} [{tid}][v{version}].nsp" entry=listmanager.parsetags(g) entry=list(entry) entry.append(g) if entry[0] in installed.keys(): if int((intalled[entry[0]])[1])<version: installed[entry[0]]=entry else: installed[entry[0]]=entry except:pass print("2. Parsing files from Google Drive. Please Wait...") # print(pths) if isinstance(pths, dict): db={} for i in pths.keys(): db[i]={'path':pths[i],'TD_name':TDs[i]} files=concurrent_scrapper(filter='',order='name_ascending',remotelib='all',db=db) else: db={} db[pths]={'path':pths,'TD_name':TDs} files=concurrent_scrapper(filter=filter,order='name_ascending',remotelib='all',db=db) remotelist=[] for f in files: remotelist.append(f[0]) if prioritize_nsz==True: remotelist=sorted(remotelist, key=lambda x: x[-1]) remotelist.reverse() else: remotelist.reverse() # for f in remotelist: # print(f) remotegames={} for g in remotelist: try: entry=listmanager.parsetags(g) entry=list(entry) entry.append(g) if not entry[0] in remotegames: remotegames[entry[0]]=entry else: v=(remotegames[entry[0]])[1] if int(entry[1])>int(v): remotegames[entry[0]]=entry except:pass print("3. Searching new updates. Please Wait...") gamestosend={} for g in installed.keys(): if g.endswith('000') or g.endswith('800'): try: updid=g[:-3]+'800' if updid in remotegames: if updid in installed: if ((installed[updid])[1])<((remotegames[updid])[1]): if not updid in gamestosend: gamestosend[updid]=remotegames[updid] else: if ((gamestosend[updid])[1])<((remotegames[updid])[1]): gamestosend[updid]=remotegames[updid] else: if not updid in gamestosend: gamestosend[updid]=remotegames[updid] else: if ((gamestosend[updid])[1])<((remotegames[updid])[1]): gamestosend[updid]=remotegames[updid] except:pass else: try: if g in remotegames: if ((installed[g])[1])<((remotegames[g])[1]): if not g in gamestosend: gamestosend[g]=remotegames[g] else: if ((gamestosend[g])[1])<((remotegames[g])[1]): gamestosend[g]=remotegames[g] except:pass print("4. Searching new dlcs. Please Wait...") for g in installed.keys(): try: if g.endswith('000') or g.endswith('800'): baseid=g[:-3]+'000' else: baseid=(installed[g])[6] for k in remotegames.keys(): try: if not (k.endswith('000') or k.endswith('800')) and not k in installed: test=get_dlc_baseid(k) if baseid ==test: if not k in gamestosend: gamestosend[k]=remotegames[k] else: if ((gamestosend[k])[1])<((remotegames[k])[1]): gamestosend[k]=remotegames[k] except BaseException as e: # Print.error('Exception: ' + str(e)) pass except BaseException as e: # Print.error('Exception: ' + str(e)) pass print("5. List of content that will get installed...") gamepaths=[] if len(gamestosend.keys())>0: if autoupd_aut==True: for i in sorted(gamestosend.keys()): fileid,fileversion,cctag,nG,nU,nD,baseid,path=gamestosend[i] bname=os.path.basename(path) gamepaths.append(path) g0=[pos for pos, char in enumerate(bname) if char == '['] g0=(bname[0:g0[0]]).strip() print(f" * {g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}") else: options=[] for i in sorted(gamestosend.keys()): fileid,fileversion,cctag,nG,nU,nD,baseid,path=gamestosend[i] bname=os.path.basename(path) gamepaths.append(path) g0=[pos for pos, char in enumerate(bname) if char == '['] g0=(bname[0:g0[0]]).strip() cstring=f"{g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}" options.append(cstring) if options: from python_pick import Picker title = 'Select content to install: \n + Press space or right to select entries \n + Press Enter to confirm selection \n + Press E to exit selection \n + Press A to select all entries' picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False,-1 def select_all(picker): return "ALL",-1 picker.register_custom_handler(ord('e'), end_selection) picker.register_custom_handler(ord('E'), end_selection) picker.register_custom_handler(ord('a'), select_all) picker.register_custom_handler(ord('A'), select_all) selected=picker.start() if selected[0]==False: print(" User didn't select any files") return False if selected[0]=="ALL": pass else: newgpaths=[] for game in selected: g=game[1] g0=gamepaths[g] newgpaths.append(g0) gamepaths=newgpaths print("6. Generating text file...") with open(tfile,'w', encoding='utf8') as textfile: wpath='' for i in gamepaths: location=None for f in files: TD=None;ID=None if f[0]==i: location=f[2] try: ID=f[4] except:pass break if location==None: print(f"Can't find location for {i}") continue wpath=f"{location}/{i}" lib,TD,libpath=get_library_from_path(filename=wpath) if ID==None: textfile.write(f"{(wpath).strip()}|{TD}\n") else: textfile.write(f"{(wpath).strip()}|{TD}|{ID}\n") print("7. Triggering installer on loop mode.") print(" Note:If you interrupt the list use normal install mode to continue list") loop_install(tfile,destiny=destiny,outfolder=None,ch_medium=ch_medium,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,checked=True) else: print("\n --- DEVICE IS UP TO DATE ---")
def fichier_install(url,destiny="SD",ch_medium=True,ch_base=False,ch_other=False,installed_list=False): check_connection() if not os.path.exists(_1fichier_token): sys.exit("No 1fichier token setup") with open(_1fichier_token,'rt',encoding='utf8') as tfile: token=(tfile.readline().strip()) if token==None: sys.exit("Missing 1fichier token") APIkey=token auth={'Authorization':f'Bearer {APIkey}','Content-Type':'application/json'} session = requests.session() download_params = { 'url' : url, 'inline' : 0, 'cdn' : 0, 'restrict_ip': 0, 'no_ssl' : 0, } info_params={ 'url' : url } r=session.post('https://api.1fichier.com/v1/file/info.cgi',json=info_params,headers=auth) info_dict=r.json() # print(info_dict) sz=info_dict['size'] name=info_dict['filename'] r=session.post('https://api.1fichier.com/v1/download/get_token.cgi',json=download_params,headers=auth) dict_=r.json() # print(dict_) ext=name.split('.') ext=ext[-1] if not name.endswith('nsp') and not name.endswith('nsz'): sys.exit(f"Extension not supported for direct instalation {ext} in {name}") if not dict_['status']=="OK": sys.exit(f"API call returned {dict_['status']}") URL=dict_['url'] print("- Retrieving Space on device") SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info() print("- Calculating Installed size") filesize=int(sz) if destiny=="SD": print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") print(f" * File size: {filesize} ({sq_tools.getSize(filesize)})") if filesize>SD_fs: if filesize<NAND_fs and ch_medium==True: print(" Not enough space on SD. Changing target to EMMC") print(f" * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})") destiny="NAND" elif ch_medium==False: sys.exit(" NOT ENOUGH SPACE SD STORAGE") else: sys.exit(" NOT ENOUGH SPACE ON DEVICE") else: print(f" * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})") print(f" * File size: {filesize} ({sq_tools.getSize(filesize)})") if filesize>NAND_fs: if filesize<SD_fs and ch_medium==True: print(" Not enough space on EMMC. Changing target to SD") print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") destiny="SD" elif ch_medium==False: sys.exit(" NOT ENOUGH SPACE EMMC STORAGE") else: sys.exit(" NOT ENOUGH SPACE ON DEVICE") if installed_list!=False: try: fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(name) fileversion=int(fileversion) if fileid.endswith('000') and fileversion==0 and fileid in installed_list.keys() and ch_base==True: print("Base game already installed. Skipping...") return False elif fileid.endswith('000') and fileid in installed_list.keys() and ch_other==True: updid=fileid[:-3]+'800' if fileversion>((installed_list[fileid])[2]): print("Asking DBI to delete previous content") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) return False elif ch_other==True and fileid in installed_list.keys(): if fileversion>((installed_list[fileid])[2]): print("Asking DBI to delete previous update") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) return False except:pass process=subprocess.Popen([nscb_mtp,"fichierInstall","-ori",URL,"-dst",destiny,"-name",name,"-size",str(sz)]) while process.poll()==None: if process.poll()!=None: process.terminate();
def public_gdrive_install(filepath,destiny="SD",truecopy=True,outfolder=None,ch_medium=True,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,installed_list=False): check_connection() lib,TD,libpath=get_cache_lib() if lib==None: sys.exit(f"Google Drive Public Links are only supported via cache folder") filename=addtodrive(filepath,truecopy=truecopy) ID,name,type,size,md5,remote=DrivePrivate.get_Data(filename,TD=TD,Print=False) token=remote.access_token name=remote.name sz=remote.size URL='https://www.googleapis.com/drive/v3/files/'+remote.ID+'?alt=media' ext=name.split('.') ext=ext[-1] if not name.endswith('nsp') and not name.endswith('nsz') and not name.endswith('xci') and not name.endswith('xcz'): print(f"Extension not supported for direct instalation {ext} in {name}") return False print("- Retrieving Space on device") SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info() print("- Calculating Installed size") filesize=int(sz) if destiny=="SD": print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") print(f" * File size: {filesize} ({sq_tools.getSize(filesize)})") if filesize>SD_fs: if filesize<NAND_fs and ch_medium==True: print(" Not enough space on SD. Changing target to EMMC") print(f" * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})") destiny="NAND" elif ch_medium==False: sys.exit(" NOT ENOUGH SPACE SD STORAGE") else: sys.exit(" NOT ENOUGH SPACE ON DEVICE") else: print(f" * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})") print(f" * File size: {filesize} ({sq_tools.getSize(filesize)})") if filesize>NAND_fs: if filesize<SD_fs and ch_medium==True: print(" Not enough space on EMMC. Changing target to SD") print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") destiny="SD" elif ch_medium==False: sys.exit(" NOT ENOUGH SPACE EMMC STORAGE") else: sys.exit(" NOT ENOUGH SPACE ON DEVICE") kgwarning=False if check_fw==True: try: cnmtdata,files_list,remote=DriveTools.get_cnmt_data(file=remote) keygeneration=int(cnmtdata['keygeneration']) if FW!='unknown': try: FW_RSV,RRSV=sq_tools.transform_fw_string(FW) FW_kg=sq_tools.kg_by_RSV(FW_RSV) except BaseException as e: Print.error('Exception: ' + str(e)) FW='unknown' FW_kg='unknown' pass if FW!='unknown' and FW_kg!='unknown': if int(keygeneration)>int(FW_kg): kgwarning=True tgkg=int(FW_kg) else: tgkg=keygeneration else: tgkg=keygeneration print(f"- Console Firmware: {FW} ({FW_RSV}) - keygen {FW_kg})") print(f"- File keygeneration: {keygeneration}") if kgwarning==True: print("File requires a higher firmware. Skipping...") return False except: print("Error getting cnmtdata from file") if installed_list!=False: try: fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(name) fileversion=int(fileversion) if fileid.endswith('000') and fileversion==0 and fileid in installed_list.keys() and ch_base==True: print("Base game already installed. Skipping...") return False elif fileid.endswith('000') and fileid in installed_list.keys() and ch_other==True: updid=fileid[:-3]+'800' if fileversion>((installed_list[fileid])[2]): print("Asking DBI to delete previous content") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) return False elif ch_other==True and fileid in installed_list.keys(): if fileversion>((installed_list[fileid])[2]): print("Asking DBI to delete previous update") process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid]) while process.poll()==None: if process.poll()!=None: process.terminate(); else: print("The update is a previous version than the installed on device.Skipping..") listmanager.striplines(tfile,counter=True) return False except:pass if name.endswith('xci') or name.endswith('xcz'): from mtpxci_remote import install_xci_csv install_xci_csv(remote=remote,destiny=destiny,cachefolder=outfolder) else: process=subprocess.Popen([nscb_mtp,"DriveInstall","-ori",URL,"-dst",destiny,"-name",name,"-size",sz,"-tk",token]) while process.poll()==None: if process.poll()!=None: process.terminate();