2
0
Эх сурвалжийг харах

Automatically install missing mods from preset

Ivan Savenko 10 сар өмнө
parent
commit
ba5ed98da5

+ 19 - 2
launcher/modManager/cmodlistview_moc.cpp

@@ -857,6 +857,12 @@ void CModListView::installMods(QStringList archives)
 		modNames.push_back(modName);
 	}
 
+	if (!activatingPreset.isEmpty())
+	{
+		modStateModel->activatePreset(activatingPreset);
+		activatingPreset.clear();
+	}
+
 	// uninstall old version of mod, if installed
 	for(QString mod : modNames)
 	{
@@ -1151,6 +1157,17 @@ JsonNode CModListView::exportCurrentPreset() const
 
 void CModListView::importPreset(const JsonNode & data)
 {
-	modStateModel->importPreset(data);
-	modStateModel->reloadLocalState();
+	const auto & [presetName, modList] = modStateModel->importPreset(data);
+
+	if (modList.empty())
+	{
+		modStateModel->activatePreset(presetName);
+		modStateModel->reloadLocalState();
+	}
+	else
+	{
+		activatingPreset = presetName;
+		for (const auto & modID : modList)
+			doInstallMod(modID);
+	}
 }

+ 1 - 0
launcher/modManager/cmodlistview_moc.h

@@ -37,6 +37,7 @@ class CModListView : public QWidget
 	CModFilterModel * filterModel;
 	CDownloadManager * dlManager;
 	JsonNode accumulatedRepositoryData;
+	QString activatingPreset;
 
 	QStringList enqueuedModDownloads;
 

+ 5 - 2
launcher/modManager/modstatemodel.cpp

@@ -163,7 +163,10 @@ JsonNode ModStateModel::exportCurrentPreset() const
 	return modManager->exportCurrentPreset();
 }
 
-void ModStateModel::importPreset(const JsonNode & data)
+std::tuple<QString, QStringList> ModStateModel::importPreset(const JsonNode & data)
 {
-	modManager->importPreset(data);
+	std::tuple<QString, QStringList> result;
+	const auto & [presetName, modList] = modManager->importPreset(data);
+
+	return {QString::fromStdString(presetName), stringListStdToQt(modList)};
 }

+ 1 - 1
launcher/modManager/modstatemodel.h

@@ -59,5 +59,5 @@ public:
 	QString getActivePreset() const;
 
 	JsonNode exportCurrentPreset() const;
-	void importPreset(const JsonNode & data);
+	std::tuple<QString, QStringList> importPreset(const JsonNode & data);
 };

+ 24 - 4
lib/modding/ModManager.cpp

@@ -207,7 +207,12 @@ const JsonNode & ModsPresetState::getActivePresetConfig() const
 
 TModList ModsPresetState::getActiveRootMods() const
 {
-	const JsonNode & modsToActivateJson = getActivePresetConfig()["mods"];
+	return getRootMods(getActivePreset());
+}
+
+TModList ModsPresetState::getRootMods(const std::string & presetName) const
+{
+	const JsonNode & modsToActivateJson = modConfig["presets"][presetName]["mods"];
 	auto modsToActivate = modsToActivateJson.convertTo<std::vector<TModID>>();
 	if (!vstd::contains(modsToActivate, ModScope::scopeBuiltin()))
 		modsToActivate.push_back(ModScope::scopeBuiltin());
@@ -399,7 +404,7 @@ JsonNode ModsPresetState::exportCurrentPreset() const
 	return data;
 }
 
-void ModsPresetState::importPreset(const JsonNode & newConfig)
+std::string ModsPresetState::importPreset(const JsonNode & newConfig)
 {
 	std::string importedPresetName = newConfig["name"].String();
 
@@ -408,6 +413,8 @@ void ModsPresetState::importPreset(const JsonNode & newConfig)
 
 	modConfig["presets"][importedPresetName] = newConfig;
 	modConfig["presets"][importedPresetName].Struct().erase("name");
+
+	return importedPresetName;
 }
 
 ModsStorage::ModsStorage(const std::vector<TModID> & modsToLoad, const JsonNode & repositoryList)
@@ -826,10 +833,23 @@ JsonNode ModManager::exportCurrentPreset() const
 	return modsPreset->exportCurrentPreset();
 }
 
-void ModManager::importPreset(const JsonNode & data)
+std::tuple<std::string, TModList> ModManager::importPreset(const JsonNode & data)
 {
-	modsPreset->importPreset(data);
+	std::string presetName = modsPreset->importPreset(data);
+
+	TModList requiredMods = modsPreset->getRootMods(presetName);
+	TModList installedMods = modsState->getInstalledMods();
+
+	TModList missingMods;
+	for (const auto & modID : requiredMods)
+	{
+		if (!vstd::contains(installedMods, modID))
+			missingMods.push_back(modID);
+	}
+
 	modsPreset->saveConfigurationState();
+
+	return {presetName, missingMods};
 }
 
 VCMI_LIB_NAMESPACE_END

+ 10 - 2
lib/modding/ModManager.h

@@ -59,7 +59,10 @@ public:
 	std::string getActivePreset() const;
 
 	JsonNode exportCurrentPreset() const;
-	void importPreset(const JsonNode & data);
+
+	/// Imports preset from provided json
+	/// Returns name of imported preset on success
+	std::string importPreset(const JsonNode & data);
 
 	void setModActive(const TModID & modName, bool isActive);
 
@@ -75,6 +78,8 @@ public:
 
 	/// Returns list of currently active root mods (non-submod)
 	TModList getActiveRootMods() const;
+	/// Returns list of root mods present in specified preset
+	TModList getRootMods(const std::string & presetName) const;
 
 	/// Returns list of all known settings (submods) for a specified mod
 	std::map<TModID, bool> getModSettings(const TModID & modID) const;
@@ -160,7 +165,10 @@ public:
 	std::string getActivePreset() const;
 
 	JsonNode exportCurrentPreset() const;
-	void importPreset(const JsonNode & data);
+
+	/// Imports preset from provided json
+	/// Returns name of imported preset and list of mods that must be installed to activate preset
+	std::tuple<std::string, TModList> importPreset(const JsonNode & data);
 };
 
 VCMI_LIB_NAMESPACE_END