diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
| commit | 31b9a8949ed0a288143e23bf739f2eb64fdc63be (patch) | |
| tree | 8a984fa143c38fccad461a77792d6864f3e82cd3 /meshmc/launcher/meta/VersionList.cpp | |
| parent | 934382c8a1ce738589dee9ee0f14e1cec812770e (diff) | |
| parent | fad6a1066616b69d7f5fef01178efdf014c59537 (diff) | |
| download | Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.tar.gz Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.zip | |
Add 'meshmc/' from commit 'fad6a1066616b69d7f5fef01178efdf014c59537'
git-subtree-dir: meshmc
git-subtree-mainline: 934382c8a1ce738589dee9ee0f14e1cec812770e
git-subtree-split: fad6a1066616b69d7f5fef01178efdf014c59537
Diffstat (limited to 'meshmc/launcher/meta/VersionList.cpp')
| -rw-r--r-- | meshmc/launcher/meta/VersionList.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/meshmc/launcher/meta/VersionList.cpp b/meshmc/launcher/meta/VersionList.cpp new file mode 100644 index 0000000000..1bb150616a --- /dev/null +++ b/meshmc/launcher/meta/VersionList.cpp @@ -0,0 +1,285 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * 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); + } + + Task::Ptr 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->requirements(); + 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->requirements()); + 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; + } + +} // namespace Meta |
