浏览代码

Allow Godot to import .ZIP files with non-regular structure

(cherry picked from commit 9b1db715fd51e0efa5e79bdaec5239e79b23061d)
Ev1lbl0w 4 年之前
父节点
当前提交
c2b85ed865
共有 1 个文件被更改,包括 10 次插入17 次删除
  1. 10 17
      editor/project_manager.cpp

+ 10 - 17
editor/project_manager.cpp

@@ -104,6 +104,7 @@ private:
 	FileDialog *fdialog_install;
 	String zip_path;
 	String zip_title;
+	String zip_root;
 	AcceptDialog *dialog_error;
 	String fav_dir;
 
@@ -213,7 +214,9 @@ private:
 						char fname[16384];
 						ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
 
-						if (String(fname).ends_with("project.godot")) {
+						String fname_str = String(fname);
+						if (fname_str.ends_with("project.godot")) {
+							zip_root = fname_str.substr(0, fname_str.rfind("project.godot"));
 							break;
 						}
 
@@ -548,45 +551,35 @@ private:
 
 						String path = fname;
 
-						int depth = 1; //stuff from github comes with tag
-						bool skip = false;
-						while (depth > 0) {
-							int pp = path.find("/");
-							if (pp == -1) {
-								skip = true;
-								break;
-							}
-							path = path.substr(pp + 1, path.length());
-							depth--;
-						}
-
-						if (skip || path == String()) {
+						if (path == String() || path == zip_root || !zip_root.is_subsequence_of(path)) {
 							//
 						} else if (path.ends_with("/")) { // a dir
 
 							path = path.substr(0, path.length() - 1);
+							String rel_path = path.substr(zip_root.length());
 
 							DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
-							da->make_dir(dir.plus_file(path));
+							da->make_dir(dir.plus_file(rel_path));
 							memdelete(da);
 
 						} else {
 
 							Vector<uint8_t> data;
 							data.resize(info.uncompressed_size);
+							String rel_path = path.substr(zip_root.length());
 
 							//read
 							unzOpenCurrentFile(pkg);
 							unzReadCurrentFile(pkg, data.ptrw(), data.size());
 							unzCloseCurrentFile(pkg);
 
-							FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
+							FileAccess *f = FileAccess::open(dir.plus_file(rel_path), FileAccess::WRITE);
 
 							if (f) {
 								f->store_buffer(data.ptr(), data.size());
 								memdelete(f);
 							} else {
-								failed_files.push_back(path);
+								failed_files.push_back(rel_path);
 							}
 						}