refactor: allow tracking multiple mod loaders
This commit is contained in:
		| @@ -978,8 +978,10 @@ void PackProfile::disableInteraction(bool disable) | ||||
|     } | ||||
| } | ||||
|  | ||||
| ModAPI::ModLoaderType PackProfile::getModLoader() | ||||
| ModAPI::ModLoaderTypes PackProfile::getModLoaders() | ||||
| { | ||||
|     ModAPI::ModLoaderTypes result = ModAPI::Unspecified; | ||||
|  | ||||
|     QMapIterator<QString, ModAPI::ModLoaderType> i(modloaderMapping); | ||||
|  | ||||
|     while (i.hasNext()) | ||||
| @@ -987,8 +989,8 @@ ModAPI::ModLoaderType PackProfile::getModLoader() | ||||
|         i.next(); | ||||
|         Component* c = getComponent(i.key()); | ||||
|         if (c != nullptr && c->isEnabled()) { | ||||
|             return i.value(); | ||||
|             result |= i.value(); | ||||
|         } | ||||
|     } | ||||
|     return ModAPI::Unspecified; | ||||
|     return result; | ||||
| } | ||||
|   | ||||
| @@ -118,7 +118,7 @@ public: | ||||
|     // todo(merged): is this the best approach | ||||
|     void appendComponent(ComponentPtr component); | ||||
|  | ||||
|     ModAPI::ModLoaderType getModLoader(); | ||||
|     ModAPI::ModLoaderTypes getModLoaders(); | ||||
|  | ||||
| private: | ||||
|     void scheduleSave(); | ||||
|   | ||||
| @@ -16,14 +16,21 @@ class ModAPI { | ||||
|    public: | ||||
|     virtual ~ModAPI() = default; | ||||
|  | ||||
|     // https://docs.curseforge.com/?http#tocS_ModLoaderType | ||||
|     enum ModLoaderType { Unspecified = 0, Forge = 1, Cauldron = 2, LiteLoader = 3, Fabric = 4, Quilt = 5 }; | ||||
|     enum ModLoaderType { | ||||
|         Unspecified = 0, | ||||
|         Forge = 1 << 0, | ||||
|         Cauldron = 1 << 1, | ||||
|         LiteLoader = 1 << 2, | ||||
|         Fabric = 1 << 3, | ||||
|         Quilt = 1 << 4 | ||||
|     }; | ||||
|     Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType) | ||||
|  | ||||
|     struct SearchArgs { | ||||
|         int offset; | ||||
|         QString search; | ||||
|         QString sorting; | ||||
|         ModLoaderType mod_loader; | ||||
|         ModLoaderTypes loaders; | ||||
|         std::list<Version> versions; | ||||
|     }; | ||||
|  | ||||
| @@ -33,7 +40,7 @@ class ModAPI { | ||||
|     struct VersionSearchArgs { | ||||
|         QString addonId; | ||||
|         std::list<Version> mcVersions; | ||||
|         ModLoaderType loader; | ||||
|         ModLoaderTypes loaders; | ||||
|     }; | ||||
|  | ||||
|     virtual void getVersions(CallerType* caller, VersionSearchArgs&& args) const = 0; | ||||
|   | ||||
| @@ -37,14 +37,14 @@ class FlameAPI : public NetworkModAPI { | ||||
|             .arg(args.offset) | ||||
|             .arg(args.search) | ||||
|             .arg(getSortFieldInt(args.sorting)) | ||||
|             .arg(getMappedModLoader(args.mod_loader)) | ||||
|             .arg(getMappedModLoader(args.loaders)) | ||||
|             .arg(gameVersionStr); | ||||
|     }; | ||||
|  | ||||
|     inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override | ||||
|     { | ||||
|         QString gameVersionQuery = args.mcVersions.size() == 1 ? QString("gameVersion=%1&").arg(args.mcVersions.front().toString()) : ""; | ||||
|         QString modLoaderQuery = QString("modLoaderType=%1&").arg(getMappedModLoader(args.loader)); | ||||
|         QString modLoaderQuery = QString("modLoaderType=%1&").arg(getMappedModLoader(args.loaders)); | ||||
|  | ||||
|         return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&%2%3") | ||||
|             .arg(args.addonId) | ||||
| @@ -53,11 +53,16 @@ class FlameAPI : public NetworkModAPI { | ||||
|     }; | ||||
|  | ||||
|    public: | ||||
|     static auto getMappedModLoader(const ModLoaderType type) -> const ModLoaderType | ||||
|     static auto getMappedModLoader(const ModLoaderTypes loaders) -> const int | ||||
|     { | ||||
|         // https://docs.curseforge.com/?http#tocS_ModLoaderType | ||||
|         if (loaders & Forge) | ||||
|             return 1; | ||||
|         if (loaders & Fabric) | ||||
|             return 4; | ||||
|         // TODO: remove this once Quilt drops official Fabric support | ||||
|         if (type == Quilt)  // NOTE: Most if not all Fabric mods should work *currently* | ||||
|             return Fabric; | ||||
|         return type; | ||||
|         if (loaders & Quilt)  // NOTE: Most if not all Fabric mods should work *currently* | ||||
|             return 4;  // Quilt would probably be 5 | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
|   | ||||
| @@ -28,30 +28,25 @@ class ModrinthAPI : public NetworkModAPI { | ||||
|    public: | ||||
|     inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; }; | ||||
|  | ||||
|     static auto getModLoaderStrings(ModLoaderType type) -> const QStringList | ||||
|     static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList | ||||
|     { | ||||
|         QStringList l; | ||||
|         switch (type) | ||||
|         for (auto loader : {Forge, Fabric, Quilt}) | ||||
|         { | ||||
|             case Unspecified: | ||||
|                 for (auto loader : {Forge, Fabric, Quilt}) | ||||
|                 { | ||||
|                     l << ModAPI::getModLoaderString(loader); | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|             case Quilt: | ||||
|                 l << ModAPI::getModLoaderString(Fabric); | ||||
|             default: | ||||
|                 l << ModAPI::getModLoaderString(type); | ||||
|             if (types & loader || types == Unspecified) | ||||
|             { | ||||
|                 l << ModAPI::getModLoaderString(loader); | ||||
|             } | ||||
|         } | ||||
|         if (types & Quilt && ~types & Fabric)  // Add Fabric if Quilt is in use, if Fabric isn't already there | ||||
|             l << ModAPI::getModLoaderString(Fabric); | ||||
|         return l; | ||||
|     } | ||||
|  | ||||
|     static auto getModLoaderFilters(ModLoaderType type) -> const QString | ||||
|     static auto getModLoaderFilters(ModLoaderTypes types) -> const QString | ||||
|     { | ||||
|         QStringList l; | ||||
|         for (auto loader : getModLoaderStrings(type)) | ||||
|         for (auto loader : getModLoaderStrings(types)) | ||||
|         { | ||||
|             l << QString("\"categories:%1\"").arg(loader); | ||||
|         } | ||||
| @@ -61,7 +56,7 @@ class ModrinthAPI : public NetworkModAPI { | ||||
|    private: | ||||
|     inline auto getModSearchURL(SearchArgs& args) const -> QString override | ||||
|     { | ||||
|         if (!validateModLoader(args.mod_loader)) { | ||||
|         if (!validateModLoaders(args.loaders)) { | ||||
|             qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; | ||||
|             return ""; | ||||
|         } | ||||
| @@ -76,7 +71,7 @@ class ModrinthAPI : public NetworkModAPI { | ||||
|             .arg(args.offset) | ||||
|             .arg(args.search) | ||||
|             .arg(args.sorting) | ||||
|             .arg(getModLoaderFilters(args.mod_loader)) | ||||
|             .arg(getModLoaderFilters(args.loaders)) | ||||
|             .arg(getGameVersionsArray(args.versions)); | ||||
|     }; | ||||
|  | ||||
| @@ -88,7 +83,7 @@ class ModrinthAPI : public NetworkModAPI { | ||||
|                        "loaders=[\"%3\"]") | ||||
|             .arg(args.addonId) | ||||
|             .arg(getGameVersionsString(args.mcVersions)) | ||||
|             .arg(getModLoaderStrings(args.loader).join("\",\"")); | ||||
|             .arg(getModLoaderStrings(args.loaders).join("\",\"")); | ||||
|     }; | ||||
|  | ||||
|     auto getGameVersionsArray(std::list<Version> mcVersions) const -> QString | ||||
| @@ -101,9 +96,9 @@ class ModrinthAPI : public NetworkModAPI { | ||||
|         return s.isEmpty() ? QString() : QString("[%1],").arg(s); | ||||
|     } | ||||
|  | ||||
|     inline auto validateModLoader(ModLoaderType modLoader) const -> bool | ||||
|     inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool | ||||
|     { | ||||
|         return modLoader == Unspecified || modLoader == Forge || modLoader == Fabric || modLoader == Quilt; | ||||
|         return loaders == Unspecified || loaders & (Forge | Fabric | Quilt); | ||||
|     } | ||||
|  | ||||
| }; | ||||
|   | ||||
| @@ -391,7 +391,7 @@ void ModFolderPage::on_actionInstall_mods_triggered() | ||||
|         return; //this is a null instance or a legacy instance | ||||
|     } | ||||
|     auto profile = ((MinecraftInstance *)m_inst)->getPackProfile(); | ||||
|     if (profile->getModLoader() == ModAPI::Unspecified) { | ||||
|     if (profile->getModLoaders() == ModAPI::Unspecified) { | ||||
|         QMessageBox::critical(this,tr("Error"),tr("Please install a mod loader first!")); | ||||
|         return; | ||||
|     } | ||||
|   | ||||
| @@ -68,7 +68,7 @@ void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) | ||||
| { | ||||
|     auto profile = (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))->getPackProfile(); | ||||
|  | ||||
|     m_parent->apiProvider()->getVersions(this, { current.addonId.toString(), getMineVersions(), profile->getModLoader() }); | ||||
|     m_parent->apiProvider()->getVersions(this, { current.addonId.toString(), getMineVersions(), profile->getModLoaders() }); | ||||
| } | ||||
|  | ||||
| void ListModel::performPaginatedSearch() | ||||
| @@ -76,7 +76,7 @@ void ListModel::performPaginatedSearch() | ||||
|     auto profile = (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))->getPackProfile(); | ||||
|  | ||||
|     m_parent->apiProvider()->searchMods( | ||||
|         this, { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], profile->getModLoader(), getMineVersions() }); | ||||
|         this, { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], profile->getModLoaders(), getMineVersions() }); | ||||
| } | ||||
|  | ||||
| void ListModel::refresh() | ||||
|   | ||||
| @@ -175,7 +175,7 @@ void ModPage::updateModVersions(int prev_count) | ||||
|         bool valid = false; | ||||
|         for(auto& mcVer : m_filter->versions){ | ||||
|             //NOTE: Flame doesn't care about loader, so passing it changes nothing. | ||||
|             if (validateVersion(version, mcVer.toString(), packProfile->getModLoader())) { | ||||
|             if (validateVersion(version, mcVer.toString(), packProfile->getModLoaders())) { | ||||
|                 valid = true; | ||||
|                 break; | ||||
|             } | ||||
|   | ||||
| @@ -37,7 +37,7 @@ class ModPage : public QWidget, public BasePage { | ||||
|     void retranslate() override; | ||||
|  | ||||
|     auto shouldDisplay() const -> bool override = 0; | ||||
|     virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader = ModAPI::Unspecified) const -> bool = 0; | ||||
|     virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders = ModAPI::Unspecified) const -> bool = 0; | ||||
|  | ||||
|     auto apiProvider() const -> const ModAPI* { return api.get(); }; | ||||
|     auto getFilter() const -> const std::shared_ptr<ModFilterWidget::Filter> { return m_filter; } | ||||
|   | ||||
| @@ -61,9 +61,9 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) | ||||
|     connect(ui->modSelectionButton, &QPushButton::clicked, this, &FlameModPage::onModSelected); | ||||
| } | ||||
|  | ||||
| auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader) const -> bool | ||||
| auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders) const -> bool | ||||
| { | ||||
|     Q_UNUSED(loader); | ||||
|     Q_UNUSED(loaders); | ||||
|     return ver.mcVersion.contains(mineVer); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -55,7 +55,7 @@ class FlameModPage : public ModPage { | ||||
|     inline auto debugName() const -> QString override { return "Flame"; } | ||||
|     inline auto metaEntryBase() const -> QString override { return "FlameMods"; }; | ||||
|  | ||||
|     auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader = ModAPI::Unspecified) const -> bool override; | ||||
|     auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders = ModAPI::Unspecified) const -> bool override; | ||||
|  | ||||
|     auto shouldDisplay() const -> bool override; | ||||
| }; | ||||
|   | ||||
| @@ -61,9 +61,9 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instan | ||||
|     connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthModPage::onModSelected); | ||||
| } | ||||
|  | ||||
| auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader) const -> bool | ||||
| auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders) const -> bool | ||||
| { | ||||
|     auto loaderStrings = ModrinthAPI::getModLoaderStrings(loader); | ||||
|     auto loaderStrings = ModrinthAPI::getModLoaderStrings(loaders); | ||||
|  | ||||
|     auto loaderCompatible = false; | ||||
|     for (auto remoteLoader : ver.loaders) | ||||
|   | ||||
| @@ -55,7 +55,7 @@ class ModrinthModPage : public ModPage { | ||||
|     inline auto debugName() const -> QString override { return "Modrinth"; } | ||||
|     inline auto metaEntryBase() const -> QString override { return "ModrinthPacks"; }; | ||||
|  | ||||
|     auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderType loader = ModAPI::Unspecified) const -> bool override; | ||||
|     auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders = ModAPI::Unspecified) const -> bool override; | ||||
|  | ||||
|     auto shouldDisplay() const -> bool override; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user