main: Prevent installing base titles into NAND
Many users have been installing their base titles into NAND instead of adding them into the games list. This prevents users from installing any base titles and warns the user about the action.
This commit is contained in:
parent
9edfd88a8a
commit
a170aa16b6
4 changed files with 28 additions and 3 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
|
#include "core/file_sys/common_funcs.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
#include "core/file_sys/nca_metadata.h"
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
@ -592,6 +593,12 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
|
||||||
const CNMT cnmt(cnmt_file);
|
const CNMT cnmt(cnmt_file);
|
||||||
|
|
||||||
const auto title_id = cnmt.GetTitleID();
|
const auto title_id = cnmt.GetTitleID();
|
||||||
|
const auto version = cnmt.GetTitleVersion();
|
||||||
|
|
||||||
|
if (title_id == GetBaseTitleID(title_id) && version == 0) {
|
||||||
|
return InstallResult::ErrorBaseInstall;
|
||||||
|
}
|
||||||
|
|
||||||
const auto result = RemoveExistingEntry(title_id);
|
const auto result = RemoveExistingEntry(title_id);
|
||||||
|
|
||||||
// Install Metadata File
|
// Install Metadata File
|
||||||
|
|
|
@ -38,6 +38,7 @@ enum class InstallResult {
|
||||||
ErrorAlreadyExists,
|
ErrorAlreadyExists,
|
||||||
ErrorCopyFailed,
|
ErrorCopyFailed,
|
||||||
ErrorMetaFailed,
|
ErrorMetaFailed,
|
||||||
|
ErrorBaseInstall,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContentProviderEntry {
|
struct ContentProviderEntry {
|
||||||
|
|
|
@ -2101,6 +2101,7 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
QStringList new_files{}; // Newly installed files that do not yet exist in the NAND
|
QStringList new_files{}; // Newly installed files that do not yet exist in the NAND
|
||||||
QStringList overwritten_files{}; // Files that overwrote those existing in the NAND
|
QStringList overwritten_files{}; // Files that overwrote those existing in the NAND
|
||||||
QStringList failed_files{}; // Files that failed to install due to errors
|
QStringList failed_files{}; // Files that failed to install due to errors
|
||||||
|
bool detected_base_install{}; // Whether a base game was attempted to be installed
|
||||||
|
|
||||||
ui.action_Install_File_NAND->setEnabled(false);
|
ui.action_Install_File_NAND->setEnabled(false);
|
||||||
|
|
||||||
|
@ -2126,6 +2127,7 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
|
|
||||||
while (!future.isFinished()) {
|
while (!future.isFinished()) {
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = future.result();
|
result = future.result();
|
||||||
|
@ -2146,6 +2148,10 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
case InstallResult::Failure:
|
case InstallResult::Failure:
|
||||||
failed_files.append(QFileInfo(file).fileName());
|
failed_files.append(QFileInfo(file).fileName());
|
||||||
break;
|
break;
|
||||||
|
case InstallResult::BaseInstallAttempted:
|
||||||
|
failed_files.append(QFileInfo(file).fileName());
|
||||||
|
detected_base_install = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
--remaining;
|
--remaining;
|
||||||
|
@ -2153,6 +2159,13 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
|
|
||||||
install_progress->close();
|
install_progress->close();
|
||||||
|
|
||||||
|
if (detected_base_install) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Install Results"),
|
||||||
|
tr("To avoid possible conflicts, we discourage users from installing base games to the "
|
||||||
|
"NAND.\nPlease, only use this feature to install updates and DLC."));
|
||||||
|
}
|
||||||
|
|
||||||
const QString install_results =
|
const QString install_results =
|
||||||
(new_files.isEmpty() ? QString{}
|
(new_files.isEmpty() ? QString{}
|
||||||
: tr("%n file(s) were newly installed\n", "", new_files.size())) +
|
: tr("%n file(s) were newly installed\n", "", new_files.size())) +
|
||||||
|
@ -2214,11 +2227,14 @@ InstallResult GMainWindow::InstallNSPXCI(const QString& filename) {
|
||||||
const auto res =
|
const auto res =
|
||||||
Core::System::GetInstance().GetFileSystemController().GetUserNANDContents()->InstallEntry(
|
Core::System::GetInstance().GetFileSystemController().GetUserNANDContents()->InstallEntry(
|
||||||
*nsp, true, qt_raw_copy);
|
*nsp, true, qt_raw_copy);
|
||||||
if (res == FileSys::InstallResult::Success) {
|
switch (res) {
|
||||||
|
case FileSys::InstallResult::Success:
|
||||||
return InstallResult::Success;
|
return InstallResult::Success;
|
||||||
} else if (res == FileSys::InstallResult::OverwriteExisting) {
|
case FileSys::InstallResult::OverwriteExisting:
|
||||||
return InstallResult::Overwrite;
|
return InstallResult::Overwrite;
|
||||||
} else {
|
case FileSys::InstallResult::ErrorBaseInstall:
|
||||||
|
return InstallResult::BaseInstallAttempted;
|
||||||
|
default:
|
||||||
return InstallResult::Failure;
|
return InstallResult::Failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ enum class InstallResult {
|
||||||
Success,
|
Success,
|
||||||
Overwrite,
|
Overwrite,
|
||||||
Failure,
|
Failure,
|
||||||
|
BaseInstallAttempted,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ReinitializeKeyBehavior {
|
enum class ReinitializeKeyBehavior {
|
||||||
|
|
Loading…
Reference in a new issue