You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-05 17:15:09 +00:00
Add ability for PCK patches to remove files
Co-authored-by: Mikael Hermansson <mikael@hermansson.io>
This commit is contained in:
@@ -48,7 +48,7 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t
|
||||
}
|
||||
|
||||
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) {
|
||||
String simplified_path = p_path.simplify_path();
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
|
||||
bool exists = files.has(pmd5);
|
||||
@@ -68,13 +68,11 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
//search for dir
|
||||
String p = simplified_path.replace_first("res://", "");
|
||||
// Search for directory.
|
||||
PackedDir *cd = root;
|
||||
|
||||
if (p.contains("/")) { //in a subdir
|
||||
|
||||
Vector<String> ds = p.get_base_dir().split("/");
|
||||
if (simplified_path.contains("/")) { // In a subdirectory.
|
||||
Vector<String> ds = simplified_path.get_base_dir().split("/");
|
||||
|
||||
for (int j = 0; j < ds.size(); j++) {
|
||||
if (!cd->subdirs.has(ds[j])) {
|
||||
@@ -89,13 +87,40 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
|
||||
}
|
||||
}
|
||||
String filename = simplified_path.get_file();
|
||||
// Don't add as a file if the path points to a directory
|
||||
// Don't add as a file if the path points to a directory.
|
||||
if (!filename.is_empty()) {
|
||||
cd->files.insert(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PackedData::remove_path(const String &p_path) {
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
if (!files.has(pmd5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for directory.
|
||||
PackedDir *cd = root;
|
||||
|
||||
if (simplified_path.contains("/")) { // In a subdirectory.
|
||||
Vector<String> ds = simplified_path.get_base_dir().split("/");
|
||||
|
||||
for (int j = 0; j < ds.size(); j++) {
|
||||
if (!cd->subdirs.has(ds[j])) {
|
||||
return; // Subdirectory does not exist, do not bother creating.
|
||||
} else {
|
||||
cd = cd->subdirs[ds[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cd->files.erase(simplified_path.get_file());
|
||||
|
||||
files.erase(pmd5);
|
||||
}
|
||||
|
||||
void PackedData::add_pack_source(PackSource *p_source) {
|
||||
if (p_source != nullptr) {
|
||||
sources.push_back(p_source);
|
||||
@@ -103,15 +128,32 @@ void PackedData::add_pack_source(PackSource *p_source) {
|
||||
}
|
||||
|
||||
uint8_t *PackedData::get_file_hash(const String &p_path) {
|
||||
PathMD5 pmd5(p_path.md5_buffer());
|
||||
String simplified_path = p_path.simplify_path().trim_prefix("res://");
|
||||
PathMD5 pmd5(simplified_path.md5_buffer());
|
||||
HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5);
|
||||
if (!E || E->value.offset == 0) {
|
||||
if (!E) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return E->value.md5;
|
||||
}
|
||||
|
||||
HashSet<String> PackedData::get_file_paths() const {
|
||||
HashSet<String> file_paths;
|
||||
_get_file_paths(root, root->name, file_paths);
|
||||
return file_paths;
|
||||
}
|
||||
|
||||
void PackedData::_get_file_paths(PackedDir *p_dir, const String &p_parent_dir, HashSet<String> &r_paths) const {
|
||||
for (const String &E : p_dir->files) {
|
||||
r_paths.insert(p_parent_dir.path_join(E));
|
||||
}
|
||||
|
||||
for (const KeyValue<String, PackedDir *> &E : p_dir->subdirs) {
|
||||
_get_file_paths(E.value, p_parent_dir.path_join(E.key), r_paths);
|
||||
}
|
||||
}
|
||||
|
||||
void PackedData::clear() {
|
||||
files.clear();
|
||||
_free_packed_dirs(root);
|
||||
@@ -269,13 +311,17 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
|
||||
String path;
|
||||
path.parse_utf8(cs.ptr());
|
||||
|
||||
uint64_t ofs = file_base + f->get_64();
|
||||
uint64_t ofs = f->get_64();
|
||||
uint64_t size = f->get_64();
|
||||
uint8_t md5[16];
|
||||
f->get_buffer(md5, 16);
|
||||
uint32_t flags = f->get_32();
|
||||
|
||||
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED));
|
||||
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 + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user