From 5affc459a2aaffc74b11da02f4e0a47166f52095 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 19 Jun 2020 21:48:59 +0200 Subject: [PATCH] patch manager: Allow partial patch file import --- Utilities/bin_patch.cpp | 26 ++++++++++++-------------- Utilities/bin_patch.h | 2 +- rpcs3/rpcs3qt/patch_manager_dialog.cpp | 22 ++++++++++++++++++---- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 66ae7e7bb1..60661074fd 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -84,8 +84,6 @@ static void append_log_message(std::stringstream* log_messages, const std::strin bool patch_engine::load(patch_map& patches_map, const std::string& path, bool importing, std::stringstream* log_messages) { - append_log_message(log_messages, fmt::format("Reading file %s", path)); - // Load patch file fs::file file{ path }; @@ -128,8 +126,6 @@ bool patch_engine::load(patch_map& patches_map, const std::string& path, bool im return false; } - append_log_message(log_messages, fmt::format("Patch file version: %s", version)); - // We don't need the Version node in local memory anymore root.remove("Version"); } @@ -666,13 +662,16 @@ void patch_engine::save_config(const patch_map& patches_map, bool enable_legacy_ file.write(out.c_str(), out.size()); } -static bool append_patches(patch_engine::patch_map& existing_patches, const patch_engine::patch_map& new_patches, std::stringstream* log_messages) +static void append_patches(patch_engine::patch_map& existing_patches, const patch_engine::patch_map& new_patches, size_t& count, size_t& total, std::stringstream* log_messages) { for (const auto& [hash, new_container] : new_patches) { + total += new_container.patch_info_map.size(); + if (existing_patches.find(hash) == existing_patches.end()) { existing_patches[hash] = new_container; + count += new_container.patch_info_map.size(); continue; } @@ -683,6 +682,7 @@ static bool append_patches(patch_engine::patch_map& existing_patches, const patc if (container.patch_info_map.find(description) == container.patch_info_map.end()) { container.patch_info_map[description] = new_info; + count++; continue; } @@ -695,14 +695,14 @@ static bool append_patches(patch_engine::patch_map& existing_patches, const patc { patch_log.error("Failed to compare patch versions ('%s' vs '%s') for %s: %s", new_info.patch_version, info.patch_version, hash, description); append_log_message(log_messages, fmt::format("Failed to compare patch versions ('%s' vs '%s') for %s: %s", new_info.patch_version, info.patch_version, hash, description)); - return false; + continue; } if (!version_is_bigger) { patch_log.error("A higher or equal patch version already exists ('%s' vs '%s') for %s: %s", new_info.patch_version, info.patch_version, hash, description); append_log_message(log_messages, fmt::format("A higher or equal patch version already exists ('%s' vs '%s') for %s: %s", new_info.patch_version, info.patch_version, hash, description)); - return false; + continue; } if (!new_info.patch_version.empty()) info.patch_version = new_info.patch_version; @@ -712,10 +712,10 @@ static bool append_patches(patch_engine::patch_map& existing_patches, const patc 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.source_path.empty()) info.source_path = new_info.source_path; + + count++; } } - - return true; } bool patch_engine::save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages) @@ -788,16 +788,14 @@ bool patch_engine::save_patches(const patch_map& patches, const std::string& pat return true; } -bool patch_engine::import_patches(const patch_engine::patch_map& patches, const std::string& path, std::stringstream* log_messages) +bool patch_engine::import_patches(const patch_engine::patch_map& patches, const std::string& path, size_t& count, size_t& total, std::stringstream* log_messages) { patch_engine::patch_map existing_patches; if (load(existing_patches, path, true, log_messages)) { - if (append_patches(existing_patches, patches, log_messages)) - { - return save_patches(existing_patches, path, log_messages); - } + append_patches(existing_patches, patches, count, total, log_messages); + return count == 0 || save_patches(existing_patches, path, log_messages); } return false; diff --git a/Utilities/bin_patch.h b/Utilities/bin_patch.h index 645962bc80..44a3245ccd 100644 --- a/Utilities/bin_patch.h +++ b/Utilities/bin_patch.h @@ -109,7 +109,7 @@ public: static bool save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages = nullptr); // Create or append patches to a file - static bool import_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages = nullptr); + static bool import_patches(const patch_map& patches, const std::string& path, size_t& count, size_t& total, std::stringstream* log_messages = nullptr); // Remove a patch from a file static bool remove_patch(const patch_info& info); diff --git a/rpcs3/rpcs3qt/patch_manager_dialog.cpp b/rpcs3/rpcs3qt/patch_manager_dialog.cpp index 74f56b1f44..ae60f9b81b 100644 --- a/rpcs3/rpcs3qt/patch_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/patch_manager_dialog.cpp @@ -540,14 +540,28 @@ void patch_manager_dialog::dropEvent(QDropEvent* event) log_message.clear(); - if (patch_engine::import_patches(patches, imported_patch_yml_path, &log_message)) + size_t count = 0; + size_t total = 0; + + if (patch_engine::import_patches(patches, imported_patch_yml_path, count, total, &log_message)) { refresh(); - QMessageBox::information(this, tr("Import successful"), tr("The patch file was imported to:\n%0").arg(QString::fromStdString(imported_patch_yml_path))); + const QString msg = log_message.str().empty() ? "-" : QString::fromStdString(log_message.str()); + + if (count == 0) + { + QMessageBox::warning(this, tr("Nothing to import"), tr("None of the found %0 patches were imported.\n\nLog:\n\n%2") + .arg(total).arg(msg)); + } + else + { + QMessageBox::information(this, tr("Import successful"), tr("Imported %0/%1 patches to:\n%2\n\nLog:\n\n%3") + .arg(count).arg(total).arg(QString::fromStdString(imported_patch_yml_path)).arg(msg)); + } } else { - QMessageBox::information(this, tr("Import failed"), tr("The patch file was not imported.\nPlease see the log for more information.")); + QMessageBox::warning(this, tr("Import failed"), tr("The patch file was not imported.\n\nLog:\n\n").arg(QString::fromStdString(log_message.str()))); } } else @@ -558,7 +572,7 @@ void patch_manager_dialog::dropEvent(QDropEvent* event) else { patch_log.error("Errors found in patch file %s", path); - QMessageBox::warning(this, tr("Validation failed"), tr("Errors were found in the patch file. Log:\n\n") + QString::fromStdString(log_message.str())); + QMessageBox::warning(this, tr("Validation failed"), tr("Errors were found in the patch file.\n\nLog:\n\n%0").arg(QString::fromStdString(log_message.str()))); } } }