File: ModVerificationInfo.cpp

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (123 lines) | stat: -rw-r--r-- 3,147 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * ModVerificationInfo.cpp, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#include "StdInc.h"
#include "ModVerificationInfo.h"

#include "CModHandler.h"
#include "ModDescription.h"
#include "ModIncompatibility.h"
#include "ModScope.h"

#include "../json/JsonNode.h"
#include "../VCMI_Lib.h"

VCMI_LIB_NAMESPACE_BEGIN

JsonNode ModVerificationInfo::jsonSerializeList(const ModCompatibilityInfo & input)
{
	JsonNode output;

	for(const auto & mod : input)
	{
		JsonNode modWriter;
		modWriter["modId"].String() = mod.first;
		modWriter["name"].String() = mod.second.name;
		if (!mod.second.parent.empty())
			modWriter["parent"].String() = mod.second.parent;
		modWriter["version"].String() = mod.second.version.toString();
		output.Vector().push_back(modWriter);
	}

	return output;
}

ModCompatibilityInfo ModVerificationInfo::jsonDeserializeList(const JsonNode & input)
{
	ModCompatibilityInfo output;

	for(const auto & mod : input.Vector())
	{
		ModVerificationInfo info;
		info.version = CModVersion::fromString(mod["version"].String());
		info.name = mod["name"].String();
		info.parent = mod["parent"].String();
		info.checksum = 0;
		info.impactsGameplay = true;

		if(!mod["modId"].isNull())
			output[mod["modId"].String()] = info;
		else
			output[mod["name"].String()] = info;
	}

	return output;
}

ModListVerificationStatus ModVerificationInfo::verifyListAgainstLocalMods(const ModCompatibilityInfo & modList)
{
	ModListVerificationStatus result;

	for(const auto & m : VLC->modh->getActiveMods())
	{
		if(modList.count(m))
			continue;

		if (m == ModScope::scopeBuiltin())
			continue;

		if(VLC->modh->getModInfo(m).affectsGameplay())
			result[m] = ModVerificationStatus::EXCESSIVE;
	}

	for(const auto & infoPair : modList)
	{
		auto & remoteModId = infoPair.first;
		auto & remoteModInfo = infoPair.second;

		if (remoteModId == ModScope::scopeBuiltin())
			continue;

		bool modAffectsGameplay = remoteModInfo.impactsGameplay;
		//parent mod affects gameplay if child affects too
		for(const auto & subInfoPair : modList)
			modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);

		if(!vstd::contains(VLC->modh->getAllMods(), remoteModId))
		{
			result[remoteModId] = ModVerificationStatus::NOT_INSTALLED;
			continue;
		}

		const auto & localVersion = VLC->modh->getModInfo(remoteModId).getVersion();
		modAffectsGameplay |= VLC->modh->getModInfo(remoteModId).affectsGameplay();

		// skip it. Such mods should only be present in old saves or if mod changed and no longer affects gameplay
		if (!modAffectsGameplay)
			continue;

		if (!vstd::contains(VLC->modh->getActiveMods(), remoteModId))
		{
			result[remoteModId] = ModVerificationStatus::DISABLED;
			continue;
		}

		if(remoteModInfo.version != localVersion)
		{
			result[remoteModId] = ModVerificationStatus::VERSION_MISMATCH;
			continue;
		}

		result[remoteModId] = ModVerificationStatus::FULL_MATCH;
	}

	return result;
}

VCMI_LIB_NAMESPACE_END