mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-03 00:38:58 +00:00
Add system archives import
This commit is contained in:
@@ -72,6 +72,8 @@ bool SDMCImporter::ImportContent(const ContentSpecifier& specifier,
|
||||
return ImportSavegame(specifier.id, callback);
|
||||
case ContentType::Extdata:
|
||||
return ImportExtdata(specifier.id, callback);
|
||||
case ContentType::SystemArchive:
|
||||
return ImportSystemArchive(specifier.id, callback);
|
||||
case ContentType::Sysdata:
|
||||
return ImportSysdata(specifier.id, callback);
|
||||
default:
|
||||
@@ -128,6 +130,45 @@ bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback
|
||||
"Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path);
|
||||
}
|
||||
|
||||
bool SDMCImporter::ImportSystemArchive(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||
const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path, (id >> 32),
|
||||
(id & 0xFFFFFFFF));
|
||||
FileUtil::IOFile file(path, "rb");
|
||||
if (!file) {
|
||||
LOG_ERROR(Core, "Could not open {}", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<u8> data(file.GetSize());
|
||||
if (file.ReadBytes(data.data(), data.size()) != data.size()) {
|
||||
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;
|
||||
}
|
||||
|
||||
FileUtil::IOFile target(target_path, "wb");
|
||||
if (!target) {
|
||||
LOG_ERROR(Core, "Could not open {}", target_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.WriteBytes(romfs.data(), romfs.size()) != romfs.size()) {
|
||||
LOG_ERROR(Core, "Failed to write to {}", target_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDMCImporter::ImportSysdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||
switch (id) {
|
||||
case 0: { // boot9.bin
|
||||
@@ -207,6 +248,7 @@ std::vector<ContentSpecifier> SDMCImporter::ListContent() const {
|
||||
std::vector<ContentSpecifier> content_list;
|
||||
ListTitle(content_list);
|
||||
ListExtdata(content_list);
|
||||
ListSystemArchive(content_list);
|
||||
ListSysdata(content_list);
|
||||
return content_list;
|
||||
}
|
||||
@@ -361,6 +403,30 @@ void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
||||
});
|
||||
}
|
||||
|
||||
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 {
|
||||
#define CHECK_CONTENT(id, var_path, citra_path, display_name) \
|
||||
if (!var_path.empty()) { \
|
||||
@@ -418,6 +484,8 @@ void SDMCImporter::DeleteContent(const ContentSpecifier& specifier) {
|
||||
return DeleteSavegame(specifier.id);
|
||||
case ContentType::Extdata:
|
||||
return DeleteExtdata(specifier.id);
|
||||
case ContentType::SystemArchive:
|
||||
return DeleteSystemArchive(specifier.id);
|
||||
case ContentType::Sysdata:
|
||||
return DeleteSysdata(specifier.id);
|
||||
default:
|
||||
@@ -449,6 +517,12 @@ void SDMCImporter::DeleteExtdata(u64 id) const {
|
||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), (id >> 32), (id & 0xFFFFFFFF)));
|
||||
}
|
||||
|
||||
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 {
|
||||
switch (id) {
|
||||
case 0: { // boot9.bin
|
||||
@@ -501,6 +575,7 @@ std::vector<Config> LoadPresetConfig(std::string mount_point) {
|
||||
LOAD_DATA(safe_mode_firm_path, "firm/");
|
||||
LOAD_DATA(seed_db_path, SEED_DB);
|
||||
LOAD_DATA(secret_sector_path, SECRET_SECTOR);
|
||||
LOAD_DATA(system_archives_path, "sysarchives/");
|
||||
#undef LOAD_DATA
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user