mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-03 00:38:58 +00:00
A bunch of fixes to CIA building
1. Clean stale state 2. DLC CIAs 3. Build content index for ticket better
This commit is contained in:
+15
-9
@@ -526,12 +526,17 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, const std::string
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = FileUtil::ForeachDirectoryEntry(
|
const FileUtil::DirectoryEntryCallable DirectoryEntryCallback =
|
||||||
nullptr, physical_path,
|
[this, specifier, path, &DirectoryEntryCallback](u64* /*num_entries_out*/,
|
||||||
[this, path](u64* /*num_entries_out*/, const std::string& directory,
|
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 + "/")) {
|
||||||
return true;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::regex app_regex{"([0-9a-f]{8})\\.app"};
|
static const std::regex app_regex{"([0-9a-f]{8})\\.app"};
|
||||||
@@ -543,11 +548,12 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, const std::string
|
|||||||
ASSERT(match.size() >= 2);
|
ASSERT(match.size() >= 2);
|
||||||
|
|
||||||
const u32 id = static_cast<u32>(std::stoul(match[1], nullptr, 16));
|
const u32 id = static_cast<u32>(std::stoul(match[1], nullptr, 16));
|
||||||
NCCHContainer ncch(
|
const auto relative_path = directory.substr(config.sdmc_path.size() - 1) + virtual_name;
|
||||||
std::make_shared<SDMCFile>(config.sdmc_path, path + virtual_name, "rb"));
|
NCCHContainer ncch(std::make_shared<SDMCFile>(config.sdmc_path, relative_path, "rb"));
|
||||||
return cia_builder->AddContent(id, ncch);
|
return cia_builder->AddContent(id, ncch);
|
||||||
});
|
};
|
||||||
if (!ret) {
|
|
||||||
|
if (!FileUtil::ForeachDirectoryEntry(nullptr, physical_path, DirectoryEntryCallback)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ bool CIABuilder::Init(const std::string& destination, TitleMetadata tmd_,
|
|||||||
const std::string& certs_db_path, std::size_t total_size_,
|
const std::string& certs_db_path, std::size_t total_size_,
|
||||||
const ProgressCallback& callback_) {
|
const ProgressCallback& callback_) {
|
||||||
|
|
||||||
|
header = {};
|
||||||
|
meta = {};
|
||||||
|
|
||||||
file = std::make_shared<HashedFile>(destination, "wb");
|
file = std::make_shared<HashedFile>(destination, "wb");
|
||||||
if (!*file) {
|
if (!*file) {
|
||||||
LOG_ERROR(Core, "Could not open file {}", destination);
|
LOG_ERROR(Core, "Could not open file {}", destination);
|
||||||
@@ -165,13 +168,14 @@ bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) {
|
|||||||
written = Common::AlignUp(file->Tell(), CIA_ALIGNMENT);
|
written = Common::AlignUp(file->Tell(), CIA_ALIGNMENT);
|
||||||
|
|
||||||
header.content_size = written - content_offset;
|
header.content_size = written - content_offset;
|
||||||
header.SetContentPresent(content_id);
|
|
||||||
|
|
||||||
auto& tmd_chunk = tmd.GetContentChunkByID(content_id);
|
auto& tmd_chunk = tmd.GetContentChunkByID(content_id);
|
||||||
|
header.SetContentPresent(tmd_chunk.index);
|
||||||
file->GetHash(tmd_chunk.hash.data());
|
file->GetHash(tmd_chunk.hash.data());
|
||||||
file->SetHashEnabled(false);
|
file->SetHashEnabled(false);
|
||||||
|
|
||||||
if (tmd_chunk.index != TMDContentIndex::Main) {
|
// DLCs do not have a meta
|
||||||
|
if (tmd_chunk.index != TMDContentIndex::Main || (tmd.GetTitleID() & 0x0004008c'00000000)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ private:
|
|||||||
std::size_t ticket_offset{};
|
std::size_t ticket_offset{};
|
||||||
std::size_t tmd_offset{};
|
std::size_t tmd_offset{};
|
||||||
std::size_t content_offset{};
|
std::size_t content_offset{};
|
||||||
std::size_t metadata_offset{};
|
|
||||||
|
|
||||||
std::shared_ptr<HashedFile> file;
|
std::shared_ptr<HashedFile> file;
|
||||||
std::size_t written{}; // size written (with alignment)
|
std::size_t written{}; // size written (with alignment)
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ Ticket BuildFakeTicket(u64 title_id) {
|
|||||||
ticket.title_id = title_id;
|
ticket.title_id = title_id;
|
||||||
ticket.common_key_index = 0x00;
|
ticket.common_key_index = 0x00;
|
||||||
ticket.audit = 0x01;
|
ticket.audit = 0x01;
|
||||||
std::memset(ticket.content_index.data(), 0xFF, ticket.content_index.size());
|
|
||||||
std::memcpy(ticket.content_index.data(), TicketContentIndex.data(), TicketContentIndex.size());
|
std::memcpy(ticket.content_index.data(), TicketContentIndex.data(), TicketContentIndex.size());
|
||||||
|
// GodMode9 by default sets all remaining 0x80 bytes to 0xFF, but legit tickets only set 0x20
|
||||||
|
std::memset(ticket.content_index.data() + TicketContentIndex.size(), 0xFF, 0x20);
|
||||||
return ticket;
|
return ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user