fix the flame loaders match

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2024-11-01 13:44:06 +02:00
parent ba07a136dc
commit f77f0207f7
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
8 changed files with 52 additions and 31 deletions

View File

@ -48,6 +48,7 @@
#include "Version.h" #include "Version.h"
#include "minecraft/mod/ModDetails.h" #include "minecraft/mod/ModDetails.h"
#include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/LocalModParseTask.h"
#include "modplatform/ModIndex.h"
Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details() Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details()
{ {
@ -157,11 +158,8 @@ auto Mod::loaders() const -> QString
if (metadata()) { if (metadata()) {
QStringList loaders; QStringList loaders;
auto modLoaders = metadata()->loaders; auto modLoaders = metadata()->loaders;
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Cauldron, ModPlatform::LiteLoader, ModPlatform::Fabric, for (auto loader : ModPlatform::modLoaderTypesToList(modLoaders)) {
ModPlatform::Quilt }) { loaders << getModLoaderAsString(loader);
if (modLoaders & loader) {
loaders << getModLoaderAsString(loader);
}
} }
return loaders.join(", "); return loaders.join(", ");
} }

View File

@ -31,6 +31,19 @@ static const QMap<QString, IndexedVersionType::VersionType> s_indexed_version_ty
{ "alpha", IndexedVersionType::VersionType::Alpha } { "alpha", IndexedVersionType::VersionType::Alpha }
}; };
static const QList<ModLoaderType> loaderList = { NeoForge, Forge, Cauldron, LiteLoader, Quilt, Fabric };
QList<ModLoaderType> modLoaderTypesToList(ModLoaderTypes flags)
{
QList<ModLoaderType> flagList;
for (auto flag : loaderList) {
if (flags.testFlag(flag)) {
flagList.append(flag);
}
}
return flagList;
}
IndexedVersionType::IndexedVersionType(const QString& type) : IndexedVersionType(enumFromString(type)) {} IndexedVersionType::IndexedVersionType(const QString& type) : IndexedVersionType(enumFromString(type)) {}
IndexedVersionType::IndexedVersionType(const IndexedVersionType::VersionType& type) IndexedVersionType::IndexedVersionType(const IndexedVersionType::VersionType& type)

View File

@ -32,6 +32,7 @@ namespace ModPlatform {
enum ModLoaderType { NeoForge = 1 << 0, Forge = 1 << 1, Cauldron = 1 << 2, LiteLoader = 1 << 3, Fabric = 1 << 4, Quilt = 1 << 5 }; enum ModLoaderType { NeoForge = 1 << 0, Forge = 1 << 1, Cauldron = 1 << 2, LiteLoader = 1 << 3, Fabric = 1 << 4, Quilt = 1 << 5 };
Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType) Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)
QList<ModLoaderType> modLoaderTypesToList(ModLoaderTypes flags);
enum class ResourceProvider { MODRINTH, FLAME }; enum class ResourceProvider { MODRINTH, FLAME };

View File

@ -270,21 +270,35 @@ std::optional<ModPlatform::IndexedVersion> FlameAPI::getLatestVersion(QList<ModP
QList<ModPlatform::ModLoaderType> instanceLoaders, QList<ModPlatform::ModLoaderType> instanceLoaders,
ModPlatform::ModLoaderTypes modLoaders) ModPlatform::ModLoaderTypes modLoaders)
{ {
// edge case: mod has installed for forge but the instance is fabric => fabric version will be prioritizated on update QHash<ModPlatform::ModLoaderType, ModPlatform::IndexedVersion> bestMatch;
auto bestVersion = [&versions](ModPlatform::ModLoaderTypes loader) { auto checkVersion = [&bestMatch](const ModPlatform::IndexedVersion& version, const ModPlatform::ModLoaderType& loader) {
std::optional<ModPlatform::IndexedVersion> ver; if (bestMatch.contains(loader)) {
for (auto file_tmp : versions) { auto best = bestMatch.value(loader);
if (file_tmp.loaders & loader && (!ver.has_value() || file_tmp.date > ver->date)) { if (version.date > best.date) {
ver = file_tmp; bestMatch[loader] = version;
}
} else {
bestMatch[loader] = version;
}
};
for (auto file_tmp : versions) {
auto loaders = ModPlatform::modLoaderTypesToList(file_tmp.loaders);
if (loaders.isEmpty()) {
checkVersion(file_tmp, ModPlatform::ModLoaderType(0));
} else {
for (auto loader : loaders) {
checkVersion(file_tmp, loader);
} }
} }
return ver; }
}; // edge case: mod has installed for forge but the instance is fabric => fabric version will be prioritizated on update
for (auto l : instanceLoaders) { auto currentLoaders = instanceLoaders + ModPlatform::modLoaderTypesToList(modLoaders);
auto ver = bestVersion(l); currentLoaders.append(ModPlatform::ModLoaderType(0)); // add a fallback in case the versions do not define a loader
if (ver.has_value()) {
return ver; for (auto loader : currentLoaders) {
if (bestMatch.contains(loader)) {
return bestMatch.value(loader);
} }
} }
return bestVersion(modLoaders); return {};
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include "Application.h"
#include "modplatform/CheckUpdateTask.h" #include "modplatform/CheckUpdateTask.h"
#include "net/NetJob.h" #include "net/NetJob.h"

View File

@ -8,6 +8,7 @@
#include "QObjectPtr.h" #include "QObjectPtr.h"
#include "ResourceDownloadTask.h" #include "ResourceDownloadTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/helpers/HashUtils.h" #include "modplatform/helpers/HashUtils.h"
#include "tasks/ConcurrentTask.h" #include "tasks/ConcurrentTask.h"
@ -99,8 +100,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr<QByteArray> resp
// If the returned project is empty, but we have Modrinth metadata, // If the returned project is empty, but we have Modrinth metadata,
// it means this specific version is not available // it means this specific version is not available
if (project_obj.isEmpty()) { if (project_obj.isEmpty()) {
qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response." qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response." << "Hash: " << hash;
<< "Hash: " << hash;
++iter; ++iter;
continue; continue;
} }
@ -108,10 +108,8 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr<QByteArray> resp
// Sometimes a version may have multiple files, one with "forge" and one with "fabric", // Sometimes a version may have multiple files, one with "forge" and one with "fabric",
// so we may want to filter it // so we may want to filter it
QString loader_filter; QString loader_filter;
static auto flags = { ModPlatform::ModLoaderType::NeoForge, ModPlatform::ModLoaderType::Forge, if (loader.has_value()) {
ModPlatform::ModLoaderType::Quilt, ModPlatform::ModLoaderType::Fabric }; for (auto flag : ModPlatform::modLoaderTypesToList(*loader)) {
for (auto flag : flags) {
if (loader.has_value() && loader->testFlag(flag)) {
loader_filter = ModPlatform::getModLoaderAsString(flag); loader_filter = ModPlatform::getModLoaderAsString(flag);
break; break;
} }

View File

@ -190,11 +190,8 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
} }
toml::array loaders; toml::array loaders;
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Cauldron, ModPlatform::LiteLoader, ModPlatform::Fabric, for (auto loader : ModPlatform::modLoaderTypesToList(mod.loaders)) {
ModPlatform::Quilt }) { loaders.push_back(getModLoaderAsString(loader).toStdString());
if (mod.loaders & loader) {
loaders.push_back(getModLoaderAsString(loader).toStdString());
}
} }
toml::array mcVersions; toml::array mcVersions;
for (auto version : mod.mcVersions) { for (auto version : mod.mcVersions) {

View File

@ -1,4 +1,5 @@
#include "ResourceUpdateDialog.h" #include "ResourceUpdateDialog.h"
#include "Application.h"
#include "ChooseProviderDialog.h" #include "ChooseProviderDialog.h"
#include "CustomMessageBox.h" #include "CustomMessageBox.h"
#include "ProgressDialog.h" #include "ProgressDialog.h"