summaryrefslogtreecommitdiffstats
path: root/src/yuzu/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r--src/yuzu/main.cpp118
1 files changed, 101 insertions, 17 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e11833c5a..bef9df00d 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -31,6 +31,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QMessageBox>
+#include <QtConcurrent/QtConcurrent>
#include <QtGui>
#include <QtWidgets>
#include <fmt/format.h>
@@ -171,8 +172,11 @@ GMainWindow::GMainWindow()
.arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
show();
+ // Gen keys if necessary
+ OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
+
// Necessary to load titles from nand in gamelist.
- Service::FileSystem::CreateFactories(vfs);
+ Service::FileSystem::CreateFactories(*vfs);
game_list->LoadCompatibilityList();
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
@@ -443,6 +447,8 @@ void GMainWindow::ConnectMenuEvents() {
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
// Help
+ connect(ui.action_Rederive, &QAction::triggered, this,
+ std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
connect(ui.action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
}
@@ -902,22 +908,20 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
}
void GMainWindow::OnMenuLoadFile() {
- QString extensions;
- for (const auto& piece : game_list->supported_file_extensions)
- extensions += "*." + piece + " ";
-
- extensions += "main ";
+ const QString extensions =
+ QString("*.").append(GameList::supported_file_extensions.join(" *.")).append(" main");
+ const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)",
+ "%1 is an identifier for the Switch executable file extensions.")
+ .arg(extensions);
+ const QString filename = QFileDialog::getOpenFileName(
+ this, tr("Load File"), UISettings::values.roms_path, file_filter);
- QString file_filter = tr("Switch Executable") + " (" + extensions + ")";
- file_filter += ";;" + tr("All Files (*.*)");
-
- QString filename = QFileDialog::getOpenFileName(this, tr("Load File"),
- UISettings::values.roms_path, file_filter);
- if (!filename.isEmpty()) {
- UISettings::values.roms_path = QFileInfo(filename).path();
-
- BootGame(filename);
+ if (filename.isEmpty()) {
+ return;
}
+
+ UISettings::values.roms_path = QFileInfo(filename).path();
+ BootGame(filename);
}
void GMainWindow::OnMenuLoadFolder() {
@@ -1133,7 +1137,7 @@ void GMainWindow::OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget target)
FileUtil::GetUserPath(target == EmulatedDirectoryTarget::SDMC ? FileUtil::UserPath::SDMCDir
: FileUtil::UserPath::NANDDir,
dir_path.toStdString());
- Service::FileSystem::CreateFactories(vfs);
+ Service::FileSystem::CreateFactories(*vfs);
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
}
}
@@ -1375,6 +1379,86 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
}
}
+void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
+ if (behavior == ReinitializeKeyBehavior::Warning) {
+ const auto res = QMessageBox::information(
+ this, tr("Confirm Key Rederivation"),
+ tr("You are about to force rederive all of your keys. \nIf you do not know what this "
+ "means or what you are doing, \nthis is a potentially destructive action. \nPlease "
+ "make "
+ "sure this is what you want \nand optionally make backups.\n\nThis will delete your "
+ "autogenerated key files and re-run the key derivation module."),
+ QMessageBox::StandardButtons{QMessageBox::Ok, QMessageBox::Cancel});
+
+ if (res == QMessageBox::Cancel)
+ return;
+
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "prod.keys_autogenerated");
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "console.keys_autogenerated");
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "title.keys_autogenerated");
+ }
+
+ Core::Crypto::KeyManager keys{};
+ if (keys.BaseDeriveNecessary()) {
+ Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory(
+ FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};
+
+ const auto function = [this, &keys, &pdm] {
+ keys.PopulateFromPartitionData(pdm);
+ Service::FileSystem::CreateFactories(*vfs);
+ keys.DeriveETicket(pdm);
+ };
+
+ QString errors;
+
+ if (!pdm.HasFuses())
+ errors += tr("- Missing fuses - Cannot derive SBK\n");
+ if (!pdm.HasBoot0())
+ errors += tr("- Missing BOOT0 - Cannot derive master keys\n");
+ if (!pdm.HasPackage2())
+ errors += tr("- Missing BCPKG2-1-Normal-Main - Cannot derive general keys\n");
+ if (!pdm.HasProdInfo())
+ errors += tr("- Missing PRODINFO - Cannot derive title keys\n");
+
+ if (!errors.isEmpty()) {
+
+ QMessageBox::warning(
+ this, tr("Warning Missing Derivation Components"),
+ tr("The following are missing from your configuration that may hinder key "
+ "derivation. It will be attempted but may not complete.<br><br>") +
+ errors +
+ tr("<br><br>You can get all of these and dump all of your games easily by "
+ "following <a href='https://yuzu-emu.org/help/quickstart/quickstart/'>the "
+ "quickstart guide</a>. Alternatively, you can use another method of dumping "
+ "to obtain all of your keys."));
+ }
+
+ QProgressDialog prog;
+ prog.setRange(0, 0);
+ prog.setLabelText(tr("Deriving keys...\nThis may take up to a minute depending \non your "
+ "system's performance."));
+ prog.setWindowTitle(tr("Deriving Keys"));
+
+ prog.show();
+
+ auto future = QtConcurrent::run(function);
+ while (!future.isFinished()) {
+ QCoreApplication::processEvents();
+ }
+
+ prog.close();
+ }
+
+ Service::FileSystem::CreateFactories(*vfs);
+
+ if (behavior == ReinitializeKeyBehavior::Warning) {
+ game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
+ }
+}
+
bool GMainWindow::ConfirmClose() {
if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
return true;
@@ -1483,7 +1567,7 @@ void GMainWindow::UpdateUITheme() {
emit UpdateThemedIcons();
}
-void GMainWindow::SetDiscordEnabled(bool state) {
+void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
#ifdef USE_DISCORD_PRESENCE
if (state) {
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>();