Browse Source

Merge pull request #3110 from IvanSavenko/mod_compat_fix

Mod compatibility fixes
Ivan Savenko 2 years ago
parent
commit
3016014543

+ 7 - 4
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -193,13 +193,16 @@ TObjectTypeHandler CObjectClassesHandler::loadSubObjectFromJson(const std::strin
 	assert(identifier.find(':') == std::string::npos);
 	assert(!scope.empty());
 
-	if(!handlerConstructors.count(obj->handlerName))
+	std::string handler = obj->handlerName;
+	if(!handlerConstructors.count(handler))
 	{
-		logGlobal->error("Handler with name %s was not found!", obj->handlerName);
-		return nullptr;
+		logMod->error("Handler with name %s was not found!", handler);
+		// workaround for potential crash - if handler does not exists, continue with generic handler that is used for objects without any custom logc
+		handler = "generic";
+		assert(handlerConstructors.count(handler) != 0);
 	}
 
-	auto createdObject = handlerConstructors.at(obj->handlerName)();
+	auto createdObject = handlerConstructors.at(handler)();
 
 	createdObject->modScope = scope;
 	createdObject->typeName = obj->identifier;;

+ 10 - 1
lib/modding/ContentTypeHandler.cpp

@@ -104,7 +104,16 @@ bool ContentTypeHandler::loadMod(const std::string & modName, bool validate)
 		JsonNode & data = entry.second;
 
 		if (data.meta != modName)
-			logMod->warn("Mod %s is attempting to inject object %s into mod %s! This may not be supported in future versions!", data.meta, name, modName);
+		{
+			// in this scenario, entire object record comes from another mod
+			// normally, this is used to "patch" object from another mod (which is legal)
+			// however in this case there is no object to patch. This might happen in such cases:
+			// - another mod attempts to add object into this mod (technically can be supported, but might lead to weird edge cases)
+			// - another mod attempts to edit object from this mod that no longer exist - DANGER since such patch likely has very incomplete data
+			// so emit warning and skip such case
+			logMod->warn("Mod %s attempts to edit object %s from mod %s but no such object exist!", data.meta, name, modName);
+			continue;
+		}
 
 		if (vstd::contains(data.Struct(), "index") && !data["index"].isNull())
 		{