diff options
Diffstat (limited to 'launcher/settings/INIFile.cpp')
-rw-r--r-- | launcher/settings/INIFile.cpp | 168 |
1 files changed, 91 insertions, 77 deletions
diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp index 733cd444..d16256b9 100644 --- a/launcher/settings/INIFile.cpp +++ b/launcher/settings/INIFile.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * Copyright (C) 2023 flowln <flowlnlnln@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,32 +43,51 @@ #include <QSaveFile> #include <QDebug> -INIFile::INIFile() +#include <QSettings> + +INIFile::INIFile() {} + +bool INIFile::saveFile(QString fileName) { -} + if (!contains("ConfigVersion")) + insert("ConfigVersion", "1.2"); + QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; + _settings_obj.setFallbacksEnabled(false); + + for (Iterator iter = begin(); iter != end(); iter++) + _settings_obj.setValue(iter.key(), iter.value()); + + _settings_obj.sync(); + + if (auto status = _settings_obj.status(); status != QSettings::Status::NoError) { + // Shouldn't be possible! + Q_ASSERT(status != QSettings::Status::FormatError); + + if (status == QSettings::Status::AccessError) + qCritical() << "An access error occurred (e.g. trying to write to a read-only file)."; + + return false; + } -QString INIFile::unescape(QString orig) + return true; +} +QString unescape(QString orig) { QString out; QChar prev = QChar::Null; - for(auto c: orig) - { - if(prev == '\\') - { - if(c == 'n') + for (auto c : orig) { + if (prev == '\\') { + if (c == 'n') out += '\n'; - else if(c == 't') + else if (c == 't') out += '\t'; - else if(c == '#') + else if (c == '#') out += '#'; else out += c; prev = QChar::Null; - } - else - { - if(c == '\\') - { + } else { + if (c == '\\') { prev = c; continue; } @@ -78,79 +98,35 @@ QString INIFile::unescape(QString orig) return out; } -QString INIFile::escape(QString orig) -{ - QString out; - for(auto c: orig) - { - if(c == '\n') - out += "\\n"; - else if (c == '\t') - out += "\\t"; - else if(c == '\\') - out += "\\\\"; - else if(c == '#') - out += "\\#"; - else - out += c; - } - return out; -} - -bool INIFile::saveFile(QString fileName) +QString unquote(QString str) { - QByteArray outArray; - for (Iterator iter = begin(); iter != end(); iter++) - { - QString value = iter.value().toString(); - value = escape(value); - outArray.append(iter.key().toUtf8()); - outArray.append('='); - outArray.append(value.toUtf8()); - outArray.append('\n'); - } - - try - { - FS::write(fileName, outArray); - } - catch (const Exception &e) - { - qCritical() << e.what(); - return false; + if ((str.contains(QChar(';')) || str.contains(QChar('=')) || str.contains(QChar(','))) && str.endsWith("\"") && str.startsWith("\"")) { +#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) + str = str.remove(0, 1); + str = str.remove(str.size() - 1, 1); +#else + str = str.removeFirst().removeLast(); +#endif } - - return true; -} - - -bool INIFile::loadFile(QString fileName) -{ - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) - return false; - bool success = loadFile(file.readAll()); - file.close(); - return success; + return str; } -bool INIFile::loadFile(QByteArray file) +bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) { - QTextStream in(file); + QTextStream in(device.readAll()); #if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) in.setCodec("UTF-8"); #endif QStringList lines = in.readAll().split('\n'); - for (int i = 0; i < lines.count(); i++) - { - QString &lineRaw = lines[i]; + for (int i = 0; i < lines.count(); i++) { + QString& lineRaw = lines[i]; // Ignore comments. int commentIndex = 0; QString line = lineRaw; // Search for comments until no more escaped # are available - while((commentIndex = line.indexOf('#', commentIndex + 1)) != -1) { - if(commentIndex > 0 && line.at(commentIndex - 1) == '\\') { + while ((commentIndex = line.indexOf('#', commentIndex + 1)) != -1) { + if (commentIndex > 0 && line.at(commentIndex - 1) == '\\') { continue; } line = line.left(lineRaw.indexOf('#')).trimmed(); @@ -162,15 +138,53 @@ bool INIFile::loadFile(QByteArray file) QString key = line.left(eqPos).trimmed(); QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); - valueStr = unescape(valueStr); + valueStr = unquote(unescape(valueStr)); QVariant value(valueStr); - this->operator[](key) = value; + map.insert(key, value); } return true; } +bool INIFile::loadFile(QString fileName) +{ + QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; + _settings_obj.setFallbacksEnabled(false); + + if (auto status = _settings_obj.status(); status != QSettings::Status::NoError) { + if (status == QSettings::Status::AccessError) + qCritical() << "An access error occurred (e.g. trying to write to a read-only file)."; + if (status == QSettings::Status::FormatError) + qCritical() << "A format error occurred (e.g. loading a malformed INI file)."; + return false; + } + if (!_settings_obj.value("ConfigVersion").isValid()) { + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return false; + QSettings::SettingsMap map; + parseOldFileFormat(file, map); + file.close(); + for (auto&& key : map.keys()) + insert(key, map.value(key)); + insert("ConfigVersion", "1.2"); + } else if (_settings_obj.value("ConfigVersion").toString() == "1.1") { + for (auto&& key : _settings_obj.allKeys()) { + if (auto valueStr = _settings_obj.value(key).toString(); + (valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) && + valueStr.endsWith("\"") && valueStr.startsWith("\"")) { + insert(key, unquote(valueStr)); + } else + insert(key, _settings_obj.value(key)); + } + insert("ConfigVersion", "1.2"); + } else + for (auto&& key : _settings_obj.allKeys()) + insert(key, _settings_obj.value(key)); + return true; +} + QVariant INIFile::get(QString key, QVariant def) const { if (!this->contains(key)) |