mirror of
https://github.com/open-goal/jak-project
synced 2026-05-31 01:16:12 -04:00
Add xdelta3 and file patching interface
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/json_util.h"
|
||||
#include "common/util/crc32.h"
|
||||
#include "common/util/xdelta3_util.h"
|
||||
|
||||
namespace decompiler {
|
||||
namespace {
|
||||
@@ -140,6 +141,59 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
|
||||
for (auto& obj : object_files) {
|
||||
auto data = file_util::read_binary_file(obj);
|
||||
auto name = obj_filename_to_name(obj);
|
||||
if (auto it = config.object_patches.find(name); it != config.object_patches.end()) {
|
||||
// print the file CRC
|
||||
fmt::print("CRC for {} is: 0x{:X}\n", name, crc32(data.data(), data.size()));
|
||||
// write patch file if necessary
|
||||
if (config.write_patches) {
|
||||
// this is the "target" file we want to patch to
|
||||
auto data2 = file_util::read_binary_file(
|
||||
(file_util::get_jak_project_dir() / it->second.target_file).string());
|
||||
// we need to allocate a buffer to store the delta patch
|
||||
// we make it 2x the source file's size because... it seems like a good size?
|
||||
// ideally the delta patch should never be that big.
|
||||
int buf_sz = data.size() * 2;
|
||||
u8* out_buf = (u8*)malloc(buf_sz);
|
||||
size_t out_sz = 0; // this is where the actual used size of the delta patch will be stored
|
||||
int xd3_res = xd3_encode_memory(data2.data(), data2.size(), data.data(), data.size(),
|
||||
out_buf, &out_sz, buf_sz, 0);
|
||||
if (xd3_res) {
|
||||
lg::error("error patching {} with {} (out {}): {}", name, it->second.target_file,
|
||||
it->second.patch_file, xd3_strerror(xd3_res));
|
||||
} else {
|
||||
std::vector<u8> patch_data(out_sz);
|
||||
memcpy(patch_data.data(), out_buf, patch_data.size());
|
||||
file_util::write_binary_file(
|
||||
(file_util::get_jak_project_dir() / it->second.patch_file).string(),
|
||||
patch_data.data(), patch_data.size());
|
||||
}
|
||||
free(out_buf);
|
||||
}
|
||||
|
||||
// apply patch file if necessary
|
||||
// note that xd3 doesnt really have any safety against bad files so we check crc ourselves
|
||||
if (config.apply_patches && it->second.crc == crc32(data.data(), data.size())) {
|
||||
// this is the delta patch file
|
||||
auto data2 = file_util::read_binary_file(
|
||||
(file_util::get_jak_project_dir() / it->second.patch_file).string());
|
||||
// we need to allocate a buffer to store the patched file
|
||||
// the delta patch isn't gonna be this big but we allocate 2x the source file's size + the
|
||||
// delta patch's size
|
||||
int buf_sz = data.size() * 2 + data2.size();
|
||||
u8* out_buf = (u8*)malloc(buf_sz);
|
||||
size_t out_sz = 0;
|
||||
int xd3_res = xd3_decode_memory(data2.data(), data2.size(), data.data(), data.size(),
|
||||
out_buf, &out_sz, buf_sz, 0);
|
||||
if (xd3_res) {
|
||||
lg::error("error patching {} with {} (out {}): {}", name, it->second.target_file,
|
||||
it->second.patch_file, xd3_strerror(xd3_res));
|
||||
} else {
|
||||
data.resize(out_sz);
|
||||
memcpy(data.data(), out_buf, data.size());
|
||||
}
|
||||
free(out_buf);
|
||||
}
|
||||
}
|
||||
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO", config);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user