mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-03 00:38:58 +00:00
Removed special case handling for system archives & safe mode firm
This commit is contained in:
+17
-125
@@ -142,8 +142,6 @@ bool SDMCImporter::ImportContentImpl(const ContentSpecifier& specifier,
|
|||||||
} else {
|
} else {
|
||||||
return ImportNandExtdata(specifier.id, callback);
|
return ImportNandExtdata(specifier.id, callback);
|
||||||
}
|
}
|
||||||
case ContentType::SystemArchive:
|
|
||||||
return ImportSystemArchive(specifier.id, callback);
|
|
||||||
case ContentType::Sysdata:
|
case ContentType::Sysdata:
|
||||||
return ImportSysdata(specifier.id, callback);
|
return ImportSysdata(specifier.id, callback);
|
||||||
case ContentType::SystemTitle:
|
case ContentType::SystemTitle:
|
||||||
@@ -299,30 +297,6 @@ bool SDMCImporter::ImportNandExtdata(u64 id,
|
|||||||
"data/00000000000000000000000000000000/" + path);
|
"data/00000000000000000000000000000000/" + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDMCImporter::ImportSystemArchive(u64 id,
|
|
||||||
[[maybe_unused]] const Common::ProgressCallback& callback) {
|
|
||||||
const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path, (id >> 32),
|
|
||||||
(id & 0xFFFFFFFF));
|
|
||||||
FileUtil::IOFile file(path, "rb");
|
|
||||||
std::vector<u8> data = file.GetData();
|
|
||||||
if (data.empty()) {
|
|
||||||
LOG_ERROR(Core, "Failed to read from {}", path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& romfs = LoadSharedRomFS(data);
|
|
||||||
|
|
||||||
const auto target_path = fmt::format(
|
|
||||||
"{}00000000000000000000000000000000/title/{:08x}/{:08x}/content/00000000.app.romfs",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (id >> 32), (id & 0xFFFFFFFF));
|
|
||||||
if (!FileUtil::CreateFullPath(target_path)) {
|
|
||||||
LOG_ERROR(Core, "Could not create path {}", target_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileUtil::WriteBytesToFile(target_path, romfs.data(), romfs.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDMCImporter::ImportSysdata(u64 id,
|
bool SDMCImporter::ImportSysdata(u64 id,
|
||||||
[[maybe_unused]] const Common::ProgressCallback& callback) {
|
[[maybe_unused]] const Common::ProgressCallback& callback) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
@@ -334,36 +308,6 @@ bool SDMCImporter::ImportSysdata(u64 id,
|
|||||||
}
|
}
|
||||||
return FileUtil::Copy(config.bootrom_path, target_path);
|
return FileUtil::Copy(config.bootrom_path, target_path);
|
||||||
}
|
}
|
||||||
case 1: { // safe mode firm
|
|
||||||
// Our GM9 script dumps to different folders for different version (new/old)
|
|
||||||
std::string real_path;
|
|
||||||
bool is_new_3ds = false;
|
|
||||||
if (FileUtil::Exists(config.safe_mode_firm_path + "new/")) {
|
|
||||||
real_path = config.safe_mode_firm_path + "new/";
|
|
||||||
is_new_3ds = true;
|
|
||||||
} else {
|
|
||||||
real_path = config.safe_mode_firm_path + "old/";
|
|
||||||
}
|
|
||||||
return FileUtil::ForeachDirectoryEntry(
|
|
||||||
nullptr, real_path,
|
|
||||||
[is_new_3ds](u64* /*num_entries_out*/, const std::string& directory,
|
|
||||||
const std::string& virtual_name) {
|
|
||||||
if (FileUtil::IsDirectory(directory + virtual_name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto target_path =
|
|
||||||
fmt::format("{}00000000000000000000000000000000/title/00040138/{}/content/{}",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir),
|
|
||||||
(is_new_3ds ? "20000003" : "00000003"), virtual_name);
|
|
||||||
|
|
||||||
if (!FileUtil::CreateFullPath(target_path)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileUtil::Copy(directory + virtual_name, target_path);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
case 2: { // seed db
|
case 2: { // seed db
|
||||||
const auto target_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + SEED_DB;
|
const auto target_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + SEED_DB;
|
||||||
LOG_INFO(Core, "Dumping SeedDB from {} to {}", SEED_DB, config.seed_db_path, target_path);
|
LOG_INFO(Core, "Dumping SeedDB from {} to {}", SEED_DB, config.seed_db_path, target_path);
|
||||||
@@ -453,7 +397,6 @@ std::vector<ContentSpecifier> SDMCImporter::ListContent() const {
|
|||||||
ListNandTitle(content_list);
|
ListNandTitle(content_list);
|
||||||
ListNandSavegame(content_list);
|
ListNandSavegame(content_list);
|
||||||
ListExtdata(content_list);
|
ListExtdata(content_list);
|
||||||
ListSystemArchive(content_list);
|
|
||||||
ListSysdata(content_list);
|
ListSysdata(content_list);
|
||||||
return content_list;
|
return content_list;
|
||||||
}
|
}
|
||||||
@@ -558,11 +501,24 @@ std::shared_ptr<FileUtil::IOFile> SDMCImporter::OpenContent(const ContentSpecifi
|
|||||||
using TitleData = std::tuple<std::string, u64, std::vector<u16>>;
|
using TitleData = std::tuple<std::string, u64, std::vector<u16>>;
|
||||||
|
|
||||||
static TitleData LoadTitleData(NCCHContainer& ncch) {
|
static TitleData LoadTitleData(NCCHContainer& ncch) {
|
||||||
std::string codeset_name;
|
static const std::unordered_map<u64, const char*> NamedTitles{{
|
||||||
ncch.ReadCodesetName(codeset_name);
|
{0x0004009b'00010202, "Mii Data"},
|
||||||
|
{0x0004009b'00010402, "Region Manifest"},
|
||||||
|
{0x0004009b'00014002, "Shared Font (JPN/EUR/USA)"},
|
||||||
|
{0x0004009b'00014102, "Shared Font (CHN)"},
|
||||||
|
{0x0004009b'00014202, "Shared Font (KOR)"},
|
||||||
|
{0x0004009b'00014302, "Shared Font (TWN)"},
|
||||||
|
{0x000400db'00010302, "Bad word list"},
|
||||||
|
}};
|
||||||
|
|
||||||
u64 program_id{};
|
u64 program_id{};
|
||||||
ncch.ReadProgramId(program_id);
|
ncch.ReadProgramId(program_id);
|
||||||
|
if (NamedTitles.count(program_id)) {
|
||||||
|
return TitleData{NamedTitles.at(program_id), 0, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string codeset_name;
|
||||||
|
ncch.ReadCodesetName(codeset_name);
|
||||||
|
|
||||||
std::string title_name_from_codeset;
|
std::string title_name_from_codeset;
|
||||||
if (!codeset_name.empty()) {
|
if (!codeset_name.empty()) {
|
||||||
@@ -983,8 +939,10 @@ void SDMCImporter::ListNandTitle(std::vector<ContentSpecifier>& out) const {
|
|||||||
ProcessDirectory(0x00040010);
|
ProcessDirectory(0x00040010);
|
||||||
ProcessDirectory(0x0004001b);
|
ProcessDirectory(0x0004001b);
|
||||||
ProcessDirectory(0x00040030);
|
ProcessDirectory(0x00040030);
|
||||||
|
ProcessDirectory(0x0004009b);
|
||||||
ProcessDirectory(0x000400db);
|
ProcessDirectory(0x000400db);
|
||||||
ProcessDirectory(0x00040130);
|
ProcessDirectory(0x00040130);
|
||||||
|
ProcessDirectory(0x00040138);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::ListNandSavegame(std::vector<ContentSpecifier>& out) const {
|
void SDMCImporter::ListNandSavegame(std::vector<ContentSpecifier>& out) const {
|
||||||
@@ -1059,30 +1017,6 @@ void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
|||||||
"data/00000000000000000000000000000000/extdata/00048000/{}");
|
"data/00000000000000000000000000000000/extdata/00048000/{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::ListSystemArchive(std::vector<ContentSpecifier>& out) const {
|
|
||||||
constexpr std::array<std::pair<u64, const char*>, 8> SystemArchives{{
|
|
||||||
{0x0004009b'00010202, "Mii Data"},
|
|
||||||
{0x0004009b'00010402, "Region Manifest"},
|
|
||||||
{0x0004009b'00014002, "Shared Font (JPN/EUR/USA)"},
|
|
||||||
{0x0004009b'00014102, "Shared Font (CHN)"},
|
|
||||||
{0x0004009b'00014202, "Shared Font (KOR)"},
|
|
||||||
{0x0004009b'00014302, "Shared Font (TWN)"},
|
|
||||||
{0x000400db'00010302, "Bad word list"},
|
|
||||||
}};
|
|
||||||
|
|
||||||
for (const auto& [id, name] : SystemArchives) {
|
|
||||||
const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path,
|
|
||||||
(id >> 32), (id & 0xFFFFFFFF));
|
|
||||||
if (FileUtil::Exists(path)) {
|
|
||||||
const auto target_path = fmt::format(
|
|
||||||
"{}00000000000000000000000000000000/title/{:08x}/{:08x}/content/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (id >> 32), (id & 0xFFFFFFFF));
|
|
||||||
out.push_back({ContentType::SystemArchive, id, FileUtil::Exists(target_path),
|
|
||||||
FileUtil::GetSize(path), name});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDMCImporter::ListSysdata(std::vector<ContentSpecifier>& out) const {
|
void SDMCImporter::ListSysdata(std::vector<ContentSpecifier>& out) const {
|
||||||
const auto CheckContent = [&out](u64 id, const std::string& var_path,
|
const auto CheckContent = [&out](u64 id, const std::string& var_path,
|
||||||
const std::string& citra_path,
|
const std::string& citra_path,
|
||||||
@@ -1111,30 +1045,6 @@ void SDMCImporter::ListSysdata(std::vector<ContentSpecifier>& out) const {
|
|||||||
"Config savegame");
|
"Config savegame");
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
if (config.safe_mode_firm_path.empty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_new = false;
|
|
||||||
if (FileUtil::Exists(config.safe_mode_firm_path + "new/")) {
|
|
||||||
is_new = true;
|
|
||||||
}
|
|
||||||
if (!is_new && !FileUtil::Exists(config.safe_mode_firm_path + "old/")) {
|
|
||||||
LOG_ERROR(Core, "Safe mode firm path specified but not found");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto citra_path = fmt::format(
|
|
||||||
"{}00000000000000000000000000000000/title/00040138/{}/content/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (is_new ? "20000003" : "00000003"));
|
|
||||||
if (!config.safe_mode_firm_path.empty()) {
|
|
||||||
out.push_back({ContentType::Sysdata, 1, FileUtil::Exists(citra_path),
|
|
||||||
FileUtil::GetDirectoryTreeSize(config.safe_mode_firm_path),
|
|
||||||
"Safe mode firm"});
|
|
||||||
}
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
// Check for seeddb
|
// Check for seeddb
|
||||||
if (config.seed_db_path.empty()) {
|
if (config.seed_db_path.empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -1174,8 +1084,6 @@ void SDMCImporter::DeleteContent(const ContentSpecifier& specifier) const {
|
|||||||
return DeleteSavegame(specifier.id);
|
return DeleteSavegame(specifier.id);
|
||||||
case ContentType::Extdata:
|
case ContentType::Extdata:
|
||||||
return DeleteExtdata(specifier.id);
|
return DeleteExtdata(specifier.id);
|
||||||
case ContentType::SystemArchive:
|
|
||||||
return DeleteSystemArchive(specifier.id);
|
|
||||||
case ContentType::Sysdata:
|
case ContentType::Sysdata:
|
||||||
return DeleteSysdata(specifier.id);
|
return DeleteSysdata(specifier.id);
|
||||||
case ContentType::SystemTitle:
|
case ContentType::SystemTitle:
|
||||||
@@ -1228,25 +1136,11 @@ void SDMCImporter::DeleteExtdata(u64 id) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::DeleteSystemArchive(u64 id) const {
|
|
||||||
FileUtil::DeleteDirRecursively(fmt::format(
|
|
||||||
"{}00000000000000000000000000000000/title/{:08x}/{:08x}/content/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (id >> 32), (id & 0xFFFFFFFF)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDMCImporter::DeleteSysdata(u64 id) const {
|
void SDMCImporter::DeleteSysdata(u64 id) const {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 0: { // boot9.bin
|
case 0: { // boot9.bin
|
||||||
FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + BOOTROM9);
|
FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + BOOTROM9);
|
||||||
}
|
}
|
||||||
case 1: { // safe mode firm
|
|
||||||
const bool is_new_3ds = FileUtil::Exists(config.safe_mode_firm_path + "new/");
|
|
||||||
const auto target_path =
|
|
||||||
fmt::format("{}00000000000000000000000000000000/title/00040138/{}/",
|
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir),
|
|
||||||
(is_new_3ds ? "20000003" : "00000003"));
|
|
||||||
FileUtil::DeleteDirRecursively(target_path);
|
|
||||||
}
|
|
||||||
case 2: { // seed db
|
case 2: { // seed db
|
||||||
FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + SEED_DB);
|
FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + SEED_DB);
|
||||||
}
|
}
|
||||||
@@ -1291,11 +1185,9 @@ std::vector<Config> LoadPresetConfig(std::string mount_point) {
|
|||||||
LOAD_DATA(certs_db_path, CERTS_DB);
|
LOAD_DATA(certs_db_path, CERTS_DB);
|
||||||
LOAD_DATA(nand_title_db_path, TITLE_DB);
|
LOAD_DATA(nand_title_db_path, TITLE_DB);
|
||||||
LOAD_DATA(ticket_db_path, TICKET_DB);
|
LOAD_DATA(ticket_db_path, TICKET_DB);
|
||||||
LOAD_DATA(safe_mode_firm_path, "firm/");
|
|
||||||
LOAD_DATA(seed_db_path, SEED_DB);
|
LOAD_DATA(seed_db_path, SEED_DB);
|
||||||
LOAD_DATA(secret_sector_path, SECRET_SECTOR);
|
LOAD_DATA(secret_sector_path, SECRET_SECTOR);
|
||||||
LOAD_DATA(config_savegame_path, "config.sav");
|
LOAD_DATA(config_savegame_path, "config.sav");
|
||||||
LOAD_DATA(system_archives_path, "sysarchives/");
|
|
||||||
LOAD_DATA(system_titles_path, "title/");
|
LOAD_DATA(system_titles_path, "title/");
|
||||||
LOAD_DATA(nand_data_path, "data/");
|
LOAD_DATA(nand_data_path, "data/");
|
||||||
#undef LOAD_DATA
|
#undef LOAD_DATA
|
||||||
|
|||||||
+1
-7
@@ -31,7 +31,6 @@ enum class ContentType {
|
|||||||
DLC,
|
DLC,
|
||||||
Savegame,
|
Savegame,
|
||||||
Extdata,
|
Extdata,
|
||||||
SystemArchive,
|
|
||||||
Sysdata,
|
Sysdata,
|
||||||
SystemTitle,
|
SystemTitle,
|
||||||
SystemApplet, // This should belong to System Title, but they cause problems so a new category.
|
SystemApplet, // This should belong to System Title, but they cause problems so a new category.
|
||||||
@@ -75,18 +74,16 @@ struct Config {
|
|||||||
// Optional, used while building CIA, but usually missing these files won't hinder CIA building.
|
// Optional, used while building CIA, but usually missing these files won't hinder CIA building.
|
||||||
std::string nand_title_db_path; ///< Path to NAND title.db. Entirely optional.
|
std::string nand_title_db_path; ///< Path to NAND title.db. Entirely optional.
|
||||||
std::string ticket_db_path; ///< Path to ticket.db. Entirely optional.
|
std::string ticket_db_path; ///< Path to ticket.db. Entirely optional.
|
||||||
std::string enc_title_keys_bin_path; ///< Path to encTitleKeys.bin. Entireley optional.
|
std::string enc_title_keys_bin_path; ///< Path to encTitleKeys.bin. Entirely optional.
|
||||||
|
|
||||||
// The following system files are optional for importing and are only copied so that Citra
|
// The following system files are optional for importing and are only copied so that Citra
|
||||||
// will be able to decrypt imported encrypted ROMs.
|
// will be able to decrypt imported encrypted ROMs.
|
||||||
|
|
||||||
std::string safe_mode_firm_path; ///< Path to safe mode firm (A folder) (Sysdata 1)
|
|
||||||
std::string seed_db_path; ///< Path to seeddb.bin (Sysdata 2)
|
std::string seed_db_path; ///< Path to seeddb.bin (Sysdata 2)
|
||||||
std::string secret_sector_path; ///< Path to secret sector (New3DS only) (Sysdata 3)
|
std::string secret_sector_path; ///< Path to secret sector (New3DS only) (Sysdata 3)
|
||||||
// Note: Sysdata 4 is aes_keys.txt (slot0x25KeyX)
|
// Note: Sysdata 4 is aes_keys.txt (slot0x25KeyX)
|
||||||
std::string config_savegame_path; ///< Path to config savegame (Sysdata 5)
|
std::string config_savegame_path; ///< Path to config savegame (Sysdata 5)
|
||||||
|
|
||||||
std::string system_archives_path; ///< Path to system archives.
|
|
||||||
std::string system_titles_path; ///< Path to system titles.
|
std::string system_titles_path; ///< Path to system titles.
|
||||||
std::string nand_data_path; ///< Path to NAND data. (Extdata and savedata)
|
std::string nand_data_path; ///< Path to NAND data. (Extdata and savedata)
|
||||||
|
|
||||||
@@ -201,14 +198,12 @@ private:
|
|||||||
bool ImportNandSavegame(u64 id, const Common::ProgressCallback& callback);
|
bool ImportNandSavegame(u64 id, const Common::ProgressCallback& callback);
|
||||||
bool ImportExtdata(u64 id, const Common::ProgressCallback& callback);
|
bool ImportExtdata(u64 id, const Common::ProgressCallback& callback);
|
||||||
bool ImportNandExtdata(u64 id, const Common::ProgressCallback& callback);
|
bool ImportNandExtdata(u64 id, const Common::ProgressCallback& callback);
|
||||||
bool ImportSystemArchive(u64 id, const Common::ProgressCallback& callback);
|
|
||||||
bool ImportSysdata(u64 id, const Common::ProgressCallback& callback);
|
bool ImportSysdata(u64 id, const Common::ProgressCallback& callback);
|
||||||
|
|
||||||
void ListTitle(std::vector<ContentSpecifier>& out) const;
|
void ListTitle(std::vector<ContentSpecifier>& out) const;
|
||||||
void ListNandTitle(std::vector<ContentSpecifier>& out) const;
|
void ListNandTitle(std::vector<ContentSpecifier>& out) const;
|
||||||
void ListNandSavegame(std::vector<ContentSpecifier>& out) const;
|
void ListNandSavegame(std::vector<ContentSpecifier>& out) const;
|
||||||
void ListExtdata(std::vector<ContentSpecifier>& out) const;
|
void ListExtdata(std::vector<ContentSpecifier>& out) const;
|
||||||
void ListSystemArchive(std::vector<ContentSpecifier>& out) const;
|
|
||||||
void ListSysdata(std::vector<ContentSpecifier>& out) const;
|
void ListSysdata(std::vector<ContentSpecifier>& out) const;
|
||||||
|
|
||||||
void DeleteContent(const ContentSpecifier& specifier) const;
|
void DeleteContent(const ContentSpecifier& specifier) const;
|
||||||
@@ -216,7 +211,6 @@ private:
|
|||||||
void DeleteNandTitle(u64 id) const;
|
void DeleteNandTitle(u64 id) const;
|
||||||
void DeleteSavegame(u64 id) const;
|
void DeleteSavegame(u64 id) const;
|
||||||
void DeleteExtdata(u64 id) const;
|
void DeleteExtdata(u64 id) const;
|
||||||
void DeleteSystemArchive(u64 id) const;
|
|
||||||
void DeleteSysdata(u64 id) const;
|
void DeleteSysdata(u64 id) const;
|
||||||
|
|
||||||
bool is_good{};
|
bool is_good{};
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ static constexpr std::array<std::tuple<Core::ContentType, const char*, const cha
|
|||||||
{Core::ContentType::DLC, QT_TR_NOOP("DLC"), QT_TR_NOOP("DLCs"), "dlc"},
|
{Core::ContentType::DLC, QT_TR_NOOP("DLC"), QT_TR_NOOP("DLCs"), "dlc"},
|
||||||
{Core::ContentType::Savegame, QT_TR_NOOP("Save Data"), QT_TR_NOOP("Save Data"), "save_data"},
|
{Core::ContentType::Savegame, QT_TR_NOOP("Save Data"), QT_TR_NOOP("Save Data"), "save_data"},
|
||||||
{Core::ContentType::Extdata, QT_TR_NOOP("Extra Data"), QT_TR_NOOP("Extra Data"), "save_data"},
|
{Core::ContentType::Extdata, QT_TR_NOOP("Extra Data"), QT_TR_NOOP("Extra Data"), "save_data"},
|
||||||
{Core::ContentType::SystemArchive, QT_TR_NOOP("System Archive"), QT_TR_NOOP("System Archives"), "system_archive"},
|
|
||||||
{Core::ContentType::Sysdata, QT_TR_NOOP("System Data"), QT_TR_NOOP("System Data"), "system_data"},
|
{Core::ContentType::Sysdata, QT_TR_NOOP("System Data"), QT_TR_NOOP("System Data"), "system_data"},
|
||||||
{Core::ContentType::SystemTitle, QT_TR_NOOP("System Title"), QT_TR_NOOP("System Titles"), "hos"},
|
{Core::ContentType::SystemTitle, QT_TR_NOOP("System Title"), QT_TR_NOOP("System Titles"), "hos"},
|
||||||
{Core::ContentType::SystemApplet, QT_TR_NOOP("System Applet"), QT_TR_NOOP("System Applets"), "hos"},
|
{Core::ContentType::SystemApplet, QT_TR_NOOP("System Applet"), QT_TR_NOOP("System Applets"), "hos"},
|
||||||
@@ -213,8 +212,7 @@ void ImportDialog::InsertTopLevelItem(QString text, QPixmap icon, u64 total_size
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Content types that themselves form a 'Title' like entity.
|
// Content types that themselves form a 'Title' like entity.
|
||||||
constexpr std::array<Core::ContentType, 4> SpecialContentTypeList{{
|
constexpr std::array<Core::ContentType, 3> SpecialContentTypeList{{
|
||||||
Core::ContentType::SystemArchive,
|
|
||||||
Core::ContentType::Sysdata,
|
Core::ContentType::Sysdata,
|
||||||
Core::ContentType::SystemTitle,
|
Core::ContentType::SystemTitle,
|
||||||
Core::ContentType::SystemApplet,
|
Core::ContentType::SystemApplet,
|
||||||
@@ -255,9 +253,8 @@ void ImportDialog::InsertSecondLevelItem(std::size_t row, const Core::ContentSpe
|
|||||||
content.type != Core::ContentType::SystemApplet) {
|
content.type != Core::ContentType::SystemApplet) {
|
||||||
icon = GetContentTypeIcon(content.type);
|
icon = GetContentTypeIcon(content.type);
|
||||||
} else {
|
} else {
|
||||||
// When not in title view, System Data and System Archive groups use category icons.
|
// When not in title view, System Data groups use category icons.
|
||||||
const bool use_category_icon = content.type == Core::ContentType::Sysdata ||
|
const bool use_category_icon = content.type == Core::ContentType::Sysdata;
|
||||||
content.type == Core::ContentType::SystemArchive;
|
|
||||||
icon = GetContentIcon(content, use_category_icon);
|
icon = GetContentIcon(content, use_category_icon);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -296,8 +293,7 @@ void ImportDialog::OnItemChanged(QTreeWidgetItem* item, int column) {
|
|||||||
total_selected_size += specifier.maximum_size;
|
total_selected_size += specifier.maximum_size;
|
||||||
} else {
|
} else {
|
||||||
if (!system_warning_shown && !specifier.already_exists &&
|
if (!system_warning_shown && !specifier.already_exists &&
|
||||||
(specifier.type == Core::ContentType::SystemArchive ||
|
(specifier.type == Core::ContentType::Sysdata ||
|
||||||
specifier.type == Core::ContentType::Sysdata ||
|
|
||||||
specifier.type == Core::ContentType::SystemTitle)) {
|
specifier.type == Core::ContentType::SystemTitle)) {
|
||||||
|
|
||||||
QMessageBox::warning(this, tr("Warning"),
|
QMessageBox::warning(this, tr("Warning"),
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ bool IsConfigGood(const Core::Config& config) {
|
|||||||
!config.movable_sed_path.empty() && !config.bootrom_path.empty();
|
!config.movable_sed_path.empty() && !config.bootrom_path.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsConfigComplete(const Core::Config& config) {
|
||||||
|
return IsConfigGood(config) && !config.certs_db_path.empty() &&
|
||||||
|
!config.nand_title_db_path.empty() && !config.ticket_db_path.empty() &&
|
||||||
|
!config.config_savegame_path.empty() && !config.system_titles_path.empty() &&
|
||||||
|
!config.nand_data_path.empty();
|
||||||
|
}
|
||||||
|
|
||||||
MainDialog::MainDialog(QWidget* parent)
|
MainDialog::MainDialog(QWidget* parent)
|
||||||
: DPIAwareDialog(parent, 640, 256), ui(std::make_unique<Ui::MainDialog>()) {
|
: DPIAwareDialog(parent, 640, 256), ui(std::make_unique<Ui::MainDialog>()) {
|
||||||
|
|
||||||
@@ -145,10 +152,7 @@ void MainDialog::LoadPresetConfig() {
|
|||||||
status = tr("No Configuration Found");
|
status = tr("No Configuration Found");
|
||||||
} else if (list[i].version != Core::CurrentDumperVersion) {
|
} else if (list[i].version != Core::CurrentDumperVersion) {
|
||||||
status = tr("Version Dismatch");
|
status = tr("Version Dismatch");
|
||||||
} else if (list[i].safe_mode_firm_path.empty() ||
|
} else if (!IsConfigComplete(list[i])) {
|
||||||
list[i].config_savegame_path.empty() ||
|
|
||||||
list[i].system_archives_path.empty()) {
|
|
||||||
|
|
||||||
status = tr("Missing System Files");
|
status = tr("Missing System Files");
|
||||||
} else if (list[i].seed_db_path.empty()) {
|
} else if (list[i].seed_db_path.empty()) {
|
||||||
status = tr("Good, Missing Seeds");
|
status = tr("Good, Missing Seeds");
|
||||||
@@ -217,8 +221,7 @@ void MainDialog::LaunchImportDialog() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.safe_mode_firm_path.empty() || config.config_savegame_path.empty() ||
|
if (!IsConfigComplete(config)) {
|
||||||
config.system_archives_path.empty()) {
|
|
||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
this, tr("Warning"),
|
this, tr("Warning"),
|
||||||
tr("Certain system files are missing from your configuration.<br>Some contents "
|
tr("Certain system files are missing from your configuration.<br>Some contents "
|
||||||
|
|||||||
Reference in New Issue
Block a user