Pārlūkot izejas kodu

Fix Scene Importer crashing when mesh or animation save paths are invalid

(cherry picked from commit cd87916d98ad2d17e1a6282ee33be5234c336436)
BlueCube3310 1 gadu atpakaļ
vecāks
revīzija
3553d33708

+ 51 - 20
editor/import/resource_importer_scene.cpp

@@ -31,6 +31,7 @@
 #include "resource_importer_scene.h"
 
 #include "core/error/error_macros.h"
+#include "core/io/dir_access.h"
 #include "core/io/resource_saver.h"
 #include "core/object/script_language.h"
 #include "editor/editor_node.h"
@@ -2393,6 +2394,21 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM
 	return scene;
 }
 
+Error ResourceImporterScene::_check_resource_save_paths(const Dictionary &p_data) {
+	Array keys = p_data.keys();
+	for (int i = 0; i < keys.size(); i++) {
+		const Dictionary &settings = p_data[keys[i]];
+
+		if (bool(settings.get("save_to_file/enabled", false)) && settings.has("save_to_file/path")) {
+			const String &save_path = settings["save_to_file/path"];
+
+			ERR_FAIL_COND_V(!save_path.is_empty() && !DirAccess::exists(save_path.get_base_dir()), ERR_FILE_BAD_PATH);
+		}
+	}
+
+	return OK;
+}
+
 Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
 	const String &src_path = p_source_file;
 
@@ -2445,7 +2461,42 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 		import_flags |= EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
 	}
 
+	Dictionary subresources = p_options["_subresources"];
+
+	Dictionary node_data;
+	if (subresources.has("nodes")) {
+		node_data = subresources["nodes"];
+	}
+
+	Dictionary material_data;
+	if (subresources.has("materials")) {
+		material_data = subresources["materials"];
+	}
+
+	Dictionary animation_data;
+	if (subresources.has("animations")) {
+		animation_data = subresources["animations"];
+	}
+
+	Dictionary mesh_data;
+	if (subresources.has("meshes")) {
+		mesh_data = subresources["meshes"];
+	}
+
 	Error err = OK;
+
+	// Check whether any of the meshes or animations have nonexistent save paths
+	// and if they do, fail the import immediately.
+	err = _check_resource_save_paths(mesh_data);
+	if (err != OK) {
+		return err;
+	}
+
+	err = _check_resource_save_paths(animation_data);
+	if (err != OK) {
+		return err;
+	}
+
 	List<String> missing_deps; // for now, not much will be done with this
 	Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err);
 	if (!scene || err != OK) {
@@ -2469,22 +2520,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 			scene_3d->scale(scale);
 		}
 	}
-	Dictionary subresources = p_options["_subresources"];
-
-	Dictionary node_data;
-	if (subresources.has("nodes")) {
-		node_data = subresources["nodes"];
-	}
-
-	Dictionary material_data;
-	if (subresources.has("materials")) {
-		material_data = subresources["materials"];
-	}
-
-	Dictionary animation_data;
-	if (subresources.has("animations")) {
-		animation_data = subresources["animations"];
-	}
 
 	HashSet<Ref<ImporterMesh>> scanned_meshes;
 	HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
@@ -2564,10 +2599,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 		}
 	}
 
-	Dictionary mesh_data;
-	if (subresources.has("meshes")) {
-		mesh_data = subresources["meshes"];
-	}
 	scene = _generate_meshes(scene, mesh_data, gen_lods, create_shadow_meshes, LightBakeMode(light_bake_mode), lightmap_texel_size, src_lightmap_cache, mesh_lightmap_caches);
 
 	if (mesh_lightmap_caches.size()) {

+ 1 - 0
editor/import/resource_importer_scene.h

@@ -214,6 +214,7 @@ class ResourceImporterScene : public ResourceImporter {
 		SHAPE_TYPE_CAPSULE,
 	};
 
+	static Error _check_resource_save_paths(const Dictionary &p_data);
 	Array _get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node);
 	void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
 	Node *_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);