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");
|
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.
|
// Create the sound instance.
|
||||||
#ifdef OPENAL_SOUND
|
#ifdef OPENAL_SOUND
|
||||||
|
|
|
@ -19,22 +19,18 @@
|
||||||
|
|
||||||
#include "app/modman.h"
|
#include "app/modman.h"
|
||||||
|
|
||||||
//TODO: clean up includes
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/pathman.h"
|
#include "app/pathman.h"
|
||||||
|
|
||||||
|
#include "common/config_file.h"
|
||||||
#include "common/logger.h"
|
#include "common/logger.h"
|
||||||
#include "common/restext.h"
|
|
||||||
#include "common/settings.h"
|
|
||||||
#include "common/stringutils.h"
|
|
||||||
|
|
||||||
#include "common/resources/resourcemanager.h"
|
#include "common/resources/resourcemanager.h"
|
||||||
|
|
||||||
#include "common/system/system.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/algorithm/string.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();
|
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 mod{};
|
||||||
mod.name = boost::filesystem::path(modPath).stem().string();
|
mod.name = savedModNames[i];
|
||||||
mod.path = modPath;
|
if (i < savedEnabled.size())
|
||||||
mod.enabled = m_pathManager->ModLoaded(mod.path); //TODO: load from some config file
|
{
|
||||||
|
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);
|
m_mods.push_back(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,23 +126,38 @@ void CModManager::DisableMod(const std::string& modName)
|
||||||
mod->enabled = false;
|
mod->enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModManager::ReloadMods()
|
void CModManager::UpdatePaths()
|
||||||
{
|
{
|
||||||
|
m_pathManager->RemoveAllMods();
|
||||||
for (const auto& mod : m_mods)
|
for (const auto& mod : m_mods)
|
||||||
{
|
{
|
||||||
bool loaded = m_pathManager->ModLoaded(mod.path);
|
if (mod.enabled)
|
||||||
if (mod.enabled && !loaded)
|
|
||||||
{
|
{
|
||||||
m_pathManager->AddMod(mod.path);
|
m_pathManager->AddMod(mod.path);
|
||||||
}
|
}
|
||||||
else if (!mod.enabled && loaded)
|
|
||||||
{
|
|
||||||
m_pathManager->RemoveMod(mod.path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModManager::ReloadResources()
|
||||||
|
{
|
||||||
m_app->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)
|
boost::optional<Mod> CModManager::GetMod(const std::string& modName)
|
||||||
{
|
{
|
||||||
Mod* mod = FindMod(modName);
|
Mod* mod = FindMod(modName);
|
||||||
|
|
|
@ -30,8 +30,8 @@ class CPathManager;
|
||||||
|
|
||||||
struct Mod
|
struct Mod
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name{};
|
||||||
std::string path;
|
std::string path{};
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
//TODO: add metadata for UI
|
//TODO: add metadata for UI
|
||||||
};
|
};
|
||||||
|
@ -41,6 +41,7 @@ struct Mod
|
||||||
* \brief Main application
|
* \brief Main application
|
||||||
*
|
*
|
||||||
* This class handles the list of currently loaded mods.
|
* This class handles the list of currently loaded mods.
|
||||||
|
* The order matters since the order in which files are loaded matters.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CModManager
|
class CModManager
|
||||||
|
@ -49,7 +50,7 @@ public:
|
||||||
CModManager(CApplication* app, CPathManager* pathManager);
|
CModManager(CApplication* app, CPathManager* pathManager);
|
||||||
|
|
||||||
//! Finds all the mods along with their metadata
|
//! Finds all the mods along with their metadata
|
||||||
void ReinitMods();
|
void FindMods();
|
||||||
|
|
||||||
//! Removes a mod from the list of loaded mods
|
//! Removes a mod from the list of loaded mods
|
||||||
void EnableMod(const std::string& modName);
|
void EnableMod(const std::string& modName);
|
||||||
|
@ -58,7 +59,13 @@ public:
|
||||||
void DisableMod(const std::string& modName);
|
void DisableMod(const std::string& modName);
|
||||||
|
|
||||||
//! Reloads application resources so the enabled mods are applied
|
//! 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);
|
boost::optional<Mod> GetMod(const std::string& modName);
|
||||||
const std::vector<Mod>& GetMods() const;
|
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());
|
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
|
||||||
CResourceManager::AddLocation(modPath, true);
|
CResourceManager::AddLocation(modPath, true);
|
||||||
|
m_mods.push_back(modPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPathManager::RemoveMod(const std::string &modPath)
|
void CPathManager::RemoveMod(const std::string &modPath)
|
||||||
{
|
{
|
||||||
GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str());
|
GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str());
|
||||||
CResourceManager::RemoveLocation(modPath);
|
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)
|
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
|
std::vector<std::string> CPathManager::FindMods() const
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
void AddModSearchDir(const std::string &modSearchDirPath);
|
void AddModSearchDir(const std::string &modSearchDirPath);
|
||||||
void AddMod(const std::string &modPath);
|
void AddMod(const std::string &modPath);
|
||||||
void RemoveMod(const std::string &modPath);
|
void RemoveMod(const std::string &modPath);
|
||||||
|
void RemoveAllMods();
|
||||||
bool ModLoaded(const std::string& modPath);
|
bool ModLoaded(const std::string& modPath);
|
||||||
std::vector<std::string> FindMods() const;
|
std::vector<std::string> FindMods() const;
|
||||||
|
|
||||||
|
@ -65,4 +66,6 @@ private:
|
||||||
std::string m_savePath;
|
std::string m_savePath;
|
||||||
//! Mod search paths
|
//! Mod search paths
|
||||||
std::vector<std::string> m_modSearchDirs;
|
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;
|
Math::Point pos, ddim;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
m_modManager->FindMods();
|
||||||
|
|
||||||
CScreenSetup::CreateInterface();
|
CScreenSetup::CreateInterface();
|
||||||
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
|
||||||
if ( pw == nullptr ) return;
|
if ( pw == nullptr ) return;
|
||||||
|
@ -155,7 +157,9 @@ bool CScreenSetupMods::EventProcess(const Event &event)
|
||||||
modName = pl->GetItemName(pl->GetSelect());
|
modName = pl->GetItemName(pl->GetSelect());
|
||||||
|
|
||||||
m_modManager->EnableMod(modName);
|
m_modManager->EnableMod(modName);
|
||||||
m_modManager->ReloadMods();
|
m_modManager->SaveMods();
|
||||||
|
m_modManager->UpdatePaths();
|
||||||
|
m_modManager->ReloadResources();
|
||||||
|
|
||||||
m_main->ChangePhase(PHASE_SETUPm);
|
m_main->ChangePhase(PHASE_SETUPm);
|
||||||
break;
|
break;
|
||||||
|
@ -166,7 +170,9 @@ bool CScreenSetupMods::EventProcess(const Event &event)
|
||||||
modName = pl->GetItemName(pl->GetSelect());
|
modName = pl->GetItemName(pl->GetSelect());
|
||||||
|
|
||||||
m_modManager->DisableMod(modName);
|
m_modManager->DisableMod(modName);
|
||||||
m_modManager->ReloadMods();
|
m_modManager->SaveMods();
|
||||||
|
m_modManager->UpdatePaths();
|
||||||
|
m_modManager->ReloadResources();
|
||||||
|
|
||||||
m_main->ChangePhase(PHASE_SETUPm);
|
m_main->ChangePhase(PHASE_SETUPm);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue