Titles without tickets are now handled correctly

Entire UI is now locked out during downloads to prevent changing options and breaking things, and new titles cannot be selected from the list mid-download
This commit is contained in:
Campbell 2024-04-15 10:42:46 -04:00
parent 1c2370b6cb
commit ff3eea8d5e
3 changed files with 69 additions and 30 deletions

View File

@ -47,6 +47,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.ui.download_btn.clicked.connect(self.download_btn_pressed) self.ui.download_btn.clicked.connect(self.download_btn_pressed)
self.ui.pack_wad_chkbox.clicked.connect(self.pack_wad_chkbox_toggled) self.ui.pack_wad_chkbox.clicked.connect(self.pack_wad_chkbox_toggled)
self.ui.log_text_browser.setText("NUSD-Py v1.0\nDeveloped by NinjaCheetah\nPowered by libWiiPy\n\n"
"Select a title from the list on the left, or enter a Title ID to begin.")
tree = self.ui.title_tree tree = self.ui.title_tree
self.tree_categories = [] self.tree_categories = []
@ -81,18 +84,20 @@ class MainWindow(QMainWindow, Ui_MainWindow):
@Slot(QTreeWidgetItem, int) @Slot(QTreeWidgetItem, int)
def onItemClicked(self, item, col): def onItemClicked(self, item, col):
global regions if self.ui.download_btn.isEnabled() is True:
region_names = [] global regions
for region in regions: region_names = []
region_names.append(region[1]) for region in regions:
if item.parent() is not None and item.parent() not in self.tree_categories: region_names.append(region[1])
category = item.parent().parent().parent().text(0) if (item.parent() is not None and item.parent() not in self.tree_categories
for title in wii_database[category]: and item.parent().parent() not in self.tree_categories):
if item.parent().parent().text(0) == (title["TID"] + " - " + title["Name"]): category = item.parent().parent().parent().text(0)
selected_title = title for title in wii_database[category]:
selected_version = item.text(0) if item.parent().parent().text(0) == (title["TID"] + " - " + title["Name"]):
selected_region = item.parent().text(0) selected_title = title
self.load_title_data(selected_title, selected_version, selected_region) selected_version = item.text(0)
selected_region = item.parent().text(0)
self.load_title_data(selected_title, selected_version, selected_region)
def update_log_text(self, new_text): def update_log_text(self, new_text):
self.log_text += new_text + "\n" self.log_text += new_text + "\n"
@ -121,12 +126,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
danger_text = selected_title["Danger"] danger_text = selected_title["Danger"]
except KeyError: except KeyError:
pass pass
if selected_title["Ticket"] is False:
danger_text = danger_text + ("\n\nNote: This Title does not have a Ticket available, so it cannot be "
"packed into a WAD or decrypted.")
self.log_text = (tid + " - " + selected_title["Name"] + "\n" + "Version: " + selected_version + "\n\n" + self.log_text = (tid + " - " + selected_title["Name"] + "\n" + "Version: " + selected_version + "\n\n" +
danger_text + "\n") danger_text + "\n")
self.ui.log_text_browser.setText(self.log_text) self.ui.log_text_browser.setText(self.log_text)
def download_btn_pressed(self): def download_btn_pressed(self):
self.ui.tid_entry.setEnabled(False)
self.ui.version_entry.setEnabled(False)
self.ui.download_btn.setEnabled(False) self.ui.download_btn.setEnabled(False)
self.ui.pack_wad_chkbox.setEnabled(False)
self.ui.keep_enc_chkbox.setEnabled(False)
self.ui.create_dec_chkbox.setEnabled(False)
self.ui.use_local_chkbox.setEnabled(False)
self.ui.wad_file_entry.setEnabled(False)
self.log_text = "" self.log_text = ""
self.ui.log_text_browser.setText(self.log_text) self.ui.log_text_browser.setText(self.log_text)
@ -154,7 +169,23 @@ class MainWindow(QMainWindow, Ui_MainWindow):
" title database, and that the provided version exists for the title you are" " title database, and that the provided version exists for the title you are"
" attempting to download.") " attempting to download.")
msgBox.exec() msgBox.exec()
elif result == 1:
msgBox.setIcon(QMessageBox.Icon.Warning)
msgBox.setWindowTitle("Ticket Not Available")
msgBox.setText("No Ticket is Available for the Requested Title!")
msgBox.setInformativeText("A ticket could not be downloaded for the requested title, but you have selected "
"\"Pack WAD\" or \"Create Decrypted Contents\". These options are not available "
"for titles without a ticket. Only encrypted contents have been saved.")
msgBox.exec()
self.ui.tid_entry.setEnabled(True)
self.ui.version_entry.setEnabled(True)
self.ui.download_btn.setEnabled(True) self.ui.download_btn.setEnabled(True)
self.ui.pack_wad_chkbox.setEnabled(True)
self.ui.keep_enc_chkbox.setEnabled(True)
self.ui.create_dec_chkbox.setEnabled(True)
self.ui.use_local_chkbox.setEnabled(True)
if self.ui.pack_wad_chkbox.isChecked() is True:
self.ui.wad_file_entry.setEnabled(True)
def run_nus_download(self, progress_callback): def run_nus_download(self, progress_callback):
tid = self.ui.tid_entry.text() tid = self.ui.tid_entry.text()
@ -165,6 +196,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
except ValueError: except ValueError:
version = None version = None
pack_wad_enabled = self.ui.pack_wad_chkbox.isChecked()
decrypt_contents_enabled = self.ui.create_dec_chkbox.isChecked()
title = libWiiPy.Title() title = libWiiPy.Title()
title_dir = pathlib.Path(os.path.join(out_folder, tid)) title_dir = pathlib.Path(os.path.join(out_folder, tid))
@ -195,10 +229,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
tmd_out.close() tmd_out.close()
progress_callback.emit(" - Downloading and parsing Ticket...") progress_callback.emit(" - Downloading and parsing Ticket...")
title.load_ticket(libWiiPy.download_ticket(tid)) try:
ticket_out = open(os.path.join(version_dir, "tik"), "wb") title.load_ticket(libWiiPy.download_ticket(tid))
ticket_out.write(title.ticket.dump()) ticket_out = open(os.path.join(version_dir, "tik"), "wb")
ticket_out.close() ticket_out.write(title.ticket.dump())
ticket_out.close()
except ValueError:
progress_callback.emit(" - No Ticket is available!")
pack_wad_enabled = False
decrypt_contents_enabled = False
title.load_content_records() title.load_content_records()
content_list = [] content_list = []
@ -229,7 +268,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
enc_content_out.close() enc_content_out.close()
title.content.content_list = content_list title.content.content_list = content_list
if self.ui.create_dec_chkbox.isChecked() is True: if decrypt_contents_enabled is True:
for content in range(len(title.tmd.content_records)): for content in range(len(title.tmd.content_records)):
progress_callback.emit(" - Decrypting content " + str(content + 1) + " of " + progress_callback.emit(" - Decrypting content " + str(content + 1) + " of " +
str(len(title.tmd.content_records)) + "...") str(len(title.tmd.content_records)) + "...")
@ -242,7 +281,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
dec_content_out.write(dec_content) dec_content_out.write(dec_content)
dec_content_out.close() dec_content_out.close()
if self.ui.pack_wad_chkbox.isChecked() is True: if pack_wad_enabled is True:
progress_callback.emit(" - Building certificate...") progress_callback.emit(" - Building certificate...")
title.wad.set_cert_data(libWiiPy.download_cert()) title.wad.set_cert_data(libWiiPy.download_cert())
@ -258,6 +297,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
file.close() file.close()
progress_callback.emit("Download complete!") progress_callback.emit("Download complete!")
if ((not pack_wad_enabled and self.ui.pack_wad_chkbox.isChecked()) or
(not decrypt_contents_enabled and self.ui.create_dec_chkbox.isChecked())):
return 1
return 0
def pack_wad_chkbox_toggled(self): def pack_wad_chkbox_toggled(self):
if self.ui.pack_wad_chkbox.isChecked() is True: if self.ui.pack_wad_chkbox.isChecked() is True:

View File

@ -126,7 +126,7 @@ class Ui_MainWindow(object):
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow) self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar") self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 610, 30)) self.menubar.setGeometry(QRect(0, 0, 610, 29))
MainWindow.setMenuBar(self.menubar) MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow) self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar") self.statusbar.setObjectName(u"statusbar")
@ -145,14 +145,12 @@ class Ui_MainWindow(object):
self.label.setText(QCoreApplication.translate("MainWindow", u"v", None)) self.label.setText(QCoreApplication.translate("MainWindow", u"v", None))
self.version_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Version", None)) self.version_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Version", None))
self.download_btn.setText(QCoreApplication.translate("MainWindow", u"Start NUS Download!", None)) self.download_btn.setText(QCoreApplication.translate("MainWindow", u"Start NUS Download!", None))
self.log_text_browser.setMarkdown(QCoreApplication.translate("MainWindow", u"Select a title from the list on the left, or enter a Title ID to begin.\n" self.log_text_browser.setMarkdown("")
"\n"
"", None))
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n" "p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;\">\n" "</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Select a title from the list on the left, or enter a Title ID to begin.</p></body></html>", None)) "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", None))
self.pack_wad_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack WAD", None)) self.pack_wad_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack WAD", None))
self.wad_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None)) self.wad_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep Enc. Contents", None)) self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep Enc. Contents", None))

View File

@ -105,16 +105,14 @@
<item> <item>
<widget class="QTextBrowser" name="log_text_browser"> <widget class="QTextBrowser" name="log_text_browser">
<property name="markdown"> <property name="markdown">
<string>Select a title from the list on the left, or enter a Title ID to begin. <string/>
</string>
</property> </property>
<property name="html"> <property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Select a title from the list on the left, or enter a Title ID to begin.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -176,7 +174,7 @@ p, li { white-space: pre-wrap; }
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>610</width> <width>610</width>
<height>30</height> <height>29</height>
</rect> </rect>
</property> </property>
</widget> </widget>