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

148 lines
4.1 KiB
C
Raw Normal View History

2020-12-25 03:18:36 +01:00
#pragma once
2017-03-29 01:54:05 +02:00
#include <vector>
#include <string>
#include <unordered_map>
#include "util/types.hpp"
2020-06-02 10:39:24 +02:00
#include "util/yaml.hpp"
namespace patch_key
{
static const std::string all = "All";
static const std::string anchors = "Anchors";
static const std::string author = "Author";
static const std::string games = "Games";
static const std::string group = "Group";
static const std::string notes = "Notes";
static const std::string patch = "Patch";
static const std::string patch_version = "Patch Version";
static const std::string version = "Version";
}
inline static const std::string patch_engine_version = "1.2";
2017-03-29 01:54:05 +02:00
enum class patch_type
{
invalid,
load,
2017-03-29 01:54:05 +02:00
byte,
le16,
le32,
le64,
lef32,
lef64,
2017-03-29 01:54:05 +02:00
be16,
be32,
bd32, // be32 with data hint (non-code)
2017-03-29 01:54:05 +02:00
be64,
bd64, // be64 with data hint (non-code)
bef32,
bef64,
utf8, // Text of string (not null-terminated automatically)
2017-03-29 01:54:05 +02:00
};
class patch_engine
{
2020-06-02 10:39:24 +02:00
public:
struct patch_data
2017-03-29 01:54:05 +02:00
{
2020-06-02 10:39:24 +02:00
patch_type type = patch_type::load;
u32 offset = 0;
2021-03-30 17:31:46 +02:00
std::string original_value{}; // Used for import consistency (avoid rounding etc.)
2020-06-12 21:09:08 +02:00
union
{
u64 long_value;
f64 double_value;
2021-03-30 17:31:46 +02:00
} value{0};
2017-03-29 01:54:05 +02:00
};
using patch_app_versions = std::unordered_map<std::string /*app_version*/, bool /*enabled*/>;
using patch_serials = std::unordered_map<std::string /*serial*/, patch_app_versions>;
using patch_titles = std::unordered_map<std::string /*serial*/, patch_serials>;
2017-03-29 01:54:05 +02:00
2020-06-02 10:39:24 +02:00
struct patch_info
{
// Patch information
2021-03-30 17:31:46 +02:00
std::vector<patch_data> data_list{};
patch_titles titles{};
std::string description{};
std::string patch_version{};
std::string patch_group{};
std::string author{};
std::string notes{};
std::string source_path{};
2017-03-29 01:54:05 +02:00
// Redundant information for accessibility (see patch_container)
2021-03-30 17:31:46 +02:00
std::string hash{};
std::string version{};
2020-06-02 10:39:24 +02:00
};
struct patch_container
2020-06-02 10:39:24 +02:00
{
2021-03-30 17:31:46 +02:00
std::unordered_map<std::string /*description*/, patch_info> patch_info_map{};
std::string hash{};
std::string version{};
2020-06-02 10:39:24 +02:00
};
using patch_map = std::unordered_map<std::string /*hash*/, patch_container>;
2020-06-02 10:39:24 +02:00
patch_engine();
patch_engine(const patch_engine&) = delete;
patch_engine& operator=(const patch_engine&) = delete;
2020-06-02 10:39:24 +02:00
// Returns the directory in which patch_config.yml is located
static std::string get_patch_config_path();
// Returns the directory in which patches are located
static std::string get_patches_path();
// Returns the filepath for the imported_patch.yml
static std::string get_imported_patch_path();
2020-06-02 10:39:24 +02:00
// Load from file and append to specified patches map
2020-09-06 11:47:45 +02:00
static bool load(patch_map& patches, const std::string& path, std::string content = "", bool importing = false, std::stringstream* log_messages = nullptr);
2020-06-02 10:39:24 +02:00
// Read and add a patch node to the patch info
2020-06-12 21:09:08 +02:00
static bool read_patch_node(patch_info& info, YAML::Node node, const YAML::Node& root, std::stringstream* log_messages = nullptr);
2020-06-02 10:39:24 +02:00
// Get the patch type of a patch node
static patch_type get_patch_type(YAML::Node node);
// Add the data of a patch node
2020-06-12 21:09:08 +02:00
static bool add_patch_data(YAML::Node node, patch_info& info, u32 modifier, const YAML::Node& root, std::stringstream* log_messages = nullptr);
2020-06-02 10:39:24 +02:00
// Save to patch_config.yml
2021-01-08 18:36:12 +01:00
static void save_config(const patch_map& patches_map);
2020-06-02 10:39:24 +02:00
2020-06-12 21:09:08 +02:00
// Save a patch file
static bool save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages = nullptr);
2020-06-12 21:09:08 +02:00
// Create or append patches to a file
2020-12-18 08:39:54 +01:00
static bool import_patches(const patch_map& patches, const std::string& path, usz& count, usz& total, std::stringstream* log_messages = nullptr);
2020-06-12 21:09:08 +02:00
// Remove a patch from a file
static bool remove_patch(const patch_info& info);
2020-06-02 10:39:24 +02:00
// Load patch_config.yml
2021-01-08 18:36:12 +01:00
static patch_map load_config();
2020-06-02 10:39:24 +02:00
// Load from file and append to member patches map
void append_global_patches();
// Load from title relevant files and append to member patches map
void append_title_patches(const std::string& title_id);
2017-03-29 01:54:05 +02:00
// Apply patch (returns the number of entries applied)
std::basic_string<u32> apply(const std::string& name, u8* dst, u32 filesz = -1, u32 min_addr = 0);
2020-06-02 10:39:24 +02:00
private:
// Database
2021-03-30 17:31:46 +02:00
patch_map m_map{};
// Only one patch per patch group can be applied
2021-03-30 17:31:46 +02:00
std::set<std::string> m_applied_groups{};
2017-03-29 01:54:05 +02:00
};