mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-03 00:38:58 +00:00
core: Add NAND data importing
This commit is contained in:
Vendored
+19
-1
@@ -117,6 +117,24 @@ decrypt $[OUT]/sysarchives/000400db/00010302.app
|
|||||||
# === Config savegame
|
# === Config savegame
|
||||||
cp -w -n 1:/data/$[SYSID0]/sysdata/00010017/00000000 $[OUT]/config.sav
|
cp -w -n 1:/data/$[SYSID0]/sysdata/00010017/00000000 $[OUT]/config.sav
|
||||||
|
|
||||||
|
# === NAND data
|
||||||
|
if not find $[OUT]/data NULL
|
||||||
|
mkdir $[OUT]/data
|
||||||
|
end
|
||||||
|
|
||||||
|
if not find $[OUT]/data/extdata NULL
|
||||||
|
mkdir $[OUT]/data/extdata
|
||||||
|
end
|
||||||
|
cp -w -n "1:/data/$[SYSID0]/extdata" $[OUT]/data/extdata
|
||||||
|
|
||||||
|
if not find $[OUT]/data/sysdata NULL
|
||||||
|
mkdir $[OUT]/data/sysdata
|
||||||
|
end
|
||||||
|
cp -w -n "1:/data/$[SYSID0]/sysdata" $[OUT]/data/sysdata
|
||||||
|
|
||||||
|
# Already dumped above
|
||||||
|
rm $[OUT]/data/sysdata/00010017
|
||||||
|
|
||||||
# === Other system titles
|
# === Other system titles
|
||||||
if not find $[OUT]/title NULL
|
if not find $[OUT]/title NULL
|
||||||
mkdir $[OUT]/title
|
mkdir $[OUT]/title
|
||||||
@@ -169,7 +187,7 @@ else
|
|||||||
end
|
end
|
||||||
|
|
||||||
# === Write version
|
# === Write version
|
||||||
dumptxt $[OUT]/version.txt 2
|
dumptxt $[OUT]/version.txt 3
|
||||||
|
|
||||||
set PREVIEW_MODE "threeSD Dumper\nby zhaowenlan1779\n \nSuccess!"
|
set PREVIEW_MODE "threeSD Dumper\nby zhaowenlan1779\n \nSuccess!"
|
||||||
echo "Successfully dumped necessary\nfiles for threeSD."
|
echo "Successfully dumped necessary\nfiles for threeSD."
|
||||||
|
|||||||
+124
-9
@@ -76,9 +76,17 @@ bool SDMCImporter::ImportContent(const ContentSpecifier& specifier,
|
|||||||
case ContentType::DLC:
|
case ContentType::DLC:
|
||||||
return ImportTitle(specifier, callback);
|
return ImportTitle(specifier, callback);
|
||||||
case ContentType::Savegame:
|
case ContentType::Savegame:
|
||||||
|
if ((specifier.id >> 32) == 0) {
|
||||||
|
return ImportNandSavegame(specifier.id, callback);
|
||||||
|
} else {
|
||||||
return ImportSavegame(specifier.id, callback);
|
return ImportSavegame(specifier.id, callback);
|
||||||
|
}
|
||||||
case ContentType::Extdata:
|
case ContentType::Extdata:
|
||||||
|
if ((specifier.id >> 32) == 0) {
|
||||||
return ImportExtdata(specifier.id, callback);
|
return ImportExtdata(specifier.id, callback);
|
||||||
|
} else {
|
||||||
|
return ImportNandExtdata(specifier.id, callback);
|
||||||
|
}
|
||||||
case ContentType::SystemArchive:
|
case ContentType::SystemArchive:
|
||||||
return ImportSystemArchive(specifier.id, callback);
|
return ImportSystemArchive(specifier.id, callback);
|
||||||
case ContentType::Sysdata:
|
case ContentType::Sysdata:
|
||||||
@@ -182,6 +190,37 @@ bool SDMCImporter::ImportSavegame(u64 id, [[maybe_unused]] const ProgressCallbac
|
|||||||
"Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path);
|
"Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDMCImporter::ImportNandSavegame(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||||
|
const auto path = fmt::format("sysdata/{:08x}/00000000", (id & 0xFFFFFFFF));
|
||||||
|
|
||||||
|
FileUtil::IOFile file(config.nand_data_path + path, "rb");
|
||||||
|
if (!file) {
|
||||||
|
LOG_ERROR(Core, "Could not open file {}", 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataContainer container(std::move(data));
|
||||||
|
std::vector<std::vector<u8>> container_data;
|
||||||
|
if (!container.GetIVFCLevel4Data(container_data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDSavegame save(std::move(container_data));
|
||||||
|
if (!save.IsGood()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return save.ExtractDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
||||||
|
"data/00000000000000000000000000000000/" + path + "/",
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||||
const auto path = fmt::format("extdata/{:08x}/{:08x}/", (id >> 32), (id & 0xFFFFFFFF));
|
const auto path = fmt::format("extdata/{:08x}/{:08x}/", (id >> 32), (id & 0xFFFFFFFF));
|
||||||
SDExtdata extdata("/" + path, *decryptor);
|
SDExtdata extdata("/" + path, *decryptor);
|
||||||
@@ -194,6 +233,17 @@ bool SDMCImporter::ImportExtdata(u64 id, [[maybe_unused]] const ProgressCallback
|
|||||||
"Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path);
|
"Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000/" + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDMCImporter::ImportNandExtdata(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||||
|
const auto path = fmt::format("extdata/{:08x}/{:08x}/", (id >> 32), (id & 0xFFFFFFFF));
|
||||||
|
SDExtdata extdata(config.nand_data_path + path);
|
||||||
|
if (!extdata.IsGood()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return extdata.Extract(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
||||||
|
"data/00000000000000000000000000000000/" + path);
|
||||||
|
}
|
||||||
|
|
||||||
bool SDMCImporter::ImportSystemArchive(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
bool SDMCImporter::ImportSystemArchive(u64 id, [[maybe_unused]] const ProgressCallback& callback) {
|
||||||
const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path, (id >> 32),
|
const auto path = fmt::format("{}{:08x}/{:08x}.app", config.system_archives_path, (id >> 32),
|
||||||
(id & 0xFFFFFFFF));
|
(id & 0xFFFFFFFF));
|
||||||
@@ -364,6 +414,7 @@ std::vector<ContentSpecifier> SDMCImporter::ListContent() const {
|
|||||||
std::vector<ContentSpecifier> content_list;
|
std::vector<ContentSpecifier> content_list;
|
||||||
ListTitle(content_list);
|
ListTitle(content_list);
|
||||||
ListNandTitle(content_list);
|
ListNandTitle(content_list);
|
||||||
|
ListNandSavegame(content_list);
|
||||||
ListExtdata(content_list);
|
ListExtdata(content_list);
|
||||||
ListSystemArchive(content_list);
|
ListSystemArchive(content_list);
|
||||||
ListSysdata(content_list);
|
ListSysdata(content_list);
|
||||||
@@ -740,9 +791,9 @@ void SDMCImporter::ListNandTitle(std::vector<ContentSpecifier>& out) const {
|
|||||||
ProcessDirectory(0x00040130);
|
ProcessDirectory(0x00040130);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
void SDMCImporter::ListNandSavegame(std::vector<ContentSpecifier>& out) const {
|
||||||
FileUtil::ForeachDirectoryEntry(
|
FileUtil::ForeachDirectoryEntry(
|
||||||
nullptr, fmt::format("{}extdata/00000000/", config.sdmc_path),
|
nullptr, fmt::format("{}sysdata/", config.nand_data_path),
|
||||||
[&out](u64* /*num_entries_out*/, const std::string& directory,
|
[&out](u64* /*num_entries_out*/, const std::string& directory,
|
||||||
const std::string& virtual_name) {
|
const std::string& virtual_name) {
|
||||||
if (!FileUtil::IsDirectory(directory + virtual_name + "/")) {
|
if (!FileUtil::IsDirectory(directory + virtual_name + "/")) {
|
||||||
@@ -753,16 +804,67 @@ void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto path = directory + virtual_name + "/00000000";
|
||||||
|
|
||||||
|
// Read the file to test.
|
||||||
|
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, "Could not read from {}", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DataContainer container(std::move(data));
|
||||||
|
if (!container.IsGood()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const u64 id = std::stoull(virtual_name, nullptr, 16);
|
const u64 id = std::stoull(virtual_name, nullptr, 16);
|
||||||
const auto citra_path =
|
const auto citra_path =
|
||||||
fmt::format("{}Nintendo "
|
fmt::format("{}data/00000000000000000000000000000000/sysdata/{}/00000000",
|
||||||
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/"
|
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), virtual_name);
|
||||||
"extdata/00000000/{}",
|
out.push_back(
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), virtual_name);
|
{ContentType::Savegame, id, FileUtil::Exists(citra_path), FileUtil::GetSize(path)});
|
||||||
out.push_back({ContentType::Extdata, id, FileUtil::Exists(citra_path),
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
||||||
|
const auto ProcessDirectory = [this, &out](u64 id_high, const std::string& path,
|
||||||
|
const std::string& citra_path_template) {
|
||||||
|
FileUtil::ForeachDirectoryEntry(
|
||||||
|
nullptr, path,
|
||||||
|
[&out, id_high, citra_path_template](u64* /*num_entries_out*/,
|
||||||
|
const std::string& directory,
|
||||||
|
const std::string& virtual_name) {
|
||||||
|
if (!FileUtil::IsDirectory(directory + virtual_name + "/")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::regex_match(virtual_name, title_regex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 id = std::stoull(virtual_name, nullptr, 16);
|
||||||
|
const auto citra_path = fmt::format(citra_path_template, virtual_name);
|
||||||
|
out.push_back({ContentType::Extdata, (id_high << 32) | id,
|
||||||
|
FileUtil::Exists(citra_path),
|
||||||
FileUtil::GetDirectoryTreeSize(directory + virtual_name + "/")});
|
FileUtil::GetDirectoryTreeSize(directory + virtual_name + "/")});
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
ProcessDirectory(0, fmt::format("{}extdata/00000000/", config.sdmc_path),
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) +
|
||||||
|
"Nintendo "
|
||||||
|
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/"
|
||||||
|
"extdata/00000000/{}");
|
||||||
|
ProcessDirectory(0x00048000, fmt::format("{}extdata/00048000/", config.nand_data_path),
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
|
||||||
|
"data/00000000000000000000000000000000/extdata/00048000/{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::ListSystemArchive(std::vector<ContentSpecifier>& out) const {
|
void SDMCImporter::ListSystemArchive(std::vector<ContentSpecifier>& out) const {
|
||||||
@@ -907,19 +1009,31 @@ void SDMCImporter::DeleteNandTitle(u64 id) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::DeleteSavegame(u64 id) const {
|
void SDMCImporter::DeleteSavegame(u64 id) const {
|
||||||
|
if ((id >> 32) == 0) { // NAND
|
||||||
|
FileUtil::DeleteDirRecursively(
|
||||||
|
fmt::format("{}data/00000000000000000000000000000000/sysdata/{:08x}/",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (id & 0xFFFFFFFF)));
|
||||||
|
} else { // SDMC
|
||||||
FileUtil::DeleteDirRecursively(fmt::format(
|
FileUtil::DeleteDirRecursively(fmt::format(
|
||||||
"{}Nintendo "
|
"{}Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/{:08x}/{:08x}/"
|
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/title/{:08x}/"
|
||||||
"data/",
|
"{:08x}/data/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), (id >> 32), (id & 0xFFFFFFFF)));
|
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), (id >> 32), (id & 0xFFFFFFFF)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::DeleteExtdata(u64 id) const {
|
void SDMCImporter::DeleteExtdata(u64 id) const {
|
||||||
|
if ((id >> 32) == 0) { // SDMC
|
||||||
FileUtil::DeleteDirRecursively(fmt::format(
|
FileUtil::DeleteDirRecursively(fmt::format(
|
||||||
"{}Nintendo "
|
"{}Nintendo "
|
||||||
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/extdata/{:08x}/"
|
"3DS/00000000000000000000000000000000/00000000000000000000000000000000/extdata/{:08x}/"
|
||||||
"{:08x}/",
|
"{:08x}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), (id >> 32), (id & 0xFFFFFFFF)));
|
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), (id >> 32), (id & 0xFFFFFFFF)));
|
||||||
|
} else { // NAND
|
||||||
|
FileUtil::DeleteDirRecursively(fmt::format(
|
||||||
|
"{}data/00000000000000000000000000000000/extdata/{:08x}/{:08x}/",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), (id >> 32), (id & 0xFFFFFFFF)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDMCImporter::DeleteSystemArchive(u64 id) const {
|
void SDMCImporter::DeleteSystemArchive(u64 id) const {
|
||||||
@@ -989,6 +1103,7 @@ std::vector<Config> LoadPresetConfig(std::string mount_point) {
|
|||||||
LOAD_DATA(config_savegame_path, "config.sav");
|
LOAD_DATA(config_savegame_path, "config.sav");
|
||||||
LOAD_DATA(system_archives_path, "sysarchives/");
|
LOAD_DATA(system_archives_path, "sysarchives/");
|
||||||
LOAD_DATA(system_titles_path, "title/");
|
LOAD_DATA(system_titles_path, "title/");
|
||||||
|
LOAD_DATA(nand_data_path, "data/");
|
||||||
#undef LOAD_DATA
|
#undef LOAD_DATA
|
||||||
|
|
||||||
// Load version
|
// Load version
|
||||||
|
|||||||
+5
-1
@@ -83,12 +83,13 @@ struct Config {
|
|||||||
|
|
||||||
std::string system_archives_path; ///< Path to system archives.
|
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)
|
||||||
|
|
||||||
int version = 0; ///< Version of the dumper used.
|
int version = 0; ///< Version of the dumper used.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Version of the current dumper.
|
// Version of the current dumper.
|
||||||
constexpr int CurrentDumperVersion = 2;
|
constexpr int CurrentDumperVersion = 3;
|
||||||
|
|
||||||
class SDMCFile;
|
class SDMCFile;
|
||||||
class NCCHContainer;
|
class NCCHContainer;
|
||||||
@@ -170,12 +171,15 @@ private:
|
|||||||
bool ImportTitle(const ContentSpecifier& specifier, const ProgressCallback& callback);
|
bool ImportTitle(const ContentSpecifier& specifier, const ProgressCallback& callback);
|
||||||
bool ImportNandTitle(const ContentSpecifier& specifier, const ProgressCallback& callback);
|
bool ImportNandTitle(const ContentSpecifier& specifier, const ProgressCallback& callback);
|
||||||
bool ImportSavegame(u64 id, const ProgressCallback& callback);
|
bool ImportSavegame(u64 id, const ProgressCallback& callback);
|
||||||
|
bool ImportNandSavegame(u64 id, const ProgressCallback& callback);
|
||||||
bool ImportExtdata(u64 id, const ProgressCallback& callback);
|
bool ImportExtdata(u64 id, const ProgressCallback& callback);
|
||||||
|
bool ImportNandExtdata(u64 id, const ProgressCallback& callback);
|
||||||
bool ImportSystemArchive(u64 id, const ProgressCallback& callback);
|
bool ImportSystemArchive(u64 id, const ProgressCallback& callback);
|
||||||
bool ImportSysdata(u64 id, const ProgressCallback& callback);
|
bool ImportSysdata(u64 id, const 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 ListExtdata(std::vector<ContentSpecifier>& out) const;
|
void ListExtdata(std::vector<ContentSpecifier>& out) const;
|
||||||
void ListSystemArchive(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;
|
||||||
|
|||||||
+32
-3
@@ -253,20 +253,49 @@ ArchiveFormatInfo SDSavegame::GetFormatInfo() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDExtdata::SDExtdata(std::string data_path_, const SDMCDecryptor& decryptor_)
|
SDExtdata::SDExtdata(std::string data_path_, const SDMCDecryptor& decryptor_)
|
||||||
: data_path(std::move(data_path_)), decryptor(decryptor_) {
|
: data_path(std::move(data_path_)), decryptor(&decryptor_) {
|
||||||
|
|
||||||
if (data_path.back() != '/' && data_path.back() != '\\') {
|
if (data_path.back() != '/' && data_path.back() != '\\') {
|
||||||
data_path += '/';
|
data_path += '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use_decryptor = true;
|
||||||
|
is_good = Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDExtdata::SDExtdata(std::string data_path_) : data_path(std::move(data_path_)) {
|
||||||
|
if (data_path.back() != '/' && data_path.back() != '\\') {
|
||||||
|
data_path += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
use_decryptor = false;
|
||||||
is_good = Init();
|
is_good = Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDExtdata::~SDExtdata() = default;
|
SDExtdata::~SDExtdata() = default;
|
||||||
|
|
||||||
|
std::vector<u8> SDExtdata::ReadFile(const std::string& path) const {
|
||||||
|
if (use_decryptor) {
|
||||||
|
return decryptor->DecryptFile(path);
|
||||||
|
} else {
|
||||||
|
FileUtil::IOFile file(path, "rb");
|
||||||
|
if (!file) {
|
||||||
|
LOG_ERROR(Core, "Failed to open {}", path);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> data(file.GetSize());
|
||||||
|
if (file.ReadBytes(data.data(), data.size()) != data.size()) {
|
||||||
|
LOG_ERROR(Core, "Failed to read from {}", path);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SDExtdata::Init() {
|
bool SDExtdata::Init() {
|
||||||
// Read VSXE file
|
// Read VSXE file
|
||||||
auto vsxe_raw = decryptor.DecryptFile(data_path + "00000000/00000001");
|
auto vsxe_raw = ReadFile(data_path + "00000000/00000001");
|
||||||
if (vsxe_raw.empty()) {
|
if (vsxe_raw.empty()) {
|
||||||
LOG_ERROR(Core, "Failed to load or decrypt VSXE");
|
LOG_ERROR(Core, "Failed to load or decrypt VSXE");
|
||||||
return false;
|
return false;
|
||||||
@@ -367,7 +396,7 @@ bool SDExtdata::ExtractFile(const std::string& path, std::size_t index) const {
|
|||||||
std::string device_file_path =
|
std::string device_file_path =
|
||||||
fmt::format("{}{:08x}/{:08x}", data_path, sub_directory_id, sub_file_id);
|
fmt::format("{}{:08x}/{:08x}", data_path, sub_directory_id, sub_file_id);
|
||||||
|
|
||||||
auto container_data = decryptor.DecryptFile(device_file_path);
|
auto container_data = ReadFile(device_file_path);
|
||||||
if (container_data.empty()) { // File does not exist?
|
if (container_data.empty()) { // File does not exist?
|
||||||
LOG_WARNING(Core, "Ignoring file {}", device_file_path);
|
LOG_WARNING(Core, "Ignoring file {}", device_file_path);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+10
-1
@@ -183,17 +183,26 @@ public:
|
|||||||
* @param decryptor Const reference to the SDMCDecryptor.
|
* @param decryptor Const reference to the SDMCDecryptor.
|
||||||
*/
|
*/
|
||||||
explicit SDExtdata(std::string data_path, const SDMCDecryptor& decryptor);
|
explicit SDExtdata(std::string data_path, const SDMCDecryptor& decryptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an Extdata folder without encryption.
|
||||||
|
* @param data_path Path to the DECRYPTED extdata folder
|
||||||
|
*/
|
||||||
|
explicit SDExtdata(std::string data_path);
|
||||||
|
|
||||||
~SDExtdata() override;
|
~SDExtdata() override;
|
||||||
|
|
||||||
bool Extract(std::string path) const override;
|
bool Extract(std::string path) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<u8> ReadFile(const std::string& path) const;
|
||||||
bool Init();
|
bool Init();
|
||||||
bool ExtractFile(const std::string& path, std::size_t index) const override;
|
bool ExtractFile(const std::string& path, std::size_t index) const override;
|
||||||
ArchiveFormatInfo GetFormatInfo() const override;
|
ArchiveFormatInfo GetFormatInfo() const override;
|
||||||
|
|
||||||
std::string data_path;
|
std::string data_path;
|
||||||
const SDMCDecryptor& decryptor;
|
const SDMCDecryptor* decryptor = nullptr;
|
||||||
|
bool use_decryptor = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|||||||
Reference in New Issue
Block a user