Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { EditorProgress ep("savepack","Packing",102); String tmppath = EditorSettings::get_singleton()->get_settings_path()+"/tmp/packtmp"; FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); uint64_t ofs_begin = dst->get_pos(); dst->store_32(0x43504447); //GDPK dst->store_32(0); //pack version dst->store_32(VERSION_MAJOR); dst->store_32(VERSION_MINOR); dst->store_32(VERSION_REVISION); for(int i=0;i<16;i++) { //reserved dst->store_32(0); } size_t fcountpos = dst->get_pos(); dst->store_32(0); PackData pd; pd.ep=&ep; pd.f=dst; pd.ftmp=tmp; pd.count=0; Error err = export_project_files(save_pack_file,&pd,p_make_bundles); memdelete(tmp); if (err) return err; size_t ofsplus = dst->get_pos(); //append file tmp = FileAccess::open(tmppath,FileAccess::READ); ERR_FAIL_COND_V(!tmp,ERR_CANT_OPEN;)
Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files) { EditorProgress ep("savepack", TTR("Packing"), 102, true); String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE) PackData pd; pd.ep = &ep; pd.f = ftmp; pd.so_files = p_so_files; Error err = export_project_files(p_preset, _save_pack_file, &pd, _add_shared_object); memdelete(ftmp); //close tmp file if (err) return err; pd.file_ofs.sort(); //do sort, so we can do binary search later FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE); ERR_FAIL_COND_V(!f, ERR_CANT_CREATE) f->store_32(0x43504447); //GDPK f->store_32(1); //pack version f->store_32(VERSION_MAJOR); f->store_32(VERSION_MINOR); f->store_32(0); //hmph for (int i = 0; i < 16; i++) { //reserved f->store_32(0); } f->store_32(pd.file_ofs.size()); //amount of files size_t header_size = f->get_position(); //precalculate header size for (int i = 0; i < pd.file_ofs.size(); i++) { header_size += 4; // size of path string (32 bits is enough) uint32_t string_len = pd.file_ofs[i].path_utf8.length(); header_size += string_len + _get_pad(4, string_len); ///size of path string header_size += 8; // offset to file _with_ header size included header_size += 8; // size of file header_size += 16; // md5 } size_t header_padding = _get_pad(PCK_PADDING, header_size); for (int i = 0; i < pd.file_ofs.size(); i++) { uint32_t string_len = pd.file_ofs[i].path_utf8.length(); uint32_t pad = _get_pad(4, string_len); ; f->store_32(string_len + pad); f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); for (uint32_t j = 0; j < pad; j++) { f->store_8(0); } f->store_64(pd.file_ofs[i].ofs + header_padding + header_size); f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file } for (uint32_t j = 0; j < header_padding; j++) { f->store_8(0); } //save the rest of the data ftmp = FileAccess::open(tmppath, FileAccess::READ); if (!ftmp) { memdelete(f); ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE) }
Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p_debug,const String& p_password) { String src_template; EditorProgress ep("export","Exporting for javascript",104); String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/"; if (p_debug) { src_template=custom_debug_package!=""?custom_debug_package:template_path+"javascript_debug.zip"; } else { src_template=custom_release_package!=""?custom_release_package:template_path+"javascript_release.zip"; } FileAccess *src_f=NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); ep.step("Exporting to HTML5",0); unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io); if (!pkg) { EditorNode::add_io_error("Could not find template HTML5 to export:\n"+src_template); return ERR_FILE_NOT_FOUND; } ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); int ret = unzGoToFirstFile(pkg); while(ret==UNZ_OK) { //get filename unz_file_info info; char fname[16384]; ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); String file=fname; Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); unzReadCurrentFile(pkg,data.ptr(),data.size()); unzCloseCurrentFile(pkg); //write if (file=="godot.html") { _fix_html(data,p_path.get_file().basename(),1<<(max_memory+5)); file=p_path.get_file(); } if (file=="godot.js") { //_fix_godot(data); file=p_path.get_file().basename()+".js"; } String dst = p_path.get_base_dir().plus_file(file); FileAccess *f=FileAccess::open(dst,FileAccess::WRITE); if (!f) { EditorNode::add_io_error("Could not create file for writing:\n"+dst); unzClose(pkg); return ERR_FILE_CANT_WRITE; } f->store_buffer(data.ptr(),data.size()); memdelete(f); ret = unzGoToNextFile(pkg); } ep.step("Finding Files..",1); Vector<String> remaps; FileAccess *f=FileAccess::open(p_path.basename()+"_files.js",FileAccess::WRITE); if (!f) { EditorNode::add_io_error("Could not create file for writing:\n"+p_path.basename()+"_files.js"); return ERR_FILE_CANT_WRITE; } f->store_buffer((const uint8_t*)files_pre,strlen(files_pre)); if (pack_mode==PACK_SINGLE_FILE) { String ftmp = EditorSettings::get_singleton()->get_settings_path()+"/tmp/webpack.pck"; FileAccess *f2 = FileAccess::open(ftmp,FileAccess::WRITE); if (!f2) { memdelete(f); return ERR_CANT_CREATE; } Error err = save_pack(f2,false); memdelete(f2); if (err) { memdelete(f); return ERR_CANT_CREATE; } Vector<uint8_t> data = FileAccess::get_file_as_array(ftmp); store_file_buffer(f,"data.pck",data); } else { JSExportData ed; ed.ep=&ep; ed.f=f; Error err =export_project_files(save_pack_file_js,&ed,false); if (err) return err; } f->store_buffer((const uint8_t*)files_post,strlen(files_post)); memdelete(f); return OK; }