Merge pull request #40400 from Arivval/load-resourcepack-with-offset

Added PCK file loading with offset feature
This commit is contained in:
Rémi Verschelde 2020-09-03 07:33:19 +02:00 committed by GitHub
commit 4a5138bb99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 13 deletions

View file

@ -34,9 +34,9 @@
#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, size_t p_offset) {
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_offset)) {
return OK;
}
}
@ -123,15 +123,24 @@ 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, size_t p_offset) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
return false;
}
f->seek(p_offset);
uint32_t magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
// loading with offset feature not supported for self contained exe files
if (p_offset != 0) {
f->close();
memdelete(f);
ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported.");
}
//maybe at the end.... self contained exe
f->seek_end();
f->seek(f->get_position() - 4);
@ -191,7 +200,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this, p_replace_files);
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files);
}
f->close();

View file

@ -108,7 +108,7 @@ public:
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
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, size_t p_offset);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
@ -119,14 +119,14 @@ public:
class PackSource {
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, size_t p_offset) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
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, size_t p_offset);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};

View file

@ -147,8 +147,11 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
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, size_t p_offset = 0) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
// load with offset feature only supported for PCK files
ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives.");
if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) {
return false;
}

View file

@ -69,7 +69,7 @@ public:
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, size_t p_offset);
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive *get_singleton();

View file

@ -291,12 +291,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, int p_offset) {
if (PackedData::get_singleton()->is_disabled()) {
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_offset) == OK;
if (!ok) {
return false;
@ -1030,7 +1030,7 @@ void ProjectSettings::_bind_methods() {
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("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", "offset"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(0));
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);

View file

@ -107,7 +107,7 @@ protected:
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, int p_offset = 0);
void _add_property_info_bind(const Dictionary &p_info);

View file

@ -92,9 +92,12 @@
</argument>
<argument index="1" name="replace_files" type="bool" default="true">
</argument>
<argument index="2" name="offset" type="int" default="0">
</argument>
<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.
[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] The optional [code]offset[/code] parameter can be used to specify the offset in bytes to the start of the resource pack. This is only supported for .pck files.
</description>
</method>
<method name="localize_path" qualifiers="const">