summaryrefslogtreecommitdiff
path: root/editor/export_template_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/export_template_manager.cpp')
-rw-r--r--editor/export_template_manager.cpp138
1 files changed, 135 insertions, 3 deletions
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index ce1d545510..4e499021f9 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -193,6 +193,7 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
int fc = 0; //count them and find version
String version;
+ String contents_dir;
while (ret == UNZ_OK) {
@@ -225,6 +226,7 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
}
version = data_str;
+ contents_dir = file.get_base_dir().trim_suffix("/").trim_suffix("\\");
}
if (file.get_file().size() != 0) {
@@ -268,7 +270,9 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
char fname[16384];
unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
- String file = String(fname).get_file();
+ String file_path(String(fname).simplify_path());
+
+ String file = file_path.get_file();
if (file.size() == 0) {
ret = unzGoToNextFile(pkg);
@@ -283,11 +287,29 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
+ String base_dir = file_path.get_base_dir().trim_suffix("/");
+
+ if (base_dir != contents_dir && base_dir.begins_with(contents_dir)) {
+ base_dir = base_dir.substr(contents_dir.length(), file_path.length()).trim_prefix("/");
+ file = base_dir.plus_file(file);
+
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ ERR_CONTINUE(!da);
+
+ String output_dir = template_path.plus_file(base_dir);
+
+ if (!DirAccess::exists(output_dir)) {
+ Error mkdir_err = da->make_dir_recursive(output_dir);
+ ERR_CONTINUE(mkdir_err != OK);
+ }
+ }
+
if (p) {
p->step(TTR("Importing:") + " " + file, fc);
}
- FileAccess *f = FileAccess::open(template_path.plus_file(file), FileAccess::WRITE);
+ String to_write = template_path.plus_file(file);
+ FileAccess *f = FileAccess::open(to_write, FileAccess::WRITE);
if (!f) {
ret = unzGoToNextFile(pkg);
@@ -299,6 +321,10 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
memdelete(f);
+#ifndef WINDOWS_ENABLED
+ FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF);
+#endif
+
ret = unzGoToNextFile(pkg);
fc++;
}
@@ -520,6 +546,112 @@ void ExportTemplateManager::_notification(int p_what) {
}
}
+bool ExportTemplateManager::can_install_android_template() {
+
+ return FileAccess::exists(EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip"));
+}
+
+Error ExportTemplateManager::install_android_template() {
+
+ DirAccessRef da = DirAccess::open("res://");
+ ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
+ //make android dir (if it does not exist)
+
+ da->make_dir("android");
+ {
+ //add an empty .gdignore file to avoid scan
+ FileAccessRef f = FileAccess::open("res://android/.gdignore", FileAccess::WRITE);
+ ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
+ f->store_line("");
+ f->close();
+ }
+ {
+ //add version, to ensure building won't work if template and Godot version don't match
+ FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::WRITE);
+ ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
+ f->store_line(VERSION_FULL_CONFIG);
+ f->close();
+ }
+
+ Error err = da->make_dir_recursive("android/build");
+ ERR_FAIL_COND_V(err != OK, err);
+
+ String source_zip = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip");
+ ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN);
+
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ unzFile pkg = unzOpen2(source_zip.utf8().get_data(), &io);
+ ERR_EXPLAIN("Android sources not in zip format");
+ ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
+
+ int ret = unzGoToFirstFile(pkg);
+
+ int total_files = 0;
+ //count files
+ while (ret == UNZ_OK) {
+ total_files++;
+ ret = unzGoToNextFile(pkg);
+ }
+
+ ret = unzGoToFirstFile(pkg);
+ //decompress files
+ ProgressDialog::get_singleton()->add_task("uncompress", TTR("Uncompressing Android Build Sources"), total_files);
+
+ Set<String> dirs_tested;
+
+ int idx = 0;
+ while (ret == UNZ_OK) {
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
+
+ String name = fname;
+
+ String base_dir = name.get_base_dir();
+
+ if (!name.ends_with("/")) {
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg, data.ptrw(), data.size());
+ unzCloseCurrentFile(pkg);
+
+ if (!dirs_tested.has(base_dir)) {
+ da->make_dir_recursive(String("android/build").plus_file(base_dir));
+ dirs_tested.insert(base_dir);
+ }
+
+ String to_write = String("res://android/build").plus_file(name);
+ FileAccess *f = FileAccess::open(to_write, FileAccess::WRITE);
+ if (f) {
+ f->store_buffer(data.ptr(), data.size());
+ memdelete(f);
+#ifndef WINDOWS_ENABLED
+ FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF);
+#endif
+ } else {
+ ERR_PRINTS("Can't uncompress file: " + to_write);
+ }
+ }
+
+ ProgressDialog::get_singleton()->task_step("uncompress", name, idx);
+
+ idx++;
+ ret = unzGoToNextFile(pkg);
+ }
+
+ ProgressDialog::get_singleton()->end_task("uncompress");
+ unzClose(pkg);
+
+ return OK;
+}
+
void ExportTemplateManager::_bind_methods() {
ClassDB::bind_method("_download_template", &ExportTemplateManager::_download_template);
@@ -558,7 +690,7 @@ ExportTemplateManager::ExportTemplateManager() {
remove_confirm->connect("confirmed", this, "_uninstall_template_confirm");
template_open = memnew(FileDialog);
- template_open->set_title(TTR("Select template file"));
+ template_open->set_title(TTR("Select Template File"));
template_open->add_filter("*.tpz ; Godot Export Templates");
template_open->set_access(FileDialog::ACCESS_FILESYSTEM);
template_open->set_mode(FileDialog::MODE_OPEN_FILE);