diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp index bb44d2495..6b3a0e156 100644 --- a/launcher/ResourceDownloadTask.cpp +++ b/launcher/ResourceDownloadTask.cpp @@ -77,8 +77,8 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack::Ptr pack, auto action = Net::ApiDownload::makeFile(m_pack_version.downloadUrl, m_pack_model->dir().absoluteFilePath(getFilename()), Net::Download::Option::NoOptions, createModrinthMeta(m_pack_model->instance(), std::move(downloadReason))); - if (!m_pack_version.hash_type.isEmpty() && !m_pack_version.hash.isEmpty()) { - switch (Hashing::algorithmFromString(m_pack_version.hash_type)) { + if (!m_pack_version.hashType.isEmpty() && !m_pack_version.hash.isEmpty()) { + switch (Hashing::algorithmFromString(m_pack_version.hashType)) { case Hashing::Algorithm::Md4: action->addValidator(new Net::ChecksumValidator(QCryptographicHash::Algorithm::Md4, m_pack_version.hash)); break; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index 77b8de972..0924ab38e 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -193,7 +193,7 @@ QList GetModDependenciesTask::getDependenciesForVersion return cDependencies; } -Task::Ptr GetModDependenciesTask::getProjectInfoTask(std::shared_ptr pDep) +Task::Ptr GetModDependenciesTask::getProjectInfoTask(const std::shared_ptr& pDep) { auto provider = pDep->pack->provider; auto [info, responseInfo] = getAPI(provider)->getProject(pDep->pack->addonId.toString()); @@ -249,10 +249,10 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen .dependency = dep, .mcVersion = m_version, .loader = m_loaderType, .includeChangelog = true }; ResourceAPI::Callback callbacks; - callbacks.on_fail = [](const QString& reason, int) { + callbacks.onFail = [](const QString& reason, int) { qCritical() << tr("A network error occurred. Could not load project dependencies:%1").arg(reason); }; - callbacks.on_succeed = [dep, provider, pDep, level, this](auto& pack) { + callbacks.onSucceed = [dep, provider, pDep, level, this](auto& pack) { pDep->version = pack; if (!pDep->version.addonId.isValid()) { if (m_loaderType & ModPlatform::Quilt) { // falback for quilt @@ -268,7 +268,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen removePack(dep.addonId); return; } - pDep->version.is_currently_selected = true; + pDep->version.isCurrentlySelected = true; pDep->pack->versions = { pDep->version }; pDep->pack->versionsLoaded = true; @@ -350,7 +350,7 @@ auto GetModDependenciesTask::getExtraInfo() -> QHash pDep) +bool GetModDependenciesTask::isLocalyInstalled(const std::shared_ptr& pDep) { return pDep->version.fileName.isEmpty() || std::ranges::find_if(m_selected, @@ -362,13 +362,13 @@ bool GetModDependenciesTask::isLocalyInstalled(std::shared_ptr p [pDep](const QString& i) { return !i.isEmpty() && laxCompare(i, pDep->version.fileName); }) != m_modsFileNames.end() || // check the existing mods - std::ranges::find_if(m_packDependencies, [pDep](std::shared_ptr i) { + std::ranges::find_if(m_packDependencies, [pDep](const std::shared_ptr& i) { return pDep->pack->addonId != i->pack->addonId && !i->version.fileName.isEmpty() && laxCompare(pDep->version.fileName, i->version.fileName); }) != m_packDependencies.end(); // check loaded dependencies } -bool GetModDependenciesTask::maybeInstalled(std::shared_ptr pDep) +bool GetModDependenciesTask::maybeInstalled(const std::shared_ptr& pDep) { return std::ranges::find_if(m_modsFileNames, [pDep](const QString& i) { return !i.isEmpty() && laxCompare(i, pDep->version.fileName, true); diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h index cc605ee22..f0f6767c3 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -71,12 +71,12 @@ class GetModDependenciesTask : public SequentialTask { QList getDependenciesForVersion(const ModPlatform::IndexedVersion&, ModPlatform::ResourceProvider providerName); void prepare(); - Task::Ptr getProjectInfoTask(std::shared_ptr pDep); + Task::Ptr getProjectInfoTask(const std::shared_ptr& pDep); ModPlatform::Dependency getOverride(const ModPlatform::Dependency&, ModPlatform::ResourceProvider providerName); void removePack(const QVariant& addonId); + bool isLocalyInstalled(const std::shared_ptr& pDep); - bool isLocalyInstalled(std::shared_ptr pDep); - bool maybeInstalled(std::shared_ptr pDep); + bool maybeInstalled(const std::shared_ptr& pDep); private: QList> m_packDependencies; diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index 2c7e485e5..68dfe4276 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -7,7 +7,6 @@ #include "Json.h" #include "QObjectPtr.h" -#include "minecraft/mod/Mod.h" #include "minecraft/mod/tasks/LocalResourceUpdateTask.h" #include "modplatform/flame/FlameAPI.h" @@ -15,44 +14,47 @@ #include "modplatform/helpers/HashUtils.h" #include "modplatform/modrinth/ModrinthAPI.h" #include "modplatform/modrinth/ModrinthPackIndex.h" +#include "settings/SettingsObject.h" +#include "tasks/ConcurrentTask.h" -static ModrinthAPI modrinth_api; -static FlameAPI flame_api; - -EnsureMetadataTask::EnsureMetadataTask(Resource* resource, QDir dir, ModPlatform::ResourceProvider prov) - : Task(), m_indexDir(dir), m_provider(prov), m_hashingTask(nullptr), m_currentTask(nullptr) +EnsureMetadataTask::EnsureMetadataTask(Resource* resource, const QDir& dir, ModPlatform::ResourceProvider prov) + : m_indexDir(dir), m_provider(prov), m_hashingTask(nullptr), m_currentTask(nullptr) { auto hashTask = createNewHash(resource); - if (!hashTask) + if (!hashTask) { return; - connect(hashTask.get(), &Hashing::Hasher::resultsReady, [this, resource](QString hash) { m_resources.insert(hash, resource); }); + } + connect(hashTask.get(), &Hashing::Hasher::resultsReady, [this, resource](const QString& hash) { m_resources.insert(hash, resource); }); connect(hashTask.get(), &Task::failed, [this, resource] { emitFail(resource, "", RemoveFromList::No); }); m_hashingTask = hashTask; } -EnsureMetadataTask::EnsureMetadataTask(QList& resources, QDir dir, ModPlatform::ResourceProvider prov) - : Task(), m_indexDir(dir), m_provider(prov), m_currentTask(nullptr) +EnsureMetadataTask::EnsureMetadataTask(QList& resources, const QDir& dir, ModPlatform::ResourceProvider prov) + : m_indexDir(dir), m_provider(prov), m_currentTask(nullptr) { - auto hashTask = makeShared("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); - m_hashingTask = hashTask; + auto cHashTask = makeShared("MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); + m_hashingTask = cHashTask; for (auto* resource : resources) { - auto hash_task = createNewHash(resource); - if (!hash_task) + auto hashTask = createNewHash(resource); + if (!hashTask) { continue; - connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, resource](QString hash) { m_resources.insert(hash, resource); }); - connect(hash_task.get(), &Task::failed, [this, resource] { emitFail(resource, "", RemoveFromList::No); }); - hashTask->addTask(hash_task); + } + connect(hashTask.get(), &Hashing::Hasher::resultsReady, + [this, resource](const QString& hash) { m_resources.insert(hash, resource); }); + connect(hashTask.get(), &Task::failed, [this, resource] { emitFail(resource, "", RemoveFromList::No); }); + cHashTask->addTask(hashTask); } } -EnsureMetadataTask::EnsureMetadataTask(QHash& resources, QDir dir, ModPlatform::ResourceProvider prov) - : Task(), m_resources(resources), m_indexDir(dir), m_provider(prov), m_currentTask(nullptr) +EnsureMetadataTask::EnsureMetadataTask(QHash& resources, const QDir& dir, ModPlatform::ResourceProvider prov) + : m_resources(resources), m_indexDir(dir), m_provider(prov), m_currentTask(nullptr) {} Hashing::Hasher::Ptr EnsureMetadataTask::createNewHash(Resource* resource) { - if (!resource || !resource->valid() || resource->type() == ResourceType::FOLDER) + if (!resource || !resource->valid() || resource->type() == ResourceType::FOLDER) { return nullptr; + } return Hashing::createHasher(resource->fileinfo().absoluteFilePath(), m_provider); } @@ -63,8 +65,9 @@ QString EnsureMetadataTask::getExistingHash(Resource* resource) // (linear on the number of mods vs. linear on the size of the mod's JAR) auto it = m_resources.keyValueBegin(); while (it != m_resources.keyValueEnd()) { - if ((*it).second == resource) + if ((*it).second == resource) { break; + } it++; } @@ -80,10 +83,11 @@ QString EnsureMetadataTask::getExistingHash(Resource* resource) bool EnsureMetadataTask::abort() { // Prevent sending signals to a dead object - disconnect(this, 0, 0, 0); + QObject::disconnect(this, nullptr, nullptr, nullptr); - if (m_currentTask) + if (m_currentTask) { return m_currentTask->abort(); + } return true; } @@ -111,70 +115,74 @@ void EnsureMetadataTask::executeTask() } } - Task::Ptr version_task; + Task::Ptr versionTask; switch (m_provider) { case (ModPlatform::ResourceProvider::MODRINTH): - version_task = modrinthVersionsTask(); + versionTask = modrinthVersionsTask(); break; case (ModPlatform::ResourceProvider::FLAME): - version_task = flameVersionsTask(); + versionTask = flameVersionsTask(); break; } - auto invalidade_leftover = [this] { - for (auto resource = m_resources.constBegin(); resource != m_resources.constEnd(); resource++) + auto invalidadeLeftover = [this] { + for (auto resource = m_resources.constBegin(); resource != m_resources.constEnd(); resource++) { emitFail(resource.value(), resource.key(), RemoveFromList::No); + } m_resources.clear(); emitSucceeded(); }; - connect(version_task.get(), &Task::finished, this, [this, invalidade_leftover] { - Task::Ptr project_task; + connect(versionTask.get(), &Task::finished, this, [this, invalidadeLeftover] { + Task::Ptr projectTask; switch (m_provider) { case (ModPlatform::ResourceProvider::MODRINTH): - project_task = modrinthProjectsTask(); + projectTask = modrinthProjectsTask(); break; case (ModPlatform::ResourceProvider::FLAME): - project_task = flameProjectsTask(); + projectTask = flameProjectsTask(); break; } - if (!project_task) { - invalidade_leftover(); + if (!projectTask) { + invalidadeLeftover(); return; } - connect(project_task.get(), &Task::finished, this, [this, invalidade_leftover, project_task] { - invalidade_leftover(); - project_task->deleteLater(); - if (m_currentTask) + connect(projectTask.get(), &Task::finished, this, [this, invalidadeLeftover, projectTask] { + invalidadeLeftover(); + projectTask->deleteLater(); + if (m_currentTask) { m_currentTask.reset(); + } }); - connect(project_task.get(), &Task::failed, this, &EnsureMetadataTask::emitFailed); + connect(projectTask.get(), &Task::failed, this, &EnsureMetadataTask::emitFailed); - m_currentTask = project_task; - project_task->start(); + m_currentTask = projectTask; + projectTask->start(); }); - if (m_resources.size() > 1) + if (m_resources.size() > 1) { setStatus(tr("Requesting metadata information from %1...").arg(ModPlatform::ProviderCapabilities::readableName(m_provider))); - else if (!m_resources.empty()) + } else if (!m_resources.empty()) { setStatus(tr("Requesting metadata information from %1 for '%2'...") .arg(ModPlatform::ProviderCapabilities::readableName(m_provider), m_resources.begin().value()->name())); + } - m_currentTask = version_task; - version_task->start(); + m_currentTask = versionTask; + versionTask->start(); } void EnsureMetadataTask::emitReady(Resource* resource, QString key, RemoveFromList remove) { if (!resource) { qCritical() << "Tried to mark a null resource as ready."; - if (!key.isEmpty()) + if (!key.isEmpty()) { m_resources.remove(key); + } return; } @@ -183,8 +191,9 @@ void EnsureMetadataTask::emitReady(Resource* resource, QString key, RemoveFromLi emit metadataReady(resource); if (remove == RemoveFromList::Yes) { - if (key.isEmpty()) + if (key.isEmpty()) { key = getExistingHash(resource); + } m_resources.remove(key); } } @@ -193,8 +202,9 @@ void EnsureMetadataTask::emitFail(Resource* resource, QString key, RemoveFromLis { if (!resource) { qCritical() << "Tried to mark a null resource as failed."; - if (!key.isEmpty()) + if (!key.isEmpty()) { m_resources.remove(key); + } return; } @@ -203,8 +213,9 @@ void EnsureMetadataTask::emitFail(Resource* resource, QString key, RemoveFromLis emit metadataFailed(resource); if (remove == RemoveFromList::Yes) { - if (key.isEmpty()) + if (key.isEmpty()) { key = getExistingHash(resource); + } m_resources.remove(key); } } @@ -213,30 +224,31 @@ void EnsureMetadataTask::emitFail(Resource* resource, QString key, RemoveFromLis Task::Ptr EnsureMetadataTask::modrinthVersionsTask() { - auto hash_type = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first(); + auto hashType = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first(); - auto [ver_task, response] = modrinth_api.currentVersions(m_resources.keys(), hash_type); + auto [verTask, response] = ModrinthAPI::currentVersions(m_resources.keys(), hashType); // Prevents unfortunate timings when aborting the task - if (!ver_task) + if (!verTask) { return Task::Ptr{ nullptr }; + } - connect(ver_task.get(), &Task::succeeded, this, [this, response] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at" << parse_error.offset - << "reason:" << parse_error.errorString(); + connect(verTask.get(), &Task::succeeded, this, [this, response] { + QJsonParseError parseError{}; + const QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; - failed(parse_error.errorString()); + failed(parseError.errorString()); return; } try { auto entries = Json::requireObject(doc); for (auto& hash : m_resources.keys()) { - auto resource = m_resources.find(hash).value(); + auto* resource = m_resources.find(hash).value(); try { auto entry = Json::requireObject(entries, hash); @@ -257,36 +269,38 @@ Task::Ptr EnsureMetadataTask::modrinthVersionsTask() } }); - return ver_task; + return verTask; } Task::Ptr EnsureMetadataTask::modrinthProjectsTask() { QHash addonIds; - for (const auto& data : m_tempVersions) + for (const auto& data : m_tempVersions) { addonIds.insert(data.addonId.toString(), data.hash); + } - Task::Ptr proj_task; - QByteArray* response; + Task::Ptr projTask; + QByteArray* response = nullptr; if (addonIds.isEmpty()) { qWarning() << "No addonId found!"; } else if (addonIds.size() == 1) { - std::tie(proj_task, response) = modrinth_api.getProject(*addonIds.keyBegin()); + std::tie(projTask, response) = ModrinthAPI().getProject(*addonIds.keyBegin()); } else { - std::tie(proj_task, response) = modrinth_api.getProjects(addonIds.keys()); + std::tie(projTask, response) = ModrinthAPI().getProjects(addonIds.keys()); } // Prevents unfortunate timings when aborting the task - if (!proj_task) + if (!projTask) { return Task::Ptr{ nullptr }; + } - connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { - QJsonParseError parse_error{}; - auto doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth projects task at" << parse_error.offset - << "reason:" << parse_error.errorString(); + connect(projTask.get(), &Task::succeeded, this, [this, response, addonIds] { + QJsonParseError parseError{}; + auto doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth projects task at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; return; } @@ -294,10 +308,11 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() QJsonArray entries; try { - if (addonIds.size() == 1) + if (addonIds.size() == 1) { entries = { doc.object() }; - else + } else { entries = Json::requireArray(doc); + } } catch (Json::JsonException& e) { qDebug() << e.cause(); qDebug() << doc; @@ -307,9 +322,9 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() ModPlatform::IndexedPack pack; try { - auto entry_obj = Json::requireObject(entry); + auto entryObj = Json::requireObject(entry); - Modrinth::loadIndexedPack(pack, entry_obj); + Modrinth::loadIndexedPack(pack, entryObj); } catch (Json::JsonException& e) { qDebug() << e.cause(); qDebug() << doc; @@ -320,13 +335,13 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() auto hash = addonIds.find(pack.addonId.toString()).value(); - auto resource_iter = m_resources.find(hash); - if (resource_iter == m_resources.end()) { + auto resourceIter = m_resources.find(hash); + if (resourceIter == m_resources.end()) { qWarning() << "Invalid project id from the API response."; continue; } - auto* resource = resource_iter.value(); + auto* resource = resourceIter.value(); setStatus(tr("Parsing API response from Modrinth for '%1'...").arg(resource->name())); @@ -334,7 +349,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask() } }); - return proj_task; + return projTask; } // Flame @@ -345,42 +360,42 @@ Task::Ptr EnsureMetadataTask::flameVersionsTask() fingerprints.push_back(murmur.toUInt()); } - auto [ver_task, response] = flame_api.matchFingerprints(fingerprints); + auto [verTask, response] = FlameAPI::matchFingerprints(fingerprints); - connect(ver_task.get(), &Task::succeeded, this, [this, response] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame::CurrentVersions at" << parse_error.offset - << "reason:" << parse_error.errorString(); + connect(verTask.get(), &Task::succeeded, this, [this, response] { + QJsonParseError parseError{}; + const QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame::CurrentVersions at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; - failed(parse_error.errorString()); + failed(parseError.errorString()); return; } try { - auto doc_obj = Json::requireObject(doc); - auto data_obj = Json::requireObject(doc_obj, "data"); - auto data_arr = Json::requireArray(data_obj, "exactMatches"); + auto docObj = Json::requireObject(doc); + auto dataObj = Json::requireObject(docObj, "data"); + auto dataArr = Json::requireArray(dataObj, "exactMatches"); - if (data_arr.isEmpty()) { + if (dataArr.isEmpty()) { qWarning() << "No matches found for fingerprint search!"; return; } - for (auto match : data_arr) { - auto match_obj = match.toObject(); - auto file_obj = match_obj["file"].toObject(); + for (auto match : dataArr) { + auto matchObj = match.toObject(); + auto fileObj = matchObj["file"].toObject(); - if (match_obj.isEmpty() || file_obj.isEmpty()) { + if (matchObj.isEmpty() || fileObj.isEmpty()) { qWarning() << "Fingerprint match is empty!"; return; } - auto fingerprint = QString::number(file_obj["fileFingerprint"].toInteger()); + auto fingerprint = QString::number(fileObj["fileFingerprint"].toInteger()); auto resource = m_resources.find(fingerprint); if (resource == m_resources.end()) { qWarning() << "Invalid fingerprint from the API response."; @@ -389,7 +404,7 @@ Task::Ptr EnsureMetadataTask::flameVersionsTask() setStatus(tr("Parsing API response from CurseForge for '%1'...").arg((*resource)->name())); - m_tempVersions.insert(fingerprint, FlameMod::loadIndexedPackVersion(file_obj)); + m_tempVersions.insert(fingerprint, FlameMod::loadIndexedPackVersion(fileObj)); } } catch (Json::JsonException& e) { @@ -398,7 +413,7 @@ Task::Ptr EnsureMetadataTask::flameVersionsTask() } }); - return ver_task; + return verTask; } Task::Ptr EnsureMetadataTask::flameProjectsTask() @@ -408,56 +423,59 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask() if (m_tempVersions.contains(hash)) { auto data = m_tempVersions.find(hash).value(); - auto id_str = data.addonId.toString(); - if (!id_str.isEmpty()) + auto idStr = data.addonId.toString(); + if (!idStr.isEmpty()) { addonIds.insert(data.addonId.toString(), hash); + } } } - Task::Ptr proj_task; - QByteArray* response; + Task::Ptr projTask; + QByteArray* response = nullptr; if (addonIds.isEmpty()) { qWarning() << "No addonId found!"; } else if (addonIds.size() == 1) { - std::tie(proj_task, response) = flame_api.getProject(*addonIds.keyBegin()); + std::tie(projTask, response) = FlameAPI().getProject(*addonIds.keyBegin()); } else { - std::tie(proj_task, response) = flame_api.getProjects(addonIds.keys()); + std::tie(projTask, response) = FlameAPI().getProjects(addonIds.keys()); } // Prevents unfortunate timings when aborting the task - if (!proj_task) + if (!projTask) { return Task::Ptr{ nullptr }; + } - connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] { - QJsonParseError parse_error{}; - auto doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame projects task at" << parse_error.offset - << "reason:" << parse_error.errorString(); + connect(projTask.get(), &Task::succeeded, this, [this, response, addonIds] { + QJsonParseError parseError{}; + auto doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame projects task at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; return; } try { QJsonArray entries; - if (addonIds.size() == 1) + if (addonIds.size() == 1) { entries = { Json::requireObject(Json::requireObject(doc), "data") }; - else + } else { entries = Json::requireArray(Json::requireObject(doc), "data"); + } for (auto entry : entries) { - auto entry_obj = Json::requireObject(entry); + auto entryObj = Json::requireObject(entry); - auto id = QString::number(Json::requireInteger(entry_obj, "id")); + auto id = QString::number(Json::requireInteger(entryObj, "id")); auto hash = addonIds.find(id).value(); - auto resource = m_resources.find(hash).value(); + auto* resource = m_resources.find(hash).value(); ModPlatform::IndexedPack pack; try { setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(resource->name())); - FlameMod::loadIndexedPack(pack, entry_obj); + FlameMod::loadIndexedPack(pack, entryObj); } catch (Json::JsonException& e) { qDebug() << e.cause(); @@ -473,7 +491,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask() } }); - return proj_task; + return projTask; } void EnsureMetadataTask::updateMetadata(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, Resource* resource) @@ -481,8 +499,9 @@ void EnsureMetadataTask::updateMetadata(ModPlatform::IndexedPack& pack, ModPlatf try { // Prevent file name mismatch ver.fileName = resource->fileinfo().fileName(); - if (ver.fileName.endsWith(".disabled")) + if (ver.fileName.endsWith(".disabled")) { ver.fileName.chop(9); + } auto task = makeShared(m_indexDir, pack, ver); diff --git a/launcher/modplatform/EnsureMetadataTask.h b/launcher/modplatform/EnsureMetadataTask.h index 3d8a8ba53..0aeace359 100644 --- a/launcher/modplatform/EnsureMetadataTask.h +++ b/launcher/modplatform/EnsureMetadataTask.h @@ -1,25 +1,22 @@ #pragma once #include "ModIndex.h" -#include "net/NetJob.h" #include "modplatform/helpers/HashUtils.h" -#include "minecraft/mod/Resource.h" -#include "tasks/ConcurrentTask.h" +#include -class Mod; -class QDir; +#include "minecraft/mod/Resource.h" class EnsureMetadataTask : public Task { Q_OBJECT public: - EnsureMetadataTask(Resource*, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); - EnsureMetadataTask(QList&, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); - EnsureMetadataTask(QHash&, QDir, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); + EnsureMetadataTask(Resource*, const QDir&, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); + EnsureMetadataTask(QList&, const QDir&, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); + EnsureMetadataTask(QHash&, const QDir&, ModPlatform::ResourceProvider = ModPlatform::ResourceProvider::MODRINTH); - ~EnsureMetadataTask() = default; + ~EnsureMetadataTask() override = default; Task::Ptr getHashingTask() { return m_hashingTask; } @@ -37,7 +34,7 @@ class EnsureMetadataTask : public Task { Task::Ptr flameProjectsTask(); // Helpers - enum class RemoveFromList { Yes, No }; + enum class RemoveFromList : std::uint8_t { Yes, No }; void emitReady(Resource*, QString key = {}, RemoveFromList = RemoveFromList::Yes); void emitFail(Resource*, QString key = {}, RemoveFromList = RemoveFromList::Yes); diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h index cfdda419d..05831a005 100644 --- a/launcher/modplatform/ModIndex.h +++ b/launcher/modplatform/ModIndex.h @@ -113,27 +113,27 @@ struct IndexedVersion { QVariant addonId; QVariant fileId; QString version; - QString version_number; - IndexedVersionType version_type; + QString versionNumber; + IndexedVersionType versionType; QStringList mcVersion; QString downloadUrl; QString date; QString fileName; ModLoaderTypes loaders; - QString hash_type; + QString hashType; QString hash; - bool is_preferred = true; + bool isPreferred = true; QString changelog; QList dependencies; Side side = Side::NoSide; // this is for flame API // For internal use, not provided by APIs - bool is_currently_selected = false; + bool isCurrentlySelected = false; QString getVersionDisplayString() const { - auto release_type = version_type.isValid() ? QString(" [%1]").arg(version_type.toString()) : ""; - auto versionStr = !version.contains(version_number) ? version_number : ""; + auto releaseType = versionType.isValid() ? QString(" [%1]").arg(versionType.toString()) : ""; + auto versionStr = !version.contains(versionNumber) ? versionNumber : ""; QString gameVersion = ""; for (const auto& v : mcVersion) { if (version.contains(v)) { @@ -144,7 +144,7 @@ struct IndexedVersion { gameVersion = QObject::tr(" for %1").arg(v); } } - return QString("%1%2 — %3%4").arg(version, gameVersion, versionStr, release_type); + return QString("%1%2 — %3%4").arg(version, gameVersion, versionStr, releaseType); } }; @@ -191,7 +191,7 @@ struct IndexedPack { return false; } - return versions.at(index).is_currently_selected; + return versions.at(index).isCurrentlySelected; } bool isAnyVersionSelected() const { @@ -199,7 +199,7 @@ struct IndexedPack { return false; } - return std::any_of(versions.constBegin(), versions.constEnd(), [](const auto& v) { return v.is_currently_selected; }); + return std::any_of(versions.constBegin(), versions.constEnd(), [](const auto& v) { return v.isCurrentlySelected; }); } }; diff --git a/launcher/modplatform/ResourceAPI.cpp b/launcher/modplatform/ResourceAPI.cpp index bd683ed21..45edbfee7 100644 --- a/launcher/modplatform/ResourceAPI.cpp +++ b/launcher/modplatform/ResourceAPI.cpp @@ -1,5 +1,7 @@ #include "modplatform/ResourceAPI.h" +#include + #include "Application.h" #include "Json.h" #include "net/NetJob.h" @@ -8,30 +10,30 @@ #include "net/ApiDownload.h" -Task::Ptr ResourceAPI::searchProjects(SearchArgs&& args, Callback>&& callbacks) const +Task::Ptr ResourceAPI::searchProjects(const SearchArgs& args, const Callback>& callbacks) const { - auto search_url_optional = getSearchURL(args); - if (!search_url_optional.has_value()) { - callbacks.on_fail("Failed to create search URL", -1); + auto searchUrlOptional = getSearchURL(args); + if (!searchUrlOptional.has_value()) { + callbacks.onFail("Failed to create search URL", -1); return nullptr; } - auto search_url = search_url_optional.value(); + const auto& searchUrl = searchUrlOptional.value(); auto netJob = makeShared(QString("%1::Search").arg(debugName()), APPLICATION->network()); - auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(search_url)); + auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(searchUrl)); netJob->addNetAction(action); QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from" << debugName() << "at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from" << debugName() << "at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; - callbacks.on_fail(parse_error.errorString(), -1); + callbacks.onFail(parseError.errorString(), -1); return; } @@ -52,7 +54,7 @@ Task::Ptr ResourceAPI::searchProjects(SearchArgs&& args, CallbackgetFailedActions().at(0); failed_action) - network_error_code = failed_action->replyStatusCode(); + if (auto* failedAction = netJob->getFailedActions().at(0); failedAction) { + networkErrorCode = failedAction->replyStatusCode(); + } } - callbacks.on_fail(reason, network_error_code); + callbacks.onFail(reason, networkErrorCode); }); QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { - if (callbacks.on_abort != nullptr) - callbacks.on_abort(); + if (callbacks.onAbort != nullptr) { + callbacks.onAbort(); + } }); return netJob; } -Task::Ptr ResourceAPI::getProjectVersions(VersionSearchArgs&& args, Callback>&& callbacks) const +Task::Ptr ResourceAPI::getProjectVersions(const VersionSearchArgs& args, + const Callback>& callbacks) const { - auto versions_url_optional = getVersionsURL(args); - if (!versions_url_optional.has_value()) + auto versionsUrlOptional = getVersionsURL(args); + if (!versionsUrlOptional.has_value()) { return nullptr; + } - auto versions_url = versions_url_optional.value(); + const auto& versionsUrl = versionsUrlOptional.value(); auto netJob = makeShared(QString("%1::Versions").arg(args.pack->name), APPLICATION->network()); - auto [action, response] = Net::ApiDownload::makeByteArray(versions_url); + auto [action, response] = Net::ApiDownload::makeByteArray(versionsUrl); netJob->addNetAction(action); QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks, args] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response for getting versions at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for getting versions at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; return; } @@ -119,13 +125,13 @@ Task::Ptr ResourceAPI::getProjectVersions(VersionSearchArgs&& args, Callback b.date; }; - std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + std::ranges::sort(unsortedVersions, orderSortPredicate); } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading" << debugName() << "resource version:" << e.cause(); } - callbacks.on_succeed(unsortedVersions); + callbacks.onSucceed(unsortedVersions); }); // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues. @@ -133,87 +139,93 @@ Task::Ptr ResourceAPI::getProjectVersions(VersionSearchArgs&& args, CallbackgetFailedActions().at(0); failed_action) - network_error_code = failed_action->replyStatusCode(); + if (auto* failedAction = netJob->getFailedActions().at(0); failedAction) { + networkErrorCode = failedAction->replyStatusCode(); + } } - callbacks.on_fail(reason, network_error_code); + callbacks.onFail(reason, networkErrorCode); }); QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { - if (callbacks.on_abort != nullptr) - callbacks.on_abort(); + if (callbacks.onAbort != nullptr) { + callbacks.onAbort(); + } }); return netJob; } -Task::Ptr ResourceAPI::getProjectInfo(ProjectInfoArgs&& args, Callback&& callbacks, bool askRetry) const +Task::Ptr ResourceAPI::getProjectInfo(const ProjectInfoArgs& args, + const Callback& callbacks, + bool askRetry) const { auto [job, response] = getProject(args.pack->addonId.toString(), askRetry); QObject::connect(job.get(), &NetJob::succeeded, [this, response, callbacks, args] { auto pack = args.pack; - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response for mod info at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for mod info at" << parseError.offset << "reason:" << parseError.errorString(); qWarning() << *response; return; } try { auto obj = Json::requireObject(doc); - if (obj.contains("data")) + if (obj.contains("data")) { obj = Json::requireObject(obj, "data"); + } loadIndexedPack(*pack, obj); loadExtraPackInfo(*pack, obj); } catch (const JSONValidationError& e) { qDebug() << doc; qWarning() << "Error while reading" << debugName() << "resource info:" << e.cause(); } - callbacks.on_succeed(pack); + callbacks.onSucceed(pack); }); // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues. // This prevents the lambda from extending the lifetime of the shared resource, // as it only temporarily locks the resource when needed. auto weak = job.toWeakRef(); QObject::connect(job.get(), &NetJob::failed, [weak, callbacks](const QString& reason) { - int network_error_code = -1; + int networkErrorCode = -1; if (auto job = weak.lock()) { if (auto netJob = qSharedPointerDynamicCast(job)) { - if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) { - network_error_code = failed_action->replyStatusCode(); + if (auto* failedAction = netJob->getFailedActions().at(0); failedAction) { + networkErrorCode = failedAction->replyStatusCode(); } } } - callbacks.on_fail(reason, network_error_code); + callbacks.onFail(reason, networkErrorCode); }); QObject::connect(job.get(), &NetJob::aborted, [callbacks] { - if (callbacks.on_abort != nullptr) - callbacks.on_abort(); + if (callbacks.onAbort != nullptr) { + callbacks.onAbort(); + } }); return job; } -Task::Ptr ResourceAPI::getDependencyVersion(DependencySearchArgs&& args, Callback&& callbacks) const +Task::Ptr ResourceAPI::getDependencyVersion(const DependencySearchArgs& args, const Callback& callbacks) const { - auto versions_url_optional = getDependencyURL(args); - if (!versions_url_optional.has_value()) + auto versionsUrlOptional = getDependencyURL(args); + if (!versionsUrlOptional.has_value()) { return nullptr; + } - auto versions_url = versions_url_optional.value(); + const auto& versionsUrl = versionsUrlOptional.value(); auto netJob = makeShared(QString("%1::Dependency").arg(args.dependency.addonId.toString()), APPLICATION->network()); - auto [action, response] = Net::ApiDownload::makeByteArray(versions_url); + auto [action, response] = Net::ApiDownload::makeByteArray(versionsUrl); netJob->addNetAction(action); QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks, args] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response for getting dependency version at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for getting dependency version at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; return; } @@ -230,21 +242,23 @@ Task::Ptr ResourceAPI::getDependencyVersion(DependencySearchArgs&& args, Callbac auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj, ModPlatform::ResourceType::Mod); - if (!file.addonId.isValid()) + if (!file.addonId.isValid()) { file.addonId = args.dependency.addonId; + } if (file.fileId.isValid() && - (!file.loaders || args.loader & file.loaders)) // Heuristic to check if the returned value is valid + (!file.loaders || args.loader & file.loaders)) { // Heuristic to check if the returned value is valid versions.append(file); + } } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { // dates are in RFC 3339 format return a.date > b.date; }; - std::sort(versions.begin(), versions.end(), orderSortPredicate); + std::ranges::sort(versions, orderSortPredicate); auto bestMatch = versions.size() != 0 ? versions.front() : ModPlatform::IndexedVersion(); - callbacks.on_succeed(bestMatch); + callbacks.onSucceed(bestMatch); }); // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues. @@ -252,50 +266,52 @@ Task::Ptr ResourceAPI::getDependencyVersion(DependencySearchArgs&& args, Callbac // as it only temporarily locks the resource when needed. auto weak = netJob.toWeakRef(); QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) { - int network_error_code = -1; + int networkErrorCode = -1; if (auto netJob = weak.lock()) { - if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) - network_error_code = failed_action->replyStatusCode(); + if (auto* failedAction = netJob->getFailedActions().at(0); failedAction) { + networkErrorCode = failedAction->replyStatusCode(); + } } - callbacks.on_fail(reason, network_error_code); + callbacks.onFail(reason, networkErrorCode); }); return netJob; } -QString ResourceAPI::getGameVersionsString(std::vector mcVersions) const +QString ResourceAPI::getGameVersionsString(const std::vector& mcVersions) { QString s; - for (auto& ver : mcVersions) { + for (const auto& ver : mcVersions) { s += QString("\"%1\",").arg(mapMCVersionToModrinth(ver)); } s.remove(s.length() - 1, 1); // remove last comma return s; } -QString ResourceAPI::mapMCVersionToModrinth(Version v) const +QString ResourceAPI::mapMCVersionToModrinth(const Version& v) { - static const QString preString = " Pre-Release "; + static const QString s_preString = " Pre-Release "; auto verStr = v.toString(); - if (verStr.contains(preString)) { - verStr.replace(preString, "-pre"); + if (verStr.contains(s_preString)) { + verStr.replace(s_preString, "-pre"); } verStr.replace(" ", "-"); return verStr; } -std::pair ResourceAPI::getProject(QString addonId, bool askRetry) const +std::pair ResourceAPI::getProject(const QString& addonId, bool askRetry) const { - auto project_url_optional = getInfoURL(addonId); - if (!project_url_optional.has_value()) + auto projectUrlOptional = getInfoURL(addonId); + if (!projectUrlOptional.has_value()) { return { nullptr, nullptr }; + } - auto project_url = project_url_optional.value(); + const auto& projectUrl = projectUrlOptional.value(); auto netJob = makeShared(QString("%1::GetProject").arg(addonId), APPLICATION->network()); netJob->setAskRetry(askRetry); - auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(project_url)); + auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(projectUrl)); netJob->addNetAction(action); return { netJob, response }; diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h index 51b6d4b50..ee6610810 100644 --- a/launcher/modplatform/ResourceAPI.h +++ b/launcher/modplatform/ResourceAPI.h @@ -42,7 +42,6 @@ #include #include -#include #include #include @@ -65,14 +64,14 @@ class ResourceAPI { // Used by Modrinth in the API request. QString name; // The human-readable name of the sorting, used for display in the UI. - QString readable_name; + QString readableName; }; template struct Callback { - std::function on_succeed; - std::function on_fail; - std::function on_abort; + std::function onSucceed; + std::function onFail; + std::function onAbort; }; struct SearchArgs { @@ -113,21 +112,21 @@ class ResourceAPI { virtual auto getSortingMethods() const -> QList = 0; public slots: - virtual Task::Ptr searchProjects(SearchArgs&&, Callback>&&) const; + virtual Task::Ptr searchProjects(const SearchArgs&, const Callback>&) const; - virtual std::pair getProject(QString addonId, bool askRetry = true) const; + virtual std::pair getProject(const QString& addonId, bool askRetry = true) const; virtual std::pair getProjects(QStringList addonIds) const = 0; - virtual Task::Ptr getProjectInfo(ProjectInfoArgs&&, Callback&&, bool askRetry = true) const; - Task::Ptr getProjectVersions(VersionSearchArgs&& args, Callback>&& callbacks) const; - virtual Task::Ptr getDependencyVersion(DependencySearchArgs&&, Callback&&) const; + virtual Task::Ptr getProjectInfo(const ProjectInfoArgs&, const Callback&, bool askRetry = true) const; + Task::Ptr getProjectVersions(const VersionSearchArgs& args, const Callback>& callbacks) const; + virtual Task::Ptr getDependencyVersion(const DependencySearchArgs&, const Callback&) const; protected: - inline QString debugName() const { return "External resource API"; } + virtual QString debugName() const { return "External resource API"; } - QString mapMCVersionToModrinth(Version v) const; + static QString mapMCVersionToModrinth(const Version& v); - QString getGameVersionsString(std::vector mcVersions) const; + static QString getGameVersionsString(const std::vector& mcVersions); public: virtual auto getSearchURL(const SearchArgs& args) const -> std::optional = 0; diff --git a/launcher/modplatform/ResourceType.cpp b/launcher/modplatform/ResourceType.cpp index 2758f113f..4e9a50c34 100644 --- a/launcher/modplatform/ResourceType.cpp +++ b/launcher/modplatform/ResourceType.cpp @@ -22,7 +22,7 @@ #include "ResourceType.h" namespace ModPlatform { -static const QMap s_packedTypeNames = { { ResourceType::ResourcePack, QObject::tr("resource pack") }, +static const QMap g_packedTypeNames = { { ResourceType::ResourcePack, QObject::tr("resource pack") }, { ResourceType::TexturePack, QObject::tr("texture pack") }, { ResourceType::DataPack, QObject::tr("data pack") }, { ResourceType::ShaderPack, QObject::tr("shader pack") }, @@ -34,7 +34,7 @@ namespace ResourceTypeUtils { QString getName(ResourceType type) { - return s_packedTypeNames.constFind(type).value(); + return g_packedTypeNames.constFind(type).value(); } } // namespace ResourceTypeUtils diff --git a/launcher/modplatform/ResourceType.h b/launcher/modplatform/ResourceType.h index 49e29e16b..e44c2ad3e 100644 --- a/launcher/modplatform/ResourceType.h +++ b/launcher/modplatform/ResourceType.h @@ -32,8 +32,8 @@ namespace ModPlatform { enum class ResourceType : std::uint8_t { Mod, ResourcePack, ShaderPack, Modpack, DataPack, World, Screenshots, TexturePack, Unknown }; namespace ResourceTypeUtils { -static const std::set VALID_RESOURCES = { ResourceType::DataPack, ResourceType::ResourcePack, ResourceType::TexturePack, - ResourceType::ShaderPack, ResourceType::World, ResourceType::Mod }; +static const std::set g_VALID_RESOURCES = { ResourceType::DataPack, ResourceType::ResourcePack, ResourceType::TexturePack, + ResourceType::ShaderPack, ResourceType::World, ResourceType::Mod }; QString getName(ResourceType type); } // namespace ResourceTypeUtils } // namespace ModPlatform diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 7d4b1ee94..83f8055c5 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -18,6 +18,7 @@ #include "FileResolvingTask.h" #include +#include #include "Json.h" #include "modplatform/ModIndex.h" @@ -27,13 +28,11 @@ #include "modplatform/modrinth/ModrinthPackIndex.h" #include "net/NetJob.h" +#include "settings/SettingsObject.h" #include "tasks/Task.h" #include "Application.h" -static const FlameAPI flameAPI; -static ModrinthAPI modrinthAPI; - Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess) : m_manifest(toProcess) {} bool Flame::FileResolvingTask::abort() @@ -55,32 +54,32 @@ void Flame::FileResolvingTask::executeTask() setProgress(0, 3); QStringList fileIds; - for (auto file : m_manifest.files) { + for (const auto& file : m_manifest.files) { fileIds.push_back(QString::number(file.fileId)); } - auto [task, response] = flameAPI.getFiles(fileIds); + auto [task, response] = FlameAPI::getFiles(fileIds); m_task = task; - auto step_progress = std::make_shared(); - connect(m_task.get(), &Task::succeeded, this, [this, response, step_progress]() { - step_progress->state = TaskStepState::Succeeded; - stepProgress(*step_progress); + auto stepProgress2 = std::make_shared(); + connect(m_task.get(), &Task::succeeded, this, [this, response, stepProgress2]() { + stepProgress2->state = TaskStepState::Succeeded; + stepProgress(*stepProgress2); netJobFinished(response); }); - connect(m_task.get(), &Task::failed, this, [this, step_progress](QString reason) { - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); - emitFailed(reason); + connect(m_task.get(), &Task::failed, this, [this, stepProgress2](QString reason) { + stepProgress2->state = TaskStepState::Failed; + stepProgress(*stepProgress2); + emitFailed(std::move(reason)); }); connect(m_task.get(), &Task::stepProgress, this, &FileResolvingTask::propagateStepProgress); - connect(m_task.get(), &Task::progress, this, [this, step_progress](qint64 current, qint64 total) { + connect(m_task.get(), &Task::progress, this, [this, stepProgress2](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; - step_progress->update(current, total); - stepProgress(*step_progress); + stepProgress2->update(current, total); + stepProgress(*stepProgress2); }); - connect(m_task.get(), &Task::status, this, [this, step_progress](QString status) { - step_progress->status = status; - stepProgress(*step_progress); + connect(m_task.get(), &Task::status, this, [this, stepProgress2](QString status) { + stepProgress2->status = std::move(status); + stepProgress(*stepProgress2); }); m_task->start(); @@ -115,7 +114,7 @@ void Flame::FileResolvingTask::netJobFinished(QByteArray* response) Q_ASSERT(m_manifest.files.contains(fileid)); m_manifest.files[fileid].version = version; auto url = QUrl(version.downloadUrl, QUrl::TolerantMode); - if (!url.isValid() && "sha1" == version.hash_type && !version.hash.isEmpty()) { + if (!url.isValid() && "sha1" == version.hashType && !version.hash.isEmpty()) { hashes.push_back(version.hash); } } catch (Json::JsonException& e) { @@ -131,18 +130,18 @@ void Flame::FileResolvingTask::netJobFinished(QByteArray* response) getFlameProjects(); return; } - auto [modrinthTask, modrinthResponse] = modrinthAPI.currentVersions(hashes, "sha1"); + auto [modrinthTask, modrinthResponse] = ModrinthAPI::currentVersions(hashes, "sha1"); m_task = modrinthTask; (dynamic_cast(m_task.get()))->setAskRetry(false); - auto step_progress = std::make_shared(); - connect(m_task.get(), &Task::succeeded, this, [this, modrinthResponse, step_progress]() { - step_progress->state = TaskStepState::Succeeded; - stepProgress(*step_progress); - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*modrinthResponse, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at" << parse_error.offset - << "reason:" << parse_error.errorString(); + auto stepProgress2 = std::make_shared(); + connect(m_task.get(), &Task::succeeded, this, [this, modrinthResponse, stepProgress2]() { + stepProgress2->state = TaskStepState::Succeeded; + stepProgress(*stepProgress2); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*modrinthResponse, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth::CurrentVersions at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *modrinthResponse; getFlameProjects(); @@ -153,7 +152,7 @@ void Flame::FileResolvingTask::netJobFinished(QByteArray* response) auto entries = Json::requireObject(doc); for (auto& out : m_manifest.files) { auto url = QUrl(out.version.downloadUrl, QUrl::TolerantMode); - if (!url.isValid() && "sha1" == out.version.hash_type && !out.version.hash.isEmpty()) { + if (!url.isValid() && "sha1" == out.version.hashType && !out.version.hash.isEmpty()) { try { auto entry = Json::requireObject(entries, out.version.hash); @@ -174,20 +173,20 @@ void Flame::FileResolvingTask::netJobFinished(QByteArray* response) } getFlameProjects(); }); - connect(m_task.get(), &Task::failed, this, [this, step_progress](QString reason) { - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); + connect(m_task.get(), &Task::failed, this, [this, stepProgress2](const QString& /*reason*/) { + stepProgress2->state = TaskStepState::Failed; + stepProgress(*stepProgress2); getFlameProjects(); }); connect(m_task.get(), &Task::stepProgress, this, &FileResolvingTask::propagateStepProgress); - connect(m_task.get(), &Task::progress, this, [this, step_progress](qint64 current, qint64 total) { + connect(m_task.get(), &Task::progress, this, [this, stepProgress2](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; - step_progress->update(current, total); - stepProgress(*step_progress); + stepProgress2->update(current, total); + stepProgress(*stepProgress2); }); - connect(m_task.get(), &Task::status, this, [this, step_progress](QString status) { - step_progress->status = status; - stepProgress(*step_progress); + connect(m_task.get(), &Task::status, this, [this, stepProgress2](QString status) { + stepProgress2->status = std::move(status); + stepProgress(*stepProgress2); }); m_task->start(); } @@ -196,20 +195,20 @@ void Flame::FileResolvingTask::getFlameProjects() { setProgress(2, 3); QStringList addonIds; - for (auto file : m_manifest.files) { + for (const auto& file : m_manifest.files) { addonIds.push_back(QString::number(file.projectId)); } - auto [task, response] = flameAPI.getProjects(addonIds); + auto [task, response] = FlameAPI().getProjects(addonIds); m_task = task; - auto step_progress = std::make_shared(); - connect(m_task.get(), &Task::succeeded, this, [this, response, step_progress] { - QJsonParseError parse_error{}; - auto doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth projects task at" << parse_error.offset - << "reason:" << parse_error.errorString(); + auto stepProgress2 = std::make_shared(); + connect(m_task.get(), &Task::succeeded, this, [this, response, stepProgress2] { + QJsonParseError parseError{}; + auto doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth projects task at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; return; } @@ -219,8 +218,8 @@ void Flame::FileResolvingTask::getFlameProjects() entries = Json::requireArray(Json::requireObject(doc), "data"); for (auto entry : entries) { - auto entry_obj = Json::requireObject(entry); - auto id = Json::requireInteger(entry_obj, "id"); + auto entryObj = Json::requireObject(entry); + auto id = Json::requireInteger(entryObj, "id"); auto file = std::find_if(m_manifest.files.begin(), m_manifest.files.end(), [id](const Flame::File& file) { return file.projectId == id; }); if (file == m_manifest.files.end()) { @@ -228,7 +227,7 @@ void Flame::FileResolvingTask::getFlameProjects() } setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(file->version.fileName)); - FlameMod::loadIndexedPack(file->pack, entry_obj); + FlameMod::loadIndexedPack(file->pack, entryObj); if (file->pack.resourceType == ModPlatform::ResourceType::World) { file->targetFolder = "saves"; } @@ -237,25 +236,25 @@ void Flame::FileResolvingTask::getFlameProjects() qDebug() << e.cause(); qDebug() << doc; } - step_progress->state = TaskStepState::Succeeded; - stepProgress(*step_progress); + stepProgress2->state = TaskStepState::Succeeded; + stepProgress(*stepProgress2); emitSucceeded(); }); - connect(m_task.get(), &Task::failed, this, [this, step_progress](QString reason) { - step_progress->state = TaskStepState::Failed; - stepProgress(*step_progress); - emitFailed(reason); + connect(m_task.get(), &Task::failed, this, [this, stepProgress2](QString reason) { + stepProgress2->state = TaskStepState::Failed; + stepProgress(*stepProgress2); + emitFailed(std::move(reason)); }); connect(m_task.get(), &Task::stepProgress, this, &FileResolvingTask::propagateStepProgress); - connect(m_task.get(), &Task::progress, this, [this, step_progress](qint64 current, qint64 total) { + connect(m_task.get(), &Task::progress, this, [this, stepProgress2](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; - step_progress->update(current, total); - stepProgress(*step_progress); + stepProgress2->update(current, total); + stepProgress(*stepProgress2); }); - connect(m_task.get(), &Task::status, this, [this, step_progress](QString status) { - step_progress->status = status; - stepProgress(*step_progress); + connect(m_task.get(), &Task::status, this, [this, stepProgress2](QString status) { + stepProgress2->status = std::move(status); + stepProgress(*stepProgress2); }); m_task->start(); diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h index 21fa53d2d..1b61559dd 100644 --- a/launcher/modplatform/flame/FileResolvingTask.h +++ b/launcher/modplatform/flame/FileResolvingTask.h @@ -25,7 +25,7 @@ class FileResolvingTask : public Task { Q_OBJECT public: explicit FileResolvingTask(Flame::Manifest& toProcess); - virtual ~FileResolvingTask() = default; + ~FileResolvingTask() override = default; bool canAbort() const override { return true; } bool abort() override; @@ -33,7 +33,7 @@ class FileResolvingTask : public Task { const Flame::Manifest& getResults() const { return m_manifest; } protected: - virtual void executeTask() override; + void executeTask() override; protected slots: void netJobFinished(QByteArray* response); diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index fa0e3616d..2314749a5 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -3,10 +3,8 @@ // SPDX-License-Identifier: GPL-3.0-only #include "FlameAPI.h" -#include #include #include "BuildConfig.h" -#include "FlameModIndex.h" #include "Application.h" #include "Json.h" @@ -19,17 +17,17 @@ std::pair FlameAPI::matchFingerprints(const QList& { auto netJob = makeShared(QString("Flame::MatchFingerprints"), APPLICATION->network()); - QJsonObject body_obj; - QJsonArray fingerprints_arr; - for (auto& fp : fingerprints) { - fingerprints_arr.append(QString("%1").arg(fp)); + QJsonObject bodyObj; + QJsonArray fingerprintsArr; + for (const auto& fp : fingerprints) { + fingerprintsArr.append(QString("%1").arg(fp)); } - body_obj["fingerprints"] = fingerprints_arr; + bodyObj["fingerprints"] = fingerprintsArr; - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); - auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/fingerprints"), body_raw); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); + auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/fingerprints"), bodyRaw); netJob->addNetAction(action); return { netJob, response }; @@ -47,14 +45,14 @@ QString FlameAPI::getModFileChangelog(int modId, int fileId) netJob->addNetAction(action); QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &changelog] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame::FileChangelog at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame::FileChangelog at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; - netJob->failed(parse_error.errorString()); + netJob->failed(parseError.errorString()); return; } @@ -80,14 +78,14 @@ QString FlameAPI::getModDescription(int modId) netJob->addNetAction(action); QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &description] { - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame::ModDescription at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame::ModDescription at" << parseError.offset + << "reason:" << parseError.errorString(); qWarning() << *response; - netJob->failed(parse_error.errorString()); + netJob->failed(parseError.errorString()); return; } @@ -106,48 +104,48 @@ std::pair FlameAPI::getProjects(QStringList addonIds) co { auto netJob = makeShared(QString("Flame::GetProjects"), APPLICATION->network()); - QJsonObject body_obj; - QJsonArray addons_arr; + QJsonObject bodyObj; + QJsonArray addonsArr; for (auto& addonId : addonIds) { - addons_arr.append(addonId); + addonsArr.append(addonId); } - body_obj["modIds"] = addons_arr; + bodyObj["modIds"] = addonsArr; - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); - auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/mods"), body_raw); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); + auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/mods"), bodyRaw); netJob->addNetAction(action); - QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); + QObject::connect(netJob.get(), &NetJob::failed, [bodyRaw] { qDebug() << bodyRaw; }); return { netJob, response }; } -std::pair FlameAPI::getFiles(const QStringList& fileIds) const +std::pair FlameAPI::getFiles(const QStringList& fileIds) { auto netJob = makeShared(QString("Flame::GetFiles"), APPLICATION->network()); - QJsonObject body_obj; - QJsonArray files_arr; - for (auto& fileId : fileIds) { - files_arr.append(fileId); + QJsonObject bodyObj; + QJsonArray filesArr; + for (const auto& fileId : fileIds) { + filesArr.append(fileId); } - body_obj["fileIds"] = files_arr; + bodyObj["fileIds"] = filesArr; - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); - auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/mods/files"), body_raw); + auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.FLAME_BASE_URL + "/mods/files"), bodyRaw); netJob->addNetAction(action); - QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; }); + QObject::connect(netJob.get(), &NetJob::failed, [bodyRaw] { qDebug() << bodyRaw; }); return { netJob, response }; } -std::pair FlameAPI::getFile(const QString& addonId, const QString& fileId) const +std::pair FlameAPI::getFile(const QString& addonId, const QString& fileId) { auto netJob = makeShared(QString("Flame::GetFile"), APPLICATION->network()); auto [action, response] = @@ -162,14 +160,14 @@ std::pair FlameAPI::getFile(const QString& addonId, cons QList FlameAPI::getSortingMethods() const { // https://docs.curseforge.com/?python#tocS_ModsSearchSortField - return { { .index = 1, .name = "Featured", .readable_name = QObject::tr("Sort by Featured") }, - { .index = 2, .name = "Popularity", .readable_name = QObject::tr("Sort by Popularity") }, - { .index = 3, .name = "LastUpdated", .readable_name = QObject::tr("Sort by Last Updated") }, - { .index = 4, .name = "Name", .readable_name = QObject::tr("Sort by Name") }, - { .index = 5, .name = "Author", .readable_name = QObject::tr("Sort by Author") }, - { .index = 6, .name = "TotalDownloads", .readable_name = QObject::tr("Sort by Downloads") }, - { .index = 7, .name = "Category", .readable_name = QObject::tr("Sort by Category") }, - { .index = 8, .name = "GameVersion", .readable_name = QObject::tr("Sort by Game Version") } }; + return { { .index = 1, .name = "Featured", .readableName = QObject::tr("Sort by Featured") }, + { .index = 2, .name = "Popularity", .readableName = QObject::tr("Sort by Popularity") }, + { .index = 3, .name = "LastUpdated", .readableName = QObject::tr("Sort by Last Updated") }, + { .index = 4, .name = "Name", .readableName = QObject::tr("Sort by Name") }, + { .index = 5, .name = "Author", .readableName = QObject::tr("Sort by Author") }, + { .index = 6, .name = "TotalDownloads", .readableName = QObject::tr("Sort by Downloads") }, + { .index = 7, .name = "Category", .readableName = QObject::tr("Sort by Category") }, + { .index = 8, .name = "GameVersion", .readableName = QObject::tr("Sort by Game Version") } }; } namespace { @@ -205,7 +203,7 @@ std::pair FlameAPI::getCategories(ModPlatform::ResourceT auto [action, response] = Net::ApiDownload::makeByteArray( QUrl(QString(BuildConfig.FLAME_BASE_URL + "/categories?gameId=432&classId=%1").arg(getClassId(type)))); netJob->addNetAction(action); - QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Flame failed to get categories:" << msg; }); + QObject::connect(netJob.get(), &Task::failed, [](const QString& msg) { qDebug() << "Flame failed to get categories:" << msg; }); return { netJob, response }; } @@ -217,11 +215,10 @@ std::pair FlameAPI::getModCategories() QList FlameAPI::loadModCategories(const QByteArray& response) { QList categories; - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from categories at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from categories at" << parseError.offset << "reason:" << parseError.errorString(); qWarning() << *response; return categories; } @@ -245,17 +242,17 @@ QList FlameAPI::loadModCategories(const QByteArray& respo return categories; }; -std::optional FlameAPI::getLatestVersion(QList versions, - QList instanceLoaders, - ModPlatform::ModLoaderTypes modLoaders, +std::optional FlameAPI::getLatestVersion(const QList& versions, + const QList& instanceLoaders, + ModPlatform::ModLoaderTypes fallback, bool checkLoaders) { - static const auto noLoader = ModPlatform::ModLoaderType(0); + static const auto s_noLoader = ModPlatform::ModLoaderType(0); if (!checkLoaders) { std::optional ver; - for (auto file_tmp : versions) { - if (!ver.has_value() || file_tmp.date > ver->date) { - ver = file_tmp; + for (const auto& fileTmp : versions) { + if (!ver.has_value() || fileTmp.date > ver->date) { + ver = fileTmp; } } return ver; @@ -271,26 +268,26 @@ std::optional FlameAPI::getLatestVersion(QList fabric version will be prioritizated on update - auto currentLoaders = instanceLoaders + ModPlatform::modLoaderTypesToList(modLoaders); - currentLoaders.append(noLoader); // add a fallback in case the versions do not define a loader + auto currentLoaders = instanceLoaders + ModPlatform::modLoaderTypesToList(fallback); + currentLoaders.append(s_noLoader); // add a fallback in case the versions do not define a loader for (auto loader : currentLoaders) { if (bestMatch.contains(loader)) { auto bestForLoader = bestMatch.value(loader); // awkward case where the mod has only two loaders and one of them is not specified - if (loader != noLoader && bestMatch.contains(noLoader) && bestMatch.size() == 2) { - auto bestForNoLoader = bestMatch.value(noLoader); + if (loader != s_noLoader && bestMatch.contains(s_noLoader) && bestMatch.size() == 2) { + auto bestForNoLoader = bestMatch.value(s_noLoader); if (bestForNoLoader.date > bestForLoader.date) { return bestForNoLoader; } diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 9faf97967..0b5d91937 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -4,10 +4,12 @@ #pragma once +#include +#include +#include #include #include #include "BuildConfig.h" -#include "Json.h" #include "Version.h" #include "modplatform/ModIndex.h" #include "modplatform/ResourceAPI.h" @@ -15,18 +17,18 @@ class FlameAPI : public ResourceAPI { public: - QString getModFileChangelog(int modId, int fileId); - QString getModDescription(int modId); + static QString getModFileChangelog(int modId, int fileId); + static QString getModDescription(int modId); - std::optional getLatestVersion(QList versions, - QList instanceLoaders, - ModPlatform::ModLoaderTypes fallback, - bool checkLoaders); + static std::optional getLatestVersion(const QList& versions, + const QList& instanceLoaders, + ModPlatform::ModLoaderTypes fallback, + bool checkLoaders); std::pair getProjects(QStringList addonIds) const override; - std::pair matchFingerprints(const QList& fingerprints); - std::pair getFiles(const QStringList& fileIds) const; - std::pair getFile(const QString& addonId, const QString& fileId) const; + static std::pair matchFingerprints(const QList& fingerprints); + static std::pair getFiles(const QStringList& fileIds); + static std::pair getFile(const QString& addonId, const QString& fileId); static std::pair getCategories(ModPlatform::ResourceType type); static std::pair getModCategories(); @@ -34,9 +36,9 @@ class FlameAPI : public ResourceAPI { QList getSortingMethods() const override; - static inline bool validateModLoaders(ModPlatform::ModLoaderTypes loaders) + static bool validateModLoaders(ModPlatform::ModLoaderTypes loaders) { - return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt); + return (loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt)) != 0; } static ModPlatform::ResourceType getResourceType(int classId); @@ -71,44 +73,49 @@ class FlameAPI : public ResourceAPI { return 0; } - static const QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types) + static QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types) { QStringList l; for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt }) { - if (types & loader) { + if ((types & loader) != 0) { l << QString::number(getMappedModLoader(loader)); } } return l; } - static const QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; } + static QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; } public: std::optional getSearchURL(const SearchArgs& args) const override { - QStringList get_arguments; - get_arguments.append(QString("classId=%1").arg(getClassId(args.type))); - get_arguments.append(QString("index=%1").arg(args.offset)); - get_arguments.append("pageSize=25"); - if (args.search.has_value()) - get_arguments.append(QString("searchFilter=%1").arg(args.search.value())); - if (args.sorting.has_value()) - get_arguments.append(QString("sortField=%1").arg(args.sorting.value().index)); - get_arguments.append("sortOrder=desc"); + QStringList getArguments; + getArguments.append(QString("classId=%1").arg(getClassId(args.type))); + getArguments.append(QString("index=%1").arg(args.offset)); + getArguments.append("pageSize=25"); + if (args.search.has_value()) { + getArguments.append(QString("searchFilter=%1").arg(args.search.value())); + } + if (args.sorting.has_value()) { + getArguments.append(QString("sortField=%1").arg(args.sorting.value().index)); + } + getArguments.append("sortOrder=desc"); if (args.loaders.has_value()) { ModPlatform::ModLoaderTypes loaders = args.loaders.value(); loaders &= ~static_cast(ModPlatform::ModLoaderType::DataPack); - if (loaders != 0) - get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(loaders))); + if (loaders != 0) { + getArguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(loaders))); + } + } + if (args.categoryIds.has_value() && !args.categoryIds->empty()) { + getArguments.append(QString("categoryIds=[%1]").arg(args.categoryIds->join(","))); } - if (args.categoryIds.has_value() && !args.categoryIds->empty()) - get_arguments.append(QString("categoryIds=[%1]").arg(args.categoryIds->join(","))); - if (args.versions.has_value() && !args.versions.value().empty()) - get_arguments.append(QString("gameVersion=%1").arg(args.versions.value().front().toString())); + if (args.versions.has_value() && !args.versions.value().empty()) { + getArguments.append(QString("gameVersion=%1").arg(args.versions.value().front().toString())); + } - return BuildConfig.FLAME_BASE_URL + "/mods/search?gameId=432&" + get_arguments.join('&'); + return BuildConfig.FLAME_BASE_URL + "/mods/search?gameId=432&" + getArguments.join('&'); } std::optional getVersionsURL(const VersionSearchArgs& args) const override @@ -116,8 +123,9 @@ class FlameAPI : public ResourceAPI { auto addonId = args.pack->addonId.toString(); QString url = QString(BuildConfig.FLAME_BASE_URL + "/mods/%1/files?pageSize=10000").arg(addonId); - if (args.mcVersions.has_value()) + if (args.mcVersions.has_value()) { url += QString("&gameVersion=%1").arg(args.mcVersions.value().front().toString()); + } if (args.loaders.has_value() && args.loaders.value() != ModPlatform::ModLoaderType::DataPack && ModPlatform::hasSingleModLoaderSelected(args.loaders.value())) { @@ -136,15 +144,15 @@ class FlameAPI : public ResourceAPI { return arr; } // FIXME: Client-side version filtering. This won't take into account any user-selected filtering. - const auto& mc_versions = arr.mcVersion; + const auto& mcVersions = arr.mcVersion; - if (std::any_of(mc_versions.constBegin(), mc_versions.constEnd(), - [](const auto& mc_version) { return Version(mc_version) <= Version("1.6"); })) { + if (std::any_of(mcVersions.constBegin(), mcVersions.constEnd(), + [](const auto& mcVersion) { return Version(mcVersion) <= Version("1.6"); })) { return arr; } return {}; }; - void loadExtraPackInfo(ModPlatform::IndexedPack& m, [[maybe_unused]] QJsonObject&) const override { FlameMod::loadBody(m); } + void loadExtraPackInfo(ModPlatform::IndexedPack& m, [[maybe_unused]] QJsonObject& /*unused*/) const override { FlameMod::loadBody(m); } private: std::optional getInfoURL(const QString& id) const override { return QString(BuildConfig.FLAME_BASE_URL + "/mods/%1").arg(id); } @@ -153,7 +161,7 @@ class FlameAPI : public ResourceAPI { auto addonId = args.dependency.addonId.toString(); auto url = QString(BuildConfig.FLAME_BASE_URL + "/mods/%1/files?pageSize=10000&gameVersion=%2").arg(addonId, args.mcVersion.toString()); - if (args.loader && ModPlatform::hasSingleModLoaderSelected(args.loader)) { + if ((args.loader != 0U) && ModPlatform::hasSingleModLoaderSelected(args.loader)) { int mappedModLoader = getMappedModLoader(static_cast(static_cast(args.loader))); url += QString("&modLoaderType=%1").arg(mappedModLoader); } diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index 577f9967a..fd1418ee1 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.cpp +++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp @@ -122,7 +122,7 @@ void FlameCheckUpdate::getLatestVersionCallback(Resource* resource, QByteArray* } auto downloadTask = makeShared(pack, latestVer.value(), m_resourceModel, true, "update"); - m_updates.emplace_back(pack->name, resource->metadata()->hash, oldVersion, latestVer->version, latestVer->version_type, + m_updates.emplace_back(pack->name, resource->metadata()->hash, oldVersion, latestVer->version, latestVer->versionType, FlameAPI().getModFileChangelog(latestVer->addonId.toInt(), latestVer->fileId.toInt()), ModPlatform::ResourceProvider::FLAME, downloadTask, resource->enabled()); } diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index f4d11a5ce..67d3bbf70 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -55,13 +55,13 @@ #include "settings/INISettingsObject.h" -#include "SysInfo.h" #include "tasks/ConcurrentTask.h" #include "ui/dialogs/BlockedModsDialog.h" #include "ui/dialogs/CustomMessageBox.h" #include #include +#include #include "HardwareInfo.h" #include "meta/Index.h" @@ -70,163 +70,170 @@ #include "net/ApiDownload.h" #include "ui/pages/modplatform/OptionalModDialog.h" -static const FlameAPI api; - bool FlameCreationTask::abort() { - if (!canAbort()) + if (!canAbort()) { return false; + } - if (m_processUpdateFileInfoJob) + if (m_processUpdateFileInfoJob) { m_processUpdateFileInfoJob->abort(); - if (m_filesJob) + } + if (m_filesJob) { m_filesJob->abort(); - if (m_modIdResolver) + } + if (m_modIdResolver) { m_modIdResolver->abort(); + } return InstanceCreationTask::abort(); } bool FlameCreationTask::updateInstance() { - auto instance_list = APPLICATION->instances(); + auto* instanceList = APPLICATION->instances(); // FIXME: How to handle situations when there's more than one install already for a given modpack? - BaseInstance* inst; - if (auto original_id = originalInstanceID(); !original_id.isEmpty()) { - inst = instance_list->getInstanceById(original_id); + BaseInstance* inst = nullptr; + if (auto originalId = originalInstanceID(); !originalId.isEmpty()) { + inst = instanceList->getInstanceById(originalId); Q_ASSERT(inst); } else { - inst = instance_list->getInstanceByManagedName(originalName()); + inst = instanceList->getInstanceByManagedName(originalName()); if (!inst) { - inst = instance_list->getInstanceById(originalName()); + inst = instanceList->getInstanceById(originalName()); - if (!inst) + if (!inst) { return false; + } } } - QString index_path(FS::PathCombine(m_stagingPath, "manifest.json")); + QString indexPath(FS::PathCombine(m_stagingPath, "manifest.json")); try { - Flame::loadManifest(m_pack, index_path); + Flame::loadManifest(m_pack, indexPath); } catch (const JSONValidationError& e) { setError(tr("Could not understand pack manifest:\n") + e.cause()); return false; } - auto version_id = inst->getManagedPackVersionName(); - auto version_str = !version_id.isEmpty() ? tr(" (version %1)").arg(version_id) : ""; + auto versionId = inst->getManagedPackVersionName(); + auto versionStr = !versionId.isEmpty() ? tr(" (version %1)").arg(versionId) : ""; if (shouldConfirmUpdate()) { - auto should_update = askIfShouldUpdate(m_parent, version_str); - if (should_update == ShouldUpdate::SkipUpdating) + auto shouldUpdate = askIfShouldUpdate(m_parent, versionStr); + if (shouldUpdate == ShouldUpdate::SkipUpdating) { return false; - if (should_update == ShouldUpdate::Cancel) { + } + if (shouldUpdate == ShouldUpdate::Cancel) { m_abort = true; return false; } } - QDir old_inst_dir(inst->instanceRoot()); + QDir oldInstDir(inst->instanceRoot()); - QString old_index_folder(FS::PathCombine(old_inst_dir.absolutePath(), "flame")); - QString old_index_path(FS::PathCombine(old_index_folder, "manifest.json")); + QString oldIndexFolder(FS::PathCombine(oldInstDir.absolutePath(), "flame")); + QString oldIndexPath(FS::PathCombine(oldIndexFolder, "manifest.json")); - QFileInfo old_index_file(old_index_path); - if (old_index_file.exists()) { - Flame::Manifest old_pack; - Flame::loadManifest(old_pack, old_index_path); + QFileInfo oldIndexFile(oldIndexPath); + if (oldIndexFile.exists()) { + Flame::Manifest oldPack; + Flame::loadManifest(oldPack, oldIndexPath); - auto& old_files = old_pack.files; + auto& oldFiles = oldPack.files; auto& files = m_pack.files; // Remove repeated files, we don't need to download them! - auto files_iterator = files.begin(); - while (files_iterator != files.end()) { - const auto& file = files_iterator; + auto filesIterator = files.begin(); + while (filesIterator != files.end()) { + const auto& file = filesIterator; - auto old_file = old_files.find(file.key()); - if (old_file != old_files.end()) { + auto oldFile = oldFiles.find(file.key()); + if (oldFile != oldFiles.end()) { // We found a match, but is it a different version? - if (old_file->fileId == file->fileId) { + if (oldFile->fileId == file->fileId) { qDebug() << "Removed file at" << file->targetFolder << "with id" << file->fileId << "from list of downloads"; - old_files.remove(file.key()); - files_iterator = files.erase(files_iterator); + oldFiles.remove(file.key()); + filesIterator = files.erase(filesIterator); - if (files_iterator != files.begin()) - files_iterator--; + if (filesIterator != files.begin()) { + filesIterator--; + } } } - files_iterator++; + filesIterator++; } - QDir old_minecraft_dir(inst->gameRoot()); + QDir oldMinecraftDir(inst->gameRoot()); // We will remove all the previous overrides, to prevent duplicate files! // TODO: Currently 'overrides' will always override the stuff on update. How do we preserve unchanged overrides? // FIXME: We may want to do something about disabled mods. - auto old_overrides = Override::readOverrides("overrides", old_index_folder); - for (const auto& entry : old_overrides) { - scheduleToDelete(m_parent, old_minecraft_dir, entry); + auto oldOverrides = Override::readOverrides("overrides", oldIndexFolder); + for (const auto& entry : oldOverrides) { + scheduleToDelete(m_parent, oldMinecraftDir, entry); } // Remove remaining old files (we need to do an API request to know which ids are which files...) QStringList fileIds; - for (auto& file : old_files) { + for (auto& file : oldFiles) { fileIds.append(QString::number(file.fileId)); } - auto [job, raw_response] = api.getFiles(fileIds); + auto [job, rawResponse] = FlameAPI::getFiles(fileIds); QEventLoop loop; - connect(job.get(), &Task::succeeded, this, [this, raw_response, fileIds, old_inst_dir, &old_files, old_minecraft_dir] { + connect(job.get(), &Task::succeeded, this, [this, rawResponse, fileIds, oldInstDir, &oldFiles, oldMinecraftDir] { // Parse the API response - QJsonParseError parse_error{}; - auto doc = QJsonDocument::fromJson(*raw_response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame files task at" << parse_error.offset - << "reason:" << parse_error.errorString(); - qWarning() << *raw_response; + QJsonParseError parseError{}; + auto doc = QJsonDocument::fromJson(*rawResponse, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame files task at" << parseError.offset + << "reason:" << parseError.errorString(); + qWarning() << *rawResponse; return; } try { QJsonArray entries; - if (fileIds.size() == 1) + if (fileIds.size() == 1) { entries = { Json::requireObject(Json::requireObject(doc), "data") }; - else + } else { entries = Json::requireArray(Json::requireObject(doc), "data"); + } for (auto entry : entries) { - auto entry_obj = Json::requireObject(entry); + auto entryObj = Json::requireObject(entry); Flame::File file; // We don't care about blocked mods, we just need local data to delete the file - file.version = FlameMod::loadIndexedPackVersion(entry_obj); - auto id = Json::requireInteger(entry_obj, "id"); - old_files.insert(id, file); + file.version = FlameMod::loadIndexedPackVersion(entryObj); + auto id = Json::requireInteger(entryObj, "id"); + oldFiles.insert(id, file); } } catch (Json::JsonException& e) { qCritical() << e.cause() << e.what(); } // Delete the files - for (auto& file : old_files) { - if (file.version.fileName.isEmpty() || file.targetFolder.isEmpty()) + for (auto& file : oldFiles) { + if (file.version.fileName.isEmpty() || file.targetFolder.isEmpty()) { continue; + } - QString relative_path(FS::PathCombine(file.targetFolder, file.version.fileName)); - scheduleToDelete(m_parent, old_minecraft_dir, relative_path, true); + QString relativePath(FS::PathCombine(file.targetFolder, file.version.fileName)); + scheduleToDelete(m_parent, oldMinecraftDir, relativePath, true); } }); - connect(job.get(), &Task::failed, this, [](QString reason) { qCritical() << "Failed to get files:" << reason; }); + connect(job.get(), &Task::failed, this, [](const QString& reason) { qCritical() << "Failed to get files:" << reason; }); connect(job.get(), &Task::finished, &loop, &QEventLoop::quit); m_processUpdateFileInfoJob = job; @@ -237,10 +244,10 @@ bool FlameCreationTask::updateInstance() m_processUpdateFileInfoJob = nullptr; } else { // We don't have an old index file, so we may duplicate stuff! - auto dialog = CustomMessageBox::selectable(m_parent, tr("No index file."), - tr("We couldn't find a suitable index file for the older version. This may cause some " - "of the files to be duplicated. Do you want to continue?"), - QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); + auto* dialog = CustomMessageBox::selectable(m_parent, tr("No index file."), + tr("We couldn't find a suitable index file for the older version. This may cause some " + "of the files to be duplicated. Do you want to continue?"), + QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Cancel); if (dialog->exec() == QDialog::DialogCode::Rejected) { m_abort = true; @@ -257,7 +264,10 @@ bool FlameCreationTask::updateInstance() return false; } -QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QString loaderVersion, QString mcVersion) +QString FlameCreationTask::getVersionForLoader(const QString& uid, + const QString& loaderType, + QString loaderVersion, + const QString& mcVersion) { if (loaderVersion == "recommended") { auto vlist = APPLICATION->metadataIndex()->get(uid); @@ -270,27 +280,29 @@ QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QEventLoop loadVersionLoop; auto task = vlist->getLoadTask(); connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit); - if (!task->isRunning()) + if (!task->isRunning()) { task->start(); + } loadVersionLoop.exec(); } - for (auto version : vlist->versions()) { + for (const auto& version : vlist->versions()) { // first recommended build we find, we use. - if (!version->isRecommended()) + if (!version->isRecommended()) { continue; + } auto reqs = version->requiredSet(); // filter by minecraft version, if the loader depends on a certain version. // not all mod loaders depend on a given Minecraft version, so we won't do this // filtering for those loaders. if (loaderType == "forge" || loaderType == "neoforge") { - auto iter = std::find_if(reqs.begin(), reqs.end(), [mcVersion](const Meta::Require& req) { - return req.uid == "net.minecraft" && req.equalsVersion == mcVersion; - }); - if (iter == reqs.end()) + auto iter = std::ranges::find_if( + reqs, [mcVersion](const Meta::Require& req) { return req.uid == "net.minecraft" && req.equalsVersion == mcVersion; }); + if (iter == reqs.end()) { continue; + } } return version->descriptor(); } @@ -311,17 +323,18 @@ std::unique_ptr FlameCreationTask::createInstance() { QEventLoop loop; - QString parent_folder(FS::PathCombine(m_stagingPath, "flame")); + QString parentFolder(FS::PathCombine(m_stagingPath, "flame")); try { - QString index_path(FS::PathCombine(m_stagingPath, "manifest.json")); - if (!m_pack.is_loaded) - Flame::loadManifest(m_pack, index_path); + QString indexPath(FS::PathCombine(m_stagingPath, "manifest.json")); + if (!m_pack.isLoaded) { + Flame::loadManifest(m_pack, indexPath); + } // Keep index file in case we need it some other time (like when changing versions) - QString new_index_place(FS::PathCombine(parent_folder, "manifest.json")); - FS::ensureFilePathExists(new_index_place); - FS::move(index_path, new_index_place); + QString newIndexPlace(FS::PathCombine(parentFolder, "manifest.json")); + FS::ensureFilePathExists(newIndexPlace); + FS::move(indexPath, newIndexPlace); } catch (const JSONValidationError& e) { setError(tr("Could not understand pack manifest:\n") + e.cause()); @@ -332,7 +345,7 @@ std::unique_ptr FlameCreationTask::createInstance() QString overridePath = FS::PathCombine(m_stagingPath, m_pack.overrides); if (QFile::exists(overridePath)) { // Create a list of overrides in "overrides.txt" inside flame/ - Override::createOverrides("overrides", parent_folder, overridePath); + Override::createOverrides("overrides", parentFolder, overridePath); QString mcPath = FS::PathCombine(m_stagingPath, "minecraft"); if (!FS::move(overridePath, mcPath)) { @@ -353,8 +366,9 @@ std::unique_ptr FlameCreationTask::createInstance() auto id = loader.id; if (id.startsWith("neoforge-")) { id.remove("neoforge-"); - if (id.startsWith("1.20.1-")) + if (id.startsWith("1.20.1-")) { id.remove("1.20.1-"); // this is a mess for curseforge + } loaderType = "neoforge"; loaderUid = "net.neoforged"; } else if (id.startsWith("forge-")) { @@ -388,13 +402,14 @@ std::unique_ptr FlameCreationTask::createInstance() logWarning(tr("Mysterious trailing dots removed from Minecraft version while importing pack.")); } - auto components = instance->getPackProfile(); + auto* components = instance->getPackProfile(); components->buildingFromScratch(); components->setComponentVersion("net.minecraft", mcVersion, true); if (!loaderType.isEmpty()) { auto version = getVersionForLoader(loaderUid, loaderType, loaderVersion, mcVersion); - if (version.isEmpty()) + if (version.isEmpty()) { return nullptr; + } components->setComponentVersion(loaderUid, version); } @@ -415,13 +430,13 @@ std::unique_ptr FlameCreationTask::createInstance() // only set memory if this is a fresh instance if (!m_instance && recommendedRAM > 0) { const uint64_t sysMiB = HardwareInfo::totalRamMiB(); - const uint64_t max = sysMiB * 0.9; + const auto max = sysMiB * 9 / 10; if (static_cast(recommendedRAM) > max) { logWarning(tr("The recommended memory of the modpack exceeds 90% of your system RAM—reducing it from %1 MiB to %2 MiB!") .arg(recommendedRAM) .arg(max)); - recommendedRAM = max; + recommendedRAM = static_cast(max); } instance->settings()->set("OverrideMemory", true); @@ -439,23 +454,24 @@ std::unique_ptr FlameCreationTask::createInstance() qDebug() << info.fileName(); jarMods.push_back(info.absoluteFilePath()); } - auto profile = instance->getPackProfile(); + auto* profile = instance->getPackProfile(); profile->installJarMods(jarMods); // nuke the original files FS::deletePath(jarmodsPath); } // Don't add managed info to packs without an ID (most likely imported from ZIP) - if (!m_managedId.isEmpty()) + if (!m_managedId.isEmpty()) { instance->setManagedPack("flame", m_managedId, m_pack.name, m_managedVersionId, m_pack.version); - else + } else { instance->setManagedPack("flame", "", name(), "", ""); + } instance->setName(name()); m_modIdResolver.reset(new Flame::FileResolvingTask(m_pack)); connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, this, [this, &loop] { idResolverSucceeded(loop); }); - connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [this, &loop](QString reason) { + connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [this, &loop](const QString& reason) { m_modIdResolver.reset(); setError(tr("Unable to resolve mod IDs:\n") + reason); loop.quit(); @@ -469,17 +485,17 @@ std::unique_ptr FlameCreationTask::createInstance() loop.exec(); - bool did_succeed = getError().isEmpty(); + bool didSucceed = getError().isEmpty(); // Update information of the already installed instance, if any. - if (m_instance && did_succeed) { + if (m_instance && didSucceed) { setAbortable(false); - auto inst = m_instance.value(); + auto* inst = *m_instance; inst->copyManagedPack(*instance); } - if (did_succeed) { + if (didSucceed) { return instance; } return nullptr; @@ -508,7 +524,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) } // first check for blocked mods - QList blocked_mods; + QList blockedMods; auto anyBlocked = false; for (const auto& result : results.values()) { if (result.pack.resourceType != ModPlatform::ResourceType::Mod) { @@ -517,19 +533,19 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) // skip optional mods that were not selected if (result.version.downloadUrl.isEmpty()) { - BlockedMod blocked_mod; - blocked_mod.name = result.version.fileName; - blocked_mod.websiteUrl = QString("%1/download/%2").arg(result.pack.websiteUrl, QString::number(result.fileId)); - blocked_mod.hash = result.version.hash; - blocked_mod.matched = false; - blocked_mod.localPath = ""; - blocked_mod.targetFolder = result.targetFolder; + BlockedMod blockedMod; + blockedMod.name = result.version.fileName; + blockedMod.websiteUrl = QString("%1/download/%2").arg(result.pack.websiteUrl, QString::number(result.fileId)); + blockedMod.hash = result.version.hash; + blockedMod.matched = false; + blockedMod.localPath = ""; + blockedMod.targetFolder = result.targetFolder; auto fileName = result.version.fileName; fileName = FS::RemoveInvalidPathChars(fileName); auto relpath = FS::PathCombine(result.targetFolder, fileName); - blocked_mod.disabled = !result.required && !m_selectedOptionalMods.contains(relpath); + blockedMod.disabled = !result.required && !m_selectedOptionalMods.contains(relpath); - blocked_mods.append(blocked_mod); + blockedMods.append(blockedMod); anyBlocked = true; } @@ -537,16 +553,16 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) if (anyBlocked) { qWarning() << "Blocked mods found, displaying mod list"; - BlockedModsDialog message_dialog(m_parent, tr("Blocked mods found"), - tr("The following files are not available for download in third party launchers.
" - "You will need to manually download them and add them to the instance."), - blocked_mods); + BlockedModsDialog messageDialog(m_parent, tr("Blocked mods found"), + tr("The following files are not available for download in third party launchers.
" + "You will need to manually download them and add them to the instance."), + blockedMods); - message_dialog.setModal(true); + messageDialog.setModal(true); - if (message_dialog.exec()) { - qDebug() << "Post dialog blocked mods list:" << blocked_mods; - copyBlockedMods(blocked_mods); + if (messageDialog.exec() != 0) { + qDebug() << "Post dialog blocked mods list:" << blockedMods; + copyBlockedMods(blockedMods); setupDownloadJob(loop); } else { m_modIdResolver.reset(); @@ -586,7 +602,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) m_filesJob.reset(); validateOtherResources(loop); }); - connect(m_filesJob.get(), &NetJob::failed, [this](QString reason) { + connect(m_filesJob.get(), &NetJob::failed, [this](const QString& reason) { m_filesJob.reset(); setError(reason); }); @@ -602,22 +618,23 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) /// @brief copy the matched blocked mods to the instance staging area /// @param blocked_mods list of the blocked mods and their matched paths -void FlameCreationTask::copyBlockedMods(const QList& blocked_mods) +void FlameCreationTask::copyBlockedMods(const QList& blockedMods) { setStatus(tr("Copying Blocked Mods...")); setAbortable(false); int i = 0; - int total = blocked_mods.length(); + auto total = blockedMods.length(); setProgress(i, total); - for (const auto& mod : blocked_mods) { + for (const auto& mod : blockedMods) { if (!mod.matched) { qDebug() << mod.name << "was not matched to a local file, skipping copy"; continue; } auto destPath = FS::PathCombine(m_stagingPath, "minecraft", mod.targetFolder, mod.name); - if (mod.disabled) + if (mod.disabled) { destPath += ".disabled"; + } setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); @@ -644,13 +661,13 @@ void FlameCreationTask::validateOtherResources(QEventLoop& loop) { qDebug() << "Validating whether other resources are in the right place"; QStringList zipMods; - for (auto [fileName, targetFolder] : m_otherResources) { + for (const auto& [fileName, targetFolder] : m_otherResources) { qDebug() << "Checking" << fileName << "..."; auto localPath = FS::PathCombine(m_stagingPath, "minecraft", targetFolder, fileName); /// @brief check the target and move the the file /// @return path where file can now be found - auto validatePath = [&localPath, this](QString fileName, QString targetFolder, QString realTarget) { + auto validatePath = [&localPath, this](const QString& fileName, const QString& targetFolder, const QString& realTarget) { if (targetFolder != realTarget) { qDebug() << "Target folder of" << fileName << "is incorrect, it belongs in" << realTarget; auto destPath = FS::PathCombine(m_stagingPath, "minecraft", realTarget, fileName); @@ -664,7 +681,7 @@ void FlameCreationTask::validateOtherResources(QEventLoop& loop) return localPath; }; - auto installWorld = [this](QString worldPath) { + auto installWorld = [this](const QString& worldPath) { qDebug() << "Installing World from" << worldPath; QFileInfo worldFileInfo(worldPath); World w(worldFileInfo); @@ -714,7 +731,7 @@ void FlameCreationTask::validateOtherResources(QEventLoop& loop) auto task = makeShared("CreateModMetadata", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); auto results = m_modIdResolver->getResults().files; auto folder = FS::PathCombine(m_stagingPath, "minecraft", "mods", ".index"); - for (auto file : results) { + for (const auto& file : results) { if (file.targetFolder != "mods" || (file.version.fileName.endsWith(".zip") && !zipMods.contains(file.version.fileName))) { continue; } diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h index 221ceaf22..42eb272a2 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.h +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h @@ -51,18 +51,18 @@ class FlameCreationTask final : public InstanceCreationTask { Q_OBJECT public: - FlameCreationTask(const QString& staging_path, - SettingsObject* global_settings, + FlameCreationTask(const QString& stagingPath, + SettingsObject* globalSettings, QWidget* parent, QString id, - QString version_id, - QString original_instance_id = {}) - : InstanceCreationTask(), m_parent(parent), m_managedId(std::move(id)), m_managedVersionId(std::move(version_id)) + QString versionId, + QString originalInstanceId = {}) + : m_parent(parent), m_managedId(std::move(id)), m_managedVersionId(std::move(versionId)) { - setStagingPath(staging_path); - setParentSettings(global_settings); + setStagingPath(stagingPath); + setParentSettings(globalSettings); - m_original_instance_id = std::move(original_instance_id); + m_original_instance_id = std::move(originalInstanceId); } bool abort() override; @@ -73,9 +73,9 @@ class FlameCreationTask final : public InstanceCreationTask { private slots: void idResolverSucceeded(QEventLoop&); void setupDownloadJob(QEventLoop&); - void copyBlockedMods(QList const& blocked_mods); + void copyBlockedMods(const QList& blockedMods); void validateOtherResources(QEventLoop& loop); - QString getVersionForLoader(QString uid, QString loaderType, QString version, QString mcVersion); + QString getVersionForLoader(const QString& uid, const QString& loaderType, QString version, const QString& mcVersion); private: QWidget* m_parent = nullptr; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 06e2a64f7..67227053e 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -1,14 +1,12 @@ #include "FlameModIndex.h" +#include + #include "FileSystem.h" #include "Json.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" #include "modplatform/ModIndex.h" #include "modplatform/flame/FlameAPI.h" -static FlameAPI api; - void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) { pack.addonId = Json::requireInteger(obj, "id"); @@ -44,35 +42,41 @@ void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj) { - auto links_obj = obj["links"].toObject(); + auto linksObj = obj["links"].toObject(); - pack.extraData.issuesUrl = links_obj["issuesUrl"].toString(); - if (pack.extraData.issuesUrl.endsWith('/')) + pack.extraData.issuesUrl = linksObj["issuesUrl"].toString(); + if (pack.extraData.issuesUrl.endsWith('/')) { pack.extraData.issuesUrl.chop(1); + } - pack.extraData.sourceUrl = links_obj["sourceUrl"].toString(); - if (pack.extraData.sourceUrl.endsWith('/')) + pack.extraData.sourceUrl = linksObj["sourceUrl"].toString(); + if (pack.extraData.sourceUrl.endsWith('/')) { pack.extraData.sourceUrl.chop(1); + } - pack.extraData.wikiUrl = links_obj["wikiUrl"].toString(); - if (pack.extraData.wikiUrl.endsWith('/')) + pack.extraData.wikiUrl = linksObj["wikiUrl"].toString(); + if (pack.extraData.wikiUrl.endsWith('/')) { pack.extraData.wikiUrl.chop(1); + } - if (!pack.extraData.body.isEmpty()) + if (!pack.extraData.body.isEmpty()) { pack.extraDataLoaded = true; + } } void FlameMod::loadBody(ModPlatform::IndexedPack& pack) { - pack.extraData.body = api.getModDescription(pack.addonId.toInt()); + pack.extraData.body = FlameAPI::getModDescription(pack.addonId.toInt()); - if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty()) + if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty()) { pack.extraDataLoaded = true; + } } -static QString enumToString(int hash_algorithm) +namespace { +QString enumToString(int hashAlgorithm) { - switch (hash_algorithm) { + switch (hashAlgorithm) { default: case 1: return "sha1"; @@ -80,6 +84,7 @@ static QString enumToString(int hash_algorithm) return "md5"; } } +} // namespace void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr) { @@ -88,23 +93,25 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArra auto obj = versionIter.toObject(); auto file = loadIndexedPackVersion(obj); - if (!file.addonId.isValid()) + if (!file.addonId.isValid()) { file.addonId = pack.addonId; + } - if (file.fileId.isValid()) // Heuristic to check if the returned value is valid + if (file.fileId.isValid()) { // Heuristic to check if the returned value is valid unsortedVersions.append(file); + } } auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { // dates are in RFC 3339 format return a.date > b.date; }; - std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + std::ranges::sort(unsortedVersions, orderSortPredicate); pack.versions = unsortedVersions; pack.versionsLoaded = true; } -auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> ModPlatform::IndexedVersion +auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool loadChangelog) -> ModPlatform::IndexedVersion { auto versionArray = Json::requireArray(obj, "gameVersions"); @@ -112,27 +119,29 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> for (auto mcVer : versionArray) { auto str = mcVer.toString(); - if (str.contains('.')) + if (str.contains('.')) { file.mcVersion.append(str); + } file.side = ModPlatform::Side::NoSide; - if (auto loader = str.toLower(); loader == "neoforge") + if (auto loader = str.toLower(); loader == "neoforge") { file.loaders |= ModPlatform::NeoForge; - else if (loader == "forge") + } else if (loader == "forge") { file.loaders |= ModPlatform::Forge; - else if (loader == "cauldron") + } else if (loader == "cauldron") { file.loaders |= ModPlatform::Cauldron; - else if (loader == "liteloader") + } else if (loader == "liteloader") { file.loaders |= ModPlatform::LiteLoader; - else if (loader == "fabric") + } else if (loader == "fabric") { file.loaders |= ModPlatform::Fabric; - else if (loader == "quilt") + } else if (loader == "quilt") { file.loaders |= ModPlatform::Quilt; - else if (loader == "server" || loader == "client") { - if (file.side == ModPlatform::Side::NoSide) + } else if (loader == "server" || loader == "client") { + if (file.side == ModPlatform::Side::NoSide) { file.side = ModPlatform::SideUtils::fromString(loader); - else if (file.side != ModPlatform::SideUtils::fromString(loader)) + } else if (file.side != ModPlatform::SideUtils::fromString(loader)) { file.side = ModPlatform::Side::UniversalSide; + } } } @@ -144,31 +153,31 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> file.fileName = Json::requireString(obj, "fileName"); file.fileName = FS::RemoveInvalidPathChars(file.fileName); - ModPlatform::IndexedVersionType ver_type; + ModPlatform::IndexedVersionType verType; switch (Json::requireInteger(obj, "releaseType")) { case 1: - ver_type = ModPlatform::IndexedVersionType::Release; + verType = ModPlatform::IndexedVersionType::Release; break; case 2: - ver_type = ModPlatform::IndexedVersionType::Beta; + verType = ModPlatform::IndexedVersionType::Beta; break; case 3: - ver_type = ModPlatform::IndexedVersionType::Alpha; + verType = ModPlatform::IndexedVersionType::Alpha; break; default: - ver_type = ModPlatform::IndexedVersionType::Unknown; + verType = ModPlatform::IndexedVersionType::Unknown; break; } - file.version_type = ver_type; + file.versionType = verType; - auto hash_list = obj["hashes"].toArray(); - for (auto h : hash_list) { - auto hash_entry = h.toObject(); - auto hash_types = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::FLAME); - auto hash_algo = enumToString(hash_entry["algo"].toInt(1)); - if (hash_types.contains(hash_algo)) { - file.hash = Json::requireString(hash_entry, "value"); - file.hash_type = hash_algo; + auto hashList = obj["hashes"].toArray(); + for (auto h : hashList) { + auto hashEntry = h.toObject(); + auto hashTypes = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::FLAME); + auto hashAlgo = enumToString(hashEntry["algo"].toInt(1)); + if (hashTypes.contains(hashAlgo)) { + file.hash = Json::requireString(hashEntry, "value"); + file.hashType = hashAlgo; break; } } @@ -204,8 +213,9 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> file.dependencies.append(dependency); } - if (load_changelog) - file.changelog = api.getModFileChangelog(file.addonId.toInt(), file.fileId.toInt()); + if (loadChangelog) { + file.changelog = FlameAPI::getModFileChangelog(file.addonId.toInt(), file.fileId.toInt()); + } return file; } diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h index 2631fab74..5e039d910 100644 --- a/launcher/modplatform/flame/FlameModIndex.h +++ b/launcher/modplatform/flame/FlameModIndex.h @@ -6,13 +6,11 @@ #include "modplatform/ModIndex.h" -#include "BaseInstance.h" - namespace FlameMod { -void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj); -void loadURLs(ModPlatform::IndexedPack& m, QJsonObject& obj); -void loadBody(ModPlatform::IndexedPack& m); +void loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj); +void loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj); +void loadBody(ModPlatform::IndexedPack& pack); void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr); -ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false); +ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, bool loadChangelog = false); } // namespace FlameMod diff --git a/launcher/modplatform/flame/PackManifest.cpp b/launcher/modplatform/flame/PackManifest.cpp index dc176d770..755b1772a 100644 --- a/launcher/modplatform/flame/PackManifest.cpp +++ b/launcher/modplatform/flame/PackManifest.cpp @@ -1,20 +1,21 @@ #include "PackManifest.h" #include "Json.h" -static void loadFileV1(Flame::File& f, QJsonObject& file) +namespace { +void loadFileV1(Flame::File& f, QJsonObject& file) { f.projectId = Json::requireInteger(file, "projectID"); f.fileId = Json::requireInteger(file, "fileID"); f.required = file["required"].toBool(true); } -static void loadModloaderV1(Flame::Modloader& m, QJsonObject& modLoader) +void loadModloaderV1(Flame::Modloader& m, QJsonObject& modLoader) { m.id = Json::requireString(modLoader, "id"); m.primary = modLoader["primary"].toBool(); } -static void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft) +void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft) { m.version = Json::requireString(minecraft, "version"); // extra libraries... apparently only used for a custom Minecraft launcher in the 1.2.5 FTB retro pack @@ -30,7 +31,7 @@ static void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft) m.recommendedRAM = minecraft["recommendedRam"].toInt(); } -static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest) +void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest) { auto mc = Json::requireObject(manifest, "minecraft"); @@ -52,8 +53,9 @@ static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest) pack.overrides = manifest["overrides"].toString("overrides"); - pack.is_loaded = true; + pack.isLoaded = true; } +} // namespace void Flame::loadManifest(Flame::Manifest& m, const QString& filepath) { diff --git a/launcher/modplatform/flame/PackManifest.h b/launcher/modplatform/flame/PackManifest.h index ff9bec7df..1d5035fd9 100644 --- a/launcher/modplatform/flame/PackManifest.h +++ b/launcher/modplatform/flame/PackManifest.h @@ -79,7 +79,7 @@ struct Manifest { QMap files; QString overrides; - bool is_loaded = false; + bool isLoaded = false; }; void loadManifest(Flame::Manifest& m, const QString& filepath); diff --git a/launcher/modplatform/modrinth/ModrinthAPI.cpp b/launcher/modplatform/modrinth/ModrinthAPI.cpp index eb1f55a62..e8b4ed650 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.cpp +++ b/launcher/modplatform/modrinth/ModrinthAPI.cpp @@ -12,93 +12,93 @@ #include "net/ApiUpload.h" #include "net/NetJob.h" -std::pair ModrinthAPI::currentVersion(const QString& hash, const QString& hash_format) const +std::pair ModrinthAPI::currentVersion(const QString& hash, const QString& hashFormat) { auto netJob = makeShared(QString("Modrinth::GetCurrentVersion"), APPLICATION->network()); auto [action, response] = - Net::ApiDownload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1?algorithm=%2").arg(hash, hash_format)); + Net::ApiDownload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1?algorithm=%2").arg(hash, hashFormat)); netJob->addNetAction(action); return { netJob, response }; } -std::pair ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_format) const +std::pair ModrinthAPI::currentVersions(const QStringList& hashes, const QString& hashFormat) { auto netJob = makeShared(QString("Modrinth::GetCurrentVersions"), APPLICATION->network()); - QJsonObject body_obj; + QJsonObject bodyObj; - Json::writeStringList(body_obj, "hashes", hashes); - Json::writeString(body_obj, "algorithm", hash_format); + Json::writeStringList(bodyObj, "hashes", hashes); + Json::writeString(bodyObj, "algorithm", hashFormat); - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); - auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), body_raw); + auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), bodyRaw); netJob->addNetAction(action); netJob->setAskRetry(false); return { netJob, response }; } std::pair ModrinthAPI::latestVersion(const QString& hash, - const QString& hash_format, + const QString& hashFormat, std::optional> mcVersions, std::optional loaders) const { auto netJob = makeShared(QString("Modrinth::GetLatestVersion"), APPLICATION->network()); - QJsonObject body_obj; + QJsonObject bodyObj; if (loaders.has_value()) { - Json::writeStringList(body_obj, "loaders", getModLoaderStrings(loaders.value())); + Json::writeStringList(bodyObj, "loaders", getModLoaderStrings(loaders.value())); } if (mcVersions.has_value()) { - QStringList game_versions; + QStringList gameVersions; for (auto& ver : mcVersions.value()) { - game_versions.append(mapMCVersionToModrinth(ver)); + gameVersions.append(mapMCVersionToModrinth(ver)); } - Json::writeStringList(body_obj, "game_versions", game_versions); + Json::writeStringList(bodyObj, "game_versions", gameVersions); } - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); auto [action, response] = Net::ApiUpload::makeByteArray( - QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hash_format), body_raw); + QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hashFormat), bodyRaw); netJob->addNetAction(action); return { netJob, response }; } std::pair ModrinthAPI::latestVersions(const QStringList& hashes, - const QString& hash_format, + const QString& hashFormat, std::optional> mcVersions, std::optional loaders) const { auto netJob = makeShared(QString("Modrinth::GetLatestVersions"), APPLICATION->network()); - QJsonObject body_obj; + QJsonObject bodyObj; - Json::writeStringList(body_obj, "hashes", hashes); - Json::writeString(body_obj, "algorithm", hash_format); + Json::writeStringList(bodyObj, "hashes", hashes); + Json::writeString(bodyObj, "algorithm", hashFormat); if (loaders.has_value()) { - Json::writeStringList(body_obj, "loaders", getModLoaderStrings(loaders.value())); + Json::writeStringList(bodyObj, "loaders", getModLoaderStrings(loaders.value())); } if (mcVersions.has_value()) { - QStringList game_versions; + QStringList gameVersions; for (auto& ver : mcVersions.value()) { - game_versions.append(mapMCVersionToModrinth(ver)); + gameVersions.append(mapMCVersionToModrinth(ver)); } - Json::writeStringList(body_obj, "game_versions", game_versions); + Json::writeStringList(bodyObj, "game_versions", gameVersions); } - QJsonDocument body(body_obj); - auto body_raw = body.toJson(); - auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), body_raw); + QJsonDocument body(bodyObj); + auto bodyRaw = body.toJson(); + auto [action, response] = Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), bodyRaw); netJob->addNetAction(action); return { netJob, response }; @@ -118,14 +118,14 @@ std::pair ModrinthAPI::getProjects(QStringList addonIds) QList ModrinthAPI::getSortingMethods() const { // https://docs.modrinth.com/api-spec/#tag/projects/operation/searchProjects - return { { .index = 1, .name = "relevance", .readable_name = QObject::tr("Sort by Relevance") }, - { .index = 2, .name = "downloads", .readable_name = QObject::tr("Sort by Downloads") }, - { .index = 3, .name = "follows", .readable_name = QObject::tr("Sort by Follows") }, - { .index = 4, .name = "newest", .readable_name = QObject::tr("Sort by Newest") }, - { .index = 5, .name = "updated", .readable_name = QObject::tr("Sort by Last Updated") } }; + return { { .index = 1, .name = "relevance", .readableName = QObject::tr("Sort by Relevance") }, + { .index = 2, .name = "downloads", .readableName = QObject::tr("Sort by Downloads") }, + { .index = 3, .name = "follows", .readableName = QObject::tr("Sort by Follows") }, + { .index = 4, .name = "newest", .readableName = QObject::tr("Sort by Newest") }, + { .index = 5, .name = "updated", .readableName = QObject::tr("Sort by Last Updated") } }; } namespace { -const auto resourceTypeMap = std::array{ +const auto g_resourceTypeMap = std::array{ std::pair{ ModPlatform::ResourceType::Mod, "mod" }, std::pair{ ModPlatform::ResourceType::ResourcePack, "resourcepack" }, std::pair{ ModPlatform::ResourceType::ShaderPack, "shader" }, std::pair{ ModPlatform::ResourceType::DataPack, "datapack" }, std::pair{ ModPlatform::ResourceType::Modpack, "modpack" }, @@ -134,7 +134,7 @@ const auto resourceTypeMap = std::array{ ModPlatform::ResourceType ModrinthAPI::getResourceType(const QString& param) { - for (const auto& [key, value] : resourceTypeMap) { + for (const auto& [key, value] : g_resourceTypeMap) { if (value == param) { return key; } @@ -146,7 +146,7 @@ ModPlatform::ResourceType ModrinthAPI::getResourceType(const QString& param) QString ModrinthAPI::resourceTypeParameter(ModPlatform::ResourceType type) { - for (const auto& [key, value] : resourceTypeMap) { + for (const auto& [key, value] : g_resourceTypeMap) { if (key == type) { return value; } @@ -169,11 +169,10 @@ std::pair ModrinthAPI::getModCategories() QList ModrinthAPI::loadCategories(const QByteArray& response, const QString& projectType) { QList categories; - QJsonParseError parse_error{}; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from categories at" << parse_error.offset - << "reason:" << parse_error.errorString(); + QJsonParseError parseError{}; + QJsonDocument doc = QJsonDocument::fromJson(response, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from categories at" << parseError.offset << "reason:" << parseError.errorString(); qWarning() << *response; return categories; } diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 91de24793..a24e26816 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -10,21 +10,24 @@ #include "modplatform/modrinth/ModrinthPackIndex.h" #include +#include +#include +#include #include class ModrinthAPI : public ResourceAPI { public: - std::pair currentVersion(const QString& hash, const QString& hash_format) const; + static std::pair currentVersion(const QString& hash, const QString& hashFormat); - std::pair currentVersions(const QStringList& hashes, QString hash_format) const; + static std::pair currentVersions(const QStringList& hashes, const QString& hashFormat); std::pair latestVersion(const QString& hash, - const QString& hash_format, + const QString& hashFormat, std::optional> mcVersions, std::optional loaders) const; std::pair latestVersions(const QStringList& hashes, - const QString& hash_format, + const QString& hashFormat, std::optional> mcVersions, std::optional loaders) const; @@ -107,30 +110,30 @@ class ModrinthAPI : public ResourceAPI { QString createFacets(const SearchArgs& args) const { - QStringList facets_list; + QStringList facetsList; if (args.loaders.has_value() && args.loaders.value() != 0) { - facets_list.append(QString("[%1]").arg(getModLoaderFilters(args.loaders.value()))); + facetsList.append(QString("[%1]").arg(getModLoaderFilters(args.loaders.value()))); } if (args.versions.has_value() && !args.versions.value().empty()) { - facets_list.append(QString("[%1]").arg(getGameVersionsArray(args.versions.value()))); + facetsList.append(QString("[%1]").arg(getGameVersionsArray(args.versions.value()))); } if (args.side.has_value()) { auto side = getSideFilters(args.side.value()); if (!side.isEmpty()) { - facets_list.append(QString("[%1]").arg(side)); + facetsList.append(QString("[%1]").arg(side)); } } if (args.categoryIds.has_value() && !args.categoryIds->empty()) { - facets_list.append(QString("[%1]").arg(getCategoriesFilters(args.categoryIds.value()))); + facetsList.append(QString("[%1]").arg(getCategoriesFilters(args.categoryIds.value()))); } if (args.openSource) { - facets_list.append("[\"open_source:true\"]"); + facetsList.append("[\"open_source:true\"]"); } - facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type))); + facetsList.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type))); - return QString("[%1]").arg(facets_list.join(',')); + return QString("[%1]").arg(facetsList.join(',')); } public: @@ -143,18 +146,18 @@ class ModrinthAPI : public ResourceAPI { } } - QStringList get_arguments; - get_arguments.append(QString("offset=%1").arg(args.offset)); - get_arguments.append(QString("limit=25")); + QStringList getArguments; + getArguments.append(QString("offset=%1").arg(args.offset)); + getArguments.append(QString("limit=25")); if (args.search.has_value()) { - get_arguments.append(QString("query=%1").arg(args.search.value())); + getArguments.append(QString("query=%1").arg(args.search.value())); } if (args.sorting.has_value()) { - get_arguments.append(QString("index=%1").arg(args.sorting.value().name)); + getArguments.append(QString("index=%1").arg(args.sorting.value().name)); } - get_arguments.append(QString("facets=%1").arg(createFacets(args))); + getArguments.append(QString("facets=%1").arg(createFacets(args))); - return BuildConfig.MODRINTH_PROD_URL + "/search?" + get_arguments.join('&'); + return BuildConfig.MODRINTH_PROD_URL + "/search?" + getArguments.join('&'); }; auto getInfoURL(const QString& id) const -> std::optional override @@ -162,24 +165,24 @@ class ModrinthAPI : public ResourceAPI { return BuildConfig.MODRINTH_PROD_URL + "/project/" + id; }; - auto getMultipleModInfoURL(const QStringList& ids) const -> QString + static auto getMultipleModInfoURL(const QStringList& ids) -> QString { return BuildConfig.MODRINTH_PROD_URL + QString("/projects?ids=[\"%1\"]").arg(ids.join("\",\"")); }; auto getVersionsURL(const VersionSearchArgs& args) const -> std::optional override { - QStringList get_arguments; + QStringList getArguments; if (args.mcVersions.has_value()) { - get_arguments.append(QString("game_versions=[%1]").arg(getGameVersionsString(args.mcVersions.value()))); + getArguments.append(QString("game_versions=[%1]").arg(getGameVersionsString(args.mcVersions.value()))); } if (args.loaders.has_value()) { - get_arguments.append(QString("loaders=[\"%1\"]").arg(getModLoaderStrings(args.loaders.value()).join("\",\""))); + getArguments.append(QString("loaders=[\"%1\"]").arg(getModLoaderStrings(args.loaders.value()).join("\",\""))); } - get_arguments.append(QString("include_changelog=%1").arg(args.includeChangelog ? "true" : "false")); + getArguments.append(QString("include_changelog=%1").arg(args.includeChangelog ? "true" : "false")); return QString("%1/project/%2/version%3%4") - .arg(BuildConfig.MODRINTH_PROD_URL, args.pack->addonId.toString(), get_arguments.isEmpty() ? "" : "?", get_arguments.join('&')); + .arg(BuildConfig.MODRINTH_PROD_URL, args.pack->addonId.toString(), getArguments.isEmpty() ? "" : "?", getArguments.join('&')); }; QString getGameVersionsArray(const std::vector& mcVersions) const diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 0fda37e57..ace6e51b8 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -178,7 +178,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(QByteArray* response, std::optio pack->slug = resource->metadata()->slug; pack->addonId = resource->metadata()->project_id; pack->provider = ModPlatform::ResourceProvider::MODRINTH; - if ((projectVer.hash != hash && projectVer.is_preferred) || (resource->status() == ResourceStatus::NotInstalled)) { + if ((projectVer.hash != hash && projectVer.isPreferred) || (resource->status() == ResourceStatus::NotInstalled)) { auto downloadTask = makeShared(pack, projectVer, m_resourceModel, true, "update"); QString oldVersion = resource->metadata()->version_number; @@ -190,8 +190,8 @@ void ModrinthCheckUpdate::checkVersionsResponse(QByteArray* response, std::optio } } - m_updates.emplace_back(pack->name, hash, oldVersion, projectVer.version_number, projectVer.version_type, - projectVer.changelog, ModPlatform::ResourceProvider::MODRINTH, downloadTask, resource->enabled()); + m_updates.emplace_back(pack->name, hash, oldVersion, projectVer.versionNumber, projectVer.versionType, projectVer.changelog, + ModPlatform::ResourceProvider::MODRINTH, downloadTask, resource->enabled()); } m_deps.append(std::make_shared(pack, projectVer)); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 1884beb1c..7946eb01b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -22,14 +22,14 @@ #include "ModrinthAPI.h" #include "Json.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" #include "modplatform/ModIndex.h" +namespace { bool shouldDownloadOnSide(const QString& side) { return side == "required" || side == "optional"; } +} // namespace // https://docs.modrinth.com/api/operations/getproject/ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) @@ -80,31 +80,34 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj) { pack.extraData.issuesUrl = obj["issues_url"].toString(); - if (pack.extraData.issuesUrl.endsWith('/')) + if (pack.extraData.issuesUrl.endsWith('/')) { pack.extraData.issuesUrl.chop(1); + } pack.extraData.sourceUrl = obj["source_url"].toString(); - if (pack.extraData.sourceUrl.endsWith('/')) + if (pack.extraData.sourceUrl.endsWith('/')) { pack.extraData.sourceUrl.chop(1); + } pack.extraData.wikiUrl = obj["wiki_url"].toString(); - if (pack.extraData.wikiUrl.endsWith('/')) + if (pack.extraData.wikiUrl.endsWith('/')) { pack.extraData.wikiUrl.chop(1); + } pack.extraData.discordUrl = obj["discord_url"].toString(); if (pack.extraData.discordUrl.endsWith('/')) { pack.extraData.discordUrl.chop(1); } - auto donate_arr = obj["donation_urls"].toArray(); - for (auto d : donate_arr) { - auto d_obj = Json::requireObject(d); + auto donateArr = obj["donation_urls"].toArray(); + for (auto d : donateArr) { + auto dObj = Json::requireObject(d); ModPlatform::DonationData donate; - donate.id = d_obj["id"].toString(); - donate.platform = d_obj["platform"].toString(); - donate.url = d_obj["url"].toString(); + donate.id = dObj["id"].toString(); + donate.platform = dObj["platform"].toString(); + donate.url = dObj["url"].toString(); pack.extraData.donate.append(donate); } @@ -117,8 +120,8 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob } ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, - const QString& preferred_hash_type, - const QString& preferred_file_name) + const QString& preferredHashType, + const QString& preferredFileName) { ModPlatform::IndexedVersion file; @@ -150,8 +153,8 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, } } file.version = Json::requireString(obj, "name"); - file.version_number = Json::requireString(obj, "version_number"); - file.version_type = ModPlatform::IndexedVersionType::fromString(Json::requireString(obj, "version_type")); + file.versionNumber = Json::requireString(obj, "version_number"); + file.versionType = ModPlatform::IndexedVersionType::fromString(Json::requireString(obj, "version_type")); if (obj.contains("changelog")) { file.changelog = Json::requireString(obj, "changelog"); @@ -197,8 +200,8 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, auto parent = files[i].toObject(); auto fileName = Json::requireString(parent, "filename"); - if (!preferred_file_name.isEmpty() && fileName.contains(preferred_file_name)) { - file.is_preferred = true; + if (!preferredFileName.isEmpty() && fileName.contains(preferredFileName)) { + file.isPreferred = true; break; } @@ -215,18 +218,18 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, file.downloadUrl = Json::requireString(parent, "url"); file.fileName = Json::requireString(parent, "filename"); file.fileName = FS::RemoveInvalidPathChars(file.fileName); - file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1); - auto hash_list = Json::requireObject(parent, "hashes"); + file.isPreferred = Json::requireBoolean(parent, "primary") || (files.count() == 1); + auto hashList = Json::requireObject(parent, "hashes"); - if (hash_list.contains(preferred_hash_type)) { - file.hash = Json::requireString(hash_list, preferred_hash_type); - file.hash_type = preferred_hash_type; + if (hashList.contains(preferredHashType)) { + file.hash = Json::requireString(hashList, preferredHashType); + file.hashType = preferredHashType; } else { - auto hash_types = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH); - for (auto& hash_type : hash_types) { - if (hash_list.contains(hash_type)) { - file.hash = Json::requireString(hash_list, hash_type); - file.hash_type = hash_type; + auto hashTypes = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH); + for (auto& hashType : hashTypes) { + if (hashList.contains(hashType)) { + file.hash = Json::requireString(hashList, hashType); + file.hashType = hashType; break; } } diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index b38cd9ce6..f9d277065 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -19,13 +19,11 @@ #include "modplatform/ModIndex.h" -#include "BaseInstance.h" - namespace Modrinth { void loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj); void loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj); -auto loadIndexedPackVersion(QJsonObject& obj, const QString& preferred_hash_type = "sha512", const QString& preferred_file_name = "") +auto loadIndexedPackVersion(QJsonObject& obj, const QString& preferredHashType = "sha512", const QString& preferredFileName = "") -> ModPlatform::IndexedVersion; } // namespace Modrinth diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 4d162a90d..3269a63be 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -122,7 +122,7 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir, mod.url = mod_version.downloadUrl; } - mod.hash_format = mod_version.hash_type; + mod.hash_format = mod_version.hashType; mod.hash = mod_version.hash; mod.provider = mod_pack.provider; @@ -133,9 +133,9 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir, mod.mcVersions = mod_version.mcVersion; mod.mcVersions.removeDuplicates(); std::ranges::sort(mod.mcVersions, sortMCVersions); - mod.releaseType = mod_version.version_type; + mod.releaseType = mod_version.versionType; - mod.version_number = mod_version.version_number; + mod.version_number = mod_version.versionNumber; if (mod.version_number.isNull()) // on CurseForge, there is only a version name - not a version number mod.version_number = mod_version.version; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 1bdcd3f68..e96676fcb 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -655,7 +655,7 @@ void MainWindow::repopulateAccountsMenu() auto accounts = APPLICATION->accounts(); MinecraftAccountPtr defaultAccount = accounts->defaultAccount(); - + bool canChangeSkin = defaultAccount && (defaultAccount->accountType() == AccountType::MSA) && !defaultAccount->isActive(); ui->actionManageSkins->setEnabled(canChangeSkin); @@ -1126,7 +1126,7 @@ void MainWindow::processURLs(QList urls) auto type = ResourceUtils::identify(localFileInfo); - if (ModPlatform::ResourceTypeUtils::VALID_RESOURCES.count(type) == 0) { // probably instance/modpack + if (ModPlatform::ResourceTypeUtils::g_VALID_RESOURCES.count(type) == 0) { // probably instance/modpack addInstance(localFileName, extra_info); continue; } diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index eb24db604..62269e28b 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -56,9 +56,9 @@ ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, BaseInstance* inst, bool suppressInitialSearch) : QDialog(parent) - , m_base_model(baseModel) + , m_baseModel(baseModel) , m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel) - , m_vertical_layout(this) + , m_verticalLayout(this) , m_suppressInitialSearch(suppressInitialSearch) , m_instance(inst) { @@ -135,7 +135,7 @@ void ResourceDownloadDialog::initializeContainer() m_container = new PageContainer(this, {}, this); m_container->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding); m_container->layout()->setContentsMargins(0, 0, 0, 0); - m_vertical_layout.addWidget(m_container); + m_verticalLayout.addWidget(m_container); m_container->addButtons(&m_buttons); @@ -206,7 +206,7 @@ void ResourceDownloadDialog::confirm() .filename = task->getFilename(), .provider = ModPlatform::ProviderCapabilities::name(task->getProvider()), .required_by = extraInfo.requiredBy, - .version_type = task->getVersion().version_type.toString(), + .version_type = task->getVersion().versionType.toString(), .enabled = !extraInfo.maybeInstalled }); } diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h index 1b04cf8c4..76e0f1dcd 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.h +++ b/launcher/ui/dialogs/ResourceDownloadDialog.h @@ -68,7 +68,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { void removeResource(const QString&); QList getTasks(); - ResourceFolderModel* getBaseModel() const { return m_base_model; } + ResourceFolderModel* getBaseModel() const { return m_baseModel; } void setResourceMetadata(const std::shared_ptr& meta); @@ -88,12 +88,12 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider { virtual GetModDependenciesTask::Ptr getModDependenciesTask() { return nullptr; } protected: - ResourceFolderModel* m_base_model; + ResourceFolderModel* m_baseModel; PageContainer* m_container = nullptr; QDialogButtonBox m_buttons; - QVBoxLayout m_vertical_layout; + QVBoxLayout m_verticalLayout; bool m_suppressInitialSearch = false; BaseInstance* m_instance = nullptr; diff --git a/launcher/ui/dialogs/ResourceUpdateDialog.cpp b/launcher/ui/dialogs/ResourceUpdateDialog.cpp index 8a54958ba..c6d8081e9 100644 --- a/launcher/ui/dialogs/ResourceUpdateDialog.cpp +++ b/launcher/ui/dialogs/ResourceUpdateDialog.cpp @@ -243,7 +243,7 @@ void ResourceUpdateDialog::checkCandidates() auto downloadTask = makeShared(dep->pack, dep->version, m_resourceModel, true, "dependency"); auto extraInfo = dependencyExtraInfo.value(dep->version.addonId.toString()); CheckUpdateTask::Update updatable = { - dep->pack->name, dep->version.hash, tr("Not installed"), dep->version.version, dep->version.version_type, + dep->pack->name, dep->version.hash, tr("Not installed"), dep->version.version, dep->version.versionType, changelog, dep->pack->provider, downloadTask, !extraInfo.maybeInstalled, }; @@ -412,6 +412,7 @@ void ResourceUpdateDialog::onMetadataEnsured(Resource* resource) } } +namespace { ModPlatform::ResourceProvider next(ModPlatform::ResourceProvider p) { switch (p) { @@ -423,6 +424,7 @@ ModPlatform::ResourceProvider next(ModPlatform::ResourceProvider p) return ModPlatform::ResourceProvider::FLAME; } +} // namespace void ResourceUpdateDialog::onMetadataFailed(Resource* resource, bool tryOthers, ModPlatform::ResourceProvider firstChoice) { diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index d2683fa92..a7f24ed7c 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -128,7 +128,8 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi QDesktopServices::openUrl(url); }); - connect(ui->urlLine, &QLineEdit::textChanged, this, [this](QString text) { m_inst->settings()->set("ManagedPackURL", text.trimmed()); }); + connect(ui->urlLine, &QLineEdit::textChanged, this, + [this](QString text) { m_inst->settings()->set("ManagedPackURL", text.trimmed()); }); } ManagedPackPage::~ManagedPackPage() @@ -273,7 +274,7 @@ void ModrinthManagedPackPage::parseManagedPack() m_pack = { .addonId = m_inst->getManagedPackID() }; // Use default if no callbacks are set - callbacks.on_succeed = [this](auto& doc) { + callbacks.onSucceed = [this](auto& doc) { m_pack.versions = doc; m_pack.versionsLoaded = true; @@ -298,8 +299,8 @@ void ModrinthManagedPackPage::parseManagedPack() m_loaded = true; }; - callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); }; - callbacks.on_abort = [this]() { setFailState(); }; + callbacks.onFail = [this](const QString& /*reason*/, int) { setFailState(); }; + callbacks.onAbort = [this]() { setFailState(); }; m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared(m_pack), .mcVersions = {}, .loaders = {}, @@ -428,7 +429,7 @@ void FlameManagedPackPage::parseManagedPack() ResourceAPI::Callback> callbacks{}; // Use default if no callbacks are set - callbacks.on_succeed = [this](auto& doc) { + callbacks.onSucceed = [this](auto& doc) { m_pack.versions = doc; m_pack.versionsLoaded = true; @@ -451,8 +452,8 @@ void FlameManagedPackPage::parseManagedPack() m_loaded = true; }; - callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); }; - callbacks.on_abort = [this]() { setFailState(); }; + callbacks.onFail = [this](const QString& /*reason*/, int) { setFailState(); }; + callbacks.onAbort = [this]() { setFailState(); }; m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared(m_pack), .mcVersions = {}, .loaders = {}, diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index c0768b9c3..faa548492 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -22,7 +22,7 @@ ModModel::ModModel(BaseInstance& base_inst, ResourceAPI* api, QString debugName, ResourceAPI::SearchArgs ModModel::createSearchArguments() { - auto profile = static_cast(m_base_instance).getPackProfile(); + auto profile = static_cast(m_base_instance).getPackProfile(); Q_ASSERT(profile); Q_ASSERT(m_filter); @@ -50,7 +50,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments() ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(const QModelIndex& entry) { auto pack = m_packs[entry.row()]; - auto profile = static_cast(m_base_instance).getPackProfile(); + auto profile = static_cast(m_base_instance).getPackProfile(); Q_ASSERT(profile); Q_ASSERT(m_filter); @@ -128,7 +128,7 @@ bool ModModel::checkVersionFilters(const ModPlatform::IndexedVersion& v) (!loaders.has_value() || !v.loaders || loaders.value() & v.loaders) && // loaders checkSide(m_filter->side, v.side) && // side (m_filter->releases.empty() || // releases - std::find(m_filter->releases.cbegin(), m_filter->releases.cend(), v.version_type) != m_filter->releases.cend()) && + std::find(m_filter->releases.cbegin(), m_filter->releases.cend(), v.versionType) != m_filter->releases.cend()) && m_filter->checkMcVersions(v.mcVersion)); // mcVersions } diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index edd8564b6..c12a89672 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -148,7 +148,7 @@ void ResourceModel::search() if (!projectId.isEmpty()) { ResourceAPI::Callback callbacks; - callbacks.on_fail = [this](QString reason, int networkErrorCode) { + callbacks.onFail = [this](QString reason, int networkErrorCode) { if (!s_running_models.constFind(this).value()) { return; } @@ -157,14 +157,14 @@ void ResourceModel::search() } searchRequestFailed(std::move(reason), networkErrorCode); }; - callbacks.on_abort = [this] { + callbacks.onAbort = [this] { if (!s_running_models.constFind(this).value()) { return; } searchRequestAborted(); }; - callbacks.on_succeed = [this](auto& pack) { + callbacks.onSucceed = [this](auto& pack) { if (!s_running_models.constFind(this).value()) { return; } @@ -182,19 +182,19 @@ void ResourceModel::search() ResourceAPI::Callback> callbacks{}; - callbacks.on_succeed = [this](auto& doc) { + callbacks.onSucceed = [this](auto& doc) { if (!s_running_models.constFind(this).value()) { return; } searchRequestSucceeded(doc); }; - callbacks.on_fail = [this](QString reason, int networkErrorCode) { + callbacks.onFail = [this](QString reason, int networkErrorCode) { if (!s_running_models.constFind(this).value()) { return; } searchRequestFailed(std::move(reason), networkErrorCode); }; - callbacks.on_abort = [this] { + callbacks.onAbort = [this] { if (!s_running_models.constFind(this).value()) { return; } @@ -220,16 +220,16 @@ void ResourceModel::loadEntry(const QModelIndex& entry) auto addonId = pack->addonId; // Use default if no callbacks are set - if (!callbacks.on_succeed) { - callbacks.on_succeed = [this, entry, addonId](auto& doc) { + if (!callbacks.onSucceed) { + callbacks.onSucceed = [this, entry, addonId](auto& doc) { if (!s_running_models.constFind(this).value()) { return; } versionRequestSucceeded(doc, addonId, entry); }; } - if (!callbacks.on_fail) { - callbacks.on_fail = [](const QString& reason, int) { + if (!callbacks.onFail) { + callbacks.onFail = [](const QString& reason, int) { QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load project versions: %1").arg(reason)); }; @@ -244,19 +244,19 @@ void ResourceModel::loadEntry(const QModelIndex& entry) auto args{ createInfoArguments(entry) }; ResourceAPI::Callback callbacks{}; - callbacks.on_succeed = [this, entry](auto& newpack) { + callbacks.onSucceed = [this, entry](auto& newpack) { if (!s_running_models.constFind(this).value()) { return; } infoRequestSucceeded(newpack, entry); }; - callbacks.on_fail = [this](const QString& reason, int) { + callbacks.onFail = [this](const QString& reason, int) { if (!s_running_models.constFind(this).value()) { return; } QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load project info: %1").arg(reason)); }; - callbacks.on_abort = [this] { + callbacks.onAbort = [this] { if (!s_running_models.constFind(this).value()) { return; } @@ -521,7 +521,7 @@ void ResourceModel::addPack(ModPlatform::IndexedPack::Ptr pack, bool isIndexed, QString downloadReason) { - version.is_currently_selected = true; + version.isCurrentlySelected = true; m_selected.append(makeShared(std::move(pack), version, packs, isIndexed, std::move(downloadReason))); } @@ -547,7 +547,7 @@ void ResourceModel::removePack(const QString& rem) return; } for (auto& ver : pack->get()->versions) { - ver.is_currently_selected = false; + ver.isCurrentlySelected = false; } } diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h index 9124c0e66..eb7976f87 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.h +++ b/launcher/ui/pages/modplatform/ResourceModel.h @@ -139,7 +139,7 @@ class ResourceModel : public QAbstractListModel { /* Default search request callbacks */ void searchRequestSucceeded(QList&); void searchRequestForOneSucceeded(ModPlatform::IndexedPack::Ptr); - void searchRequestFailed(QString reason, int network_error_code); + void searchRequestFailed(QString reason, int networkErrorCode); void searchRequestAborted(); void versionRequestSucceeded(QVector&, QVariant, const QModelIndex&); diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp index 8baa0bbec..410b3240c 100644 --- a/launcher/ui/pages/modplatform/ResourcePage.cpp +++ b/launcher/ui/pages/modplatform/ResourcePage.cpp @@ -182,7 +182,7 @@ void ResourcePage::addSortings() std::ranges::sort(sorts, [](const auto& l, const auto& r) { return l.index < r.index; }); for (auto&& sorting : sorts) { - m_ui->sortByBox->addItem(sorting.readable_name, QVariant(sorting.index)); + m_ui->sortByBox->addItem(sorting.readableName, QVariant(sorting.index)); } } @@ -318,8 +318,8 @@ void ResourcePage::versionListUpdated(const QModelIndex& index) } auto versionText = version.version; - if (version.version_type.isValid()) { - versionText += QString(" [%1]").arg(version.version_type.toString()); + if (version.versionType.isValid()) { + versionText += QString(" [%1]").arg(version.versionType.toString()); } if (version.fileId == installedVersion) { versionText += tr(" [installed]", "Mod version select"); @@ -427,7 +427,7 @@ void ResourcePage::onResourceSelected() auto& version = currentPack->versions[m_selectedVersionIndex]; Q_ASSERT(!version.downloadUrl.isNull()); - if (version.is_currently_selected) { + if (version.isCurrentlySelected) { removeResourceFromDialog(currentPack->name); } else { addResourceToDialog(currentPack, version); diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 861dd9f22..6cc5dfa8f 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -173,14 +173,14 @@ void ListModel::performPaginatedSearch() if (!projectId.isEmpty()) { ResourceAPI::Callback callbacks; - callbacks.on_fail = [this](QString reason, int network_error_code) { - if (network_error_code == 404) { + callbacks.onFail = [this](QString reason, int networkErrorCode) { + if (networkErrorCode == 404) { m_searchState = ResetRequested; } searchRequestFailed(reason); }; - callbacks.on_succeed = [this](auto& pack) { searchRequestForOneSucceeded(pack); }; - callbacks.on_abort = [this] { + callbacks.onSucceed = [this](auto& pack) { searchRequestForOneSucceeded(pack); }; + callbacks.onAbort = [this] { qCritical() << "Search task aborted by an unknown reason!"; searchRequestFailed("Aborted"); }; @@ -198,9 +198,9 @@ void ListModel::performPaginatedSearch() ResourceAPI::Callback> callbacks{}; - callbacks.on_succeed = [this](auto& doc) { searchRequestFinished(doc); }; - callbacks.on_fail = [this](QString reason, int) { searchRequestFailed(reason); }; - callbacks.on_abort = [this] { + callbacks.onSucceed = [this](auto& doc) { searchRequestFinished(doc); }; + callbacks.onFail = [this](QString reason, int) { searchRequestFailed(reason); }; + callbacks.onAbort = [this] { qCritical() << "Search task aborted by an unknown reason!"; searchRequestFailed("Aborted"); }; diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 336133819..72111f111 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -163,7 +163,7 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde auto addonId = m_current->addonId; // Use default if no callbacks are set - callbacks.on_succeed = [this, curr, addonId](auto& doc) { + callbacks.onSucceed = [this, curr, addonId](auto& doc) { if (addonId != m_current->addonId) { return; // wrong request } @@ -200,7 +200,7 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde } suggestCurrent(); }; - callbacks.on_fail = [this](QString reason, int) { + callbacks.onFail = [this](QString reason, int) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 03518c3af..099be38e9 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -141,14 +141,14 @@ void ModpackListModel::performPaginatedSearch() if (!projectId.isEmpty()) { ResourceAPI::Callback callbacks; - callbacks.on_fail = [this](QString reason, int network_error_code) { - if (network_error_code == 404) { + callbacks.onFail = [this](QString reason, int networkErrorCode) { + if (networkErrorCode == 404) { m_searchState = ResetRequested; } - searchRequestFailed(reason, network_error_code); + searchRequestFailed(reason, networkErrorCode); }; - callbacks.on_succeed = [this](auto& pack) { searchRequestForOneSucceeded(pack); }; - callbacks.on_abort = [this] { + callbacks.onSucceed = [this](auto& pack) { searchRequestForOneSucceeded(pack); }; + callbacks.onAbort = [this] { qCritical() << "Search task aborted by an unknown reason!"; searchRequestFailed("Aborted", 0); }; @@ -166,9 +166,9 @@ void ModpackListModel::performPaginatedSearch() ResourceAPI::Callback> callbacks{}; - callbacks.on_succeed = [this](auto& doc) { searchRequestFinished(doc); }; - callbacks.on_fail = [this](QString reason, int network_error_code) { searchRequestFailed(reason, network_error_code); }; - callbacks.on_abort = [this] { + callbacks.onSucceed = [this](auto& doc) { searchRequestFinished(doc); }; + callbacks.onFail = [this](QString reason, int networkErrorCode) { searchRequestFailed(reason, networkErrorCode); }; + callbacks.onAbort = [this] { qCritical() << "Search task aborted by an unknown reason!"; searchRequestFailed("Aborted", 0); }; @@ -322,12 +322,12 @@ void ModpackListModel::searchRequestForOneSucceeded(ModPlatform::IndexedPack::Pt endInsertRows(); } -void ModpackListModel::searchRequestFailed(QString reason, int network_error_code) +void ModpackListModel::searchRequestFailed(QString reason, int networkErrorCode) { - if (network_error_code == -1) { + if (networkErrorCode == -1) { // Unknown error in network stack QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load modpacks.")); - } else if (network_error_code == 409) { + } else if (networkErrorCode == 409) { // 409 Gone, notify user to update QMessageBox::critical(nullptr, tr("Error"), //: %1 refers to the launcher itself diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 3e0fc1686..28e9ac3bf 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -85,7 +85,7 @@ class ModpackListModel : public QAbstractListModel { public slots: void searchRequestFinished(QList& doc_all); - void searchRequestFailed(QString reason, int network_error_code); + void searchRequestFailed(QString reason, int networkErrorCode); void searchRequestForOneSucceeded(ModPlatform::IndexedPack::Ptr); protected slots: diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 4798583bd..b6b8bc68d 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -150,10 +150,10 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI ResourceAPI::Callback callbacks; auto id = m_current->addonId; - callbacks.on_fail = [this](QString reason, int) { + callbacks.onFail = [this](QString reason, int) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }; - callbacks.on_succeed = [this, id, curr](auto& pack) { + callbacks.onSucceed = [this, id, curr](auto& pack) { if (id != m_current->addonId) { return; // wrong request? } @@ -182,7 +182,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI auto addonId = m_current->addonId; // Use default if no callbacks are set - callbacks.on_succeed = [this, curr, addonId](auto& doc) { + callbacks.onSucceed = [this, curr, addonId](auto& doc) { if (addonId != m_current->addonId) { return; // wrong request } @@ -215,7 +215,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI suggestCurrent(); }; - callbacks.on_fail = [this](QString reason, int) { + callbacks.onFail = [this](QString reason, int) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }; @@ -227,7 +227,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI } else { for (auto version : m_current->versions) { if (!version.version.contains(version.version)) - m_ui->versionSelectionBox->addItem(QString("%1 - %2").arg(version.version, version.version_number), + m_ui->versionSelectionBox->addItem(QString("%1 - %2").arg(version.version, version.versionNumber), QVariant(version.fileId)); else m_ui->versionSelectionBox->addItem(version.version, QVariant(version.fileId)); diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 85deb51dc..b49a5f02f 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -86,7 +86,7 @@ class ModFilterWidget : public QTabWidget { { return ((!loaders || !v.loaders || loaders & v.loaders) && // loaders (releases.empty() || // releases - std::find(releases.cbegin(), releases.cend(), v.version_type) != releases.cend()) && + std::find(releases.cbegin(), releases.cend(), v.versionType) != releases.cend()) && checkMcVersions({ v.mcVersion })); // gameVersion} } };