You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-02 16:48:55 +00:00
Add support for delta encoding to patch PCKs
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "file_access_pack.h"
|
||||
|
||||
#include "core/io/file_access_encrypted.h"
|
||||
#include "core/io/file_access_patched.h"
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/version.h"
|
||||
@@ -45,7 +46,7 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
|
||||
void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted, bool p_bundle) {
|
||||
void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted, bool p_bundle, bool p_delta) {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
|
||||
@@ -54,6 +55,7 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
|
||||
PackedFile pf;
|
||||
pf.encrypted = p_encrypted;
|
||||
pf.bundle = p_bundle;
|
||||
pf.delta = p_delta;
|
||||
pf.pack = p_pkg_path;
|
||||
pf.offset = p_ofs;
|
||||
pf.size = p_size;
|
||||
@@ -62,8 +64,11 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
|
||||
}
|
||||
pf.src = p_src;
|
||||
|
||||
if (!exists || p_replace_files) {
|
||||
if (p_delta) {
|
||||
delta_patches[pmd5].push_back(pf);
|
||||
} else if (!exists || p_replace_files) {
|
||||
files[pmd5] = pf;
|
||||
delta_patches[pmd5].clear();
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
@@ -137,6 +142,28 @@ uint8_t *PackedData::get_file_hash(const String &p_path) {
|
||||
return E->value.md5;
|
||||
}
|
||||
|
||||
Vector<PackedData::PackedFile> PackedData::get_delta_patches(const String &p_path) const {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
HashMap<PathMD5, Vector<PackedFile>, PathMD5>::ConstIterator E = delta_patches.find(pmd5);
|
||||
if (!E) {
|
||||
return Vector<PackedFile>();
|
||||
}
|
||||
|
||||
return E->value;
|
||||
}
|
||||
|
||||
bool PackedData::has_delta_patches(const String &p_path) const {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
HashMap<PathMD5, Vector<PackedFile>, PathMD5>::ConstIterator E = delta_patches.find(pmd5);
|
||||
if (!E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !E->value.is_empty();
|
||||
}
|
||||
|
||||
HashSet<String> PackedData::get_file_paths() const {
|
||||
HashSet<String> file_paths;
|
||||
_get_file_paths(root, root->name, file_paths);
|
||||
@@ -155,6 +182,7 @@ void PackedData::_get_file_paths(PackedDir *p_dir, const String &p_parent_dir, H
|
||||
|
||||
void PackedData::clear() {
|
||||
files.clear();
|
||||
delta_patches.clear();
|
||||
_free_packed_dirs(root);
|
||||
root = memnew(PackedDir);
|
||||
}
|
||||
@@ -322,7 +350,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
|
||||
if (flags & PACK_FILE_REMOVAL) { // The file was removed.
|
||||
PackedData::get_singleton()->remove_path(path);
|
||||
} else {
|
||||
PackedData::get_singleton()->add_path(p_path, path, file_base + ofs, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED), sparse_bundle);
|
||||
PackedData::get_singleton()->add_path(p_path, path, file_base + ofs, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED), sparse_bundle, (flags & PACK_FILE_DELTA));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +358,17 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
|
||||
}
|
||||
|
||||
Ref<FileAccess> PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
|
||||
return memnew(FileAccessPack(p_path, *p_file));
|
||||
Ref<FileAccess> file(memnew(FileAccessPack(p_path, *p_file)));
|
||||
|
||||
if (PackedData::get_singleton()->has_delta_patches(p_path)) {
|
||||
Ref<FileAccessPatched> file_patched;
|
||||
file_patched.instantiate();
|
||||
Error err = file_patched->open_custom(file);
|
||||
ERR_FAIL_COND_V(err != OK, Ref<FileAccess>());
|
||||
file = file_patched;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -362,7 +400,7 @@ void PackedSourceDirectory::add_directory(const String &p_path, bool p_replace_f
|
||||
for (const String &file_name : da->get_files()) {
|
||||
String file_path = p_path.path_join(file_name);
|
||||
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
PackedData::get_singleton()->add_path(p_path, file_path, 0, 0, md5, this, p_replace_files, false, false);
|
||||
PackedData::get_singleton()->add_path(p_path, file_path, 0, 0, md5, this, p_replace_files, false, false, false);
|
||||
}
|
||||
|
||||
for (const String &sub_dir_name : da->get_directories()) {
|
||||
@@ -470,6 +508,7 @@ void FileAccessPack::close() {
|
||||
}
|
||||
|
||||
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) {
|
||||
path = p_path;
|
||||
pf = p_file;
|
||||
if (pf.bundle) {
|
||||
String simplified_path = p_path.simplify_path();
|
||||
|
||||
Reference in New Issue
Block a user