From 28ff677337f9e6231a6be62cc4ec79aca6d3dd73 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 15 Oct 2017 00:07:46 +0100 Subject: [PATCH 1/3] Save 'data=...' lines correctly when exiting the wizard --- components/config/gamesettings.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index a897806c2..a1b5cc99e 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -152,9 +152,31 @@ bool Config::GameSettings::writeFile(QTextStream &stream) while (i.hasPrevious()) { i.previous(); + // 'data=...' lines need quotes and ampersands escaping to match how boost::filesystem::path uses boost::io::quoted + if (i.key() == QLatin1String("data")) + { + stream << i.key() << "="; + + // The following is based on boost::io::detail::quoted_manip.hpp, but calling this function did not work as there are too may QStrings involved + QChar delim = '\"'; + QChar escape = '&'; + QString string = i.value(); + + stream << delim; + for (QString::const_iterator it = string.begin(); it != string.end(); ++it) + { + if (*it == delim || *it == escape) + stream << escape; + stream << *it; + } + stream << delim; + + stream << '\n'; + continue; + } + // Quote paths with spaces - if (i.key() == QLatin1String("data") - || i.key() == QLatin1String("data-local") + if (i.key() == QLatin1String("data-local") || i.key() == QLatin1String("resources")) { if (i.value().contains(QChar(' '))) From 7329e6a9ef528c086f5169e570d46ed5567224f7 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 15 Oct 2017 01:59:21 +0100 Subject: [PATCH 2/3] Load 'data=...' lines correctly when starting the wizard or launcher, and save them correctly when exiting the launcher. --- components/config/gamesettings.cpp | 51 ++++++++++++++++++++--- components/files/configurationmanager.cpp | 2 - 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index a1b5cc99e..62aa034ee 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -55,7 +55,6 @@ void Config::GameSettings::validatePaths() for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) { QString path = QString::fromUtf8(it->string().c_str()); - path.remove(QChar('\"')); QDir dir(path); if (dir.exists()) @@ -64,6 +63,11 @@ void Config::GameSettings::validatePaths() // Do the same for data-local QString local = mSettings.value(QString("data-local")); + if (local.at(0) == QChar('\"')) + { + local.remove(0, 1); + local.chop(1); + } if (local.isEmpty()) return; @@ -76,7 +80,6 @@ void Config::GameSettings::validatePaths() if (!dataDirs.empty()) { QString path = QString::fromUtf8(dataDirs.front().string().c_str()); - path.remove(QChar('\"')); QDir dir(path); if (dir.exists()) @@ -120,6 +123,27 @@ bool Config::GameSettings::readFile(QTextStream &stream, QMap // Don't remove existing data entries if (key != QLatin1String("data")) settings.remove(key); + else + { + // 'data=...' line, so needs processing to deal with ampersands and quotes + QChar delim = '\"'; + QChar escape = '&'; + + if (value.at(0) == delim) + { + QString valueOriginal = value; + value = ""; + + for (QString::const_iterator it = valueOriginal.begin() + 1; it != valueOriginal.end(); ++it) + { + if (*it == escape) + ++it; + else if (*it == delim) + break; + value += *it; + } + } + } QStringList values = cache.values(key); values.append(settings.values(key)); @@ -157,7 +181,7 @@ bool Config::GameSettings::writeFile(QTextStream &stream) { stream << i.key() << "="; - // The following is based on boost::io::detail::quoted_manip.hpp, but calling this function did not work as there are too may QStrings involved + // The following is based on boost::io::detail::quoted_manip.hpp, but calling those functions did not work as there are too may QStrings involved QChar delim = '\"'; QChar escape = '&'; QString string = i.value(); @@ -380,9 +404,26 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) { it.previous(); + if (it.key() == QLatin1String("data")) + { + settingLine = it.key() + "="; + + // The following is based on boost::io::detail::quoted_manip.hpp, but calling those functions did not work as there are too may QStrings involved + QChar delim = '\"'; + QChar escape = '&'; + QString string = it.value(); + + settingLine += delim; + for (QString::const_iterator iter = string.begin(); iter != string.end(); ++iter) + { + if (*iter == delim || *iter == escape) + settingLine += escape; + settingLine += *iter; + } + settingLine += delim; + } // Quote paths with spaces - if ((it.key() == QLatin1String("data") - || it.key() == QLatin1String("data-local") + else if ((it.key() == QLatin1String("data-local") || it.key() == QLatin1String("resources")) && it.value().contains(QChar(' '))) { QString stripped = it.value(); diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 5316255ad..7c3956a29 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -75,8 +75,6 @@ void ConfigurationManager::processPaths(Files::PathContainer& dataDirs, bool cre for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) { path = it->string(); - boost::erase_all(path, "\""); - *it = boost::filesystem::path(path); // Check if path contains a token if (!path.empty() && *path.begin() == '?') From 49dbb4a9ca16ebb3d9f6d585b6a3d975d8608313 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 15 Oct 2017 02:05:22 +0100 Subject: [PATCH 3/3] Add a third copy of a comment where I felt clarification was missing --- components/config/gamesettings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index 62aa034ee..0ea28dceb 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -126,6 +126,7 @@ bool Config::GameSettings::readFile(QTextStream &stream, QMap else { // 'data=...' line, so needs processing to deal with ampersands and quotes + // The following is based on boost::io::detail::quoted_manip.hpp, but calling those functions did not work as there are too may QStrings involved QChar delim = '\"'; QChar escape = '&';