Made possible to specify where to dump the contents when loading a ".pck" file

(cherry picked from commit 3c261e0dfa)
This commit is contained in:
Michael Alexsander 2020-01-17 22:26:44 -03:00 committed by Rémi Verschelde
parent 008e0748c1
commit ffcfd9c8ea
7 changed files with 55 additions and 15 deletions

View File

@ -30,15 +30,16 @@
#include "file_access_pack.h" #include "file_access_pack.h"
#include "core/project_settings.h"
#include "core/version.h" #include "core/version.h"
#include <stdio.h> #include <stdio.h>
Error PackedData::add_pack(const String &p_path, bool p_replace_files) { Error PackedData::add_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
for (int i = 0; i < sources.size(); i++) { for (int i = 0; i < sources.size(); i++) {
if (sources[i]->try_open_pack(p_path, p_replace_files)) { if (sources[i]->try_open_pack(p_path, p_replace_files, p_destination)) {
return OK; return OK;
}; };
@ -89,7 +90,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
} }
} }
String filename = path.get_file(); String filename = 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.empty()) { if (!filename.empty()) {
cd->files.insert(filename); cd->files.insert(filename);
} }
@ -132,7 +133,7 @@ PackedData::~PackedData() {
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) { bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ); FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) if (!f)
@ -198,6 +199,24 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
String path; String path;
path.parse_utf8(cs.ptr()); path.parse_utf8(cs.ptr());
if (p_destination != "") {
String destination = ProjectSettings::get_singleton()->localize_path(p_destination);
ERR_FAIL_COND_V_MSG(!destination.begins_with("res://"), false, "The destination path must be within the resource filesystem (res://).");
if (!destination.ends_with("/")) {
destination += "/";
}
DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (!dir->dir_exists(destination)) {
memdelete(dir);
ERR_FAIL_V_MSG(false, vformat("The destination path \"%s\" does not exist.", destination));
}
memdelete(dir);
path = path.replace_first("res://", destination);
}
uint64_t ofs = f->get_64(); uint64_t ofs = f->get_64();
uint64_t size = f->get_64(); uint64_t size = f->get_64();

View File

@ -113,7 +113,7 @@ public:
_FORCE_INLINE_ bool is_disabled() const { return disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; } static PackedData *get_singleton() { return singleton; }
Error add_pack(const String &p_path, bool p_replace_files); Error add_pack(const String &p_path, bool p_replace_files, const String &p_destination);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path);
@ -125,7 +125,7 @@ public:
class PackSource { class PackSource {
public: public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0; virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "") = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {} virtual ~PackSource() {}
}; };
@ -133,7 +133,7 @@ public:
class PackedSourcePCK : public PackSource { class PackedSourcePCK : public PackSource {
public: public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files); virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "");
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
}; };

View File

@ -160,7 +160,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
return pkg; return pkg;
} }
bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) { bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0)
@ -206,7 +206,26 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
f.package = pkg_num; f.package = pkg_num;
unzGetFilePos(zfile, &f.file_pos); unzGetFilePos(zfile, &f.file_pos);
String fname = String("res://") + filename_inzip; String fname;
if (p_destination != "") {
String destination = "res://" + p_destination;
if (!destination.ends_with("/")) {
destination += "/";
}
DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (!dir->dir_exists(destination)) {
memdelete(dir);
return false;
}
memdelete(dir);
fname = destination + filename_inzip;
} else {
fname = String("res://") + filename_inzip;
}
files[fname] = f; files[fname] = f;
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

View File

@ -74,7 +74,7 @@ public:
bool file_exists(String p_name) const; bool file_exists(String p_name) const;
virtual bool try_open_pack(const String &p_path, bool p_replace_files); virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "");
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive *get_singleton(); static ZipArchive *get_singleton();

View File

@ -268,12 +268,12 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
} }
} }
bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files) { bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, const String &p_destination) {
if (PackedData::get_singleton()->is_disabled()) if (PackedData::get_singleton()->is_disabled())
return false; return false;
bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files) == OK; bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_destination) == OK;
if (!ok) if (!ok)
return false; return false;
@ -990,7 +990,7 @@ void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path); ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path); ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save); ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files"), &ProjectSettings::_load_resource_pack, DEFVAL(true)); ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "destination"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(""));
ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert);
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert);

View File

@ -104,7 +104,7 @@ protected:
void _convert_to_last_version(int p_from_version); void _convert_to_last_version(int p_from_version);
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true); bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, const String &p_destination = "");
void _add_property_info_bind(const Dictionary &p_info); void _add_property_info_bind(const Dictionary &p_info);

View File

@ -92,8 +92,10 @@
</argument> </argument>
<argument index="1" name="replace_files" type="bool" default="true"> <argument index="1" name="replace_files" type="bool" default="true">
</argument> </argument>
<argument index="2" name="destination" type="String" default="">
</argument>
<description> <description>
Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success. Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]) at the [code]destination[/code] path, if given. Returns [code]true[/code] on success.
[b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code]. [b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code].
</description> </description>
</method> </method>