1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Analyze json object modifications to detect mod conflicts

This commit is contained in:
Ivan Savenko 2024-10-02 18:58:03 +00:00
parent 2439d176a0
commit d0aba56a5e
3 changed files with 35 additions and 0 deletions

View File

@ -275,4 +275,32 @@ JsonNode JsonUtils::assembleFromFiles(const std::string & filename)
return result;
}
void JsonUtils::detectConflicts(const JsonNode & left, const JsonNode & right, const std::string & entityName, const std::string & keyName)
{
if (left == right)
return;
switch (left.getType())
{
case JsonNode::JsonType::DATA_NULL:
case JsonNode::JsonType::DATA_BOOL:
case JsonNode::JsonType::DATA_FLOAT:
case JsonNode::JsonType::DATA_INTEGER:
case JsonNode::JsonType::DATA_STRING:
case JsonNode::JsonType::DATA_VECTOR: // NOTE: comparing vectors as whole - since merge will overwrite it in its entirety
{
logMod->warn("Potential confict detected between '%s' and '%s' in object '%s'", left.getModScope(), right.getModScope(), entityName);
logMod->warn("Mod '%s' - value %s set to '%s'", left.getModScope(), keyName, left.toCompactString());
logMod->warn("Mod '%s' - value %s set to '%s'", right.getModScope(), keyName, right.toCompactString());
return;
}
case JsonNode::JsonType::DATA_STRUCT:
{
for(auto & node : left.Struct())
if (!right[node.first].isNull())
detectConflicts(node.second, right[node.first], entityName, keyName + "/" + node.first);
}
}
}
VCMI_LIB_NAMESPACE_END

View File

@ -72,6 +72,10 @@ namespace JsonUtils
/// get schema by json URI: vcmi:<name of file in schemas directory>#<entry in file, optional>
/// example: schema "vcmi:settings" is used to check user settings
DLL_LINKAGE const JsonNode & getSchema(const std::string & URI);
/// detects potential conflicts - json entries present in both nodes
/// any error messages will be printed to error log
DLL_LINKAGE void detectConflicts(const JsonNode & left, const JsonNode & right, const std::string & entityName, const std::string & keyName);
}
VCMI_LIB_NAMESPACE_END

View File

@ -79,6 +79,9 @@ bool ContentTypeHandler::preloadModData(const std::string & modName, const std::
logMod->trace("Patching object %s (%s) from %s", objectName, remoteName, modName);
JsonNode & remoteConf = modData[remoteName].patches[objectName];
if (!remoteConf.isNull())
JsonUtils::detectConflicts(remoteConf, entry.second, objectName, "<root>");
JsonUtils::merge(remoteConf, entry.second);
}
}