1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

patch_manager: prefer specific > global (per hash)

This commit is contained in:
Megamouse 2020-06-28 14:19:44 +02:00
parent cf2e2a0511
commit a5368d766a

View File

@ -559,78 +559,8 @@ std::size_t patch_engine::apply_with_ls_check(const std::string& name, u8* dst,
}
template <bool check_local_storage>
std::size_t patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
static std::size_t apply_modification(const patch_engine::patch_info& patch, u8* dst, u32 filesz, u32 ls_addr)
{
if (m_map.find(name) == m_map.cend())
{
return 0;
}
size_t applied_total = 0;
const auto& container = m_map.at(name);
const auto serial = Emu.GetTitleID();
const auto app_version = Emu.GetAppVersion();
// Apply modifications sequentially
for (const auto& [description, patch] : container.patch_info_map)
{
if (patch.is_legacy && !patch.is_enabled)
{
continue;
}
bool enabled = false;
for (const auto& [title, serials] : patch.titles)
{
std::string found_serial;
if (serials.find(serial) != serials.end())
{
found_serial = serial;
}
else if (serials.find(patch_key::all) != serials.end())
{
found_serial = patch_key::all;
}
if (!found_serial.empty())
{
const auto& app_versions = serials.at(found_serial);
std::string found_app_version;
if (app_versions.find(app_version) != app_versions.end())
{
found_app_version = app_version;
}
else if (app_versions.find(patch_key::all) != app_versions.end())
{
found_app_version = patch_key::all;
}
if (!found_app_version.empty() && app_versions.at(found_app_version))
{
enabled = true;
break;
}
}
}
if (!enabled)
{
continue;
}
if (!patch.patch_group.empty())
{
if (m_applied_groups.contains(patch.patch_group))
{
continue;
}
m_applied_groups.insert(patch.patch_group);
}
size_t applied = 0;
for (const auto& p : patch.data_list)
@ -718,16 +648,132 @@ std::size_t patch_engine::apply_patch(const std::string& name, u8* dst, u32 file
++applied;
}
if (container.is_legacy)
return applied;
}
template <bool check_local_storage>
std::size_t patch_engine::apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr)
{
if (m_map.find(name) == m_map.cend())
{
patch_log.notice("Applied legacy patch (hash='%s')(<- %d)", name, applied);
return 0;
}
size_t applied_total = 0;
const auto& container = m_map.at(name);
const auto serial = Emu.GetTitleID();
const auto app_version = Emu.GetAppVersion();
// Different containers in order to seperate the patches
std::vector<patch_engine::patch_info> patches_for_this_serial_and_this_version;
std::vector<patch_engine::patch_info> patches_for_this_serial_and_all_versions;
std::vector<patch_engine::patch_info> patches_for_all_serials_and_this_version;
std::vector<patch_engine::patch_info> patches_for_all_serials_and_all_versions;
// Sort patches into different vectors based on their serial and version
for (const auto& [description, patch] : container.patch_info_map)
{
// Find out if this legacy patch is enabled
if (patch.is_legacy && !patch.is_enabled)
{
continue;
}
// Find out if this patch is enabled
for (const auto& [title, serials] : patch.titles)
{
bool is_all_serials = false;
bool is_all_versions = false;
std::string found_serial;
if (serials.find(serial) != serials.end())
{
found_serial = serial;
}
else if (serials.find(patch_key::all) != serials.end())
{
found_serial = patch_key::all;
is_all_serials = true;
}
if (found_serial.empty())
{
continue;
}
const auto& app_versions = serials.at(found_serial);
std::string found_app_version;
if (app_versions.find(app_version) != app_versions.end())
{
found_app_version = app_version;
}
else if (app_versions.find(patch_key::all) != app_versions.end())
{
found_app_version = patch_key::all;
is_all_versions = true;
}
if (!found_app_version.empty() && app_versions.at(found_app_version))
{
// This patch is enabled
if (is_all_serials)
{
if (is_all_versions)
{
patches_for_all_serials_and_all_versions.push_back(patch);
}
else
{
patch_log.notice("Applied patch (hash='%s', description='%s', author='%s', patch_version='%s', file_version='%s') (<- %d)", name, description, patch.author, patch.patch_version, patch.version, applied);
patches_for_all_serials_and_this_version.push_back(patch);
}
}
else if (is_all_versions)
{
patches_for_this_serial_and_all_versions.push_back(patch);
}
else
{
patches_for_this_serial_and_this_version.push_back(patch);
}
break;
}
}
}
// Sort specific patches in front of global patches
std::vector<patch_engine::patch_info> sorted_patches;
sorted_patches.insert(sorted_patches.end(), patches_for_this_serial_and_this_version.begin(), patches_for_this_serial_and_this_version.end());
sorted_patches.insert(sorted_patches.end(), patches_for_this_serial_and_all_versions.begin(), patches_for_this_serial_and_all_versions.end());
sorted_patches.insert(sorted_patches.end(), patches_for_all_serials_and_this_version.begin(), patches_for_all_serials_and_this_version.end());
sorted_patches.insert(sorted_patches.end(), patches_for_all_serials_and_all_versions.begin(), patches_for_all_serials_and_all_versions.end());
// Apply modifications sequentially
for (const auto& patch : sorted_patches)
{
if (!patch.patch_group.empty())
{
if (m_applied_groups.contains(patch.patch_group))
{
continue;
}
m_applied_groups.insert(patch.patch_group);
}
const size_t applied = apply_modification<check_local_storage>(patch, dst, filesz, ls_addr);
applied_total += applied;
if (patch.is_legacy)
{
patch_log.notice("Applied legacy patch (hash='%s')(<- %d)", patch.hash, applied);
}
else
{
patch_log.notice("Applied patch (hash='%s', description='%s', author='%s', patch_version='%s', file_version='%s') (<- %d)", patch.hash, patch.description, patch.author, patch.patch_version, patch.version, applied);
}
}
return applied_total;