bool ZipArchive::try_open_pack(const String& p_name) { //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_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0) return false; zlib_filefunc_def io; FileAccess* f = FileAccess::open(p_name, FileAccess::READ); if (!f) return false; io.opaque = f; io.zopen_file = godot_open; io.zread_file = godot_read; io.zwrite_file = godot_write; io.ztell_file = godot_tell; io.zseek_file = godot_seek; io.zclose_file = godot_close; io.zerror_file = godot_testerror; unzFile zfile = unzOpen2(p_name.utf8().get_data(), &io); ERR_FAIL_COND_V(!zfile, false); unz_global_info64 gi; int err = unzGetGlobalInfo64(zfile, &gi); ERR_FAIL_COND_V(err!=UNZ_OK, false); Package pkg; pkg.filename = p_name; pkg.zfile = zfile; packages.push_back(pkg); int pkg_num = packages.size()-1; for (unsigned int i=0;i<gi.number_entry;i++) { char filename_inzip[256]; unz_file_info64 file_info; err = unzGetCurrentFileInfo64(zfile,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); ERR_CONTINUE(err != UNZ_OK); File f; f.package = pkg_num; unzGetFilePos(zfile, &f.file_pos); String 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}; PackedData::get_singleton()->add_path(p_name, fname, 1, 0, md5, this); //printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str()); if ((i+1)<gi.number_entry) { unzGoToNextFile(zfile); }; }; return true; };
Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) { String local_path; if (p_path.is_rel_path()) local_path="res://"+p_path; else local_path = Globals::get_singleton()->localize_path(p_path); String extension=p_path.extension(); Ref<ResourceImportMetadata> ret; for (int i=0;i<loader_count;i++) { if (!loader[i]->recognize(extension)) continue; Error err = loader[i]->load_import_metadata(local_path,ret); if (err==OK) break; } return ret; }
String ResourceFormatLoaderVideoStreamWebm::get_resource_type(const String &p_path) const { const String exl = p_path.extension().to_lower(); if (exl == "webm") return "VideoStreamWebm"; return ""; }
String ResourceFormatLoaderVideoStreamTheora::get_resource_type(const String &p_path) const { String exl=p_path.extension().to_lower(); if (exl=="ogm" || exl=="ogv") return "AudioStreamTheora"; return ""; }
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) { String extension=p_path.extension(); Error err=ERR_FILE_UNRECOGNIZED; for (int i=0;i<saver_count;i++) { if (!saver[i]->recognize(p_resource)) continue; List<String> extensions; bool recognized=false; saver[i]->get_recognized_extensions(p_resource,&extensions); for (List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get().nocasecmp_to(extension.extension())==0) recognized=true; } if (!recognized) continue; String old_path=p_resource->get_path(); String local_path=Globals::get_singleton()->localize_path(p_path); RES rwcopy = p_resource; if (p_flags&FLAG_CHANGE_PATH) rwcopy->set_path(local_path); err = saver[i]->save(p_path,p_resource,p_flags); if (err == OK ) { #ifdef TOOLS_ENABLED ((Resource*)p_resource.ptr())->set_edited(false); if (timestamp_on_save) { uint64_t mt = FileAccess::get_modified_time(p_path); ((Resource*)p_resource.ptr())->set_last_modified_time(mt); } #endif if (p_flags&FLAG_CHANGE_PATH) rwcopy->set_path(old_path); if (save_callback && p_path.begins_with("res://")) save_callback(p_path); return OK; } else { } } return err; }
String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const { String el = p_path.extension().to_lower(); if (el=="ttf") return "DynamicFontData"; return ""; }
String ResourceFormatLoaderText::get_resource_type(const String &p_path) const{ String ext=p_path.extension().to_lower(); if (ext=="tscn") return "PackedScene"; else if (ext!="tres") return String(); //for anyhting else must test.. FileAccess *f = FileAccess::open(p_path,FileAccess::READ); if (!f) { return ""; //could not rwead } Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText ); ria->local_path=Globals::get_singleton()->localize_path(p_path); ria->res_path=ria->local_path; // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); String r = ria->recognize(f); return r; }
String ResourceFormatLoaderBitMap::get_resource_type(const String &p_path) const { List<String> extensions; ImageLoader::get_recognized_extensions(&extensions); String ext=p_path.extension().to_lower(); for(List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get()==ext) return "BitMap"; } return ""; }
RES ResourceFormatLoaderChibi::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_FILE_CANT_OPEN; String el = p_path.extension().to_lower(); CPFileAccessWrapperImpl f; if (el=="it") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_IT loader(&f); CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false); ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); if (r_error) *r_error=OK; return esc; } else if (el=="xm") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_XM loader(&f); CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); if (r_error) *r_error=OK; return esc; } else if (el=="s3m") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_S3M loader(&f); CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); if (r_error) *r_error=OK; return esc; } else if (el=="mod") { Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); CPLoader_MOD loader(&f); CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); if (r_error) *r_error=OK; return esc; } return RES(); }
Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_fname); if (rimd.is_valid()) { if (rimd->get_editor()!="") { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name(rimd->get_editor()); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) return ce; } } } else if (EditorImportExport::get_singleton()->image_get_export_group(p_fname)) { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) { p_fname=p_fname.basename()+".tex"; return ce; } } } else if (EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE){ String xt = p_fname.extension().to_lower(); print_line("TRY FOR: "+p_fname); if (EditorImportExport::get_singleton()->get_image_formats().has(xt)) { //should check for more I guess? Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) { p_fname=p_fname.basename()+".tex"; return ce; } } } } FileAccess *f = FileAccess::open(p_fname,FileAccess::READ); ERR_FAIL_COND_V(!f,Vector<uint8_t>()); Vector<uint8_t> ret; ret.resize(f->get_len()); int rbs = f->get_buffer(ret.ptr(),ret.size()); memdelete(f); return ret; }
bool ResourceFormatLoader::recognize(const String& p_extension) const { List<String> extensions; get_recognized_extensions(&extensions); for (List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get().nocasecmp_to(p_extension.extension())==0) return true; } return false; }
String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const { String ext=p_path.extension().to_lower(); if (ext=="cube") return "CubeMap"; List<String> extensions; ImageLoader::get_recognized_extensions(&extensions); for(List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get()==ext) return "ImageTexture"; } return ""; }
Vector<uint8_t> EditorTextureExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); if (rimd.is_valid()) { if (rimd->get_editor()!="") { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name(rimd->get_editor()); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); if (ce.size()) return ce; } } } else if (EditorImportExport::get_singleton()->image_get_export_group(p_path)) { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); if (ce.size()) { p_path=p_path.basename()+".tex"; return ce; } } } else if (EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE){ String xt = p_path.extension().to_lower(); if (EditorImportExport::get_singleton()->get_image_formats().has(xt)) { //should check for more I guess? Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); if (ce.size()) { p_path=p_path.basename()+".tex"; return ce; } } } } return Vector<uint8_t>(); }
Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom) { FileAccess *f=p_custom; if (!f) { Error err; f=FileAccess::open(p_file,FileAccess::READ,&err); if (!f) { print_line("ERROR OPENING FILE: "+p_file); return err; } } String extension = p_file.extension(); for (int i=0;i<loader_count;i++) { if (!loader[i]->recognize(extension)) continue; Error err = loader[i]->load_image(p_image,f); if (err!=ERR_FILE_UNRECOGNIZED) { if (!p_custom) memdelete(f); return err; } } print_line("NO LOADER?"); if (!p_custom) memdelete(f); return ERR_FILE_UNRECOGNIZED; }
Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); if (rimd.is_null()) { StringName group = EditorImportExport::get_singleton()->image_get_export_group(p_path); if (group!=StringName()) { //handled by export group rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); int group_format=0; float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(group); int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(group); group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink(); switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(group)) { case EditorImportExport::IMAGE_ACTION_NONE: { switch(EditorImportExport::get_singleton()->get_export_image_action()) { case EditorImportExport::IMAGE_ACTION_NONE: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //? } break; //use default case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; } break; //use default case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; } break; //use default } group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality(); } break; //use default case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; } break; //use default case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; } break; //use default } int flags=0; if (Globals::get_singleton()->get("texture_import/filter")) flags|=IMAGE_FLAG_FILTER; if (!Globals::get_singleton()->get("texture_import/gen_mipmaps")) flags|=IMAGE_FLAG_NO_MIPMAPS; if (!Globals::get_singleton()->get("texture_import/repeat")) flags|=IMAGE_FLAG_REPEAT; flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; print_line("group format"+itos(group_format)); rimd->set_option("format",group_format); rimd->set_option("flags",flags); rimd->set_option("quality",group_lossy_quality); rimd->set_option("atlas",false); rimd->set_option("shrink",group_shrink); rimd->add_source(EditorImportPlugin::validate_source_path(p_path)); } else if (EditorImportExport::get_singleton()->get_image_formats().has(p_path.extension().to_lower()) && EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE) { //handled by general image export settings rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); switch(EditorImportExport::get_singleton()->get_export_image_action()) { case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_DISK_LOSSY); break; case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_RAM); break; } int flags=0; if (Globals::get_singleton()->get("texture_import/filter")) flags|=IMAGE_FLAG_FILTER; if (!Globals::get_singleton()->get("texture_import/gen_mipmaps")) flags|=IMAGE_FLAG_NO_MIPMAPS; if (!Globals::get_singleton()->get("texture_import/repeat")) flags|=IMAGE_FLAG_REPEAT; flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; rimd->set_option("shrink",EditorImportExport::get_singleton()->get_export_image_shrink()); rimd->set_option("flags",flags); rimd->set_option("quality",EditorImportExport::get_singleton()->get_export_image_quality()); rimd->set_option("atlas",false); rimd->add_source(EditorImportPlugin::validate_source_path(p_path)); } else { return Vector<uint8_t>(); } } int fmt = rimd->get_option("format"); if (fmt!=IMAGE_FORMAT_COMPRESS_RAM && fmt!=IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { print_line("no compress ram or lossy"); return Vector<uint8_t>(); //pointless to do anything, since no need to reconvert } uint32_t flags = rimd->get_option("flags"); uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1); uint8_t format = rimd->get_option("format"); uint8_t comp = (format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM)?uint8_t(p_platform->get_image_compression()):uint8_t(255); MD5_CTX ctx; uint8_t f4[4]; encode_uint32(flags,&f4[0]); MD5Init(&ctx); String gp = Globals::get_singleton()->globalize_path(p_path); CharString cs = gp.utf8(); MD5Update(&ctx,(unsigned char*)cs.get_data(),cs.length()); MD5Update(&ctx,f4,4); MD5Update(&ctx,&format,1); MD5Update(&ctx,&comp,1); MD5Update(&ctx,&shrink,1); MD5Final(&ctx); uint64_t sd=0; String smd5; String md5 = String::md5(ctx.digest); String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); bool valid=false; { //if existing, make sure it's valid FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::READ); if (f) { uint64_t d = f->get_line().strip_edges().to_int64(); sd = FileAccess::get_modified_time(p_path); if (d==sd) { valid=true; } else { String cmd5 = f->get_line().strip_edges(); smd5 = FileAccess::get_md5(p_path); if (cmd5==smd5) { valid=true; } } } } if (!valid) { //cache failed, convert Error err = import2(tmp_path+"imgexp-"+md5+".tex",rimd,p_platform->get_image_compression(),true); ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::WRITE); if (sd==0) sd = FileAccess::get_modified_time(p_path); if (smd5==String()) smd5 = FileAccess::get_md5(p_path); f->store_line(String::num(sd)); f->store_line(smd5); f->store_line(gp); //source path for reference } Vector<uint8_t> ret; FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".tex",FileAccess::READ); ERR_FAIL_COND_V(!f,ret); ret.resize(f->get_len()); f->get_buffer(ret.ptr(),ret.size()); return ret; }
EditorFileSystem::DirItem* EditorFileSystem::_scan_dir(DirAccess *da,Set<String> &extensions,String p_name,float p_from,float p_range,const String& p_path,HashMap<String,FileCache> &file_cache,HashMap<String,DirCache> &dir_cache,EditorProgressBG& p_prog) { if (abort_scan) return NULL; if (p_path!=String()) { if (FileAccess::exists(("res://"+p_path).plus_file("engine.cfg"))) { return NULL; } } List<String> dirs; List<String> files; Set<String> pngs; String path=p_path; if (path.ends_with("/")) path=path.substr(0,path.length()-1); String global_path = Globals::get_singleton()->get_resource_path().plus_file(path); path="res://"+path; uint64_t mtime = FileAccess::get_modified_time(global_path); DirCache *dc = dir_cache.getptr(path); if (false && dc && dc->modification_time==mtime) { //use the cached files, since directory did not change for (Set<String>::Element *E=dc->subdirs.front();E;E=E->next()) { dirs.push_back(E->get()); } for (Set<String>::Element *E=dc->files.front();E;E=E->next()) { files.push_back(E->get()); } } else { //use the filesystem, some files may have changed Error err = da->change_dir(global_path); if (err!=OK) { print_line("Can't change to: "+path); ERR_FAIL_COND_V(err!=OK,NULL); } da->list_dir_begin(); while (true) { bool isdir; String f = da->get_next(&isdir); if (f=="") break; if (isdir) { dirs.push_back(f); } else { String ext = f.extension().to_lower(); if (extensions.has(ext)) files.push_back(f); } } da->list_dir_end(); files.sort(); dirs.sort(); } //print_line(da->get_current_dir()+": dirs: "+itos(dirs.size())+" files:"+itos(files.size()) ); //find subdirs Vector<DirItem*> subdirs; //String current = da->get_current_dir(); float idx=0; for (List<String>::Element *E=dirs.front();E;E=E->next(),idx+=1.0) { String d = E->get(); if (d.begins_with(".")) //ignore hidden and . / .. continue; //ERR_CONTINUE( da->change_dir(d)!= OK ); DirItem *sdi = _scan_dir(da,extensions,d,p_from+(idx/dirs.size())*p_range,p_range/dirs.size(),p_path+d+"/",file_cache,dir_cache,p_prog); if (sdi) { subdirs.push_back(sdi); } //da->change_dir(current); } if (subdirs.empty() && files.empty()) { total=p_from+p_range; p_prog.step(total*100); return NULL; //give up, nothing to do here } DirItem *di = memnew( DirItem ); di->path=path; di->name=p_name; di->dirs=subdirs; di->modified_time=mtime; //add files for (List<String>::Element *E=files.front();E;E=E->next()) { SceneItem * si = memnew( SceneItem ); si->file=E->get(); si->path="res://"+p_path+si->file; FileCache *fc = file_cache.getptr(si->path); uint64_t mt = FileAccess::get_modified_time(si->path); if (fc && fc->modification_time == mt) { si->meta=fc->meta; si->type=fc->type; si->modified_time=fc->modification_time; } else { si->meta=_get_meta(si->path); si->type=ResourceLoader::get_resource_type(si->path); si->modified_time=mt; } if (si->meta.enabled) { md_count++; if (_check_meta_sources(si->meta)) { sources_changed.push_back(si->path); } } di->files.push_back(si); } total=p_from+p_range; p_prog.step(total*100); return di; }
String ResourceFormatLoaderChibi::get_resource_type(const String &p_path) const { String el = p_path.extension().to_lower(); if (el=="it" || el=="s3m" || el=="xm" || el=="mod") return "EventStreamChibi"; return ""; }
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const ScanProgress& p_progress) { uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path()); bool updated_dir=false; //print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime)); if (current_mtime!=p_dir->modified_time) { updated_dir=true; p_dir->modified_time=current_mtime; //ooooops, dir changed, see what's going on //first mark everything as veryfied for(int i=0;i<p_dir->files.size();i++) { p_dir->files[i]->verified=false; } for(int i=0;i<p_dir->subdirs.size();i++) { p_dir->get_subdir(i)->verified=false; } //then scan files and directories and check what's different DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); String cd = p_dir->get_path(); da->change_dir(cd); da->list_dir_begin(); while (true) { bool isdir; String f = da->get_next(&isdir); if (f=="") break; if (isdir) { if (f.begins_with(".")) //ignore hidden and . / .. continue; int idx = p_dir->find_dir_index(f); if (idx==-1) { if (FileAccess::exists(cd.plus_file(f).plus_file("engine.cfg"))) // skip if another project inside this continue; EditorFileSystemDirectory *efd = memnew( EditorFileSystemDirectory ); efd->parent=p_dir; efd->name=f; DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir(cd.plus_file(f)); _scan_new_dir(efd,d,p_progress.get_sub(1,1)); memdelete(d); ItemAction ia; ia.action=ItemAction::ACTION_DIR_ADD; ia.dir=p_dir; ia.file=f; ia.new_dir=efd; scan_actions.push_back(ia); } else { p_dir->subdirs[idx]->verified=true; } } else { String ext = f.extension().to_lower(); if (!valid_extensions.has(ext)) continue; //invalid int idx = p_dir->find_file_index(f); if (idx==-1) { //never seen this file, add actition to add it EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo ); fi->file=f; String path = cd.plus_file(fi->file); fi->modified_time=FileAccess::get_modified_time(path); fi->meta=_get_meta(path); fi->type=ResourceLoader::get_resource_type(path); { ItemAction ia; ia.action=ItemAction::ACTION_FILE_ADD; ia.dir=p_dir; ia.file=f; ia.new_file=fi; scan_actions.push_back(ia); } //take the chance and scan sources if (_check_meta_sources(fi->meta)) { ItemAction ia; ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; ia.dir=p_dir; ia.file=f; scan_actions.push_back(ia); } } else { p_dir->files[idx]->verified=true; } } } da->list_dir_end(); memdelete(da); } for(int i=0;i<p_dir->files.size();i++) { if (updated_dir && !p_dir->files[i]->verified) { //this file was removed, add action to remove it ItemAction ia; ia.action=ItemAction::ACTION_FILE_REMOVE; ia.dir=p_dir; ia.file=p_dir->files[i]->file; scan_actions.push_back(ia); continue; } if (_check_meta_sources(p_dir->files[i]->meta)) { ItemAction ia; ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; ia.dir=p_dir; ia.file=p_dir->files[i]->file; scan_actions.push_back(ia); } } for(int i=0;i<p_dir->subdirs.size();i++) { if (updated_dir && !p_dir->subdirs[i]->verified) { //this directory was removed, add action to remove it ItemAction ia; ia.action=ItemAction::ACTION_DIR_REMOVE; ia.dir=p_dir->subdirs[i]; scan_actions.push_back(ia); continue; } _scan_fs_changes(p_dir->get_subdir(i),p_progress); } }
Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { if (EditorImportExport::get_singleton()->sample_get_action()==EditorImportExport::SAMPLE_ACTION_NONE || p_path.extension().to_lower()!="wav") { return Vector<uint8_t>(); } Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); imd->add_source(EditorImportPlugin::validate_source_path(p_path)); imd->set_option("force/8_bit",false); imd->set_option("force/mono",false); imd->set_option("force/max_rate",true); imd->set_option("force/max_rate_hz",EditorImportExport::get_singleton()->sample_get_max_hz()); imd->set_option("edit/trim",EditorImportExport::get_singleton()->sample_get_trim()); imd->set_option("edit/normalize",false); imd->set_option("edit/loop",false); imd->set_option("compress/mode",1); String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp"); Error err = EditorSampleImportPlugin::singleton->import(savepath,imd); ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); p_path=p_path.basename()+".converted.smp"; return FileAccess::get_file_as_array(savepath); }
String ResourceFormatLoaderTheme::get_resource_type(const String &p_path) const { if (p_path.extension().to_lower()=="theme") return "Theme"; return ""; }
RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_original_path) { if (p_path.extension()=="cube") { // open as cubemap txture CubeMap* ptr = memnew(CubeMap); Ref<CubeMap> cubemap( ptr ); Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); if (err) { ERR_FAIL_COND_V( err, RES() ); } String base_path=p_path.substr( 0, p_path.find_last("/")+1 ); for(int i=0;i<6;i++) { String file = f->get_line().strip_edges(); Image image; Error err = ImageLoader::load_image(base_path+file,&image); if (err) { memdelete(f); ERR_FAIL_COND_V( err, RES() ); } if (i==0) { //cubemap->create(image.get_width(),image.get_height(),image.get_format(),Texture::FLAGS_DEFAULT|Texture::FLAG_CUBEMAP); } static const CubeMap::Side cube_side[6]= { CubeMap::SIDE_LEFT, CubeMap::SIDE_RIGHT, CubeMap::SIDE_BOTTOM, CubeMap::SIDE_TOP, CubeMap::SIDE_FRONT, CubeMap::SIDE_BACK }; cubemap->set_side(cube_side[i],image); } memdelete(f); cubemap->set_name(p_path.get_file()); return cubemap; } else { // simple image ImageTexture* ptr = memnew(ImageTexture); Ref<ImageTexture> texture( ptr ); uint64_t begtime; double total; Image image; if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); Error err = ImageLoader::load_image(p_path,&image); if (!err && debug_load_times) { double total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line("IMAGE: "+itos(image.get_width())+"x"+itos(image.get_height())); print_line(" -load: "+rtos(total)); } ERR_EXPLAIN("Failed loading image: "+p_path); ERR_FAIL_COND_V(err, RES()); #ifdef DEBUG_ENABLED #ifdef TOOLS_ENABLED if (max_texture_size && (image.get_width() > max_texture_size || image.get_height() > max_texture_size)) { if (bool(Globals::get_singleton()->get("debug/max_texture_size_alert"))) { OS::get_singleton()->alert("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+".","BAD ARTIST, NO COOKIE!"); } ERR_EXPLAIN("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+"."); ERR_FAIL_V(RES()); } #endif #endif uint32_t flags=0; if (bool(GLOBAL_DEF("texture_import/filter",true))) flags|=Texture::FLAG_FILTER; if (bool(GLOBAL_DEF("texture_import/gen_mipmaps",true))) flags|=Texture::FLAG_MIPMAPS; if (bool(GLOBAL_DEF("texture_import/repeat",true))) flags|=Texture::FLAG_REPEAT; if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); //print_line("img: "+p_path+" flags: "+itos(flags)); texture->create_from_image( image,flags ); texture->set_name(p_path.get_file()); if (debug_load_times) { total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line(" -make texture: "+rtos(total)); } return RES( texture ); } }
String TranslationLoaderPO::get_resource_type(const String &p_path) const { if (p_path.extension().to_lower()=="po") return "Translation"; return ""; }
void EditorAssetInstaller::open(const String& p_path,int p_depth) { package_path=p_path; Set<String> files_sorted; FileAccess *src_f=NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io); if (!pkg) { error->set_text("Error opening package file, not in zip format."); return; } 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 name=fname; files_sorted.insert(name); ret = unzGoToNextFile(pkg); } Map<String,Ref<Texture> > extension_guess; { extension_guess["png"]=get_icon("Texture","EditorIcons"); extension_guess["jpg"]=get_icon("Texture","EditorIcons"); extension_guess["tex"]=get_icon("Texture","EditorIcons"); extension_guess["atex"]=get_icon("Texture","EditorIcons"); extension_guess["dds"]=get_icon("Texture","EditorIcons"); extension_guess["scn"]=get_icon("PackedScene","EditorIcons"); extension_guess["tscn"]=get_icon("PackedScene","EditorIcons"); extension_guess["xml"]=get_icon("PackedScene","EditorIcons"); extension_guess["xscn"]=get_icon("PackedScene","EditorIcons"); extension_guess["mtl"]=get_icon("Material","EditorIcons"); extension_guess["shd"]=get_icon("Shader","EditorIcons"); extension_guess["gd"]=get_icon("GDScript","EditorIcons"); } Ref<Texture> generic_extension = get_icon("Object","EditorIcons"); unzClose(pkg); updating=true; tree->clear(); TreeItem *root=tree->create_item(); root->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); root->set_checked(0,true); root->set_icon(0,get_icon("folder","FileDialog")); root->set_text(0,"res://"); root->set_editable(0,true); Map<String,TreeItem*> dir_map; for(Set<String>::Element *E=files_sorted.front();E;E=E->next()) { String path = E->get(); int depth=p_depth; 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()) continue; bool isdir=false; if (path.ends_with("/")) { //a directory path=path.substr(0,path.length()-1); isdir=true; } int pp = path.find_last("/"); TreeItem *parent; if (pp==-1) { parent=root; } else { String ppath=path.substr(0,pp); print_line("PPATH IS: "+ppath); ERR_CONTINUE(!dir_map.has(ppath)); parent=dir_map[ppath]; } TreeItem *ti = tree->create_item(parent); ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); ti->set_checked(0,true); ti->set_editable(0,true); if (isdir) { dir_map[path]=ti; ti->set_text(0,path.get_file()+"/"); ti->set_icon(0,get_icon("folder","FileDialog")); } else { String file = path.get_file(); String extension = file.extension().to_lower(); if (extension_guess.has(extension)) { ti->set_icon(0,extension_guess[extension]); } else { ti->set_icon(0,generic_extension); } ti->set_text(0,file); String res_path = "res://"+path; if (FileAccess::exists(res_path)) { ti->set_custom_color(0,Color(1,0.3,0.2)); ti->set_tooltip(0,res_path+" (Already Exists)"); ti->set_checked(0,false); } else { ti->set_tooltip(0,res_path); } ti->set_metadata(0,res_path); } status_map[E->get()]=ti; } popup_centered_ratio(); updating=false; }
Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { if (!EditorImportExport::get_singleton()->get_convert_text_scenes()) { return Vector<uint8_t>(); } String extension = p_path.extension(); //step 1 check if scene if (extension=="xml" || extension=="xres") { String type = ResourceLoader::get_resource_type(p_path); if (type!="PackedScene") return Vector<uint8_t>(); } else if (extension!="tscn" && extension!="xscn") { return Vector<uint8_t>(); } //step 2 check if cached uint64_t sd=0; String smd5; String gp = Globals::get_singleton()->globalize_path(p_path); String md5=gp.md5_text(); String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); bool valid=false; { //if existing, make sure it's valid FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::READ); if (f) { uint64_t d = f->get_line().strip_edges().to_int64(); sd = FileAccess::get_modified_time(p_path); if (d==sd) { valid=true; } else { String cmd5 = f->get_line().strip_edges(); smd5 = FileAccess::get_md5(p_path); if (cmd5==smd5) { valid=true; } } } } if (!valid) { //cache failed, convert DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); String copy = p_path+".convert."+extension; // a copy will allow loading the internal resources without conflicting with opened scenes da->copy(p_path,copy); //@todo for tscn use something more efficient Ref<PackedScene> copyres = ResourceLoader::load(copy,"PackedScene"); da->remove(copy); memdelete(da); ERR_FAIL_COND_V(!copyres.is_valid(),Vector<uint8_t>()); Error err = ResourceSaver::save(tmp_path+"scnexp-"+md5+".scn",copyres); copyres=Ref<PackedScene>(); ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::WRITE); if (sd==0) sd = FileAccess::get_modified_time(p_path); if (smd5==String()) smd5 = FileAccess::get_md5(p_path); f->store_line(String::num(sd)); f->store_line(smd5); f->store_line(gp); //source path for reference } Vector<uint8_t> ret = FileAccess::get_file_as_array(tmp_path+"scnexp-"+md5+".scn"); p_path+=".converted.scn"; return ret; }
void ScriptCreateDialog::_path_changed(const String& p_path) { path_valid=false; String p =p_path; if (p=="") { path_error_label->set_text(TTR("Path is empty")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } p = Globals::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { path_error_label->set_text(TTR("Path is not local")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } if (p.find("/") || p.find("\\")) { DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (d->change_dir(p.get_base_dir())!=OK) { path_error_label->set_text(TTR("Invalid base path")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); memdelete(d); return; } memdelete(d); } FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES); create_new=!f->file_exists(p); memdelete(f); String extension=p.extension(); List<String> extensions; // get all possible extensions for script for (int l=0;l<language_menu->get_item_count();l++) { ScriptServer::get_language( l )->get_recognized_extensions(&extensions); } bool found=false; int index=0; for(List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get().nocasecmp_to(extension)==0) { language_menu->select(index); // change Language option by extension found=true; break; } index++; } if (!found) { path_error_label->set_text(TTR("Invalid extension")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } _update_controls(); path_error_label->add_color_override("font_color",Color(0,1.0,0.8,0.8)); path_valid=true; }
void ScriptCreateDialog::_path_changed(const String& p_path) { path_valid=false; String p =p_path; if (p=="") { path_error_label->set_text("Path is Empty"); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } p = Globals::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { path_error_label->set_text("Path is not local"); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } if (p.find("/") || p.find("\\")) { DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (d->change_dir(p.get_base_dir())!=OK) { path_error_label->set_text("Base Path Invalid"); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); memdelete(d); return; } memdelete(d); } FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES); if (f->file_exists(p)) { path_error_label->set_text("File Exists"); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); memdelete(f); return; } memdelete(f); String extension=p.extension(); List<String> extensions; int l=language_menu->get_selected(); ScriptServer::get_language( l )->get_recognized_extensions(&extensions); bool found=false; for(List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get().nocasecmp_to(extension)==0) { found=true; break; } } if (!found) { path_error_label->set_text("Invalid Extension"); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } path_error_label->set_text("Path is Valid"); path_error_label->add_color_override("font_color",Color(0,1.0,0.8,0.8)); path_valid=true; }
String ResourceFormatLoaderAudioStreamSpeex::get_resource_type(const String &p_path) const { if (p_path.extension().to_lower() == "spx") return "AudioStreamSpeex"; return ""; }
RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_CANT_OPEN; if (p_path.extension()=="cube") { // open as cubemap txture CubeMap* ptr = memnew(CubeMap); Ref<CubeMap> cubemap( ptr ); Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); if (err) { ERR_FAIL_COND_V( err, RES() ); } String base_path=p_path.substr( 0, p_path.find_last("/")+1 ); for(int i=0;i<6;i++) { String file = f->get_line().strip_edges(); Image image; Error err = ImageLoader::load_image(base_path+file,&image); if (err) { memdelete(f); ERR_FAIL_COND_V( err, RES() ); } if (i==0) { //cubemap->create(image.get_width(),image.get_height(),image.get_format(),Texture::FLAGS_DEFAULT|Texture::FLAG_CUBEMAP); } static const CubeMap::Side cube_side[6]= { CubeMap::SIDE_LEFT, CubeMap::SIDE_RIGHT, CubeMap::SIDE_BOTTOM, CubeMap::SIDE_TOP, CubeMap::SIDE_FRONT, CubeMap::SIDE_BACK }; cubemap->set_side(cube_side[i],image); } memdelete(f); cubemap->set_name(p_path.get_file()); if (r_error) *r_error=OK; return cubemap; } else { // simple image ImageTexture* ptr = memnew(ImageTexture); Ref<ImageTexture> texture( ptr ); uint64_t begtime; double total; Image image; if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); Error err = ImageLoader::load_image(p_path,&image); if (!err && debug_load_times) { double total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line("IMAGE: "+itos(image.get_width())+"x"+itos(image.get_height())); print_line(" -load: "+rtos(total)); } ERR_EXPLAIN("Failed loading image: "+p_path); ERR_FAIL_COND_V(err, RES()); if (r_error) *r_error=ERR_FILE_CORRUPT; #ifdef DEBUG_ENABLED #ifdef TOOLS_ENABLED if (max_texture_size && (image.get_width() > max_texture_size || image.get_height() > max_texture_size)) { if (bool(Globals::get_singleton()->get("debug/max_texture_size_alert"))) { OS::get_singleton()->alert("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+".","BAD ARTIST, NO COOKIE!"); } ERR_EXPLAIN("Texture is too large: '"+p_path+"', at "+itos(image.get_width())+"x"+itos(image.get_height())+". Max allowed size is: "+itos(max_texture_size)+"x"+itos(max_texture_size)+"."); ERR_FAIL_V(RES()); } #endif #endif uint32_t flags=0; FileAccess *f2 = FileAccess::open(p_path+".flags",FileAccess::READ); Map<String,bool> flags_found; if (f2) { while(!f2->eof_reached()) { String l2 = f2->get_line(); int eqpos = l2.find("="); if (eqpos!=-1) { String flag=l2.substr(0,eqpos).strip_edges(); String val=l2.substr(eqpos+1,l2.length()).strip_edges().to_lower(); flags_found[flag]=(val=="true" || val=="1")?true:false; } } memdelete(f2); } if (flags_found.has("filter")) { if (flags_found["filter"]) flags|=Texture::FLAG_FILTER; } else if (bool(GLOBAL_DEF("image_loader/filter",true))) { flags|=Texture::FLAG_FILTER; } if (flags_found.has("gen_mipmaps")) { if (flags_found["gen_mipmaps"]) flags|=Texture::FLAG_MIPMAPS; } else if (bool(GLOBAL_DEF("image_loader/gen_mipmaps",true))) { flags|=Texture::FLAG_MIPMAPS; } if (flags_found.has("repeat")) { if (flags_found["repeat"]) flags|=Texture::FLAG_REPEAT; } else if (bool(GLOBAL_DEF("image_loader/repeat",true))) { flags|=Texture::FLAG_REPEAT; } if (flags_found.has("anisotropic")) { if (flags_found["anisotropic"]) flags|=Texture::FLAG_ANISOTROPIC_FILTER; } if (flags_found.has("tolinear")) { if (flags_found["tolinear"]) flags|=Texture::FLAG_CONVERT_TO_LINEAR; } if (flags_found.has("mirroredrepeat")) { if (flags_found["mirroredrepeat"]) flags|=Texture::FLAG_MIRRORED_REPEAT; } if (debug_load_times) begtime=OS::get_singleton()->get_ticks_usec(); //print_line("img: "+p_path+" flags: "+itos(flags)); texture->create_from_image( image,flags ); texture->set_name(p_path.get_file()); if (debug_load_times) { total=(double)(OS::get_singleton()->get_ticks_usec()-begtime)/1000000.0; print_line(" -make texture: "+rtos(total)); } if (r_error) *r_error=OK; return RES( texture ); } }
String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const { if (p_path.extension().to_lower()=="shader") return "Shader"; return ""; }
String ResourceFormatPBM::get_resource_type(const String &p_path) const { if (p_path.extension().to_lower()=="pbm") return "BitMap"; return ""; }