|
|
@ -7,24 +7,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include <components/files/configurationmanager.hpp>
|
|
|
|
#include <components/files/configurationmanager.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/version.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if (BOOST_VERSION <= 104600)
|
|
|
|
|
|
|
|
namespace boost
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<>
|
|
|
|
|
|
|
|
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return boost::filesystem::path(arg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} /* namespace boost */
|
|
|
|
|
|
|
|
#endif /* (BOOST_VERSION <= 104600) */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char Config::GameSettings::sContentKey[] = "content";
|
|
|
|
const char Config::GameSettings::sContentKey[] = "content";
|
|
|
|
|
|
|
|
|
|
|
|
Config::GameSettings::GameSettings(Files::ConfigurationManager &cfg)
|
|
|
|
Config::GameSettings::GameSettings(Files::ConfigurationManager &cfg)
|
|
|
@ -32,9 +14,7 @@ Config::GameSettings::GameSettings(Files::ConfigurationManager &cfg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Config::GameSettings::~GameSettings()
|
|
|
|
Config::GameSettings::~GameSettings() = default;
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Config::GameSettings::validatePaths()
|
|
|
|
void Config::GameSettings::validatePaths()
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -51,8 +31,8 @@ void Config::GameSettings::validatePaths()
|
|
|
|
mCfgMgr.processPaths(dataDirs);
|
|
|
|
mCfgMgr.processPaths(dataDirs);
|
|
|
|
mDataDirs.clear();
|
|
|
|
mDataDirs.clear();
|
|
|
|
|
|
|
|
|
|
|
|
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
|
|
|
|
for (auto & dataDir : dataDirs) {
|
|
|
|
QString path = QString::fromUtf8(it->string().c_str());
|
|
|
|
QString path = QString::fromUtf8(dataDir.string().c_str());
|
|
|
|
|
|
|
|
|
|
|
|
QDir dir(path);
|
|
|
|
QDir dir(path);
|
|
|
|
if (dir.exists())
|
|
|
|
if (dir.exists())
|
|
|
@ -186,11 +166,11 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
|
|
|
|
QString string = i.value();
|
|
|
|
QString string = i.value();
|
|
|
|
|
|
|
|
|
|
|
|
stream << delim;
|
|
|
|
stream << delim;
|
|
|
|
for (QString::const_iterator it = string.begin(); it != string.end(); ++it)
|
|
|
|
for (auto it : string)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (*it == delim || *it == escape)
|
|
|
|
if (it == delim || it == escape)
|
|
|
|
stream << escape;
|
|
|
|
stream << escape;
|
|
|
|
stream << *it;
|
|
|
|
stream << it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stream << delim;
|
|
|
|
stream << delim;
|
|
|
|
|
|
|
|
|
|
|
@ -219,7 +199,7 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Config::GameSettings::isOrderedLine(const QString& line) const
|
|
|
|
bool Config::GameSettings::isOrderedLine(const QString& line)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return line.contains(QRegExp("^\\s*fallback-archive\\s*="))
|
|
|
|
return line.contains(QRegExp("^\\s*fallback-archive\\s*="))
|
|
|
|
|| line.contains(QRegExp("^\\s*fallback\\s*="))
|
|
|
|
|| line.contains(QRegExp("^\\s*fallback\\s*="))
|
|
|
@ -287,9 +267,9 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
//
|
|
|
|
//
|
|
|
|
QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$");
|
|
|
|
QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$");
|
|
|
|
std::vector<QString> comments;
|
|
|
|
std::vector<QString> comments;
|
|
|
|
std::vector<QString>::iterator commentStart = fileCopy.end();
|
|
|
|
auto commentStart = fileCopy.end();
|
|
|
|
std::map<QString, std::vector<QString> > commentsMap;
|
|
|
|
std::map<QString, std::vector<QString> > commentsMap;
|
|
|
|
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
|
|
|
|
for (auto iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (isOrderedLine(*iter))
|
|
|
|
if (isOrderedLine(*iter))
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -339,9 +319,9 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
if (commentStart == fileCopy.end())
|
|
|
|
if (commentStart == fileCopy.end())
|
|
|
|
throw std::runtime_error("Config::GameSettings: failed to parse settings - iterator is past of end of settings file");
|
|
|
|
throw std::runtime_error("Config::GameSettings: failed to parse settings - iterator is past of end of settings file");
|
|
|
|
|
|
|
|
|
|
|
|
for (std::vector<QString>::const_iterator it = comments.begin(); it != comments.end(); ++it)
|
|
|
|
for (const auto & comment : comments)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
*commentStart = *it;
|
|
|
|
*commentStart = comment;
|
|
|
|
++commentStart;
|
|
|
|
++commentStart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
comments.clear();
|
|
|
|
comments.clear();
|
|
|
@ -383,16 +363,16 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// comments at top of file
|
|
|
|
// comments at top of file
|
|
|
|
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
|
|
|
|
for (auto & iter : fileCopy)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if ((*iter).isNull())
|
|
|
|
if (iter.isNull())
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
// Below is based on readFile() code, if that changes corresponding change may be
|
|
|
|
// Below is based on readFile() code, if that changes corresponding change may be
|
|
|
|
// required (for example duplicates may be inserted if the rules don't match)
|
|
|
|
// required (for example duplicates may be inserted if the rules don't match)
|
|
|
|
if (/*(*iter).isEmpty() ||*/ (*iter).contains(QRegExp("^\\s*#")))
|
|
|
|
if (/*(*iter).isEmpty() ||*/ iter.contains(QRegExp("^\\s*#")))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
stream << *iter << "\n";
|
|
|
|
stream << iter << "\n";
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -416,11 +396,11 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
QString string = it.value();
|
|
|
|
QString string = it.value();
|
|
|
|
|
|
|
|
|
|
|
|
settingLine += delim;
|
|
|
|
settingLine += delim;
|
|
|
|
for (QString::const_iterator iter = string.begin(); iter != string.end(); ++iter)
|
|
|
|
for (auto iter : string)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (*iter == delim || *iter == escape)
|
|
|
|
if (iter == delim || iter == escape)
|
|
|
|
settingLine += escape;
|
|
|
|
settingLine += escape;
|
|
|
|
settingLine += *iter;
|
|
|
|
settingLine += iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
settingLine += delim;
|
|
|
|
settingLine += delim;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -438,8 +418,7 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
|
|
|
|
|
|
|
|
if (settingRegex.indexIn(settingLine) != -1)
|
|
|
|
if (settingRegex.indexIn(settingLine) != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::map<QString, std::vector<QString> >::iterator i =
|
|
|
|
auto i = commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2));
|
|
|
|
commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if previous removed content item with comments
|
|
|
|
// check if previous removed content item with comments
|
|
|
|
if (i == commentsMap.end())
|
|
|
|
if (i == commentsMap.end())
|
|
|
@ -448,8 +427,8 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
if (i != commentsMap.end())
|
|
|
|
if (i != commentsMap.end())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::vector<QString> cLines = i->second;
|
|
|
|
std::vector<QString> cLines = i->second;
|
|
|
|
for (std::vector<QString>::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci)
|
|
|
|
for (const auto & cLine : cLines)
|
|
|
|
stream << *ci << "\n";
|
|
|
|
stream << cLine << "\n";
|
|
|
|
|
|
|
|
|
|
|
|
commentsMap.erase(i);
|
|
|
|
commentsMap.erase(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -461,14 +440,14 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
// flush any removed settings
|
|
|
|
// flush any removed settings
|
|
|
|
if (!commentsMap.empty())
|
|
|
|
if (!commentsMap.empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::map<QString, std::vector<QString> >::const_iterator i = commentsMap.begin();
|
|
|
|
auto i = commentsMap.begin();
|
|
|
|
for (; i != commentsMap.end(); ++i)
|
|
|
|
for (; i != commentsMap.end(); ++i)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (i->first.contains(QRegExp("^\\s*content\\s*=")))
|
|
|
|
if (i->first.contains(QRegExp("^\\s*content\\s*=")))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::vector<QString> cLines = i->second;
|
|
|
|
std::vector<QString> cLines = i->second;
|
|
|
|
for (std::vector<QString>::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci)
|
|
|
|
for (const auto & cLine : cLines)
|
|
|
|
stream << *ci << "\n";
|
|
|
|
stream << cLine << "\n";
|
|
|
|
|
|
|
|
|
|
|
|
// mark the content line entry for future preocessing
|
|
|
|
// mark the content line entry for future preocessing
|
|
|
|
stream << "##" << i->first << "\n";
|
|
|
|
stream << "##" << i->first << "\n";
|
|
|
@ -481,8 +460,8 @@ bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
|
|
// flush any end comments
|
|
|
|
// flush any end comments
|
|
|
|
if (!comments.empty())
|
|
|
|
if (!comments.empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (std::vector<QString>::const_iterator ci = comments.begin(); ci != comments.end(); ++ci)
|
|
|
|
for (const auto & comment : comments)
|
|
|
|
stream << *ci << "\n";
|
|
|
|
stream << comment << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
file.resize(file.pos());
|
|
|
|
file.resize(file.pos());
|
|
|
|