diff --git a/src/core/cia_builder.cpp b/src/core/cia_builder.cpp index 577fa28..298c893 100644 --- a/src/core/cia_builder.cpp +++ b/src/core/cia_builder.cpp @@ -80,6 +80,10 @@ bool CIABuilder::Init(CIABuildType type_, const std::string& destination, TitleM header = {}; meta = {}; + if (!FileUtil::CreateFullPath(destination)) { + LOG_ERROR(Core, "Could not create {}", destination); + return false; + } file = std::make_shared(destination, "wb"); if (!*file) { LOG_ERROR(Core, "Could not open file {}", destination); @@ -342,6 +346,7 @@ bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) { std::memcpy(meta.dependencies.data(), &ncch.exheader_header.dependency_list, sizeof(meta.dependencies)); + // Note: GodMode9 has this hardcoded to 2. meta.core_version = ncch.exheader_header.arm11_system_local_caps.core_version; std::vector smdh_buffer; diff --git a/src/core/importer.cpp b/src/core/importer.cpp index 4969c67..5f29131 100644 --- a/src/core/importer.cpp +++ b/src/core/importer.cpp @@ -676,8 +676,8 @@ bool SDMCImporter::BuildCIA(CIABuildType build_type, const ContentSpecifier& spe std::string destination, const Common::ProgressCallback& callback, bool auto_filename) { - if (config.certs_db_path.empty()) { - LOG_ERROR(Core, "Missing certs.db"); + if (!Certs::IsLoaded()) { + LOG_ERROR(Core, "Missing certs"); return false; } @@ -735,48 +735,29 @@ bool SDMCImporter::BuildCIA(CIABuildType build_type, const ContentSpecifier& spe return false; } - const FileUtil::DirectoryEntryCallable DirectoryEntryCallback = - [this, tmd, is_nand, specifier, &DirectoryEntryCallback](u64* /*num_entries_out*/, - const std::string& directory, - const std::string& virtual_name) { - if (FileUtil::IsDirectory(directory + virtual_name + "/")) { - if (virtual_name == "cmd") { - return true; // Skip cmd (not used in Citra) - } - // Recursive call (necessary for DLCs) - return FileUtil::ForeachDirectoryEntry(nullptr, directory + virtual_name + "/", - DirectoryEntryCallback); - } + for (const auto& tmd_chunk : tmd.tmd_chunks) { + const auto path = + fmt::format("{}{:08x}.app", physical_path, static_cast(tmd_chunk.id)); + if (!FileUtil::Exists(path)) { + LOG_ERROR(Core, "Content {:08x} does not exist", static_cast(tmd_chunk.id)); + ret = false; + return false; + } - static const std::regex app_regex{"([0-9a-f]{8})\\.app"}; + if (is_nand) { + NCCHContainer ncch(std::make_shared(path, "rb")); + ret = cia_builder->AddContent(tmd_chunk.id, ncch); + } else { + const auto relative_path = path.substr(config.sdmc_path.size() - 1); + NCCHContainer ncch(std::make_shared(config.sdmc_path, relative_path, "rb")); + ret = cia_builder->AddContent(tmd_chunk.id, ncch); + } + if (!ret) { + return false; + } + } - std::smatch match; - if (!std::regex_match(virtual_name, match, app_regex)) { - return true; - } - ASSERT(match.size() >= 2); - - const u32 id = static_cast(std::stoul(match[1], nullptr, 16)); - if (!tmd.HasContentID(id)) { - LOG_WARNING(Core, "Ignoring content {} (not in TMD)", directory + virtual_name); - return true; - } - - if (is_nand) { - NCCHContainer ncch( - std::make_shared(directory + virtual_name, "rb")); - return cia_builder->AddContent(id, ncch); - } else { - const auto relative_path = - directory.substr(config.sdmc_path.size() - 1) + virtual_name; - NCCHContainer ncch( - std::make_shared(config.sdmc_path, relative_path, "rb")); - return cia_builder->AddContent(id, ncch); - } - }; - - ret = FileUtil::ForeachDirectoryEntry(nullptr, physical_path, DirectoryEntryCallback) && - cia_builder->Finalize(); + ret = cia_builder->Finalize(); return ret; }