1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Always convert mod ID to lower case before using it

This commit is contained in:
Ivan Savenko 2023-11-19 20:44:28 +02:00
parent c0e54b338a
commit c717bb5504
6 changed files with 44 additions and 14 deletions

View File

@ -141,6 +141,22 @@ QVariant CModEntry::getValue(QString value) const
return getValueImpl(value, true);
}
QStringList CModEntry::getDependencies() const
{
QStringList result;
for (auto const & entry : getValue("depends").toStringList())
result.push_back(entry.toLower());
return result;
}
QStringList CModEntry::getConflicts() const
{
QStringList result;
for (auto const & entry : getValue("conflicts").toStringList())
result.push_back(entry.toLower());
return result;
}
QVariant CModEntry::getBaseValue(QString value) const
{
return getValueImpl(value, false);
@ -341,8 +357,8 @@ QStringList CModList::getRequirements(QString modname)
{
auto mod = getMod(modname);
for(auto entry : mod.getValue("depends").toStringList())
ret += getRequirements(entry);
for(auto entry : mod.getDependencies())
ret += getRequirements(entry.toLower());
}
ret += modname;

View File

@ -76,6 +76,9 @@ public:
QVariant getValue(QString value) const;
QVariant getBaseValue(QString value) const;
QStringList getDependencies() const;
QStringList getConflicts() const;
static QString sizeToString(double size);
};

View File

@ -218,12 +218,12 @@ QStringList CModListView::getModNames(QStringList input)
for(const auto & modID : input)
{
auto mod = modModel->getMod(modID);
auto mod = modModel->getMod(modID.toLower());
QString modName = mod.getValue("name").toString();
if (modName.isEmpty())
result += modID;
result += modID.toLower();
else
result += modName;
}
@ -311,8 +311,8 @@ QString CModListView::genModInfoText(CModEntry & mod)
if(needToShowSupportedLanguages)
result += replaceIfNotEmpty(supportedLanguages, lineTemplate.arg(tr("Languages")));
result += replaceIfNotEmpty(getModNames(mod.getValue("depends").toStringList()), lineTemplate.arg(tr("Required mods")));
result += replaceIfNotEmpty(getModNames(mod.getValue("conflicts").toStringList()), lineTemplate.arg(tr("Conflicting mods")));
result += replaceIfNotEmpty(getModNames(mod.getDependencies()), lineTemplate.arg(tr("Required mods")));
result += replaceIfNotEmpty(getModNames(mod.getConflicts()), lineTemplate.arg(tr("Conflicting mods")));
result += replaceIfNotEmpty(getModNames(mod.getValue("description").toStringList()), textTemplate.arg(tr("Description")));
result += "<p></p>"; // to get some empty space
@ -464,7 +464,7 @@ QStringList CModListView::findBlockingMods(QString modUnderTest)
if(mod.isEnabled())
{
// one of enabled mods have requirement (or this mod) marked as conflict
for(auto conflict : mod.getValue("conflicts").toStringList())
for(auto conflict : mod.getConflicts())
{
if(required.contains(conflict))
ret.push_back(name);
@ -485,7 +485,7 @@ QStringList CModListView::findDependentMods(QString mod, bool excludeDisabled)
if(!current.isInstalled())
continue;
if(current.getValue("depends").toStringList().contains(mod))
if(current.getDependencies().contains(mod, Qt::CaseInsensitive))
{
if(!(current.isDisabled() && excludeDisabled))
ret += modName;

View File

@ -192,7 +192,7 @@ bool CModManager::canEnableMod(QString modname)
if(!mod.isCompatible())
return addError(modname, "Mod is not compatible, please update VCMI and checkout latest mod revisions");
for(auto modEntry : mod.getValue("depends").toStringList())
for(auto modEntry : mod.getDependencies())
{
if(!modList->hasMod(modEntry)) // required mod is not available
return addError(modname, QString("Required mod %1 is missing").arg(modEntry));
@ -205,11 +205,11 @@ bool CModManager::canEnableMod(QString modname)
auto mod = modList->getMod(modEntry);
// "reverse conflict" - enabled mod has this one as conflict
if(mod.isEnabled() && mod.getValue("conflicts").toStringList().contains(modname))
if(mod.isEnabled() && mod.getConflicts().contains(modname))
return addError(modname, QString("This mod conflicts with %1").arg(modEntry));
}
for(auto modEntry : mod.getValue("conflicts").toStringList())
for(auto modEntry : mod.getConflicts())
{
// check if conflicting mod installed and enabled
if(modList->hasMod(modEntry) && modList->getMod(modEntry).isEnabled())
@ -232,7 +232,7 @@ bool CModManager::canDisableMod(QString modname)
{
auto current = modList->getMod(modEntry);
if(current.getValue("depends").toStringList().contains(modname) && current.isEnabled())
if(current.getDependencies().contains(modname) && current.isEnabled())
return addError(modname, QString("This mod is needed to run %1").arg(modEntry));
}
return true;

View File

@ -22,6 +22,16 @@ static JsonNode addMeta(JsonNode config, const std::string & meta)
return config;
}
std::set<TModID> CModInfo::readModList(const JsonNode & input)
{
std::set<TModID> result;
for (auto const & string : input.convertTo<std::set<std::string>>())
result.insert(boost::to_lower_copy(string));
return result;
}
CModInfo::CModInfo():
explicitlyEnabled(false),
implicitlyEnabled(true),
@ -32,8 +42,8 @@ CModInfo::CModInfo():
CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const JsonNode & config):
identifier(identifier),
dependencies(config["depends"].convertTo<std::set<std::string>>()),
conflicts(config["conflicts"].convertTo<std::set<std::string>>()),
dependencies(readModList(config["depends"])),
conflicts(readModList(config["conflicts"])),
explicitlyEnabled(false),
implicitlyEnabled(true),
validation(PENDING),

View File

@ -20,6 +20,7 @@ class DLL_LINKAGE CModInfo
/// Do not serialize - depends on local mod version, not server/save mod version
mutable std::optional<bool> modGameplayAffecting;
static std::set<TModID> readModList(const JsonNode & input);
public:
enum EValidationStatus
{