mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Merge pull request #929 from Nordsoft91/branch-merge-versioning
Mods versioning [part 3]
This commit is contained in:
@@ -12,29 +12,53 @@
|
||||
|
||||
#include "../../lib/JsonNode.h"
|
||||
#include "../../lib/filesystem/CFileInputStream.h"
|
||||
#include "../../lib/GameConstants.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isCompatible(const QString & verMin, const QString & verMax)
|
||||
{
|
||||
const int maxSections = 3; // versions consist from up to 3 sections, major.minor.patch
|
||||
QVersionNumber vcmiVersion(GameConstants::VCMI_VERSION_MAJOR,
|
||||
GameConstants::VCMI_VERSION_MINOR,
|
||||
GameConstants::VCMI_VERSION_PATCH);
|
||||
|
||||
auto versionMin = QVersionNumber::fromString(verMin);
|
||||
auto versionMax = QVersionNumber::fromString(verMax);
|
||||
|
||||
auto buildVersion = [maxSections](QVersionNumber & ver)
|
||||
{
|
||||
if(ver.segmentCount() < maxSections)
|
||||
{
|
||||
auto segments = ver.segments();
|
||||
for(int i = segments.size() - 1; i < maxSections; ++i)
|
||||
segments.append(0);
|
||||
ver = QVersionNumber(segments);
|
||||
}
|
||||
};
|
||||
|
||||
if(!versionMin.isNull())
|
||||
{
|
||||
buildVersion(versionMin);
|
||||
if(vcmiVersion < versionMin)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!versionMax.isNull())
|
||||
{
|
||||
buildVersion(versionMax);
|
||||
if(vcmiVersion > versionMax)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CModEntry::compareVersions(QString lesser, QString greater)
|
||||
{
|
||||
static const int maxSections = 3; // versions consist from up to 3 sections, major.minor.patch
|
||||
|
||||
QStringList lesserList = lesser.split(".");
|
||||
QStringList greaterList = greater.split(".");
|
||||
|
||||
assert(lesserList.size() <= maxSections);
|
||||
assert(greaterList.size() <= maxSections);
|
||||
|
||||
for(int i = 0; i < maxSections; i++)
|
||||
{
|
||||
if(greaterList.size() <= i) // 1.1.1 > 1.1
|
||||
return false;
|
||||
|
||||
if(lesserList.size() <= i) // 1.1 < 1.1.1
|
||||
return true;
|
||||
|
||||
if(lesserList[i].toInt() != greaterList[i].toInt())
|
||||
return lesserList[i].toInt() < greaterList[i].toInt(); // 1.1 < 1.2
|
||||
}
|
||||
return false;
|
||||
auto versionLesser = QVersionNumber::fromString(lesser);
|
||||
auto versionGreater = QVersionNumber::fromString(greater);
|
||||
return versionLesser < versionGreater;
|
||||
}
|
||||
|
||||
QString CModEntry::sizeToString(double size)
|
||||
@@ -92,6 +116,15 @@ bool CModEntry::isUpdateable() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CModEntry::isCompatible() const
|
||||
{
|
||||
if(!isInstalled())
|
||||
return false;
|
||||
|
||||
auto compatibility = localData["compatibility"].toMap();
|
||||
return ::isCompatible(compatibility["min"].toString(), compatibility["max"].toString());
|
||||
}
|
||||
|
||||
bool CModEntry::isEssential() const
|
||||
{
|
||||
return getValue("storedLocaly").toBool();
|
||||
@@ -102,6 +135,11 @@ bool CModEntry::isInstalled() const
|
||||
return !localData.isEmpty();
|
||||
}
|
||||
|
||||
bool CModEntry::isValid() const
|
||||
{
|
||||
return !localData.isEmpty() || !repository.isEmpty();
|
||||
}
|
||||
|
||||
int CModEntry::getModStatus() const
|
||||
{
|
||||
int status = 0;
|
||||
@@ -193,7 +231,11 @@ static QVariant getValue(QVariant input, QString path)
|
||||
QString remainder = "/" + path.section('/', 2, -1);
|
||||
|
||||
entryName.remove(0, 1);
|
||||
return getValue(input.toMap().value(entryName), remainder);
|
||||
QMap<QString, QString> keyNormalize;
|
||||
for(auto & key : input.toMap().keys())
|
||||
keyNormalize[key.toLower()] = key;
|
||||
|
||||
return getValue(input.toMap().value(keyNormalize[entryName]), remainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -203,6 +245,7 @@ static QVariant getValue(QVariant input, QString path)
|
||||
|
||||
CModEntry CModList::getMod(QString modname) const
|
||||
{
|
||||
modname = modname.toLower();
|
||||
QVariantMap repo;
|
||||
QVariantMap local = localModList[modname].toMap();
|
||||
QVariantMap settings;
|
||||
@@ -246,14 +289,14 @@ CModEntry CModList::getMod(QString modname) const
|
||||
QVariant repoVal = getValue(entry, path);
|
||||
if(repoVal.isValid())
|
||||
{
|
||||
if(repo.empty())
|
||||
auto repoValMap = repoVal.toMap();
|
||||
auto compatibility = repoValMap["compatibility"].toMap();
|
||||
if(isCompatible(compatibility["min"].toString(), compatibility["max"].toString()))
|
||||
{
|
||||
repo = repoVal.toMap();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CModEntry::compareVersions(repo["version"].toString(), repoVal.toMap()["version"].toString()))
|
||||
repo = repoVal.toMap();
|
||||
if(repo.empty() || CModEntry::compareVersions(repo["version"].toString(), repoValMap["version"].toString()))
|
||||
{
|
||||
repo = repoValMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,12 +340,12 @@ QVector<QString> CModList::getModList() const
|
||||
{
|
||||
for(auto it = repo.begin(); it != repo.end(); it++)
|
||||
{
|
||||
knownMods.insert(it.key());
|
||||
knownMods.insert(it.key().toLower());
|
||||
}
|
||||
}
|
||||
for(auto it = localModList.begin(); it != localModList.end(); it++)
|
||||
{
|
||||
knownMods.insert(it.key());
|
||||
knownMods.insert(it.key().toLower());
|
||||
}
|
||||
|
||||
for(auto entry : knownMods)
|
||||
|
||||
@@ -51,6 +51,10 @@ public:
|
||||
bool isInstalled() const;
|
||||
// vcmi essential files
|
||||
bool isEssential() const;
|
||||
// checks if verison is compatible with vcmi
|
||||
bool isCompatible() const;
|
||||
// returns if has any data
|
||||
bool isValid() const;
|
||||
|
||||
// see ModStatus enum
|
||||
int getModStatus() const;
|
||||
|
||||
@@ -245,6 +245,7 @@ bool CModFilterModel::filterMatchesThis(const QModelIndex & source) const
|
||||
{
|
||||
CModEntry mod = base->getMod(source.data(ModRoles::ModNameRole).toString());
|
||||
return (mod.getModStatus() & filterMask) == filteredType &&
|
||||
mod.isValid() &&
|
||||
QSortFilterProxyModel::filterAcceptsRow(source.row(), source.parent());
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,10 @@ bool CModManager::canEnableMod(QString modname)
|
||||
if(!mod.isInstalled())
|
||||
return addError(modname, "Mod must be installed first");
|
||||
|
||||
//check for compatibility
|
||||
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())
|
||||
{
|
||||
if(!modList->hasMod(modEntry)) // required mod is not available
|
||||
|
||||
Reference in New Issue
Block a user