RiivolutionPatcher: Handle the possibility of the FST already containing a main.dol file.

This commit is contained in:
Admiral H. Curtiss 2021-10-22 03:14:51 +02:00
parent ba3373b476
commit 22c6f2fe3b
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 15 additions and 6 deletions

View File

@ -99,6 +99,7 @@ struct FSTBuilderNode
std::string m_filename; std::string m_filename;
u64 m_size; u64 m_size;
std::variant<std::vector<BuilderContentSource>, std::vector<FSTBuilderNode>> m_content; std::variant<std::vector<BuilderContentSource>, std::vector<FSTBuilderNode>> m_content;
void* m_user_data = nullptr;
bool IsFile() const bool IsFile() const
{ {

View File

@ -435,8 +435,10 @@ void ApplyPatchesToFiles(const std::vector<Patch>& patches,
// For file searching purposes, Riivolution assumes that the game's main.dol is in the root of the // For file searching purposes, Riivolution assumes that the game's main.dol is in the root of the
// file system. So to avoid doing a bunch of special case handling for that, we just put a node // file system. So to avoid doing a bunch of special case handling for that, we just put a node
// for this into the FST and remove it again after the file patching is done. // for this into the FST and remove it again after the file patching is done.
dol_node->m_filename = "main.dol"; // We mark the inserted node with a pointer to a stack variable so we can find it again.
fst->push_back(*dol_node); int marker = 0;
fst->emplace_back(DiscIO::FSTBuilderNode{"main.dol", dol_node->m_size,
std::move(dol_node->m_content), &marker});
for (const auto& patch : patches) for (const auto& patch : patches)
{ {
@ -483,15 +485,21 @@ void ApplyPatchesToFiles(const std::vector<Patch>& patches,
} }
} }
// Remove the inserted main.dol node again and propagate its changes.
auto main_dol_node_in_fst = auto main_dol_node_in_fst =
std::find_if(fst->begin(), fst->end(), [&](const DiscIO::FSTBuilderNode& node) { std::find_if(fst->begin(), fst->end(),
return node.m_filename == "main.dol"; [&](const DiscIO::FSTBuilderNode& node) { return node.m_user_data == &marker; });
});
if (main_dol_node_in_fst != fst->end()) if (main_dol_node_in_fst != fst->end())
{ {
*dol_node = *main_dol_node_in_fst; dol_node->m_size = main_dol_node_in_fst->m_size;
dol_node->m_content = std::move(main_dol_node_in_fst->m_content);
fst->erase(main_dol_node_in_fst); fst->erase(main_dol_node_in_fst);
} }
else
{
// The main.dol node disappeared, this should never happen.
ASSERT(false);
}
} }
static bool MemoryMatchesAt(u32 offset, const std::vector<u8>& value) static bool MemoryMatchesAt(u32 offset, const std::vector<u8>& value)