summaryrefslogtreecommitdiff
path: root/archived/projt-launcher/launcher/meta/JsonFormat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'archived/projt-launcher/launcher/meta/JsonFormat.cpp')
-rw-r--r--archived/projt-launcher/launcher/meta/JsonFormat.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/archived/projt-launcher/launcher/meta/JsonFormat.cpp b/archived/projt-launcher/launcher/meta/JsonFormat.cpp
new file mode 100644
index 0000000000..8c2d27102d
--- /dev/null
+++ b/archived/projt-launcher/launcher/meta/JsonFormat.cpp
@@ -0,0 +1,223 @@
+// 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.
+ */
+
+#include "JsonFormat.hpp"
+
+#include <QJsonArray>
+#include <QDateTime>
+
+#include "Index.hpp"
+#include "Json.h"
+#include "Version.hpp"
+#include "VersionList.hpp"
+#include "minecraft/OneSixVersionFormat.h"
+
+namespace projt::meta
+{
+
+ SchemaVersion currentSchema()
+ {
+ return SchemaVersion::V1;
+ }
+
+ SchemaVersion detectSchemaVersion(const QJsonObject& root, bool required)
+ {
+ if (!root.contains("formatVersion"))
+ return required ? SchemaVersion::Unknown : SchemaVersion::V1;
+
+ QJsonValue val = root.value("formatVersion");
+ if (!val.isDouble())
+ return SchemaVersion::Unknown;
+
+ int ver = val.toInt();
+ return (ver == 0 || ver == 1) ? SchemaVersion::V1 : SchemaVersion::Unknown;
+ }
+
+ void writeSchemaVersion(QJsonObject& target, SchemaVersion version)
+ {
+ if (version != SchemaVersion::Unknown)
+ target.insert("formatVersion", static_cast<int>(version));
+ }
+
+ DependencySet parseDependencies(const QJsonObject& source, const QString& fieldName)
+ {
+ DependencySet result;
+
+ if (!source.contains(fieldName))
+ return result;
+
+ QJsonArray arr = Json::requireArray(source, fieldName);
+ for (const QJsonValue& item : arr)
+ {
+ QJsonObject depObj = Json::requireObject(item);
+
+ ComponentDependency dep;
+ dep.uid = Json::requireString(depObj, "uid");
+ dep.equalsVersion = Json::ensureString(depObj, "equals", QString());
+ dep.suggests = Json::ensureString(depObj, "suggests", QString());
+
+ result.insert(dep);
+ }
+
+ return result;
+ }
+
+ void writeDependencies(QJsonObject& target, const DependencySet& deps, const QString& fieldName)
+ {
+ if (deps.empty())
+ return;
+
+ QJsonArray arr;
+ for (const auto& dep : deps)
+ {
+ QJsonObject obj;
+ obj.insert("uid", dep.uid);
+
+ if (!dep.equalsVersion.isEmpty())
+ obj.insert("equals", dep.equalsVersion);
+
+ if (!dep.suggests.isEmpty())
+ obj.insert("suggests", dep.suggests);
+
+ arr.append(obj);
+ }
+
+ target.insert(fieldName, arr);
+ }
+
+ namespace
+ {
+
+ MetaVersionList::Ptr buildVersionListFromPackage(const QJsonObject& pkg)
+ {
+ QString uid = Json::requireString(pkg, "uid");
+ auto list = std::make_shared<MetaVersionList>(uid);
+
+ list->setDisplayName(Json::ensureString(pkg, "name", QString()));
+ list->setExpectedChecksum(Json::ensureString(pkg, "sha256", QString()));
+
+ return list;
+ }
+
+ MetaVersion::Ptr buildVersionFromJson(const QString& componentUid, const QJsonObject& obj, bool markStability)
+ {
+ QString verId = Json::requireString(obj, "version");
+ auto ver = std::make_shared<MetaVersion>(componentUid, verId);
+
+ QString timeStr = Json::requireString(obj, "releaseTime");
+ QDateTime dt = QDateTime::fromString(timeStr, Qt::ISODate);
+ ver->setReleaseTimestamp(dt.toMSecsSinceEpoch() / 1000);
+
+ ver->setReleaseType(Json::ensureString(obj, "type", QString()));
+ ver->setStable(Json::ensureBoolean(obj, QStringLiteral("recommended"), false));
+ ver->setVolatile(Json::ensureBoolean(obj, QStringLiteral("volatile"), false));
+
+ DependencySet deps = parseDependencies(obj, "requires");
+ DependencySet conflicts = parseDependencies(obj, "conflicts");
+ ver->setDependencies(deps, conflicts);
+
+ QString sha = Json::ensureString(obj, "sha256", QString());
+ if (!sha.isEmpty())
+ ver->setExpectedChecksum(sha);
+
+ if (markStability)
+ ver->markAsStableCandidate();
+
+ return ver;
+ }
+
+ MetaVersion::Ptr buildFullVersionFromJson(const QJsonObject& obj)
+ {
+ QString uid = Json::requireString(obj, "uid");
+ auto ver = buildVersionFromJson(uid, obj, false);
+
+ VersionFilePtr data =
+ OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
+ QString("%1/%2.json").arg(uid, ver->versionId()),
+ obj.contains("order"));
+ ver->setDetailedData(data);
+
+ return ver;
+ }
+
+ MetaVersionList::Ptr buildVersionListFromPackageJson(const QJsonObject& obj)
+ {
+ QString uid = Json::requireString(obj, "uid");
+
+ QList<QJsonObject> versionObjects = Json::requireIsArrayOf<QJsonObject>(obj, "versions");
+ QList<MetaVersion::Ptr> versions;
+ versions.reserve(versionObjects.size());
+
+ for (const QJsonObject& vObj : versionObjects)
+ versions.append(buildVersionFromJson(uid, vObj, true));
+
+ auto list = std::make_shared<MetaVersionList>(uid);
+ list->setDisplayName(Json::ensureString(obj, "name", QString()));
+ list->setVersionEntries(versions);
+
+ return list;
+ }
+
+ std::shared_ptr<MetaIndex> buildIndexFromJson(const QJsonObject& obj)
+ {
+ QList<QJsonObject> packages = Json::requireIsArrayOf<QJsonObject>(obj, "packages");
+ QList<MetaVersionList::Ptr> components;
+ components.reserve(packages.size());
+
+ for (const QJsonObject& pkg : packages)
+ components.append(buildVersionListFromPackage(pkg));
+
+ return std::make_shared<MetaIndex>(components);
+ }
+
+ } // anonymous namespace
+
+ void loadIndexFromJson(const QJsonObject& json, MetaIndex* index)
+ {
+ SchemaVersion schema = detectSchemaVersion(json);
+
+ if (schema == SchemaVersion::V1)
+ index->mergeWith(buildIndexFromJson(json));
+ else
+ throw MetaParseError(QObject::tr("Unsupported metadata schema version"));
+ }
+
+ void loadVersionListFromJson(const QJsonObject& json, MetaVersionList* list)
+ {
+ SchemaVersion schema = detectSchemaVersion(json);
+
+ if (schema == SchemaVersion::V1)
+ list->mergeWith(buildVersionListFromPackageJson(json));
+ else
+ throw MetaParseError(QObject::tr("Unsupported metadata schema version"));
+ }
+
+ void loadVersionFromJson(const QJsonObject& json, MetaVersion* version)
+ {
+ SchemaVersion schema = detectSchemaVersion(json);
+
+ if (schema == SchemaVersion::V1)
+ version->updateFrom(buildFullVersionFromJson(json));
+ else
+ throw MetaParseError(QObject::tr("Unsupported metadata schema version"));
+ }
+
+} // namespace projt::meta