diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:51:45 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:51:45 +0300 |
| commit | d3261e64152397db2dca4d691a990c6bc2a6f4dd (patch) | |
| tree | fac2f7be638651181a72453d714f0f96675c2b8b /archived/projt-launcher/launcher/settings/INIFile.cpp | |
| parent | 31b9a8949ed0a288143e23bf739f2eb64fdc63be (diff) | |
| download | Project-Tick-d3261e64152397db2dca4d691a990c6bc2a6f4dd.tar.gz Project-Tick-d3261e64152397db2dca4d691a990c6bc2a6f4dd.zip | |
NOISSUE add archived projects
Signed-off-by: Mehmet Samet Duman <yongdohyun@projecttick.org>
Diffstat (limited to 'archived/projt-launcher/launcher/settings/INIFile.cpp')
| -rw-r--r-- | archived/projt-launcher/launcher/settings/INIFile.cpp | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/archived/projt-launcher/launcher/settings/INIFile.cpp b/archived/projt-launcher/launcher/settings/INIFile.cpp new file mode 100644 index 0000000000..31ce19f4ca --- /dev/null +++ b/archived/projt-launcher/launcher/settings/INIFile.cpp @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: 2026 Project Tick +// SPDX-FileContributor: Project Tick Team +/* + * ProjT Launcher - Minecraft Launcher + * Copyright (C) 2026 Project Tick + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * === Upstream License Block (Do Not Modify) ============================== + * + * + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ======================================================================== */ + +#include "settings/INIFile.h" +#include <FileSystem.h> + +#include <QDebug> +#include <QFile> +#include <QStringList> +#include <QTemporaryFile> +#include <QTextStream> + +#include <QSettings> +#include "Json.h" + +INIFile::INIFile() +{} + +bool INIFile::saveFile(QString fileName) +{ + if (!contains("ConfigVersion")) + insert("ConfigVersion", "1.3"); + QSettings _settings_obj{ fileName, QSettings::Format::IniFormat }; + _settings_obj.setFallbacksEnabled(false); + _settings_obj.clear(); + + 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; + } + + return true; +} + +QString unescape(QString orig) +{ + QString out; + QChar prev = QChar::Null; + for (auto c : orig) + { + if (prev == '\\') + { + if (c == 'n') + out += '\n'; + else if (c == 't') + out += '\t'; + else if (c == '#') + out += '#'; + else + out += c; + prev = QChar::Null; + } + else + { + if (c == '\\') + { + prev = c; + continue; + } + out += c; + prev = QChar::Null; + } + } + return out; +} + +QString unquote(QString str) +{ + 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 str; +} + +bool parseOldFileFormat(QIODevice& device, QSettings::SettingsMap& map) +{ + 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]; + // 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) == '\\') + { + continue; + } + line = line.left(lineRaw.indexOf('#')).trimmed(); + } + + int eqPos = line.indexOf('='); + if (eqPos == -1) + continue; + QString key = line.left(eqPos).trimmed(); + QString valueStr = line.right(line.length() - eqPos - 1).trimmed(); + + valueStr = unquote(unescape(valueStr)); + + QVariant value(valueStr); + map.insert(key, value); + } + + return true; +} + +QVariant migrateQByteArrayToBase64(QString key, QVariant value) +{ + static const QStringList otherByteArrays = { "MainWindowState", "MainWindowGeometry", "ConsoleWindowState", + "ConsoleWindowGeometry", "PagedGeometry", "NewInstanceGeometry", + "ModDownloadGeometry", "RPDownloadGeometry", "TPDownloadGeometry", + "ShaderDownloadGeometry" }; + if (key.startsWith("WideBarVisibility_") || (key.startsWith("UI/") && key.endsWith("_Page/Columns"))) + { + return QString::fromUtf8(value.toByteArray().toBase64()); + } + if (otherByteArrays.contains(key)) + { + return QString::fromUtf8(value.toByteArray()); + } + if (key == "linkedInstances") + { + return Json::fromStringList(value.toStringList()); + } + if (key == "Env") + { + return Json::fromMap(value.toMap()); + } + return value; +} + +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()) + { + auto value = migrateQByteArrayToBase64(key, map.value(key)); + insert(key, value); + } + insert("ConfigVersion", "1.3"); + } + else if (_settings_obj.value("ConfigVersion").toString() == "1.1") + { + for (auto&& key : _settings_obj.allKeys()) + { + auto value = migrateQByteArrayToBase64(key, _settings_obj.value(key)); + if (auto valueStr = value.toString(); + (valueStr.contains(QChar(';')) || valueStr.contains(QChar('=')) || valueStr.contains(QChar(','))) + && valueStr.endsWith("\"") && valueStr.startsWith("\"")) + { + insert(key, unquote(valueStr)); + } + else + { + insert(key, value); + } + } + insert("ConfigVersion", "1.3"); + } + else if (_settings_obj.value("ConfigVersion").toString() == "1.2") + { + for (auto&& key : _settings_obj.allKeys()) + { + auto value = migrateQByteArrayToBase64(key, _settings_obj.value(key)); + insert(key, value); + } + insert("ConfigVersion", "1.3"); + } + else + { + for (auto&& key : _settings_obj.allKeys()) + { + insert(key, _settings_obj.value(key)); + } + } + return true; +} + +bool INIFile::loadFile(QByteArray data) +{ + QTemporaryFile file; + if (!file.open()) + return false; + file.write(data); + file.flush(); + file.close(); + auto loaded = loadFile(file.fileName()); + file.remove(); + return loaded; +} + +QVariant INIFile::get(QString key, QVariant def) const +{ + if (!this->contains(key)) + return def; + else + return this->operator[](key); +} + +void INIFile::set(QString key, QVariant val) +{ + this->operator[](key) = val; +} |
