Add saving mods list in colobot.ini
parent
69d2d39c36
commit
63bf6bed08
|
@ -520,7 +520,9 @@ bool CApplication::Create()
|
|||
GetLogger()->Warn("Config could not be loaded. Default values will be used!\n");
|
||||
}
|
||||
|
||||
m_modManager->ReinitMods();
|
||||
m_modManager->FindMods();
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->UpdatePaths();
|
||||
|
||||
// Create the sound instance.
|
||||
#ifdef OPENAL_SOUND
|
||||
|
|
|
@ -19,22 +19,18 @@
|
|||
|
||||
#include "app/modman.h"
|
||||
|
||||
//TODO: clean up includes
|
||||
#include "common/config.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/pathman.h"
|
||||
|
||||
#include "common/config_file.h"
|
||||
#include "common/logger.h"
|
||||
#include "common/restext.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "common/system/system.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
@ -46,16 +42,64 @@ CModManager::CModManager(CApplication* app, CPathManager* pathManager)
|
|||
{
|
||||
}
|
||||
|
||||
void CModManager::ReinitMods()
|
||||
void CModManager::FindMods()
|
||||
{
|
||||
m_mods.clear();
|
||||
const auto foundMods = m_pathManager->FindMods();
|
||||
for (const auto& modPath : foundMods)
|
||||
|
||||
// Load names from the config file
|
||||
std::vector<std::string> savedModNames;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Names", savedModNames);
|
||||
std::vector<bool> savedEnabled;
|
||||
GetConfigFile().GetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
// Transform the data into Mod structures
|
||||
m_mods.reserve(savedModNames.size());
|
||||
for (int i = 0; i < savedModNames.size(); ++i)
|
||||
{
|
||||
Mod mod;
|
||||
mod.name = boost::filesystem::path(modPath).stem().string();
|
||||
mod.path = modPath;
|
||||
mod.enabled = m_pathManager->ModLoaded(mod.path); //TODO: load from some config file
|
||||
Mod mod{};
|
||||
mod.name = savedModNames[i];
|
||||
if (i < savedEnabled.size())
|
||||
{
|
||||
mod.enabled = savedEnabled[i];
|
||||
}
|
||||
mod.path = ""; // Find the path later
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
|
||||
// Search the folders for mods
|
||||
const auto rawPaths = m_pathManager->FindMods();
|
||||
std::map<std::string, std::string> modPaths;
|
||||
for (const auto& path : rawPaths)
|
||||
{
|
||||
auto modName = boost::filesystem::path(path).stem().string();
|
||||
modPaths.insert(std::make_pair(modName, path));
|
||||
}
|
||||
|
||||
// Find paths for already saved mods
|
||||
auto it = m_mods.begin();
|
||||
while (it != m_mods.end())
|
||||
{
|
||||
auto& mod = *it;
|
||||
const auto pathsIt = modPaths.find(mod.name);
|
||||
if (pathsIt != modPaths.end())
|
||||
{
|
||||
mod.path = (*pathsIt).second;
|
||||
modPaths.erase(pathsIt);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetLogger()->Warn("Could not find mod %s, removing it from the list\n", mod.name.c_str());
|
||||
it = m_mods.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the remaining found mods to the end of the list
|
||||
for (const auto& newMod : modPaths)
|
||||
{
|
||||
Mod mod{};
|
||||
mod.name = newMod.first;
|
||||
mod.path = newMod.second;
|
||||
m_mods.push_back(mod);
|
||||
}
|
||||
}
|
||||
|
@ -82,23 +126,38 @@ void CModManager::DisableMod(const std::string& modName)
|
|||
mod->enabled = false;
|
||||
}
|
||||
|
||||
void CModManager::ReloadMods()
|
||||
void CModManager::UpdatePaths()
|
||||
{
|
||||
m_pathManager->RemoveAllMods();
|
||||
for (const auto& mod : m_mods)
|
||||
{
|
||||
bool loaded = m_pathManager->ModLoaded(mod.path);
|
||||
if (mod.enabled && !loaded)
|
||||
if (mod.enabled)
|
||||
{
|
||||
m_pathManager->AddMod(mod.path);
|
||||
}
|
||||
else if (!mod.enabled && loaded)
|
||||
{
|
||||
m_pathManager->RemoveMod(mod.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CModManager::ReloadResources()
|
||||
{
|
||||
m_app->ReloadResources();
|
||||
}
|
||||
|
||||
void CModManager::SaveMods()
|
||||
{
|
||||
std::vector<std::string> savedNames;
|
||||
savedNames.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedNames), [](const Mod& mod) { return mod.name; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Names", savedNames);
|
||||
|
||||
std::vector<bool> savedEnabled;
|
||||
savedEnabled.reserve(m_mods.size());
|
||||
std::transform(m_mods.begin(), m_mods.end(), std::back_inserter(savedEnabled), [](const Mod& mod) { return mod.enabled; });
|
||||
GetConfigFile().SetArrayProperty("Mods", "Enabled", savedEnabled);
|
||||
|
||||
GetConfigFile().Save();
|
||||
}
|
||||
|
||||
boost::optional<Mod> CModManager::GetMod(const std::string& modName)
|
||||
{
|
||||
Mod* mod = FindMod(modName);
|
||||
|
|
|
@ -30,8 +30,8 @@ class CPathManager;
|
|||
|
||||
struct Mod
|
||||
{
|
||||
std::string name;
|
||||
std::string path;
|
||||
std::string name{};
|
||||
std::string path{};
|
||||
bool enabled = false;
|
||||
//TODO: add metadata for UI
|
||||
};
|
||||
|
@ -41,6 +41,7 @@ struct Mod
|
|||
* \brief Main application
|
||||
*
|
||||
* This class handles the list of currently loaded mods.
|
||||
* The order matters since the order in which files are loaded matters.
|
||||
*
|
||||
*/
|
||||
class CModManager
|
||||
|
@ -49,7 +50,7 @@ public:
|
|||
CModManager(CApplication* app, CPathManager* pathManager);
|
||||
|
||||
//! Finds all the mods along with their metadata
|
||||
void ReinitMods();
|
||||
void FindMods();
|
||||
|
||||
//! Removes a mod from the list of loaded mods
|
||||
void EnableMod(const std::string& modName);
|
||||
|
@ -58,7 +59,13 @@ public:
|
|||
void DisableMod(const std::string& modName);
|
||||
|
||||
//! Reloads application resources so the enabled mods are applied
|
||||
void ReloadMods();
|
||||
void ReloadResources();
|
||||
|
||||
//! Saves the current configuration of mods to the config file
|
||||
void SaveMods();
|
||||
|
||||
//! Updates the paths in Path Manager according to the current mod configuration
|
||||
void UpdatePaths();
|
||||
|
||||
boost::optional<Mod> GetMod(const std::string& modName);
|
||||
const std::vector<Mod>& GetMods() const;
|
||||
|
|
|
@ -73,17 +73,30 @@ void CPathManager::AddMod(const std::string &modPath)
|
|||
{
|
||||
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
|
||||
CResourceManager::AddLocation(modPath, true);
|
||||
m_mods.push_back(modPath);
|
||||
}
|
||||
|
||||
void CPathManager::RemoveMod(const std::string &modPath)
|
||||
{
|
||||
GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str());
|
||||
CResourceManager::RemoveLocation(modPath);
|
||||
auto it = std::find(m_mods.cbegin(), m_mods.cend(), modPath);
|
||||
if (it != m_mods.cend())
|
||||
m_mods.erase(it);
|
||||
}
|
||||
|
||||
void CPathManager::RemoveAllMods()
|
||||
{
|
||||
for (const auto& modPath : m_mods)
|
||||
{
|
||||
CResourceManager::RemoveLocation(modPath);
|
||||
}
|
||||
m_mods.clear();
|
||||
}
|
||||
|
||||
bool CPathManager::ModLoaded(const std::string& modPath)
|
||||
{
|
||||
return CResourceManager::LocationExists(modPath);
|
||||
return std::find(m_mods.cbegin(), m_mods.cend(), modPath) != m_mods.end();
|
||||
}
|
||||
|
||||
std::vector<std::string> CPathManager::FindMods() const
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
void AddModSearchDir(const std::string &modSearchDirPath);
|
||||
void AddMod(const std::string &modPath);
|
||||
void RemoveMod(const std::string &modPath);
|
||||
void RemoveAllMods();
|
||||
bool ModLoaded(const std::string& modPath);
|
||||
std::vector<std::string> FindMods() const;
|
||||
|
||||
|
@ -65,4 +66,6 @@ private:
|
|||
std::string m_savePath;
|
||||
//! Mod search paths
|
||||
std::vector<std::string> m_modSearchDirs;
|
||||
//! Mod paths
|
||||
std::vector<std::string> m_mods;
|
||||
};
|
||||
|
|
|
@ -71,6 +71,8 @@ void CScreenSetupMods::CreateInterface()
|
|||
Math::Point pos, ddim;
|
||||
std::string name;
|
||||
|
||||
m_modManager->FindMods();
|
||||
|
||||
CScreenSetup::CreateInterface();
|
||||
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||
if ( pw == nullptr ) return;
|
||||
|
@ -155,7 +157,9 @@ bool CScreenSetupMods::EventProcess(const Event &event)
|
|||
modName = pl->GetItemName(pl->GetSelect());
|
||||
|
||||
m_modManager->EnableMod(modName);
|
||||
m_modManager->ReloadMods();
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->UpdatePaths();
|
||||
m_modManager->ReloadResources();
|
||||
|
||||
m_main->ChangePhase(PHASE_SETUPm);
|
||||
break;
|
||||
|
@ -166,7 +170,9 @@ bool CScreenSetupMods::EventProcess(const Event &event)
|
|||
modName = pl->GetItemName(pl->GetSelect());
|
||||
|
||||
m_modManager->DisableMod(modName);
|
||||
m_modManager->ReloadMods();
|
||||
m_modManager->SaveMods();
|
||||
m_modManager->UpdatePaths();
|
||||
m_modManager->ReloadResources();
|
||||
|
||||
m_main->ChangePhase(PHASE_SETUPm);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue