2
0

CModInfo.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * CModInfo.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "CModInfo.h"
  12. #include "../CGeneralTextHandler.h"
  13. #include "../VCMI_Lib.h"
  14. #include "../filesystem/Filesystem.h"
  15. VCMI_LIB_NAMESPACE_BEGIN
  16. static JsonNode addMeta(JsonNode config, const std::string & meta)
  17. {
  18. config.setMeta(meta);
  19. return config;
  20. }
  21. CModInfo::CModInfo():
  22. explicitlyEnabled(false),
  23. implicitlyEnabled(true),
  24. validation(PENDING)
  25. {
  26. }
  27. CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const JsonNode & config):
  28. identifier(identifier),
  29. description(config["description"].String()),
  30. dependencies(config["depends"].convertTo<std::set<std::string>>()),
  31. conflicts(config["conflicts"].convertTo<std::set<std::string>>()),
  32. explicitlyEnabled(false),
  33. implicitlyEnabled(true),
  34. validation(PENDING),
  35. config(addMeta(config, identifier))
  36. {
  37. verificationInfo.name = config["name"].String();
  38. verificationInfo.version = CModVersion::fromString(config["version"].String());
  39. if(!config["compatibility"].isNull())
  40. {
  41. vcmiCompatibleMin = CModVersion::fromString(config["compatibility"]["min"].String());
  42. vcmiCompatibleMax = CModVersion::fromString(config["compatibility"]["max"].String());
  43. }
  44. if (!config["language"].isNull())
  45. baseLanguage = config["language"].String();
  46. else
  47. baseLanguage = "english";
  48. loadLocalData(local);
  49. }
  50. JsonNode CModInfo::saveLocalData() const
  51. {
  52. std::ostringstream stream;
  53. stream << std::noshowbase << std::hex << std::setw(8) << std::setfill('0') << verificationInfo.checksum;
  54. JsonNode conf;
  55. conf["active"].Bool() = explicitlyEnabled;
  56. conf["validated"].Bool() = validation != FAILED;
  57. conf["checksum"].String() = stream.str();
  58. return conf;
  59. }
  60. std::string CModInfo::getModDir(const std::string & name)
  61. {
  62. return "MODS/" + boost::algorithm::replace_all_copy(name, ".", "/MODS/");
  63. }
  64. JsonPath CModInfo::getModFile(const std::string & name)
  65. {
  66. return JsonPath::builtinTODO(getModDir(name) + "/mod.json");
  67. }
  68. void CModInfo::updateChecksum(ui32 newChecksum)
  69. {
  70. // comment-out next line to force validation of all mods ignoring checksum
  71. if (newChecksum != verificationInfo.checksum)
  72. {
  73. verificationInfo.checksum = newChecksum;
  74. validation = PENDING;
  75. }
  76. }
  77. void CModInfo::loadLocalData(const JsonNode & data)
  78. {
  79. bool validated = false;
  80. implicitlyEnabled = true;
  81. explicitlyEnabled = !config["keepDisabled"].Bool();
  82. verificationInfo.checksum = 0;
  83. if (data.getType() == JsonNode::JsonType::DATA_BOOL)
  84. {
  85. explicitlyEnabled = data.Bool();
  86. }
  87. if (data.getType() == JsonNode::JsonType::DATA_STRUCT)
  88. {
  89. explicitlyEnabled = data["active"].Bool();
  90. validated = data["validated"].Bool();
  91. updateChecksum(strtol(data["checksum"].String().c_str(), nullptr, 16));
  92. }
  93. //check compatibility
  94. implicitlyEnabled &= (vcmiCompatibleMin.isNull() || CModVersion::GameVersion().compatible(vcmiCompatibleMin, true, true));
  95. implicitlyEnabled &= (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(CModVersion::GameVersion(), true, true));
  96. if(!implicitlyEnabled)
  97. logGlobal->warn("Mod %s is incompatible with current version of VCMI and cannot be enabled", verificationInfo.name);
  98. if (boost::iequals(config["modType"].String(), "translation")) // compatibility code - mods use "Translation" type at the moment
  99. {
  100. if (baseLanguage != VLC->generaltexth->getPreferredLanguage())
  101. {
  102. logGlobal->warn("Translation mod %s was not loaded: language mismatch!", verificationInfo.name);
  103. implicitlyEnabled = false;
  104. }
  105. }
  106. if (isEnabled())
  107. validation = validated ? PASSED : PENDING;
  108. else
  109. validation = validated ? PASSED : FAILED;
  110. verificationInfo.impactsGameplay = checkModGameplayAffecting();
  111. }
  112. bool CModInfo::checkModGameplayAffecting() const
  113. {
  114. if (modGameplayAffecting.has_value())
  115. return *modGameplayAffecting;
  116. static const std::vector<std::string> keysToTest = {
  117. "heroClasses",
  118. "artifacts",
  119. "creatures",
  120. "factions",
  121. "objects",
  122. "heroes",
  123. "spells",
  124. "skills",
  125. "templates",
  126. "scripts",
  127. "battlefields",
  128. "terrains",
  129. "rivers",
  130. "roads",
  131. "obstacles"
  132. };
  133. JsonPath modFileResource(CModInfo::getModFile(identifier));
  134. if(CResourceHandler::get("initial")->existsResource(modFileResource))
  135. {
  136. const JsonNode modConfig(modFileResource);
  137. for(const auto & key : keysToTest)
  138. {
  139. if (!modConfig[key].isNull())
  140. {
  141. modGameplayAffecting = true;
  142. return *modGameplayAffecting;
  143. }
  144. }
  145. }
  146. modGameplayAffecting = false;
  147. return *modGameplayAffecting;
  148. }
  149. const CModInfo::VerificationInfo & CModInfo::getVerificationInfo() const
  150. {
  151. return verificationInfo;
  152. }
  153. bool CModInfo::isEnabled() const
  154. {
  155. return implicitlyEnabled && explicitlyEnabled;
  156. }
  157. void CModInfo::setEnabled(bool on)
  158. {
  159. explicitlyEnabled = on;
  160. }
  161. VCMI_LIB_NAMESPACE_END