aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp119
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h18
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.cpp146
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h27
4 files changed, 166 insertions, 144 deletions
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index beb8aec1..d52a430e 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -1,7 +1,5 @@
#include "ModModel.h"
-#include "Json.h"
-
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
@@ -31,14 +29,6 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, profile->getModLoaders(), versions };
}
-ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
-{
- return { [this](auto& doc) {
- if (!s_running_models.constFind(this).value())
- return;
- searchRequestFinished(doc);
- } };
-}
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
{
@@ -54,28 +44,12 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en
return { pack, versions, profile->getModLoaders() };
}
-ResourceAPI::VersionSearchCallbacks ModModel::createVersionsCallbacks(QModelIndex& entry)
-{
- return { [this, entry](auto& doc, auto pack) {
- if (!s_running_models.constFind(this).value())
- return;
- versionRequestSucceeded(doc, pack, entry);
- } };
-}
ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(QModelIndex& entry)
{
auto& pack = m_packs[entry.row()];
return { pack };
}
-ResourceAPI::ProjectInfoCallbacks ModModel::createInfoCallbacks(QModelIndex& entry)
-{
- return { [this, entry](auto& doc, auto pack) {
- if (!s_running_models.constFind(this).value())
- return;
- infoRequestFinished(doc, pack, entry);
- } };
-}
void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filter_changed)
{
@@ -89,97 +63,4 @@ void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filte
refresh();
}
-/******** Request callbacks ********/
-
-void ModModel::searchRequestFinished(QJsonDocument& doc)
-{
- QList<ModPlatform::IndexedPack> newList;
- auto packs = documentToArray(doc);
-
- for (auto packRaw : packs) {
- auto packObj = packRaw.toObject();
-
- ModPlatform::IndexedPack pack;
- try {
- loadIndexedPack(pack, packObj);
- newList.append(pack);
- } catch (const JSONValidationError& e) {
- qWarning() << "Error while loading mod from " << debugName() << ": " << e.cause();
- continue;
- }
- }
-
- if (packs.size() < 25) {
- m_search_state = SearchState::Finished;
- } else {
- m_next_search_offset += 25;
- m_search_state = SearchState::CanFetchMore;
- }
-
- // When you have a Qt build with assertions turned on, proceeding here will abort the application
- if (newList.size() == 0)
- return;
-
- beginInsertRows(QModelIndex(), m_packs.size(), m_packs.size() + newList.size() - 1);
- m_packs.append(newList);
- endInsertRows();
-}
-
-void ModModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
-{
- qDebug() << "Loading mod info";
-
- auto current_pack = data(index, Qt::UserRole).value<ModPlatform::IndexedPack>();
-
- // Check if the index is still valid for this mod or not
- if (pack.addonId != current_pack.addonId)
- return;
-
- try {
- auto obj = Json::requireObject(doc);
- loadExtraPackInfo(current_pack, obj);
- } catch (const JSONValidationError& e) {
- qDebug() << doc;
- qWarning() << "Error while reading " << debugName() << " mod info: " << e.cause();
- }
-
- // Cache info :^)
- QVariant new_pack;
- new_pack.setValue(current_pack);
- if (!setData(index, new_pack, Qt::UserRole)) {
- qWarning() << "Failed to cache mod info!";
- return;
- }
-
- emit projectInfoUpdated();
-}
-
-void ModModel::versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
-{
- auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
-
- auto current_pack = data(index, Qt::UserRole).value<ModPlatform::IndexedPack>();
-
- // Check if the index is still valid for this mod or not
- if (pack.addonId != current_pack.addonId)
- return;
-
- try {
- loadIndexedPackVersions(current_pack, arr);
- } catch (const JSONValidationError& e) {
- qDebug() << doc;
- qWarning() << "Error while reading " << debugName() << " mod version: " << e.cause();
- }
-
- // Cache info :^)
- QVariant new_pack;
- new_pack.setValue(current_pack);
- if (!setData(index, new_pack, Qt::UserRole)) {
- qWarning() << "Failed to cache mod versions!";
- return;
- }
-
- emit versionListUpdated();
-}
-
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index 3aeba3ef..c705371a 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -23,29 +23,19 @@ class ModModel : public ResourceModel {
/* Ask the API for more information */
void searchWithTerm(const QString& term, unsigned int sort, bool filter_changed);
- virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
- virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
- virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
+ void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0;
+ void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override = 0;
+ void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override = 0;
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
public slots:
- void searchRequestFinished(QJsonDocument& doc);
- void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
- void versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
-
- public slots:
ResourceAPI::SearchArgs createSearchArguments() override;
- ResourceAPI::SearchCallbacks createSearchCallbacks() override;
-
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override;
- ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(QModelIndex&) override;
-
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override;
- ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) override;
protected:
- virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0;
+ auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0;
protected:
std::shared_ptr<ModFilterWidget::Filter> m_filter = nullptr;
diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp
index d9c30912..05d44ee2 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.cpp
+++ b/launcher/ui/pages/modplatform/ResourceModel.cpp
@@ -8,13 +8,11 @@
#include "Application.h"
#include "BuildConfig.h"
+#include "Json.h"
#include "net/Download.h"
#include "net/NetJob.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-
#include "modplatform/ModIndex.h"
#include "ui/widgets/ProjectItem.h"
@@ -129,9 +127,14 @@ void ResourceModel::search()
auto args{ createSearchArguments() };
auto callbacks{ createSearchCallbacks() };
- Q_ASSERT(callbacks.on_succeed);
// Use defaults if no callbacks are set
+ if (!callbacks.on_succeed)
+ callbacks.on_succeed = [this](auto& doc) {
+ if (!s_running_models.constFind(this).value())
+ return;
+ searchRequestSucceeded(doc);
+ };
if (!callbacks.on_fail)
callbacks.on_fail = [this](QString reason, int network_error_code) {
if (!s_running_models.constFind(this).value())
@@ -160,6 +163,14 @@ void ResourceModel::loadEntry(QModelIndex& entry)
auto args{ createVersionsArguments(entry) };
auto callbacks{ createVersionsCallbacks(entry) };
+ // Use default if no callbacks are set
+ if (!callbacks.on_succeed)
+ callbacks.on_succeed = [this, entry](auto& doc, auto pack) {
+ if (!s_running_models.constFind(this).value())
+ return;
+ versionRequestSucceeded(doc, pack, entry);
+ };
+
if (auto job = m_api->getProjectVersions(std::move(args), std::move(callbacks)); job)
runInfoJob(job);
}
@@ -168,6 +179,14 @@ void ResourceModel::loadEntry(QModelIndex& entry)
auto args{ createInfoArguments(entry) };
auto callbacks{ createInfoCallbacks(entry) };
+ // Use default if no callbacks are set
+ if (!callbacks.on_succeed)
+ callbacks.on_succeed = [this, entry](auto& doc, auto pack) {
+ if (!s_running_models.constFind(this).value())
+ return;
+ infoRequestSucceeded(doc, pack, entry);
+ };
+
if (auto job = m_api->getProjectInfo(std::move(args), std::move(callbacks)); job)
runInfoJob(job);
}
@@ -226,10 +245,10 @@ std::optional<ResourceAPI::SortingMethod> ResourceModel::getCurrentSortingMethod
{
std::optional<ResourceAPI::SortingMethod> sort{};
- { // Find sorting method by ID
+ { // Find sorting method by ID
auto sorting_methods = getSortingMethods();
auto method = std::find_if(sorting_methods.constBegin(), sorting_methods.constEnd(),
- [this](auto const& e) { return m_current_sort_index == e.index; });
+ [this](auto const& e) { return m_current_sort_index == e.index; });
if (method != sorting_methods.constEnd())
sort = *method;
}
@@ -279,6 +298,64 @@ std::optional<QIcon> ResourceModel::getIcon(QModelIndex& index, const QUrl& url)
return {};
}
+// No 'forgor to implement' shall pass here :blobfox_knife:
+#define NEED_FOR_CALLBACK_ASSERT(name) \
+ Q_ASSERT_X(0 != 0, #name, "You NEED to re-implement this if you intend on using the default callbacks.")
+
+QJsonArray ResourceModel::documentToArray(QJsonDocument& doc) const
+{
+ NEED_FOR_CALLBACK_ASSERT("documentToArray");
+ return {};
+}
+void ResourceModel::loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&)
+{
+ NEED_FOR_CALLBACK_ASSERT("loadIndexedPack");
+}
+void ResourceModel::loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&)
+{
+ NEED_FOR_CALLBACK_ASSERT("loadExtraPackInfo");
+}
+void ResourceModel::loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&)
+{
+ NEED_FOR_CALLBACK_ASSERT("loadIndexedPackVersions");
+}
+
+/* Default callbacks */
+
+void ResourceModel::searchRequestSucceeded(QJsonDocument& doc)
+{
+ QList<ModPlatform::IndexedPack> newList;
+ auto packs = documentToArray(doc);
+
+ for (auto packRaw : packs) {
+ auto packObj = packRaw.toObject();
+
+ ModPlatform::IndexedPack pack;
+ try {
+ loadIndexedPack(pack, packObj);
+ newList.append(pack);
+ } catch (const JSONValidationError& e) {
+ qWarning() << "Error while loading resource from " << debugName() << ": " << e.cause();
+ continue;
+ }
+ }
+
+ if (packs.size() < 25) {
+ m_search_state = SearchState::Finished;
+ } else {
+ m_next_search_offset += 25;
+ m_search_state = SearchState::CanFetchMore;
+ }
+
+ // When you have a Qt build with assertions turned on, proceeding here will abort the application
+ if (newList.size() == 0)
+ return;
+
+ beginInsertRows(QModelIndex(), m_packs.size(), m_packs.size() + newList.size() - 1);
+ m_packs.append(newList);
+ endInsertRows();
+}
+
void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
{
switch (network_error_code) {
@@ -289,8 +366,7 @@ void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
case 409:
// 409 Gone, notify user to update
QMessageBox::critical(nullptr, tr("Error"),
- QString("%1")
- .arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
+ QString("%1").arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
break;
}
@@ -309,4 +385,58 @@ void ResourceModel::searchRequestAborted()
search();
}
+void ResourceModel::versionRequestSucceeded(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
+{
+ auto current_pack = data(index, Qt::UserRole).value<ModPlatform::IndexedPack>();
+
+ // Check if the index is still valid for this resource or not
+ if (pack.addonId != current_pack.addonId)
+ return;
+
+ try {
+ auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
+ loadIndexedPackVersions(current_pack, arr);
+ } catch (const JSONValidationError& e) {
+ qDebug() << doc;
+ qWarning() << "Error while reading " << debugName() << " resource version: " << e.cause();
+ }
+
+ // Cache info :^)
+ QVariant new_pack;
+ new_pack.setValue(current_pack);
+ if (!setData(index, new_pack, Qt::UserRole)) {
+ qWarning() << "Failed to cache resource versions!";
+ return;
+ }
+
+ emit versionListUpdated();
+}
+
+void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
+{
+ auto current_pack = data(index, Qt::UserRole).value<ModPlatform::IndexedPack>();
+
+ // Check if the index is still valid for this resource or not
+ if (pack.addonId != current_pack.addonId)
+ return;
+
+ try {
+ auto obj = Json::requireObject(doc);
+ loadExtraPackInfo(current_pack, obj);
+ } catch (const JSONValidationError& e) {
+ qDebug() << doc;
+ qWarning() << "Error while reading " << debugName() << " resource info: " << e.cause();
+ }
+
+ // Cache info :^)
+ QVariant new_pack;
+ new_pack.setValue(current_pack);
+ if (!setData(index, new_pack, Qt::UserRole)) {
+ qWarning() << "Failed to cache resource info!";
+ return;
+ }
+
+ emit projectInfoUpdated();
+}
+
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
index 05aa6a94..d8be3b6b 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.h
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -57,13 +57,13 @@ class ResourceModel : public QAbstractListModel {
void setSearchTerm(QString term) { m_search_term = term; }
virtual ResourceAPI::SearchArgs createSearchArguments() = 0;
- virtual ResourceAPI::SearchCallbacks createSearchCallbacks() = 0;
+ virtual ResourceAPI::SearchCallbacks createSearchCallbacks() { return {}; }
virtual ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) = 0;
- virtual ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(QModelIndex&) = 0;
+ virtual ResourceAPI::VersionSearchCallbacks createVersionsCallbacks(QModelIndex&) { return {}; }
virtual ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) = 0;
- virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) = 0;
+ virtual ResourceAPI::ProjectInfoCallbacks createInfoCallbacks(QModelIndex&) { return {}; }
/** Requests the API for more entries. */
virtual void search();
@@ -86,6 +86,22 @@ class ResourceModel : public QAbstractListModel {
[[nodiscard]] auto getCurrentSortingMethodByIndex() const -> std::optional<ResourceAPI::SortingMethod>;
+ /** Converts a JSON document to a common array format.
+ *
+ * This is needed so that different providers, with different JSON structures, can be parsed
+ * uniformally. You NEED to re-implement this if you intend on using the default callbacks.
+ */
+ [[nodiscard]] virtual auto documentToArray(QJsonDocument&) const -> QJsonArray;
+
+ /** Functions to load data into a pack.
+ *
+ * Those are needed for the same reason as ddocumentToArray, and NEED to be re-implemented in the same way.
+ */
+
+ virtual void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&);
+ virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&);
+ virtual void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&);
+
protected:
const BaseInstance& m_base_instance;
@@ -114,9 +130,14 @@ class ResourceModel : public QAbstractListModel {
private:
/* Default search request callbacks */
+ void searchRequestSucceeded(QJsonDocument&);
void searchRequestFailed(QString reason, int network_error_code);
void searchRequestAborted();
+ void versionRequestSucceeded(QJsonDocument&, ModPlatform::IndexedPack&, const QModelIndex&);
+
+ void infoRequestSucceeded(QJsonDocument&, ModPlatform::IndexedPack&, const QModelIndex&);
+
signals:
void versionListUpdated();
void projectInfoUpdated();