1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

patch manager: move title + serials to patch level

Also bump patch file version to 1.1
This commit is contained in:
Megamouse 2020-06-19 13:46:56 +02:00
parent cc5c89539b
commit 2323cd2a2d
3 changed files with 88 additions and 95 deletions

View File

@ -4,7 +4,7 @@
LOG_CHANNEL(patch_log); LOG_CHANNEL(patch_log);
static const std::string patch_engine_version = "1.0"; static const std::string patch_engine_version = "1.1";
static const std::string yml_key_enable_legacy_patches = "Enable Legacy Patches"; static const std::string yml_key_enable_legacy_patches = "Enable Legacy Patches";
template <> template <>
@ -160,10 +160,10 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im
} }
// Find or create an entry matching the key/hash in our map // Find or create an entry matching the key/hash in our map
auto& title_info = patches_map[main_key]; auto& container = patches_map[main_key];
title_info.hash = main_key; container.hash = main_key;
title_info.is_legacy = true; container.is_legacy = true;
title_info.patch_info_map["legacy"] = info; container.patch_info_map["legacy"] = info;
continue; continue;
} }
@ -183,19 +183,6 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im
continue; continue;
} }
std::string title;
std::string serials;
if (const auto title_node = pair.second["Title"])
{
title = title_node.Scalar();
}
if (const auto serials_node = pair.second["Serials"])
{
serials = serials_node.Scalar();
}
if (const auto patches_node = pair.second["Patches"]) if (const auto patches_node = pair.second["Patches"])
{ {
if (const auto yml_type = patches_node.Type(); yml_type != YAML::NodeType::Map) if (const auto yml_type = patches_node.Type(); yml_type != YAML::NodeType::Map)
@ -207,12 +194,10 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im
} }
// Find or create an entry matching the key/hash in our map // Find or create an entry matching the key/hash in our map
auto& title_info = patches_map[main_key]; auto& container = patches_map[main_key];
title_info.is_legacy = false; container.is_legacy = false;
title_info.hash = main_key; container.hash = main_key;
title_info.title = title; container.version = version;
title_info.serials = serials;
title_info.version = version;
// Go through each patch // Go through each patch
for (auto patches_entry : patches_node) for (auto patches_entry : patches_node)
@ -238,8 +223,16 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im
info.description = description; info.description = description;
info.hash = main_key; info.hash = main_key;
info.version = version; info.version = version;
info.serials = serials;
info.title = title; if (const auto title_node = patches_entry.second["Title"])
{
info.title = title_node.Scalar();
}
if (const auto serials_node = patches_entry.second["Serials"])
{
info.serials = serials_node.Scalar();
}
if (const auto author_node = patches_entry.second["Author"]) if (const auto author_node = patches_entry.second["Author"])
{ {
@ -265,7 +258,7 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im
} }
// Insert patch information // Insert patch information
title_info.patch_info_map[description] = info; container.patch_info_map[description] = info;
} }
} }
} }
@ -482,10 +475,10 @@ std::size_t patch_engine::apply_patch(const std::string& name, u8* dst, u32 file
} }
size_t applied_total = 0; size_t applied_total = 0;
const auto& title_info = m_map.at(name); const auto& container = m_map.at(name);
// Apply modifications sequentially // Apply modifications sequentially
for (const auto& [description, patch] : title_info.patch_info_map) for (const auto& [description, patch] : container.patch_info_map)
{ {
if (!patch.enabled) if (!patch.enabled)
{ {
@ -579,7 +572,7 @@ std::size_t patch_engine::apply_patch(const std::string& name, u8* dst, u32 file
++applied; ++applied;
} }
if (title_info.is_legacy) if (container.is_legacy)
{ {
patch_log.notice("Applied legacy patch (<- %d)", applied); patch_log.notice("Applied legacy patch (<- %d)", applied);
} }
@ -615,14 +608,14 @@ void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_
// Save 'enabled' state per hash and description // Save 'enabled' state per hash and description
patch_config_map config_map; patch_config_map config_map;
for (const auto& [hash, title_info] : patches_map) for (const auto& [hash, container] : patches_map)
{ {
if (title_info.is_legacy) if (container.is_legacy)
{ {
continue; continue;
} }
for (const auto& [description, patch] : title_info.patch_info_map) for (const auto& [description, patch] : container.patch_info_map)
{ {
config_map[hash][description] = patch.enabled; config_map[hash][description] = patch.enabled;
} }
@ -648,28 +641,25 @@ void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_
static void append_patches(patch_engine::patch_map& existing_patches, const patch_engine::patch_map& new_patches) static void append_patches(patch_engine::patch_map& existing_patches, const patch_engine::patch_map& new_patches)
{ {
for (const auto& [hash, new_title_info] : new_patches) for (const auto& [hash, new_container] : new_patches)
{ {
if (existing_patches.find(hash) == existing_patches.end()) if (existing_patches.find(hash) == existing_patches.end())
{ {
existing_patches[hash] = new_title_info; existing_patches[hash] = new_container;
continue; continue;
} }
auto& title_info = existing_patches[hash]; auto& container = existing_patches[hash];
if (!new_title_info.title.empty()) title_info.title = new_title_info.title; for (const auto& [description, new_info] : new_container.patch_info_map)
if (!new_title_info.serials.empty()) title_info.serials = new_title_info.serials;
for (const auto& [description, new_info] : new_title_info.patch_info_map)
{ {
if (title_info.patch_info_map.find(description) == title_info.patch_info_map.end()) if (container.patch_info_map.find(description) == container.patch_info_map.end())
{ {
title_info.patch_info_map[description] = new_info; container.patch_info_map[description] = new_info;
continue; continue;
} }
auto& info = title_info.patch_info_map[description]; auto& info = container.patch_info_map[description];
const auto version_is_bigger = [](const std::string& v0, const std::string& v1, const std::string& hash, const std::string& description) const auto version_is_bigger = [](const std::string& v0, const std::string& v1, const std::string& hash, const std::string& description)
{ {
@ -692,6 +682,8 @@ static void append_patches(patch_engine::patch_map& existing_patches, const patc
} }
if (!new_info.patch_version.empty()) info.patch_version = new_info.patch_version; if (!new_info.patch_version.empty()) info.patch_version = new_info.patch_version;
if (!new_info.title.empty()) info.title = new_info.title;
if (!new_info.serials.empty()) info.serials = new_info.serials;
if (!new_info.author.empty()) info.author = new_info.author; if (!new_info.author.empty()) info.author = new_info.author;
if (!new_info.notes.empty()) info.notes = new_info.notes; if (!new_info.notes.empty()) info.notes = new_info.notes;
if (!new_info.data_list.empty()) info.data_list = new_info.data_list; if (!new_info.data_list.empty()) info.data_list = new_info.data_list;
@ -710,23 +702,21 @@ bool patch_engine::save_patches(const patch_map& patches, const std::string& pat
YAML::Emitter out; YAML::Emitter out;
out << YAML::BeginMap; out << YAML::BeginMap;
out << "Version" << "1.0"; out << "Version" << patch_engine_version;
for (const auto& [hash, title_info] : patches) for (const auto& [hash, container] : patches)
{ {
out << YAML::Newline << YAML::Newline; out << YAML::Newline << YAML::Newline;
out << hash << YAML::BeginMap; out << hash << YAML::BeginMap;
if (!title_info.title.empty()) out << "Title" << title_info.title;
if (!title_info.serials.empty()) out << "Serials" << title_info.serials;
out << "Patches" << YAML::BeginMap; out << "Patches" << YAML::BeginMap;
for (auto [description, info] : title_info.patch_info_map) for (auto [description, info] : container.patch_info_map)
{ {
out << description; out << description;
out << YAML::BeginMap; out << YAML::BeginMap;
if (!info.title.empty()) out << "Title" << info.title;
if (!info.serials.empty()) out << "Serials" << info.serials;
if (!info.author.empty()) out << "Author" << info.author; if (!info.author.empty()) out << "Author" << info.author;
if (!info.patch_version.empty()) out << "Version" << info.patch_version; if (!info.patch_version.empty()) out << "Version" << info.patch_version;
if (!info.notes.empty()) out << "Notes" << info.notes; if (!info.notes.empty()) out << "Notes" << info.notes;

View File

@ -43,30 +43,28 @@ public:
// Patch information // Patch information
std::vector<patch_engine::patch_data> data_list; std::vector<patch_engine::patch_data> data_list;
std::string description; std::string description;
std::string title;
std::string serials;
std::string patch_version; std::string patch_version;
std::string author; std::string author;
std::string notes; std::string notes;
bool enabled = false; bool enabled = false;
// Redundant information for accessibility (see patch_title_info) // Redundant information for accessibility (see patch_container)
std::string hash; std::string hash;
std::string version; std::string version;
std::string title;
std::string serials;
bool is_legacy = false; bool is_legacy = false;
}; };
struct patch_title_info struct patch_container
{ {
std::unordered_map<std::string /*description*/, patch_engine::patch_info> patch_info_map; std::unordered_map<std::string /*description*/, patch_engine::patch_info> patch_info_map;
std::string hash; std::string hash;
std::string version; std::string version;
std::string title;
std::string serials;
bool is_legacy = false; bool is_legacy = false;
}; };
using patch_map = std::unordered_map<std::string /*hash*/, patch_title_info>; using patch_map = std::unordered_map<std::string /*hash*/, patch_container>;
using patch_config_map = std::unordered_map<std::string /*hash*/, std::unordered_map<std::string /*description*/, bool /*enabled*/>>; using patch_config_map = std::unordered_map<std::string /*hash*/, std::unordered_map<std::string /*description*/, bool /*enabled*/>>;
patch_engine(); patch_engine();
@ -78,10 +76,10 @@ public:
// Example entry: // Example entry:
// //
// PPU-8007056e52279bea26c15669d1ee08c2df321d00: // PPU-8007056e52279bea26c15669d1ee08c2df321d00:
// Title: Fancy Game
// Serials: ABCD12345, SUPA13337 v.1.3
// Patches: // Patches:
// 60fps: // 60fps:
// Title: Fancy Game
// Serials: ABCD12345, SUPA13337 v.1.3
// Author: Batman bin Suparman // Author: Batman bin Suparman
// Version: 1.3 // Version: 1.3
// Notes: This is super // Notes: This is super

View File

@ -120,33 +120,30 @@ void patch_manager_dialog::populate_tree()
{ {
ui->patch_tree->clear(); ui->patch_tree->clear();
for (const auto& [hash, title_info] : m_map) for (const auto& [hash, container] : m_map)
{ {
// Don't show legacy patches, because you can't configure them anyway // Don't show legacy patches, because you can't configure them anyway
if (title_info.is_legacy) if (container.is_legacy)
{ {
continue; continue;
} }
QTreeWidgetItem* title_level_item = nullptr; const QString q_hash = QString::fromStdString(hash);
QTreeWidgetItem* serial_level_item = nullptr;
const QString q_hash = QString::fromStdString(hash);
const QString q_serials = title_info.serials.empty() ? tr("Unknown Version") : QString::fromStdString(title_info.serials);
const QString q_title = QString::fromStdString(title_info.title);
// Find top level item for this title
if (const auto list = ui->patch_tree->findItems(q_title, Qt::MatchFlag::MatchExactly, 0); list.size() > 0)
{
title_level_item = list[0];
}
// Find out if there is a node item for this serial
serial_level_item = gui::utils::find_child(title_level_item, q_serials);
// Add patch items // Add patch items
for (const auto& [description, patch] : title_info.patch_info_map) for (const auto& [description, patch] : container.patch_info_map)
{ {
const QString q_title = patch.title.empty() ? tr("Unknown Title") : QString::fromStdString(patch.title);
const QString q_serials = patch.serials.empty() ? tr("Unknown Version") : QString::fromStdString(patch.serials);
QTreeWidgetItem* title_level_item = nullptr;
// Find top level item for this title
if (const auto list = ui->patch_tree->findItems(q_title, Qt::MatchFlag::MatchExactly, 0); list.size() > 0)
{
title_level_item = list[0];
}
// Add a top level item for this title if it doesn't exist yet // Add a top level item for this title if it doesn't exist yet
if (!title_level_item) if (!title_level_item)
{ {
@ -158,6 +155,9 @@ void patch_manager_dialog::populate_tree()
} }
assert(title_level_item); assert(title_level_item);
// Find out if there is a node item for this serial
QTreeWidgetItem* serial_level_item = gui::utils::find_child(title_level_item, q_serials);
// Add a node item for this serial if it doesn't exist yet // Add a node item for this serial if it doesn't exist yet
if (!serial_level_item) if (!serial_level_item)
{ {
@ -191,18 +191,25 @@ void patch_manager_dialog::populate_tree()
serial_level_item->addChild(patch_level_item); serial_level_item->addChild(patch_level_item);
} }
if (title_level_item)
{
title_level_item->sortChildren(0, Qt::SortOrder::AscendingOrder);
}
if (serial_level_item)
{
serial_level_item->sortChildren(0, Qt::SortOrder::AscendingOrder);
}
} }
ui->patch_tree->sortByColumn(0, Qt::SortOrder::AscendingOrder); ui->patch_tree->sortByColumn(0, Qt::SortOrder::AscendingOrder);
for (int i = 0; i < ui->patch_tree->topLevelItemCount(); i++)
{
if (auto title_level_item = ui->patch_tree->topLevelItem(i))
{
title_level_item->sortChildren(0, Qt::SortOrder::AscendingOrder);
for (int i = 0; i < title_level_item->childCount(); i++)
{
if (auto serial_level_item = title_level_item->child(i))
{
serial_level_item->sortChildren(0, Qt::SortOrder::AscendingOrder);
}
}
}
}
} }
void patch_manager_dialog::save_config() void patch_manager_dialog::save_config()
@ -265,21 +272,19 @@ void patch_manager_dialog::on_item_selected(QTreeWidgetItem *current, QTreeWidge
if (m_map.find(hash) != m_map.end()) if (m_map.find(hash) != m_map.end())
{ {
const auto& title_info = m_map.at(hash); const auto& container = m_map.at(hash);
// Find the patch for this item and show its metadata // Find the patch for this item and show its metadata
if (!title_info.is_legacy && title_info.patch_info_map.find(description) != title_info.patch_info_map.end()) if (!container.is_legacy && container.patch_info_map.find(description) != container.patch_info_map.end())
{ {
update_patch_info(title_info.patch_info_map.at(description)); update_patch_info(container.patch_info_map.at(description));
return; return;
} }
// Show shared info if no patch was found // Show shared info if no patch was found
patch_engine::patch_info info{}; patch_engine::patch_info info{};
info.hash = hash; info.hash = hash;
info.title = title_info.title; info.version = container.version;
info.serials = title_info.serials;
info.version = title_info.version;
update_patch_info(info); update_patch_info(info);
return; return;
} }
@ -306,9 +311,9 @@ void patch_manager_dialog::on_item_changed(QTreeWidgetItem *item, int /*column*/
// Enable/disable the patch for this item and show its metadata // Enable/disable the patch for this item and show its metadata
if (m_map.find(hash) != m_map.end()) if (m_map.find(hash) != m_map.end())
{ {
auto& title_info = m_map[hash]; auto& container = m_map[hash];
if (!title_info.is_legacy && title_info.patch_info_map.find(description) != title_info.patch_info_map.end()) if (!container.is_legacy && container.patch_info_map.find(description) != container.patch_info_map.end())
{ {
auto& patch = m_map[hash].patch_info_map[description]; auto& patch = m_map[hash].patch_info_map[description];
patch.enabled = enabled; patch.enabled = enabled;