aboutsummaryrefslogtreecommitdiff
path: root/api/logic/meta
diff options
context:
space:
mode:
Diffstat (limited to 'api/logic/meta')
-rw-r--r--api/logic/meta/BaseEntity.cpp168
-rw-r--r--api/logic/meta/BaseEntity.h68
-rw-r--r--api/logic/meta/Index.cpp148
-rw-r--r--api/logic/meta/Index.h71
-rw-r--r--api/logic/meta/Index_test.cpp44
-rw-r--r--api/logic/meta/JsonFormat.cpp218
-rw-r--r--api/logic/meta/JsonFormat.h83
-rw-r--r--api/logic/meta/Version.cpp140
-rw-r--r--api/logic/meta/Version.h118
-rw-r--r--api/logic/meta/VersionList.cpp245
-rw-r--r--api/logic/meta/VersionList.h101
11 files changed, 0 insertions, 1404 deletions
diff --git a/api/logic/meta/BaseEntity.cpp b/api/logic/meta/BaseEntity.cpp
deleted file mode 100644
index 5ff7a59a..00000000
--- a/api/logic/meta/BaseEntity.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* Copyright 2015-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 "BaseEntity.h"
-
-#include "Json.h"
-
-#include "net/Download.h"
-#include "net/HttpMetaCache.h"
-#include "net/NetJob.h"
-
-#include "Env.h"
-#include "Json.h"
-
-#include "BuildConfig.h"
-
-class ParsingValidator : public Net::Validator
-{
-public: /* con/des */
- ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity)
- {
- };
- virtual ~ParsingValidator()
- {
- };
-
-public: /* methods */
- bool init(QNetworkRequest &) override
- {
- return true;
- }
- bool write(QByteArray & data) override
- {
- this->data.append(data);
- return true;
- }
- bool abort() override
- {
- return true;
- }
- bool validate(QNetworkReply &) override
- {
- auto fname = m_entity->localFilename();
- try
- {
- auto doc = Json::requireDocument(data, fname);
- auto obj = Json::requireObject(doc, fname);
- m_entity->parse(obj);
- return true;
- }
- catch (const Exception &e)
- {
- qWarning() << "Unable to parse response:" << e.cause();
- return false;
- }
- }
-
-private: /* data */
- QByteArray data;
- Meta::BaseEntity *m_entity;
-};
-
-Meta::BaseEntity::~BaseEntity()
-{
-}
-
-QUrl Meta::BaseEntity::url() const
-{
- return QUrl(BuildConfig.META_URL).resolved(localFilename());
-}
-
-bool Meta::BaseEntity::loadLocalFile()
-{
- const QString fname = QDir("meta").absoluteFilePath(localFilename());
- if (!QFile::exists(fname))
- {
- return false;
- }
- // TODO: check if the file has the expected checksum
- try
- {
- auto doc = Json::requireDocument(fname, fname);
- auto obj = Json::requireObject(doc, fname);
- parse(obj);
- return true;
- }
- catch (const Exception &e)
- {
- qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause());
- // just make sure it's gone and we never consider it again.
- QFile::remove(fname);
- return false;
- }
-}
-
-void Meta::BaseEntity::load(Net::Mode loadType)
-{
- // load local file if nothing is loaded yet
- if(!isLoaded())
- {
- if(loadLocalFile())
- {
- m_loadStatus = LoadStatus::Local;
- }
- }
- // if we need remote update, run the update task
- if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate())
- {
- return;
- }
- NetJob *job = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()));
- auto url = this->url();
- auto entry = ENV.metacache()->resolveEntry("meta", localFilename());
- entry->setStale(true);
- auto dl = Net::Download::makeCached(url, entry);
- /*
- * The validator parses the file and loads it into the object.
- * If that fails, the file is not written to storage.
- */
- dl->addValidator(new ParsingValidator(this));
- job->addNetAction(dl);
- m_updateStatus = UpdateStatus::InProgress;
- m_updateTask.reset(job);
- QObject::connect(job, &NetJob::succeeded, [&]()
- {
- m_loadStatus = LoadStatus::Remote;
- m_updateStatus = UpdateStatus::Succeeded;
- m_updateTask.reset();
- });
- QObject::connect(job, &NetJob::failed, [&]()
- {
- m_updateStatus = UpdateStatus::Failed;
- m_updateTask.reset();
- });
- m_updateTask->start();
-}
-
-bool Meta::BaseEntity::isLoaded() const
-{
- return m_loadStatus > LoadStatus::NotLoaded;
-}
-
-bool Meta::BaseEntity::shouldStartRemoteUpdate() const
-{
- // TODO: version-locks and offline mode?
- return m_updateStatus != UpdateStatus::InProgress;
-}
-
-shared_qobject_ptr<Task> Meta::BaseEntity::getCurrentTask()
-{
- if(m_updateStatus == UpdateStatus::InProgress)
- {
- return m_updateTask;
- }
- return nullptr;
-}
diff --git a/api/logic/meta/BaseEntity.h b/api/logic/meta/BaseEntity.h
deleted file mode 100644
index 04a37420..00000000
--- a/api/logic/meta/BaseEntity.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2015-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.
- */
-
-#pragma once
-
-#include <QJsonObject>
-#include <QObject>
-#include "QObjectPtr.h"
-
-#include "multimc_logic_export.h"
-#include "net/Mode.h"
-
-class Task;
-namespace Meta
-{
-class MULTIMC_LOGIC_EXPORT BaseEntity
-{
-public: /* types */
- using Ptr = std::shared_ptr<BaseEntity>;
- enum class LoadStatus
- {
- NotLoaded,
- Local,
- Remote
- };
- enum class UpdateStatus
- {
- NotDone,
- InProgress,
- Failed,
- Succeeded
- };
-
-public:
- virtual ~BaseEntity();
-
- virtual void parse(const QJsonObject &obj) = 0;
-
- virtual QString localFilename() const = 0;
- virtual QUrl url() const;
-
- bool isLoaded() const;
- bool shouldStartRemoteUpdate() const;
-
- void load(Net::Mode loadType);
- shared_qobject_ptr<Task> getCurrentTask();
-
-protected: /* methods */
- bool loadLocalFile();
-
-private:
- LoadStatus m_loadStatus = LoadStatus::NotLoaded;
- UpdateStatus m_updateStatus = UpdateStatus::NotDone;
- shared_qobject_ptr<Task> m_updateTask;
-};
-}
diff --git a/api/logic/meta/Index.cpp b/api/logic/meta/Index.cpp
deleted file mode 100644
index 6802470d..00000000
--- a/api/logic/meta/Index.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright 2015-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 "Index.h"
-
-#include "VersionList.h"
-#include "JsonFormat.h"
-
-namespace Meta
-{
-Index::Index(QObject *parent)
- : QAbstractListModel(parent)
-{
-}
-Index::Index(const QVector<VersionListPtr> &lists, QObject *parent)
- : QAbstractListModel(parent), m_lists(lists)
-{
- for (int i = 0; i < m_lists.size(); ++i)
- {
- m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
- connectVersionList(i, m_lists.at(i));
- }
-}
-
-QVariant Index::data(const QModelIndex &index, int role) const
-{
- if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size())
- {
- return QVariant();
- }
-
- VersionListPtr list = m_lists.at(index.row());
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case 0: return list->humanReadable();
- default: break;
- }
- case UidRole: return list->uid();
- case NameRole: return list->name();
- case ListPtrRole: return QVariant::fromValue(list);
- }
- return QVariant();
-}
-int Index::rowCount(const QModelIndex &parent) const
-{
- return m_lists.size();
-}
-int Index::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
- {
- return tr("Name");
- }
- else
- {
- return QVariant();
- }
-}
-
-bool Index::hasUid(const QString &uid) const
-{
- return m_uids.contains(uid);
-}
-
-VersionListPtr Index::get(const QString &uid)
-{
- VersionListPtr out = m_uids.value(uid, nullptr);
- if(!out)
- {
- out = std::make_shared<VersionList>(uid);
- m_uids[uid] = out;
- }
- return out;
-}
-
-VersionPtr Index::get(const QString &uid, const QString &version)
-{
- auto list = get(uid);
- return list->getVersion(version);
-}
-
-void Index::parse(const QJsonObject& obj)
-{
- parseIndex(obj, this);
-}
-
-void Index::merge(const std::shared_ptr<Index> &other)
-{
- const QVector<VersionListPtr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
- // initial load, no need to merge
- if (m_lists.isEmpty())
- {
- beginResetModel();
- m_lists = lists;
- for (int i = 0; i < lists.size(); ++i)
- {
- m_uids.insert(lists.at(i)->uid(), lists.at(i));
- connectVersionList(i, lists.at(i));
- }
- endResetModel();
- }
- else
- {
- for (const VersionListPtr &list : lists)
- {
- if (m_uids.contains(list->uid()))
- {
- m_uids[list->uid()]->mergeFromIndex(list);
- }
- else
- {
- beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
- connectVersionList(m_lists.size(), list);
- m_lists.append(list);
- m_uids.insert(list->uid(), list);
- endInsertRows();
- }
- }
- }
-}
-
-void Index::connectVersionList(const int row, const VersionListPtr &list)
-{
- connect(list.get(), &VersionList::nameChanged, this, [this, row]()
- {
- emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
- });
-}
-}
diff --git a/api/logic/meta/Index.h b/api/logic/meta/Index.h
deleted file mode 100644
index e9412e70..00000000
--- a/api/logic/meta/Index.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright 2015-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.
- */
-
-#pragma once
-
-#include <QAbstractListModel>
-#include <memory>
-
-#include "BaseEntity.h"
-
-#include "multimc_logic_export.h"
-
-class Task;
-
-namespace Meta
-{
-using VersionListPtr = std::shared_ptr<class VersionList>;
-using VersionPtr = std::shared_ptr<class Version>;
-
-class MULTIMC_LOGIC_EXPORT Index : public QAbstractListModel, public BaseEntity
-{
- Q_OBJECT
-public:
- explicit Index(QObject *parent = nullptr);
- explicit Index(const QVector<VersionListPtr> &lists, QObject *parent = nullptr);
-
- enum
- {
- UidRole = Qt::UserRole,
- NameRole,
- ListPtrRole
- };
-
- QVariant data(const QModelIndex &index, int role) const override;
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
-
- QString localFilename() const override { return "index.json"; }
-
- // queries
- VersionListPtr get(const QString &uid);
- VersionPtr get(const QString &uid, const QString &version);
- bool hasUid(const QString &uid) const;
-
- QVector<VersionListPtr> lists() const { return m_lists; }
-
-public: // for usage by parsers only
- void merge(const std::shared_ptr<Index> &other);
- void parse(const QJsonObject &obj) override;
-
-private:
- QVector<VersionListPtr> m_lists;
- QHash<QString, VersionListPtr> m_uids;
-
- void connectVersionList(const int row, const VersionListPtr &list);
-};
-}
-
diff --git a/api/logic/meta/Index_test.cpp b/api/logic/meta/Index_test.cpp
deleted file mode 100644
index b0892070..00000000
--- a/api/logic/meta/Index_test.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <QTest>
-#include "TestUtil.h"
-
-#include "meta/Index.h"
-#include "meta/VersionList.h"
-#include "Env.h"
-
-class IndexTest : public QObject
-{
- Q_OBJECT
-private
-slots:
- void test_isProvidedByEnv()
- {
- QVERIFY(ENV.metadataIndex());
- QCOMPARE(ENV.metadataIndex(), ENV.metadataIndex());
- }
-
- void test_hasUid_and_getList()
- {
- Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
- QVERIFY(windex.hasUid("list1"));
- QVERIFY(!windex.hasUid("asdf"));
- QVERIFY(windex.get("list2") != nullptr);
- QCOMPARE(windex.get("list2")->uid(), QString("list2"));
- QVERIFY(windex.get("adsf") != nullptr);
- }
-
- void test_merge()
- {
- Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
- QCOMPARE(windex.lists().size(), 3);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")})));
- QCOMPARE(windex.lists().size(), 3);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list4"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list5")})));
- QCOMPARE(windex.lists().size(), 5);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list6")})));
- QCOMPARE(windex.lists().size(), 6);
- }
-};
-
-QTEST_GUILESS_MAIN(IndexTest)
-
-#include "Index_test.moc"
diff --git a/api/logic/meta/JsonFormat.cpp b/api/logic/meta/JsonFormat.cpp
deleted file mode 100644
index 796da4bb..00000000
--- a/api/logic/meta/JsonFormat.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/* Copyright 2015-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 "JsonFormat.h"
-
-// FIXME: remove this from here... somehow
-#include "minecraft/OneSixVersionFormat.h"
-#include "Json.h"
-
-#include "Index.h"
-#include "Version.h"
-#include "VersionList.h"
-
-using namespace Json;
-
-namespace Meta
-{
-
-MetadataVersion currentFormatVersion()
-{
- return MetadataVersion::InitialRelease;
-}
-
-// Index
-static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
-{
- const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
- QVector<VersionListPtr> lists;
- lists.reserve(objects.size());
- std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
- {
- VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
- list->setName(ensureString(obj, "name", QString()));
- return list;
- });
- return std::make_shared<Index>(lists);
-}
-
-// Version
-static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
-{
- VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
- version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
- version->setType(ensureString(obj, "type", QString()));
- version->setRecommended(ensureBoolean(obj, QString("recommended"), false));
- version->setVolatile(ensureBoolean(obj, QString("volatile"), false));
- RequireSet requires, conflicts;
- parseRequires(obj, &requires, "requires");
- parseRequires(obj, &conflicts, "conflicts");
- version->setRequires(requires, conflicts);
- return version;
-}
-
-static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj)
-{
- VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
-
- version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
- QString("%1/%2.json").arg(version->uid(), version->version()),
- obj.contains("order")));
- return version;
-}
-
-// Version list / package
-static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &obj)
-{
- const QString uid = requireString(obj, "uid");
-
- const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
- QVector<VersionPtr> versions;
- versions.reserve(versionsRaw.size());
- std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
- {
- auto version = parseCommonVersion(uid, vObj);
- version->setProvidesRecommendations();
- return version;
- });
-
- VersionListPtr list = std::make_shared<VersionList>(uid);
- list->setName(ensureString(obj, "name", QString()));
- list->setVersions(versions);
- return list;
-}
-
-
-MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required)
-{
- if (!obj.contains("formatVersion"))
- {
- if(required)
- {
- return MetadataVersion::Invalid;
- }
- return MetadataVersion::InitialRelease;
- }
- if (!obj.value("formatVersion").isDouble())
- {
- return MetadataVersion::Invalid;
- }
- switch(obj.value("formatVersion").toInt())
- {
- case 0:
- case 1:
- return MetadataVersion::InitialRelease;
- default:
- return MetadataVersion::Invalid;
- }
-}
-
-void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version)
-{
- if(version == MetadataVersion::Invalid)
- {
- return;
- }
- obj.insert("formatVersion", int(version));
-}
-
-void parseIndex(const QJsonObject &obj, Index *ptr)
-{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseIndexInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
-}
-
-void parseVersionList(const QJsonObject &obj, VersionList *ptr)
-{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseVersionListInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
-}
-
-void parseVersion(const QJsonObject &obj, Version *ptr)
-{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseVersionInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
-}
-
-/*
-[
-{"uid":"foo", "equals":"version"}
-]
-*/
-void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName)
-{
- if(obj.contains(keyName))
- {
- QSet<QString> requires;
- auto reqArray = requireArray(obj, keyName);
- auto iter = reqArray.begin();
- while(iter != reqArray.end())
- {
- auto reqObject = requireObject(*iter);
- auto uid = requireString(reqObject, "uid");
- auto equals = ensureString(reqObject, "equals", QString());
- auto suggests = ensureString(reqObject, "suggests", QString());
- ptr->insert({uid, equals, suggests});
- iter++;
- }
- }
-}
-void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName)
-{
- if(!ptr || ptr->empty())
- {
- return;
- }
- QJsonArray arrOut;
- for(auto &iter: *ptr)
- {
- QJsonObject reqOut;
- reqOut.insert("uid", iter.uid);
- if(!iter.equalsVersion.isEmpty())
- {
- reqOut.insert("equals", iter.equalsVersion);
- }
- if(!iter.suggests.isEmpty())
- {
- reqOut.insert("suggests", iter.suggests);
- }
- arrOut.append(reqOut);
- }
- obj.insert(keyName, arrOut);
-}
-
-}
-
diff --git a/api/logic/meta/JsonFormat.h b/api/logic/meta/JsonFormat.h
deleted file mode 100644
index 93217b7e..00000000
--- a/api/logic/meta/JsonFormat.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright 2015-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.
- */
-
-#pragma once
-
-#include <QJsonObject>
-#include <memory>
-
-#include "Exception.h"
-#include "meta/BaseEntity.h"
-#include <set>
-
-namespace Meta
-{
-class Index;
-class Version;
-class VersionList;
-
-enum class MetadataVersion
-{
- Invalid = -1,
- InitialRelease = 1
-};
-
-class ParseException : public Exception
-{
-public:
- using Exception::Exception;
-};
-struct Require
-{
- bool operator==(const Require & rhs) const
- {
- return uid == rhs.uid;
- }
- bool operator<(const Require & rhs) const
- {
- return uid < rhs.uid;
- }
- bool deepEquals(const Require & rhs) const
- {
- return uid == rhs.uid
- && equalsVersion == rhs.equalsVersion
- && suggests == rhs.suggests;
- }
- QString uid;
- QString equalsVersion;
- QString suggests;
-};
-
-inline Q_DECL_PURE_FUNCTION uint qHash(const Require &key, uint seed = 0) Q_DECL_NOTHROW
-{
- return qHash(key.uid, seed);
-}
-
-using RequireSet = std::set<Require>;
-
-void parseIndex(const QJsonObject &obj, Index *ptr);
-void parseVersion(const QJsonObject &obj, Version *ptr);
-void parseVersionList(const QJsonObject &obj, VersionList *ptr);
-
-MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required = true);
-void serializeFormatVersion(QJsonObject &obj, MetadataVersion version);
-
-// FIXME: this has a different shape than the others...FIX IT!?
-void parseRequires(const QJsonObject &obj, RequireSet * ptr, const char * keyName = "requires");
-void serializeRequires(QJsonObject & objOut, RequireSet* ptr, const char * keyName = "requires");
-MetadataVersion currentFormatVersion();
-}
-
-Q_DECLARE_METATYPE(std::set<Meta::Require>)
diff --git a/api/logic/meta/Version.cpp b/api/logic/meta/Version.cpp
deleted file mode 100644
index a8dc3169..00000000
--- a/api/logic/meta/Version.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright 2015-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 "Version.h"
-
-#include <QDateTime>
-
-#include "JsonFormat.h"
-#include "minecraft/PackProfile.h"
-
-Meta::Version::Version(const QString &uid, const QString &version)
- : BaseVersion(), m_uid(uid), m_version(version)
-{
-}
-
-Meta::Version::~Version()
-{
-}
-
-QString Meta::Version::descriptor()
-{
- return m_version;
-}
-QString Meta::Version::name()
-{
- if(m_data)
- return m_data->name;
- return m_uid;
-}
-QString Meta::Version::typeString() const
-{
- return m_type;
-}
-
-QDateTime Meta::Version::time() const
-{
- return QDateTime::fromMSecsSinceEpoch(m_time * 1000, Qt::UTC);
-}
-
-void Meta::Version::parse(const QJsonObject& obj)
-{
- parseVersion(obj, this);
-}
-
-void Meta::Version::mergeFromList(const Meta::VersionPtr& other)
-{
- if(other->m_providesRecommendations)
- {
- if(m_recommended != other->m_recommended)
- {
- setRecommended(other->m_recommended);
- }
- }
- if (m_type != other->m_type)
- {
- setType(other->m_type);
- }
- if (m_time != other->m_time)
- {
- setTime(other->m_time);
- }
- if (m_requires != other->m_requires)
- {
- m_requires = other->m_requires;
- }
- if (m_conflicts != other->m_conflicts)
- {
- m_conflicts = other->m_conflicts;
- }
- if(m_volatile != other->m_volatile)
- {
- setVolatile(other->m_volatile);
- }
-}
-
-void Meta::Version::merge(const VersionPtr &other)
-{
- mergeFromList(other);
- if(other->m_data)
- {
- setData(other->m_data);
- }
-}
-
-QString Meta::Version::localFilename() const
-{
- return m_uid + '/' + m_version + ".json";
-}
-
-void Meta::Version::setType(const QString &type)
-{
- m_type = type;
- emit typeChanged();
-}
-
-void Meta::Version::setTime(const qint64 time)
-{
- m_time = time;
- emit timeChanged();
-}
-
-void Meta::Version::setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts)
-{
- m_requires = requires;
- m_conflicts = conflicts;
- emit requiresChanged();
-}
-
-void Meta::Version::setVolatile(bool volatile_)
-{
- m_volatile = volatile_;
-}
-
-
-void Meta::Version::setData(const VersionFilePtr &data)
-{
- m_data = data;
-}
-
-void Meta::Version::setProvidesRecommendations()
-{
- m_providesRecommendations = true;
-}
-
-void Meta::Version::setRecommended(bool recommended)
-{
- m_recommended = recommended;
-}
diff --git a/api/logic/meta/Version.h b/api/logic/meta/Version.h
deleted file mode 100644
index a38d7bcd..00000000
--- a/api/logic/meta/Version.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright 2015-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.
- */
-
-#pragma once
-
-#include "BaseVersion.h"
-
-#include <QJsonObject>
-#include <QStringList>
-#include <QVector>
-#include <memory>
-
-#include "minecraft/VersionFile.h"
-
-#include "BaseEntity.h"
-
-#include "multimc_logic_export.h"
-
-#include "JsonFormat.h"
-
-namespace Meta
-{
-using VersionPtr = std::shared_ptr<class Version>;
-
-class MULTIMC_LOGIC_EXPORT Version : public QObject, public BaseVersion, public BaseEntity
-{
- Q_OBJECT
-
-public: /* con/des */
- explicit Version(const QString &uid, const QString &version);
- virtual ~Version();
-
- QString descriptor() override;
- QString name() override;
- QString typeString() const override;
-
- QString uid() const
- {
- return m_uid;
- }
- QString version() const
- {
- return m_version;
- }
- QString type() const
- {
- return m_type;
- }
- QDateTime time() const;
- qint64 rawTime() const
- {
- return m_time;
- }
- const Meta::RequireSet &requires() const
- {
- return m_requires;
- }
- VersionFilePtr data() const
- {
- return m_data;
- }
- bool isRecommended() const
- {
- return m_recommended;
- }
- bool isLoaded() const
- {
- return m_data != nullptr;
- }
-
- void merge(const VersionPtr &other);
- void mergeFromList(const VersionPtr &other);
- void parse(const QJsonObject &obj) override;
-
- QString localFilename() const override;
-
-public: // for usage by format parsers only
- void setType(const QString &type);
- void setTime(const qint64 time);
- void setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts);
- void setVolatile(bool volatile_);
- void setRecommended(bool recommended);
- void setProvidesRecommendations();
- void setData(const VersionFilePtr &data);
-
-signals:
- void typeChanged();
- void timeChanged();
- void requiresChanged();
-
-private:
- bool m_providesRecommendations = false;
- bool m_recommended = false;
- QString m_name;
- QString m_uid;
- QString m_version;
- QString m_type;
- qint64 m_time = 0;
- Meta::RequireSet m_requires;
- Meta::RequireSet m_conflicts;
- bool m_volatile = false;
- VersionFilePtr m_data;
-};
-}
-
-Q_DECLARE_METATYPE(Meta::VersionPtr)
diff --git a/api/logic/meta/VersionList.cpp b/api/logic/meta/VersionList.cpp
deleted file mode 100644
index 607007eb..00000000
--- a/api/logic/meta/VersionList.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Copyright 2015-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 "VersionList.h"
-
-#include <QDateTime>
-
-#include "Version.h"
-#include "JsonFormat.h"
-#include "Version.h"
-
-namespace Meta
-{
-VersionList::VersionList(const QString &uid, QObject *parent)
- : BaseVersionList(parent), m_uid(uid)
-{
- setObjectName("Version list: " + uid);
-}
-
-shared_qobject_ptr<Task> VersionList::getLoadTask()
-{
- load(Net::Mode::Online);
- return getCurrentTask();
-}
-
-bool VersionList::isLoaded()
-{
- return BaseEntity::isLoaded();
-}
-
-const BaseVersionPtr VersionList::at(int i) const
-{
- return m_versions.at(i);
-}
-int VersionList::count() const
-{
- return m_versions.size();
-}
-
-void VersionList::sortVersions()
-{
- beginResetModel();
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
- {
- return *a.get() < *b.get();
- });
- endResetModel();
-}
-
-QVariant VersionList::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid())
- {
- return QVariant();
- }
-
- VersionPtr version = m_versions.at(index.row());
-
- switch (role)
- {
- case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
- case VersionRole:
- case VersionIdRole:
- return version->version();
- case ParentVersionRole:
- {
- // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'.
- auto & reqs = version->requires();
- auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req)
- {
- return req.uid == "net.minecraft";
- });
- if (iter != reqs.end())
- {
- return (*iter).equalsVersion;
- }
- return QVariant();
- }
- case TypeRole: return version->type();
-
- case UidRole: return version->uid();
- case TimeRole: return version->time();
- case RequiresRole: return QVariant::fromValue(version->requires());
- case SortRole: return version->rawTime();
- case VersionPtrRole: return QVariant::fromValue(version);
- case RecommendedRole: return version->isRecommended();
- // FIXME: this should be determined in whatever view/proxy is used...
- // case LatestRole: return version == getLatestStable();
- default: return QVariant();
- }
-}
-
-BaseVersionList::RoleList VersionList::providesRoles() const
-{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole,
- TypeRole, UidRole, TimeRole, RequiresRole, SortRole,
- RecommendedRole, LatestRole, VersionPtrRole};
-}
-
-QHash<int, QByteArray> VersionList::roleNames() const
-{
- QHash<int, QByteArray> roles = BaseVersionList::roleNames();
- roles.insert(UidRole, "uid");
- roles.insert(TimeRole, "time");
- roles.insert(SortRole, "sort");
- roles.insert(RequiresRole, "requires");
- return roles;
-}
-
-QString VersionList::localFilename() const
-{
- return m_uid + "/index.json";
-}
-
-QString VersionList::humanReadable() const
-{
- return m_name.isEmpty() ? m_uid : m_name;
-}
-
-VersionPtr VersionList::getVersion(const QString &version)
-{
- VersionPtr out = m_lookup.value(version, nullptr);
- if(!out)
- {
- out = std::make_shared<Version>(m_uid, version);
- m_lookup[version] = out;
- }
- return out;
-}
-
-void VersionList::setName(const QString &name)
-{
- m_name = name;
- emit nameChanged(name);
-}
-
-void VersionList::setVersions(const QVector<VersionPtr> &versions)
-{
- beginResetModel();
- m_versions = versions;
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
- {
- return a->rawTime() > b->rawTime();
- });
- for (int i = 0; i < m_versions.size(); ++i)
- {
- m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i));
- setupAddedVersion(i, m_versions.at(i));
- }
-
- // FIXME: this is dumb, we have 'recommended' as part of the metadata already...
- auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; });
- m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
- endResetModel();
-}
-
-void VersionList::parse(const QJsonObject& obj)
-{
- parseVersionList(obj, this);
-}
-
-// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
-static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const Meta::VersionPtr &b)
-{
- if(!a)
- return b;
- if(!b)
- return a;
- if(a->type() == b->type())
- {
- // newer of same type wins
- return (a->rawTime() > b->rawTime() ? a : b);
- }
- // 'release' type wins
- return (a->type() == "release" ? a : b);
-}
-
-void VersionList::mergeFromIndex(const VersionListPtr &other)
-{
- if (m_name != other->m_name)
- {
- setName(other->m_name);
- }
-}
-
-void VersionList::merge(const VersionListPtr &other)
-{
- if (m_name != other->m_name)
- {
- setName(other->m_name);
- }
-
- // TODO: do not reset the whole model. maybe?
- beginResetModel();
- m_versions.clear();
- if(other->m_versions.isEmpty())
- {
- qWarning() << "Empty list loaded ...";
- }
- for (const VersionPtr &version : other->m_versions)
- {
- // we already have the version. merge the contents
- if (m_lookup.contains(version->version()))
- {
- m_lookup.value(version->version())->mergeFromList(version);
- }
- else
- {
- m_lookup.insert(version->uid(), version);
- }
- // connect it.
- setupAddedVersion(m_versions.size(), version);
- m_versions.append(version);
- m_recommended = getBetterVersion(m_recommended, version);
- }
- endResetModel();
-}
-
-void VersionList::setupAddedVersion(const int row, const VersionPtr &version)
-{
- // FIXME: do not disconnect from everythin, disconnect only the lambdas here
- version->disconnect();
- connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
- connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
- connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
-}
-
-BaseVersionPtr VersionList::getRecommended() const
-{
- return m_recommended;
-}
-
-}
diff --git a/api/logic/meta/VersionList.h b/api/logic/meta/VersionList.h
deleted file mode 100644
index bba32ca3..00000000
--- a/api/logic/meta/VersionList.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2015-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.
- */
-
-#pragma once
-
-#include "BaseEntity.h"
-#include "BaseVersionList.h"
-#include <QJsonObject>
-#include <memory>
-
-namespace Meta
-{
-using VersionPtr = std::shared_ptr<class Version>;
-using VersionListPtr = std::shared_ptr<class VersionList>;
-
-class MULTIMC_LOGIC_EXPORT VersionList : public BaseVersionList, public BaseEntity
-{
- Q_OBJECT
- Q_PROPERTY(QString uid READ uid CONSTANT)
- Q_PROPERTY(QString name READ name NOTIFY nameChanged)
-public:
- explicit VersionList(const QString &uid, QObject *parent = nullptr);
-
- enum Roles
- {
- UidRole = Qt::UserRole + 100,
- TimeRole,
- RequiresRole,
- VersionPtrRole
- };
-
- shared_qobject_ptr<Task> getLoadTask() override;
- bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
- int count() const override;
- void sortVersions() override;
-
- BaseVersionPtr getRecommended() const override;
-
- QVariant data(const QModelIndex &index, int role) const override;
- RoleList providesRoles() const override;
- QHash<int, QByteArray> roleNames() const override;
-
- QString localFilename() const override;
-
- QString uid() const
- {
- return m_uid;
- }
- QString name() const
- {
- return m_name;
- }
- QString humanReadable() const;
-
- VersionPtr getVersion(const QString &version);
-
- QVector<VersionPtr> versions() const
- {
- return m_versions;
- }
-
-public: // for usage only by parsers
- void setName(const QString &name);
- void setVersions(const QVector<VersionPtr> &versions);
- void merge(const VersionListPtr &other);
- void mergeFromIndex(const VersionListPtr &other);
- void parse(const QJsonObject &obj) override;
-
-signals:
- void nameChanged(const QString &name);
-
-protected slots:
- void updateListData(QList<BaseVersionPtr>) override
- {
- }
-
-private:
- QVector<VersionPtr> m_versions;
- QHash<QString, VersionPtr> m_lookup;
- QString m_uid;
- QString m_name;
-
- VersionPtr m_recommended;
-
- void setupAddedVersion(const int row, const VersionPtr &version);
-};
-}
-Q_DECLARE_METATYPE(Meta::VersionListPtr)