mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-06-12 13:17:41 +02:00
Resolve issue with multiple loaders during update
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
|
||||
#include "FlameAPI.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include "FlameModIndex.h"
|
||||
|
||||
#include "Application.h"
|
||||
@ -12,7 +13,6 @@
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ApiUpload.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, std::shared_ptr<QByteArray> response)
|
||||
{
|
||||
@ -34,7 +34,7 @@ Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, std::shar
|
||||
return netJob;
|
||||
}
|
||||
|
||||
auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
|
||||
QString FlameAPI::getModFileChangelog(int modId, int fileId)
|
||||
{
|
||||
QEventLoop lock;
|
||||
QString changelog;
|
||||
@ -69,7 +69,7 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
|
||||
return changelog;
|
||||
}
|
||||
|
||||
auto FlameAPI::getModDescription(int modId) -> QString
|
||||
QString FlameAPI::getModDescription(int modId)
|
||||
{
|
||||
QEventLoop lock;
|
||||
QString description;
|
||||
@ -102,7 +102,7 @@ auto FlameAPI::getModDescription(int modId) -> QString
|
||||
return description;
|
||||
}
|
||||
|
||||
auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion
|
||||
QList<ModPlatform::IndexedVersion> FlameAPI::getLatestVersions(VersionSearchArgs&& args)
|
||||
{
|
||||
auto versions_url_optional = getVersionsURL(args);
|
||||
if (!versions_url_optional.has_value())
|
||||
@ -114,7 +114,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
ModPlatform::IndexedVersion ver;
|
||||
QList<ModPlatform::IndexedVersion> ver;
|
||||
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
|
||||
|
||||
@ -134,9 +134,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
|
||||
for (auto file : arr) {
|
||||
auto file_obj = Json::requireObject(file);
|
||||
auto file_tmp = FlameMod::loadIndexedPackVersion(file_obj);
|
||||
if (file_tmp.date > ver.date && (!args.loaders.has_value() || !file_tmp.loaders || args.loaders.value() & file_tmp.loaders))
|
||||
ver = file_tmp;
|
||||
ver.append(FlameMod::loadIndexedPackVersion(file_obj));
|
||||
}
|
||||
|
||||
} catch (Json::JsonException& e) {
|
||||
@ -146,7 +144,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [&loop] { loop.quit(); });
|
||||
QObject::connect(netJob.get(), &NetJob::finished, &loop, &QEventLoop::quit);
|
||||
|
||||
netJob->start();
|
||||
|
||||
@ -260,4 +258,27 @@ QList<ModPlatform::Category> FlameAPI::loadModCategories(std::shared_ptr<QByteAr
|
||||
qDebug() << doc;
|
||||
}
|
||||
return categories;
|
||||
};
|
||||
};
|
||||
|
||||
std::optional<ModPlatform::IndexedVersion> FlameAPI::getLatestVersion(QList<ModPlatform::IndexedVersion> versions,
|
||||
QList<ModPlatform::ModLoaderType> instanceLoaders,
|
||||
ModPlatform::ModLoaderTypes modLoaders)
|
||||
{
|
||||
// edge case: mod has installed for forge but the instance is fabric => fabric version will be prioritizated on update
|
||||
auto bestVersion = [&versions](ModPlatform::ModLoaderTypes loader) {
|
||||
std::optional<ModPlatform::IndexedVersion> ver;
|
||||
for (auto file_tmp : versions) {
|
||||
if (file_tmp.loaders & loader && (!ver.has_value() || file_tmp.date > ver->date)) {
|
||||
ver = file_tmp;
|
||||
}
|
||||
}
|
||||
return ver;
|
||||
};
|
||||
for (auto l : instanceLoaders) {
|
||||
auto ver = bestVersion(l);
|
||||
if (ver.has_value()) {
|
||||
return ver;
|
||||
}
|
||||
}
|
||||
return bestVersion(modLoaders);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
@ -13,10 +12,13 @@
|
||||
|
||||
class FlameAPI : public NetworkResourceAPI {
|
||||
public:
|
||||
auto getModFileChangelog(int modId, int fileId) -> QString;
|
||||
auto getModDescription(int modId) -> QString;
|
||||
QString getModFileChangelog(int modId, int fileId);
|
||||
QString getModDescription(int modId);
|
||||
|
||||
auto getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion;
|
||||
QList<ModPlatform::IndexedVersion> getLatestVersions(VersionSearchArgs&& args);
|
||||
std::optional<ModPlatform::IndexedVersion> getLatestVersion(QList<ModPlatform::IndexedVersion> versions,
|
||||
QList<ModPlatform::ModLoaderType> instanceLoaders,
|
||||
ModPlatform::ModLoaderTypes fallback);
|
||||
|
||||
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const override;
|
||||
Task::Ptr matchFingerprints(const QList<uint>& fingerprints, std::shared_ptr<QByteArray> response);
|
||||
@ -26,9 +28,9 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
static Task::Ptr getModCategories(std::shared_ptr<QByteArray> response);
|
||||
static QList<ModPlatform::Category> loadModCategories(std::shared_ptr<QByteArray> response);
|
||||
|
||||
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||
[[nodiscard]] QList<ResourceAPI::SortingMethod> getSortingMethods() const override;
|
||||
|
||||
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||
static inline bool validateModLoaders(ModPlatform::ModLoaderTypes loaders)
|
||||
{
|
||||
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt);
|
||||
}
|
||||
@ -67,7 +69,7 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> const QStringList
|
||||
static const QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types)
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt }) {
|
||||
@ -78,10 +80,7 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
return l;
|
||||
}
|
||||
|
||||
static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> const QString
|
||||
{
|
||||
return "[" + getModLoaderStrings(types).join(',') + "]";
|
||||
}
|
||||
static const QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; }
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::optional<QString> getSearchURL(SearchArgs const& args) const override
|
||||
|
@ -132,25 +132,26 @@ void FlameCheckUpdate::executeTask()
|
||||
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
|
||||
setProgress(i++, m_mods.size());
|
||||
|
||||
auto latest_ver = api.getLatestVersion({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
|
||||
auto latest_vers = api.getLatestVersions({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
|
||||
|
||||
// Check if we were aborted while getting the latest version
|
||||
if (m_was_aborted) {
|
||||
aborted();
|
||||
return;
|
||||
}
|
||||
auto latest_ver = api.getLatestVersion(latest_vers, m_loaders_list, mod->loaders());
|
||||
|
||||
setStatus(tr("Parsing the API response from CurseForge for '%1'...").arg(mod->name()));
|
||||
|
||||
if (!latest_ver.addonId.isValid()) {
|
||||
if (!latest_ver.has_value() || !latest_ver->addonId.isValid()) {
|
||||
emit checkFailed(mod, tr("No valid version found for this mod. It's probably unavailable for the current game "
|
||||
"version / mod loader."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (latest_ver.downloadUrl.isEmpty() && latest_ver.fileId != mod->metadata()->file_id) {
|
||||
auto pack = getProjectInfo(latest_ver);
|
||||
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver.fileId.toString());
|
||||
if (latest_ver->downloadUrl.isEmpty() && latest_ver->fileId != mod->metadata()->file_id) {
|
||||
auto pack = getProjectInfo(latest_ver.value());
|
||||
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver->fileId.toString());
|
||||
emit checkFailed(mod, tr("Mod has a new update available, but is not downloadable using CurseForge."), recover_url);
|
||||
|
||||
continue;
|
||||
@ -166,19 +167,19 @@ void FlameCheckUpdate::executeTask()
|
||||
pack->authors.append({ author });
|
||||
pack->description = mod->description();
|
||||
pack->provider = ModPlatform::ResourceProvider::FLAME;
|
||||
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
|
||||
if (!latest_ver->hash.isEmpty() && (mod->metadata()->hash != latest_ver->hash || mod->status() == ModStatus::NotInstalled)) {
|
||||
auto old_version = mod->version();
|
||||
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
|
||||
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
|
||||
auto current_ver = getFileInfo(latest_ver->addonId.toInt(), mod->metadata()->file_id.toInt());
|
||||
old_version = current_ver.version;
|
||||
}
|
||||
|
||||
auto download_task = makeShared<ResourceDownloadTask>(pack, latest_ver, m_mods_folder);
|
||||
m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver.version, latest_ver.version_type,
|
||||
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
||||
auto download_task = makeShared<ResourceDownloadTask>(pack, latest_ver.value(), m_mods_folder);
|
||||
m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver->version, latest_ver->version_type,
|
||||
api.getModFileChangelog(latest_ver->addonId.toInt(), latest_ver->fileId.toInt()),
|
||||
ModPlatform::ResourceProvider::FLAME, download_task);
|
||||
}
|
||||
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver));
|
||||
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver.value()));
|
||||
}
|
||||
|
||||
emitSucceeded();
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Application.h"
|
||||
#include "modplatform/CheckUpdateTask.h"
|
||||
#include "net/NetJob.h"
|
||||
|
||||
@ -11,8 +10,9 @@ class FlameCheckUpdate : public CheckUpdateTask {
|
||||
FlameCheckUpdate(QList<Mod*>& mods,
|
||||
std::list<Version>& mcVersions,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
QList<ModPlatform::ModLoaderType> loadersList,
|
||||
std::shared_ptr<ModFolderModel> mods_folder)
|
||||
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
||||
: CheckUpdateTask(mods, mcVersions, loaders, loadersList, mods_folder)
|
||||
{}
|
||||
|
||||
public slots:
|
||||
|
Reference in New Issue
Block a user