summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/file_access_pack.cpp27
-rw-r--r--core/io/file_access_pack.h6
-rw-r--r--core/io/file_access_zip.cpp23
-rw-r--r--core/io/file_access_zip.h2
4 files changed, 48 insertions, 10 deletions
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 0a7dee9444..aa10afe642 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -30,15 +30,16 @@
#include "file_access_pack.h"
+#include "core/project_settings.h"
#include "core/version.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++) {
- 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;
};
@@ -89,7 +90,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
}
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()) {
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);
if (!f)
@@ -198,6 +199,24 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files)
String path;
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 size = f->get_64();
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 8df6826ac9..1a46bef0f6 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -113,7 +113,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, const String &p_destination);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
@@ -125,7 +125,7 @@ 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, const String &p_destination = "") = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
@@ -133,7 +133,7 @@ public:
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, const String &p_destination = "");
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 57de66afaf..5696e47193 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -160,7 +160,7 @@ 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, 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"));
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;
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;
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index d5ce7d7a8d..5bcaea7ed9 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -74,7 +74,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, const String &p_destination = "");
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive *get_singleton();