diff --git a/config/schemas/settings.json b/config/schemas/settings.json index da312e19d..276903873 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -3,7 +3,7 @@ { "type" : "object", "$schema" : "http://json-schema.org/draft-04/schema", - "required" : [ "general", "video", "adventure", "battle", "input", "server", "logging", "launcher", "lobby", "gameTweaks" ], + "required" : [ "general", "video", "adventure", "battle", "input", "server", "logging", "launcher", "lobby", "gameTweaks", "mods" ], "definitions" : { "logLevelEnum" : { "type" : "string", @@ -149,6 +149,23 @@ } } }, + + "mods" : { + "type" : "object", + "additionalProperties" : false, + "default" : {}, + "required" : [ + "validation" + ], + "properties" : { + "validation" : { + "type" : "string", + "enum" : [ "off", "basic", "full" ], + "default" : "basic" + } + } + }, + "video" : { "type" : "object", "additionalProperties" : false, diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 8cb8c32a0..541a909de 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -182,6 +182,13 @@ void CSettingsView::loadSettings() else ui->buttonFontScalable->setChecked(true); + if (settings["mods"]["validation"].String() == "off") + ui->buttonValidationOff->setChecked(true); + else if (settings["mods"]["validation"].String() == "basic") + ui->buttonValidationBasic->setChecked(true); + else + ui->buttonValidationFull->setChecked(true); + loadToggleButtonSettings(); } @@ -791,3 +798,21 @@ void CSettingsView::on_buttonFontOriginal_clicked(bool checked) Settings node = settings.write["video"]["fontsType"]; node->String() = "original"; } + +void CSettingsView::on_buttonValidationOff_clicked(bool checked) +{ + Settings node = settings.write["mods"]["validation"]; + node->String() = "off"; +} + +void CSettingsView::on_buttonValidationBasic_clicked(bool checked) +{ + Settings node = settings.write["mods"]["validation"]; + node->String() = "basic"; +} + +void CSettingsView::on_buttonValidationFull_clicked(bool checked) +{ + Settings node = settings.write["mods"]["validation"]; + node->String() = "full"; +} diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 1e76f6f2e..512762d0c 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -83,19 +83,20 @@ private slots: void on_sliderToleranceDistanceController_valueChanged(int value); void on_lineEditGameLobbyHost_textChanged(const QString &arg1); void on_spinBoxNetworkPortLobby_valueChanged(int arg1); - void on_sliderControllerSticksAcceleration_valueChanged(int value); - void on_sliderControllerSticksSensitivity_valueChanged(int value); - - //void on_buttonTtfFont_toggled(bool value); - void on_sliderScalingFont_valueChanged(int value); - void on_buttonFontAuto_clicked(bool checked); void on_buttonFontScalable_clicked(bool checked); void on_buttonFontOriginal_clicked(bool checked); + + void on_buttonValidationOff_clicked(bool checked); + + void on_buttonValidationBasic_clicked(bool checked); + + void on_buttonValidationFull_clicked(bool checked); + private: Ui::CSettingsView * ui; diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index 578fd55b4..c0082edd8 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -47,88 +47,19 @@ 0 - 0 + -800 729 - 1449 + 1506 - - - - false - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - - 0 - 0 - - + + - - true - - - - - Use Relative Pointer Mode - - - - - - - 25 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 5 - - - - - - - Additional repository - - - - - - - Music Volume - - - - - - @@ -157,374 +88,6 @@ - - - - Long Touch Duration - - - - - - - false - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - - true - - - - Video - - - 5 - - - - - - - - true - - - - General - - - 5 - - - - - - - Heroes III Translation - - - - - - - Show Tutorial again - - - - - - - Online Lobby port - - - - - - - Relative Pointer Speed - - - - - - - Touch Tap Tolerance - - - - - - - Select display mode for game - -Windowed - game will run inside a window that covers part of your screen - -Borderless Windowed Mode - game will run in a window that covers entirely of your screen, using same resolution as your screen. - -Fullscreen Exclusive Mode - game will cover entirety of your screen and will use selected resolution. - - - 0 - - - - Windowed - - - - - Borderless fullscreen - - - - - Exclusive fullscreen - - - - - - - - 500 - - - 2000 - - - 250 - - - 250 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 250 - - - - - - - Neutral AI in battles - - - - - - - - true - - - - Input - Mouse - - - 5 - - - - - - - - 0 - 0 - - - - Automatic - - - true - - - true - - - buttonGroup - - - - - - - Adventure Map Enemies - - - - - - - VCAI - - - - VCAI - - - - - Nullkiller - - - - - - - - 0 - - - 50 - - - 1 - - - 10 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Autosave - - - - - - - Renderer - - - - - - - Autosave limit (0 = off) - - - - - - - Default repository - - - - - - - 100 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Sticks Sensitivity - - - - - - - - true - - - - Audio - - - 5 - - - - - - - - - - Downscaling Filter - - - - - - - 1024 - - - 65535 - - - 3030 - - - - - - - 0 - - - 50 - - - 1 - - - 10 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 10 - - - - - - - Ignore SSL errors - - - @@ -532,120 +95,6 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - Refresh now - - - - - - - true - - - - 0 - 0 - - - - - - - true - - - false - - - - - - - VSync - - - - - - - Resolution - - - - - - - VCMI Language - - - - - - - Interface Scaling - - - - - - - - - - - - - - - - - Online Lobby address - - - - - - - VCAI - - - - VCAI - - - - - Nullkiller - - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - - - - @@ -674,38 +123,37 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + + + false + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + - Autosave prefix + Additional repository - - + + - Reserved screen area - - - - - - - Sound Volume - - - - - - - Font Scaling (experimental) - - - - - - - Framerate Limit + Ignore SSL errors @@ -728,8 +176,130 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + + + VCMI Language + + + + + + + + 0 + 0 + + + + Automatic + + + true + + + true + + + buttonGroupFonts + + + + + + + + true + + + + Video + + + 5 + + + + + + + Show intro + + + + + + + Heroes III Translation + + + + + + + 0 + + + 50 + + + 1 + + + 10 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + + 0 + 0 + + + + Scalable + + + true + + + true + + + buttonGroupFonts + + + + + + + Touch Tap Tolerance + + + + + + + + + + + + 100 @@ -744,56 +314,13 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - - Automatic - - - - - None - - - - - xBRZ x2 - - - - - xBRZ x3 - - - - - xBRZ x4 - - - + + - - + + - Autocombat AI in battles - - - - - - - Use scalable fonts - - - - - - - - - - true + Renderer @@ -812,87 +339,24 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + - Fullscreen + Neutral AI in battles - - - - 500 - - - 2500 - - - 25 - - - 250 - - - 500 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 250 - - - - - + + - Enemy AI in battles + VSync - - + + - Sticks Acceleration - - - - - - - 100 - - - 300 - - - Qt::Horizontal - - - QSlider::TicksAbove - - - 25 - - - - - - - - 0 - 0 - - - - - - - true + Framerate Limit @@ -903,8 +367,61 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + + + + true + + + + Input - Touchscreen + + + 5 + + + + + + + 0 + + + 50 + + + 1 + + + 10 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + Relative Pointer Speed + + + + + + + + true @@ -925,29 +442,6 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - - 0 - 0 - - - - - - - true - - - - - - - - - - @@ -964,33 +458,20 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + - Adventure Map Allies + Long Touch Duration - - - - Haptic Feedback - - + + - - - - % - - - 50 - - - 400 - - - 10 + + + + Check on startup @@ -1013,72 +494,6 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - Mouse Click Tolerance - - - - - - - BattleAI - - - - BattleAI - - - - - StupidAI - - - - - - - - true - - - - 0 - 0 - - - - - - - true - - - false - - - - - - - Reset - - - - - - - - - - Network port - - - - - - @@ -1094,15 +509,8 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - Display index - - - - - + + 0 @@ -1117,128 +525,6 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - - - - true - - - - Network - - - 5 - - - - - - - - 0 - 0 - - - - Original - - - true - - - true - - - buttonGroup - - - - - - - - - - - - - - Show intro - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - 1024 - - - 65535 - - - 3030 - - - - - - - - true - - - - Input - Touchscreen - - - 5 - - - - - - - 20 - - - 1000 - - - 10 - - - - - - - Controller Click Tolerance - - - - - - - Check on startup - - - @@ -1270,15 +556,53 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - - + + - Software Cursor + Downscaling Filter - - + + + + Select display mode for game + +Windowed - game will run inside a window that covers part of your screen + +Borderless Windowed Mode - game will run in a window that covers entirely of your screen, using same resolution as your screen. + +Fullscreen Exclusive Mode - game will cover entirety of your screen and will use selected resolution. + + + 0 + + + + Windowed + + + + + Borderless fullscreen + + + + + Exclusive fullscreen + + + + + + + + Use scalable fonts + + + + + 0 @@ -1286,7 +610,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - Scalable + Original true @@ -1295,13 +619,786 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use true - buttonGroup + buttonGroupFonts + + + + + + + + Automatic + + + + + None + + + + + xBRZ x2 + + + + + xBRZ x3 + + + + + xBRZ x4 + + + + + + + + Online Lobby port + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + VCAI + + + + VCAI + + + + + Nullkiller + + + + + + + + + true + + + + Network + + + 5 + + + + + + + Refresh now + + + + + + + 500 + + + 2500 + + + 25 + + + 250 + + + 500 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 250 + + + + + + + Display index + + + + + + + 500 + + + 2000 + + + 250 + + + 250 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 250 + + + + + + + false + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + + + Adventure Map Enemies + + + + + + + + + + true + + + + + + + Reset + + + + + + + Show Tutorial again + + + + + + + Fullscreen + + + + + + + Use Relative Pointer Mode + + + + + + + + + + + + + + Sticks Acceleration + + + + + + + Autosave limit (0 = off) + + + + + + + Mouse Click Tolerance + + + + + + + + true + + + + General + + + 5 + + + + + + + Online Lobby address + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + Interface Scaling + + + + + + + Default repository + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + Haptic Feedback + + + + + + + + + + Autosave prefix + + + + + + + + true + + + + Input - Mouse + + + 5 + + + + + + + 25 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 5 + + + + + + + 20 + + + 1000 + + + 10 + + + + + + + 1024 + + + 65535 + + + 3030 + + + + + + + 100 + + + 300 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 25 + + + + + + + Enemy AI in battles + + + + + + + Reserved screen area + + + + + + + % + + + 50 + + + 400 + + + 10 + + + + + + + Music Volume + + + + + + + BattleAI + + + + BattleAI + + + + + StupidAI + + + + + + + + Autosave + + + + + + + 100 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 10 + + + + + + + Network port + + + + + + + true + + + + 0 + 0 + + + + + + + true + + + false + + + + + + + Resolution + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + Sound Volume + + + + + + + Controller Click Tolerance + + + + + + + Adventure Map Allies + + + + + + + + true + + + + Miscellaneous + + + 5 + + + + + + + 1024 + + + 65535 + + + 3030 + + + + + + + VCAI + + + + VCAI + + + + + Nullkiller + + + + + + + + + true + + + + Audio + + + 5 + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + Software Cursor + + + + + + + Autocombat AI in battles + + + + + + + + + + + + + + true + + + + 0 + 0 + + + + + + + true + + + false + + + + + + + Font Scaling (experimental) + + + + + + + Sticks Sensitivity + + + + + + + Mods Validation + + + + + + + true + + + + 0 + 0 + + + + Off + + + true + + + false + + + buttonGroupValidation + + + + + + + true + + + + 0 + 0 + + + + Basic + + + true + + + false + + + buttonGroupValidation + + + + + + + true + + + + 0 + 0 + + + + Full + + + true + + + false + + + buttonGroupValidation + + + @@ -1311,6 +1408,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use - + + diff --git a/lib/mapObjectConstructors/CRewardableConstructor.cpp b/lib/mapObjectConstructors/CRewardableConstructor.cpp index 80d842a47..bbdff2bf2 100644 --- a/lib/mapObjectConstructors/CRewardableConstructor.cpp +++ b/lib/mapObjectConstructors/CRewardableConstructor.cpp @@ -14,6 +14,7 @@ #include "../mapObjects/CRewardableObject.h" #include "../texts/CGeneralTextHandler.h" #include "../IGameCallback.h" +#include "../CConfigHandler.h" VCMI_LIB_NAMESPACE_BEGIN @@ -25,7 +26,8 @@ void CRewardableConstructor::initTypeData(const JsonNode & config) if (!config["name"].isNull()) VLC->generaltexth->registerString( config.getModScope(), getNameTextID(), config["name"].String()); - JsonUtils::validate(config, "vcmi:rewardable", getJsonKey()); + if (settings["mods"]["validation"].String() != "off") + JsonUtils::validate(config, "vcmi:rewardable", getJsonKey()); } diff --git a/lib/modding/CModHandler.cpp b/lib/modding/CModHandler.cpp index 15c9d22e4..ccd71e2a6 100644 --- a/lib/modding/CModHandler.cpp +++ b/lib/modding/CModHandler.cpp @@ -17,6 +17,7 @@ #include "ModIncompatibility.h" #include "../CCreatureHandler.h" +#include "../CConfigHandler.h" #include "../CStopWatch.h" #include "../GameSettings.h" #include "../ScriptHandler.h" @@ -339,25 +340,28 @@ void CModHandler::loadModFilesystems() for(std::string & modName : activeMods) CResourceHandler::addFilesystem("data", modName, modFilesystems[modName]); - for(std::string & leftModName : activeMods) + if (settings["mods"]["validation"].String() == "full") { - for(std::string & rightModName : activeMods) + for(std::string & leftModName : activeMods) { - if (leftModName == rightModName) - continue; - - if (getModDependencies(leftModName).count(rightModName) || getModDependencies(rightModName).count(leftModName)) - continue; - - const auto & filter = [](const ResourcePath &path){return path.getType() != EResType::DIRECTORY;}; - - std::unordered_set leftResources = modFilesystems[leftModName]->getFilteredFiles(filter); - std::unordered_set rightResources = modFilesystems[rightModName]->getFilteredFiles(filter); - - for (auto const & leftFile : leftResources) + for(std::string & rightModName : activeMods) { - if (rightResources.count(leftFile)) - logMod->warn("Potential confict detected between '%s' and '%s': both mods add file '%s'", leftModName, rightModName, leftFile.getOriginalName()); + if (leftModName == rightModName) + continue; + + if (getModDependencies(leftModName).count(rightModName) || getModDependencies(rightModName).count(leftModName)) + continue; + + const auto & filter = [](const ResourcePath &path){return path.getType() != EResType::DIRECTORY;}; + + std::unordered_set leftResources = modFilesystems[leftModName]->getFilteredFiles(filter); + std::unordered_set rightResources = modFilesystems[rightModName]->getFilteredFiles(filter); + + for (auto const & leftFile : leftResources) + { + if (rightResources.count(leftFile)) + logMod->warn("Potential confict detected between '%s' and '%s': both mods add file '%s'", leftModName, rightModName, leftFile.getOriginalName()); + } } } } @@ -508,8 +512,8 @@ void CModHandler::load() content->loadCustom(); -// for(const TModID & modName : activeMods) -// loadTranslation(modName); + for(const TModID & modName : activeMods) + loadTranslation(modName); #if 0 for(const TModID & modName : activeMods) diff --git a/lib/modding/ContentTypeHandler.cpp b/lib/modding/ContentTypeHandler.cpp index 60289ca6e..f2887a711 100644 --- a/lib/modding/ContentTypeHandler.cpp +++ b/lib/modding/ContentTypeHandler.cpp @@ -17,6 +17,7 @@ #include "../BattleFieldHandler.h" #include "../CArtHandler.h" #include "../CCreatureHandler.h" +#include "../CConfigHandler.h" #include "../entities/faction/CTownHandler.h" #include "../texts/CGeneralTextHandler.h" #include "../CHeroHandler.h" @@ -79,7 +80,7 @@ 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()) + if (!remoteConf.isNull() && settings["mods"]["validation"].String() != "off") JsonUtils::detectConflicts(conflictList, remoteConf, entry.second, objectName); JsonUtils::merge(remoteConf, entry.second); @@ -162,67 +163,70 @@ void ContentTypeHandler::loadCustom() void ContentTypeHandler::afterLoadFinalization() { - for (auto const & data : modData) + if (settings["mods"]["validation"].String() != "off") { - if (data.second.modData.isNull()) + for (auto const & data : modData) { - for (auto node : data.second.patches.Struct()) - logMod->warn("Mod '%s' have added patch for object '%s' from mod '%s', but this mod was not loaded or has no new objects.", node.second.getModScope(), node.first, data.first); - } - - for(auto & otherMod : modData) - { - if (otherMod.first == data.first) - continue; - - if (otherMod.second.modData.isNull()) - continue; - - for(auto & otherObject : otherMod.second.modData.Struct()) + if (data.second.modData.isNull()) { - if (data.second.modData.Struct().count(otherObject.first)) + for (auto node : data.second.patches.Struct()) + logMod->warn("Mod '%s' have added patch for object '%s' from mod '%s', but this mod was not loaded or has no new objects.", node.second.getModScope(), node.first, data.first); + } + + for(auto & otherMod : modData) + { + if (otherMod.first == data.first) + continue; + + if (otherMod.second.modData.isNull()) + continue; + + for(auto & otherObject : otherMod.second.modData.Struct()) { - logMod->warn("Mod '%s' have added object with name '%s' that is also available in mod '%s'", data.first, otherObject.first, otherMod.first); - logMod->warn("Two objects with same name were loaded. Please use form '%s:%s' if mod '%s' needs to modify this object instead", otherMod.first, otherObject.first, data.first); + if (data.second.modData.Struct().count(otherObject.first)) + { + logMod->warn("Mod '%s' have added object with name '%s' that is also available in mod '%s'", data.first, otherObject.first, otherMod.first); + logMod->warn("Two objects with same name were loaded. Please use form '%s:%s' if mod '%s' needs to modify this object instead", otherMod.first, otherObject.first, data.first); + } } } } - } - for (const auto& [conflictPath, conflictModData] : conflictList.Struct()) - { - std::set conflictingMods; - std::set resolvedConflicts; - - for (auto const & conflictModData : conflictModData.Struct()) - conflictingMods.insert(conflictModData.first); - - for (auto const & modID : conflictingMods) - resolvedConflicts.merge(VLC->modh->getModDependencies(modID)); - - vstd::erase_if(conflictingMods, [&resolvedConflicts](const std::string & entry){ return resolvedConflicts.count(entry);}); - - if (conflictingMods.size() < 2) - continue; // all conflicts were resolved - either via compatibility patch (mod that depends on 2 conflicting mods) or simple mod that depends on another one - - bool allEqual = true; - - for (auto const & modID : conflictingMods) + for (const auto& [conflictPath, conflictModData] : conflictList.Struct()) { - if (conflictModData[modID] != conflictModData[*conflictingMods.begin()]) + std::set conflictingMods; + std::set resolvedConflicts; + + for (auto const & conflictModData : conflictModData.Struct()) + conflictingMods.insert(conflictModData.first); + + for (auto const & modID : conflictingMods) + resolvedConflicts.merge(VLC->modh->getModDependencies(modID)); + + vstd::erase_if(conflictingMods, [&resolvedConflicts](const std::string & entry){ return resolvedConflicts.count(entry);}); + + if (conflictingMods.size() < 2) + continue; // all conflicts were resolved - either via compatibility patch (mod that depends on 2 conflicting mods) or simple mod that depends on another one + + bool allEqual = true; + + for (auto const & modID : conflictingMods) { - allEqual = false; - break; + if (conflictModData[modID] != conflictModData[*conflictingMods.begin()]) + { + allEqual = false; + break; + } } + + if (allEqual) + continue; // conflict still present, but all mods use the same value for conflicting entry - permit it + + logMod->warn("Potential confict in '%s'", conflictPath); + + for (auto const & modID : conflictingMods) + logMod->warn("Mod '%s' - value set to %s", modID, conflictModData[modID].toCompactString()); } - - if (allEqual) - continue; // conflict still present, but all mods use the same value for conflicting entry - permit it - - logMod->warn("Potential confict in '%s'", conflictPath); - - for (auto const & modID : conflictingMods) - logMod->warn("Mod '%s' - value set to %s", modID, conflictModData[modID].toCompactString()); } handler->afterLoadFinalization(); @@ -288,7 +292,7 @@ void CContentHandler::afterLoadFinalization() void CContentHandler::preloadData(CModInfo & mod) { - bool validate = (mod.validation != CModInfo::PASSED); + bool validate = validateMod(mod); // print message in format [<8-symbols checksum>] auto & info = mod.getVerificationInfo(); @@ -305,7 +309,7 @@ void CContentHandler::preloadData(CModInfo & mod) void CContentHandler::load(CModInfo & mod) { - bool validate = (mod.validation != CModInfo::PASSED); + bool validate = validateMod(mod); if (!loadMod(mod.identifier, validate)) mod.validation = CModInfo::FAILED; @@ -326,4 +330,18 @@ const ContentTypeHandler & CContentHandler::operator[](const std::string & name) return handlers.at(name); } +bool CContentHandler::validateMod(const CModInfo & mod) const +{ + if (settings["mods"]["validation"].String() == "full") + return true; + + if (mod.validation == CModInfo::PASSED) + return false; + + if (settings["mods"]["validation"].String() == "off") + return false; + + return true; +} + VCMI_LIB_NAMESPACE_END diff --git a/lib/modding/ContentTypeHandler.h b/lib/modding/ContentTypeHandler.h index 6c3f553c5..5c21bf182 100644 --- a/lib/modding/ContentTypeHandler.h +++ b/lib/modding/ContentTypeHandler.h @@ -58,6 +58,7 @@ class DLL_LINKAGE CContentHandler std::map handlers; + bool validateMod(const CModInfo & mod) const; public: void init();