浏览代码

Fix installation of mods with complex dependencies such as H3Evo

Ivan Savenko 1 年之前
父节点
当前提交
eab03c24ee
共有 3 个文件被更改,包括 35 次插入7 次删除
  1. 1 1
      launcher/modManager/cmodlistview_moc.cpp
  2. 33 6
      lib/modding/ModManager.cpp
  3. 1 0
      lib/modding/ModManager.h

+ 1 - 1
launcher/modManager/cmodlistview_moc.cpp

@@ -590,7 +590,7 @@ QStringList CModListView::getModsToInstall(QString mod)
 			}
 		}
 	}
-	assert(result.removeDuplicates() == 0);
+	result.removeDuplicates();
 	return result;
 }
 

+ 33 - 6
lib/modding/ModManager.cpp

@@ -262,6 +262,20 @@ void ModsPresetState::setSettingActive(const TModID & modName, const TModID & se
 	currentPreset["settings"][modName][settingName].Bool() = isActive;
 }
 
+void ModsPresetState::removeOldMods(const TModList & modsToKeep)
+{
+	const std::string & currentPresetName = modConfig["activePreset"].String();
+	JsonNode & currentPreset = modConfig["presets"][currentPresetName];
+
+	vstd::erase_if(currentPreset["mods"].Vector(), [&](const JsonNode & entry){
+		return !vstd::contains(modsToKeep, entry.String());
+	});
+
+	vstd::erase_if(currentPreset["settings"].Struct(), [&](const auto & entry){
+		return !vstd::contains(modsToKeep, entry.first);
+	});
+}
+
 void ModsPresetState::eraseRootMod(const TModID & modName)
 {
 	const std::string & currentPresetName = modConfig["activePreset"].String();
@@ -438,14 +452,10 @@ void ModManager::eraseMissingModsFromPreset()
 	const TModList & installedMods = modsState->getInstalledMods();
 	const TModList & rootMods = modsPreset->getActiveRootMods();
 
+	modsPreset->removeOldMods(installedMods);
+
 	for(const auto & rootMod : rootMods)
 	{
-		if(!vstd::contains(installedMods, rootMod))
-		{
-			modsPreset->eraseRootMod(rootMod);
-			continue;
-		}
-
 		const auto & modSettings = modsPreset->getModSettings(rootMod);
 
 		for(const auto & modSetting : modSettings)
@@ -531,6 +541,23 @@ void ModManager::tryEnableMods(const TModList & modList)
 
 	testResolver.tryAddMods(additionalActiveMods, *modsStorage);
 
+	TModList additionalActiveSubmods;
+	for (const auto & modName : modList)
+	{
+		if (modName.find('.') != std::string::npos)
+			continue;
+
+		auto modSettings = modsPreset->getModSettings(modName);
+		for (const auto & entry : modSettings)
+		{
+			TModID fullModID = modName + '.' + entry.first;
+			if (entry.second && !vstd::contains(requiredActiveMods, fullModID))
+				additionalActiveSubmods.push_back(fullModID);
+		}
+	}
+
+	testResolver.tryAddMods(additionalActiveSubmods, *modsStorage);
+
 	for (const auto & modName : modList)
 		if (!vstd::contains(testResolver.getActiveMods(), modName))
 			throw std::runtime_error("Failed to enable mod! Mod " + modName + " remains disabled!");

+ 1 - 0
lib/modding/ModManager.h

@@ -54,6 +54,7 @@ public:
 
 	void addRootMod(const TModID & modName);
 	void eraseRootMod(const TModID & modName);
+	void removeOldMods(const TModList & modsToKeep);
 
 	void setSettingActive(const TModID & modName, const TModID & settingName, bool isActive);
 	void eraseModSetting(const TModID & modName, const TModID & settingName);