|
@@ -1045,10 +1045,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
// Silence a warning that can happen during the initial filesystem scan due to cache being regenerated.
|
|
|
if (ResourceLoader::get_resource_uid(res_path) != er.uid) {
|
|
|
- WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
|
|
|
+ WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
|
|
|
}
|
|
|
#else
|
|
|
- WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UUID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
|
|
|
+ WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data());
|
|
|
#endif
|
|
|
}
|
|
|
}
|
|
@@ -2209,12 +2209,130 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re
|
|
|
return OK;
|
|
|
}
|
|
|
|
|
|
+Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceUID::ID p_uid) {
|
|
|
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
|
|
|
+ ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file '" + p_path + "'.");
|
|
|
+
|
|
|
+ Ref<FileAccess> fw;
|
|
|
+
|
|
|
+ local_path = p_path.get_base_dir();
|
|
|
+
|
|
|
+ uint8_t header[4];
|
|
|
+ f->get_buffer(header, 4);
|
|
|
+ if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
|
|
+ // Compressed.
|
|
|
+ Ref<FileAccessCompressed> fac;
|
|
|
+ fac.instantiate();
|
|
|
+ Error err = fac->open_after_magic(f);
|
|
|
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'.");
|
|
|
+ f = fac;
|
|
|
+
|
|
|
+ Ref<FileAccessCompressed> facw;
|
|
|
+ facw.instantiate();
|
|
|
+ facw->configure("RSCC");
|
|
|
+ err = facw->open_internal(p_path + ".uidren", FileAccess::WRITE);
|
|
|
+ ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Cannot create file '" + p_path + ".uidren'.");
|
|
|
+
|
|
|
+ fw = facw;
|
|
|
+
|
|
|
+ } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
|
|
+ // Not a binary resource.
|
|
|
+ return ERR_FILE_UNRECOGNIZED;
|
|
|
+ } else {
|
|
|
+ fw = FileAccess::open(p_path + ".uidren", FileAccess::WRITE);
|
|
|
+ ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + ".uidren'.");
|
|
|
+
|
|
|
+ uint8_t magich[4] = { 'R', 'S', 'R', 'C' };
|
|
|
+ fw->store_buffer(magich, 4);
|
|
|
+ }
|
|
|
+
|
|
|
+ big_endian = f->get_32();
|
|
|
+ bool use_real64 = f->get_32();
|
|
|
+ f->set_big_endian(big_endian != 0); //read big endian if saved as big endian
|
|
|
+#ifdef BIG_ENDIAN_ENABLED
|
|
|
+ fw->store_32(!big_endian);
|
|
|
+#else
|
|
|
+ fw->store_32(big_endian);
|
|
|
+#endif
|
|
|
+ fw->set_big_endian(big_endian != 0);
|
|
|
+ fw->store_32(use_real64); //use real64
|
|
|
+
|
|
|
+ uint32_t ver_major = f->get_32();
|
|
|
+ uint32_t ver_minor = f->get_32();
|
|
|
+ uint32_t ver_format = f->get_32();
|
|
|
+
|
|
|
+ if (ver_format < FORMAT_VERSION_CAN_RENAME_DEPS) {
|
|
|
+ fw.unref();
|
|
|
+
|
|
|
+ {
|
|
|
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
|
|
+ da->remove(p_path + ".uidren");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Use the old approach.
|
|
|
+
|
|
|
+ WARN_PRINT("This file is old, so it does not support UIDs, opening and resaving '" + p_path + "'.");
|
|
|
+ return ERR_UNAVAILABLE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
|
|
|
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED,
|
|
|
+ vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).",
|
|
|
+ local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Since we're not actually converting the file contents, leave the version
|
|
|
+ // numbers in the file untouched.
|
|
|
+ fw->store_32(ver_major);
|
|
|
+ fw->store_32(ver_minor);
|
|
|
+ fw->store_32(ver_format);
|
|
|
+
|
|
|
+ save_ustring(fw, get_ustring(f)); //type
|
|
|
+
|
|
|
+ fw->store_64(f->get_64()); //metadata offset
|
|
|
+
|
|
|
+ uint32_t flags = f->get_32();
|
|
|
+ flags |= ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS;
|
|
|
+ f->get_64(); // Skip previous UID
|
|
|
+
|
|
|
+ fw->store_32(flags);
|
|
|
+ fw->store_64(p_uid);
|
|
|
+
|
|
|
+ //rest of file
|
|
|
+ uint8_t b = f->get_8();
|
|
|
+ while (!f->eof_reached()) {
|
|
|
+ fw->store_8(b);
|
|
|
+ b = f->get_8();
|
|
|
+ }
|
|
|
+
|
|
|
+ f.unref();
|
|
|
+
|
|
|
+ bool all_ok = fw->get_error() == OK;
|
|
|
+
|
|
|
+ if (!all_ok) {
|
|
|
+ return ERR_CANT_CREATE;
|
|
|
+ }
|
|
|
+
|
|
|
+ fw.unref();
|
|
|
+
|
|
|
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
|
|
+ da->remove(p_path);
|
|
|
+ da->rename(p_path + ".uidren", p_path);
|
|
|
+ return OK;
|
|
|
+}
|
|
|
+
|
|
|
Error ResourceFormatSaverBinary::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) {
|
|
|
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
|
|
ResourceFormatSaverBinaryInstance saver;
|
|
|
return saver.save(local_path, p_resource, p_flags);
|
|
|
}
|
|
|
|
|
|
+Error ResourceFormatSaverBinary::set_uid(const String &p_path, ResourceUID::ID p_uid) {
|
|
|
+ String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
|
|
+ ResourceFormatSaverBinaryInstance saver;
|
|
|
+ return saver.set_uid(local_path, p_uid);
|
|
|
+}
|
|
|
+
|
|
|
bool ResourceFormatSaverBinary::recognize(const Ref<Resource> &p_resource) const {
|
|
|
return true; //all recognized
|
|
|
}
|