NOISSUE Redo Curse import on top of modpacks.ch API

This commit is contained in:
Petr Mrázek
2022-05-17 00:22:23 +02:00
parent 40e67d2bc6
commit ceaea5db2f
17 changed files with 460 additions and 51 deletions

View File

@@ -735,12 +735,14 @@ SET(LAUNCHER_SOURCES
ui/pages/modplatform/atlauncher/AtlPage.cpp ui/pages/modplatform/atlauncher/AtlPage.cpp
ui/pages/modplatform/atlauncher/AtlPage.h ui/pages/modplatform/atlauncher/AtlPage.h
ui/pages/modplatform/ftb/FtbFilterModel.cpp ui/pages/modplatform/modpacksch/MCHFilterModel.cpp
ui/pages/modplatform/ftb/FtbFilterModel.h ui/pages/modplatform/modpacksch/MCHFilterModel.h
ui/pages/modplatform/ftb/FtbListModel.cpp ui/pages/modplatform/modpacksch/MCHListModel.cpp
ui/pages/modplatform/ftb/FtbListModel.h ui/pages/modplatform/modpacksch/MCHListModel.h
ui/pages/modplatform/ftb/FtbPage.cpp ui/pages/modplatform/modpacksch/FtbPage.cpp
ui/pages/modplatform/ftb/FtbPage.h ui/pages/modplatform/modpacksch/FtbPage.h
ui/pages/modplatform/modpacksch/CursePage.cpp
ui/pages/modplatform/modpacksch/CursePage.h
ui/pages/modplatform/legacy_ftb/Page.cpp ui/pages/modplatform/legacy_ftb/Page.cpp
ui/pages/modplatform/legacy_ftb/Page.h ui/pages/modplatform/legacy_ftb/Page.h
@@ -881,7 +883,8 @@ qt5_wrap_ui(LAUNCHER_UI
ui/pages/modplatform/flame/FlamePage.ui ui/pages/modplatform/flame/FlamePage.ui
ui/pages/modplatform/legacy_ftb/Page.ui ui/pages/modplatform/legacy_ftb/Page.ui
ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/ImportPage.ui
ui/pages/modplatform/ftb/FtbPage.ui ui/pages/modplatform/modpacksch/FtbPage.ui
ui/pages/modplatform/modpacksch/CursePage.ui
ui/pages/modplatform/modrinth/ModrinthPage.ui ui/pages/modplatform/modrinth/ModrinthPage.ui
ui/pages/modplatform/technic/TechnicPage.ui ui/pages/modplatform/technic/TechnicPage.ui
ui/widgets/InstanceCardWidget.ui ui/widgets/InstanceCardWidget.ui

View File

@@ -30,7 +30,7 @@ class PackInstallTask : public InstanceTask
Q_OBJECT Q_OBJECT
public: public:
explicit PackInstallTask(Modpack pack, QString version, PackType type = PackType::ModpacksCH); explicit PackInstallTask(Modpack pack, QString version, PackType type = PackType::FTB);
virtual ~PackInstallTask(){} virtual ~PackInstallTask(){}
bool canAbort() const override { return true; } bool canAbort() const override { return true; }

View File

@@ -22,6 +22,7 @@
#include <QUrl> #include <QUrl>
#include <QJsonObject> #include <QJsonObject>
#include <QMetaType> #include <QMetaType>
#include "MCHPackType.h"
namespace ModpacksCH namespace ModpacksCH
{ {
@@ -72,16 +73,17 @@ struct VersionInfo
struct Modpack struct Modpack
{ {
int id; PackType packType = PackType::FTB;
int id = 0;
QString name; QString name;
QString synopsis; QString synopsis;
QString description; QString description;
QString type; QString type;
bool featured; bool featured = false;
int installs; int installs = 0;
int plays; int plays = 0;
int64_t updated; int64_t updated = 0;
int64_t refreshed; int64_t refreshed = 0;
QVector<Art> art; QVector<Art> art;
QVector<Author> authors; QVector<Author> authors;
QVector<VersionInfo> versions; QVector<VersionInfo> versions;

View File

@@ -23,7 +23,7 @@ namespace ModpacksCH {
QString getRealmForPackType(PackType type) QString getRealmForPackType(PackType type)
{ {
switch (type) { switch (type) {
case PackType::ModpacksCH: case PackType::FTB:
return "modpack"; return "modpack";
case PackType::CurseForge: case PackType::CurseForge:
return "curseforge"; return "curseforge";

View File

@@ -21,7 +21,7 @@
namespace ModpacksCH { namespace ModpacksCH {
enum class PackType { enum class PackType {
ModpacksCH, FTB,
CurseForge, CurseForge,
}; };

View File

@@ -35,7 +35,8 @@
#include "ui/widgets/PageContainer.h" #include "ui/widgets/PageContainer.h"
#include "ui/pages/modplatform/VanillaPage.h" #include "ui/pages/modplatform/VanillaPage.h"
#include "ui/pages/modplatform/atlauncher/AtlPage.h" #include "ui/pages/modplatform/atlauncher/AtlPage.h"
#include "ui/pages/modplatform/ftb/FtbPage.h" #include "ui/pages/modplatform/modpacksch/FtbPage.h"
#include "ui/pages/modplatform/modpacksch/CursePage.h"
#include "ui/pages/modplatform/legacy_ftb/Page.h" #include "ui/pages/modplatform/legacy_ftb/Page.h"
#include "ui/pages/modplatform/flame/FlamePage.h" #include "ui/pages/modplatform/flame/FlamePage.h"
#include "ui/pages/modplatform/ImportPage.h" #include "ui/pages/modplatform/ImportPage.h"
@@ -125,14 +126,13 @@ void NewInstanceDialog::accept()
QList<BasePage *> NewInstanceDialog::getPages() QList<BasePage *> NewInstanceDialog::getPages()
{ {
importPage = new ImportPage(this); importPage = new ImportPage(this);
flamePage = new FlamePage(this);
auto technicPage = new TechnicPage(this); auto technicPage = new TechnicPage(this);
return return
{ {
new VanillaPage(this), new VanillaPage(this),
importPage, importPage,
new AtlPage(this), new AtlPage(this),
flamePage, new CursePage(this),
new FtbPage(this), new FtbPage(this),
new LegacyFTB::Page(this), new LegacyFTB::Page(this),
new ModrinthPage(this), new ModrinthPage(this),

View File

@@ -29,7 +29,6 @@ class NewInstanceDialog;
class PageContainer; class PageContainer;
class QDialogButtonBox; class QDialogButtonBox;
class ImportPage; class ImportPage;
class FlamePage;
class NewInstanceDialog : public QDialog, public BasePageProvider class NewInstanceDialog : public QDialog, public BasePageProvider
{ {
@@ -69,7 +68,6 @@ private:
QString InstIconKey; QString InstIconKey;
ImportPage *importPage = nullptr; ImportPage *importPage = nullptr;
FlamePage *flamePage = nullptr;
std::unique_ptr<InstanceTask> creationTask; std::unique_ptr<InstanceTask> creationTask;
bool importIcon = false; bool importIcon = false;

View File

@@ -0,0 +1,168 @@
/*
* Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
* Copyright 2021 Philip T <me@phit.link>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "CursePage.h"
#include "ui_CursePage.h"
#include <QKeyEvent>
#include "ui/dialogs/NewInstanceDialog.h"
#include "modplatform/modpacksch/FTBPackInstallTask.h"
#include "HoeDown.h"
CursePage::CursePage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), ui(new Ui::CursePage), dialog(dialog)
{
ui->setupUi(this);
connect(ui->searchButton, &QPushButton::clicked, this, &CursePage::triggerSearch);
filterModel = new ModpacksCH::FilterModel(this);
listModel = new ModpacksCH::ListModel(this);
filterModel->setSourceModel(listModel);
ui->packView->setModel(filterModel);
ui->packView->setSortingEnabled(true);
ui->packView->header()->hide();
ui->packView->setIndentation(0);
ui->searchEdit->installEventFilter(this);
ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
for(int i = 0; i < filterModel->getAvailableSortings().size(); i++)
{
ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i));
}
ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting());
connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &CursePage::onSortingSelectionChanged);
connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &CursePage::onSelectionChanged);
connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &CursePage::onVersionSelectionChanged);
}
CursePage::~CursePage()
{
delete ui;
}
bool CursePage::eventFilter(QObject* watched, QEvent* event)
{
if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return) {
triggerSearch();
keyEvent->accept();
return true;
}
}
return QWidget::eventFilter(watched, event);
}
bool CursePage::shouldDisplay() const
{
return true;
}
void CursePage::openedImpl()
{
if(!initialised)
{
initialised = true;
}
suggestCurrent();
}
void CursePage::suggestCurrent()
{
if(!isOpened)
{
return;
}
if (selectedVersion.isEmpty())
{
dialog->setSuggestedPack();
return;
}
auto & selectedPack = selected;
dialog->setSuggestedPack(selectedVersion, new ModpacksCH::PackInstallTask(selectedPack, selectedVersion, selected.packType));
for(auto art : selectedPack.art) {
if(art.type == "square") {
QString editedLogoName;
editedLogoName = selectedPack.name;
listModel->getLogo(selectedPack.name, art.url, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName);
});
}
}
}
void CursePage::triggerSearch()
{
listModel->requestCurse(ui->searchEdit->text());
}
void CursePage::onSortingSelectionChanged(QString data)
{
auto toSet = filterModel->getAvailableSortings().value(data);
filterModel->setSorting(toSet);
}
void CursePage::onSelectionChanged(QModelIndex first, QModelIndex second)
{
ui->versionSelectionBox->clear();
if(!first.isValid())
{
if(isOpened)
{
dialog->setSuggestedPack();
}
return;
}
selected = filterModel->data(first, Qt::UserRole).value<ModpacksCH::Modpack>();
auto & selectedPack = selected;
HoeDown hoedown;
QString output = hoedown.process(selectedPack.description.toUtf8());
ui->packDescription->setHtml(output);
// reverse foreach, so that the newest versions are first
for (auto i = selectedPack.versions.size(); i--;) {
ui->versionSelectionBox->addItem(selectedPack.versions.at(i).name);
}
suggestCurrent();
}
void CursePage::onVersionSelectionChanged(QString data)
{
if(data.isNull() || data.isEmpty())
{
selectedVersion = "";
return;
}
selectedVersion = data;
suggestCurrent();
}

View File

@@ -0,0 +1,83 @@
/* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "MCHFilterModel.h"
#include "MCHListModel.h"
#include <QWidget>
#include "Application.h"
#include "ui/pages/BasePage.h"
#include "tasks/Task.h"
namespace Ui
{
class CursePage;
}
class NewInstanceDialog;
class CursePage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit CursePage(NewInstanceDialog* dialog, QWidget *parent = 0);
virtual ~CursePage();
virtual QString displayName() const override
{
return tr("CurseForge");
}
virtual QIcon icon() const override
{
return APPLICATION->getThemedIcon("flame");
}
virtual QString id() const override
{
return "flame";
}
virtual QString helpPage() const override
{
return "Flame-platform";
}
virtual bool shouldDisplay() const override;
void openedImpl() override;
bool eventFilter(QObject * watched, QEvent * event) override;
private:
void suggestCurrent();
private slots:
void triggerSearch();
void onSortingSelectionChanged(QString data);
void onSelectionChanged(QModelIndex first, QModelIndex second);
void onVersionSelectionChanged(QString data);
private:
Ui::CursePage *ui = nullptr;
NewInstanceDialog* dialog = nullptr;
ModpacksCH::ListModel* listModel = nullptr;
ModpacksCH::FilterModel* filterModel = nullptr;
ModpacksCH::Modpack selected;
QString selectedVersion;
bool initialised { false };
};

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CursePage</class>
<widget class="QWidget" name="CursePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>875</width>
<height>745</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLineEdit" name="searchEdit">
<property name="placeholderText">
<string>Search...</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="searchButton">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTreeView" name="packView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTextBrowser" name="packDescription">
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
<item row="0" column="2">
<widget class="QComboBox" name="versionSelectionBox"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Version selected:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="sortByBox"/>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>searchEdit</tabstop>
<tabstop>versionSelectionBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -30,8 +30,8 @@ FtbPage::FtbPage(NewInstanceDialog* dialog, QWidget *parent)
{ {
ui->setupUi(this); ui->setupUi(this);
filterModel = new Ftb::FilterModel(this); filterModel = new ModpacksCH::FilterModel(this);
listModel = new Ftb::ListModel(this); listModel = new ModpacksCH::ListModel(this);
filterModel->setSourceModel(listModel); filterModel->setSourceModel(listModel);
ui->packView->setModel(filterModel); ui->packView->setModel(filterModel);
ui->packView->setSortingEnabled(true); ui->packView->setSortingEnabled(true);
@@ -102,13 +102,14 @@ void FtbPage::suggestCurrent()
return; return;
} }
dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ModpacksCH::PackInstallTask(selected, selectedVersion)); auto & selectedPack = selected;
for(auto art : selected.art) { dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ModpacksCH::PackInstallTask(selectedPack, selectedVersion, selected.packType));
for(auto art : selectedPack.art) {
if(art.type == "square") { if(art.type == "square") {
QString editedLogoName; QString editedLogoName;
editedLogoName = selected.name; editedLogoName = selectedPack.name;
listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo) listModel->getLogo(selectedPack.name, art.url, [this, editedLogoName](QString logo)
{ {
dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName); dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName);
}); });
@@ -141,14 +142,15 @@ void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second)
} }
selected = filterModel->data(first, Qt::UserRole).value<ModpacksCH::Modpack>(); selected = filterModel->data(first, Qt::UserRole).value<ModpacksCH::Modpack>();
auto & selectedPack = selected;
HoeDown hoedown; HoeDown hoedown;
QString output = hoedown.process(selected.description.toUtf8()); QString output = hoedown.process(selectedPack.description.toUtf8());
ui->packDescription->setHtml(output); ui->packDescription->setHtml(output);
// reverse foreach, so that the newest versions are first // reverse foreach, so that the newest versions are first
for (auto i = selected.versions.size(); i--;) { for (auto i = selectedPack.versions.size(); i--;) {
ui->versionSelectionBox->addItem(selected.versions.at(i).name); ui->versionSelectionBox->addItem(selectedPack.versions.at(i).name);
} }
suggestCurrent(); suggestCurrent();

View File

@@ -15,8 +15,8 @@
#pragma once #pragma once
#include "FtbFilterModel.h" #include "MCHFilterModel.h"
#include "FtbListModel.h" #include "MCHListModel.h"
#include <QWidget> #include <QWidget>
@@ -73,8 +73,8 @@ private slots:
private: private:
Ui::FtbPage *ui = nullptr; Ui::FtbPage *ui = nullptr;
NewInstanceDialog* dialog = nullptr; NewInstanceDialog* dialog = nullptr;
Ftb::ListModel* listModel = nullptr; ModpacksCH::ListModel* listModel = nullptr;
Ftb::FilterModel* filterModel = nullptr; ModpacksCH::FilterModel* filterModel = nullptr;
ModpacksCH::Modpack selected; ModpacksCH::Modpack selected;
QString selectedVersion; QString selectedVersion;

View File

@@ -14,14 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
#include "FtbFilterModel.h" #include "MCHFilterModel.h"
#include <QDebug> #include <QDebug>
#include "modplatform/modpacksch/FTBPackManifest.h" #include "modplatform/modpacksch/FTBPackManifest.h"
#include <MMCStrings.h> #include <MMCStrings.h>
namespace Ftb { namespace ModpacksCH {
FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent)
{ {

View File

@@ -18,7 +18,7 @@
#include <QtCore/QSortFilterProxyModel> #include <QtCore/QSortFilterProxyModel>
namespace Ftb { namespace ModpacksCH {
class FilterModel : public QSortFilterProxyModel class FilterModel : public QSortFilterProxyModel
{ {

View File

@@ -14,15 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
#include "FtbListModel.h" #include "MCHListModel.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "Application.h" #include "Application.h"
#include "Json.h" #include "Json.h"
#include <QPainter> #include <QPainter>
#include <algorithm>
namespace Ftb { namespace ModpacksCH {
ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
{ {
@@ -50,7 +51,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const
return QString("INVALID INDEX %1").arg(pos); return QString("INVALID INDEX %1").arg(pos);
} }
ModpacksCH::Modpack pack = modpacks.at(pos); auto &pack = modpacks.at(pos);
if(role == Qt::DisplayRole) if(role == Qt::DisplayRole)
{ {
return pack.name; return pack.name;
@@ -103,6 +104,13 @@ void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallbac
void ListModel::request() void ListModel::request()
{ {
if(jobPtr) {
jobPtr->abort();
jobPtr.reset();
}
requestedPackType = PackType::FTB;
beginResetModel(); beginResetModel();
modpacks.clear(); modpacks.clear();
endResetModel(); endResetModel();
@@ -117,6 +125,29 @@ void ListModel::request()
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed); QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
} }
void ListModel::requestCurse(const QString & searchTerm) {
if(jobPtr) {
jobPtr->abort();
jobPtr.reset();
}
requestedPackType = PackType::CurseForge;
beginResetModel();
modpacks.clear();
endResetModel();
auto *netJob = new NetJob("Ftb::RequestCurse", APPLICATION->network());
auto url = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/search/25?term=" + searchTerm);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
jobPtr = netJob;
jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
}
void ListModel::requestFinished() void ListModel::requestFinished()
{ {
jobPtr.reset(); jobPtr.reset();
@@ -129,11 +160,22 @@ void ListModel::requestFinished()
qWarning() << response; qWarning() << response;
return; return;
} }
qDebug() << response;
auto packs = doc.object().value("packs").toArray(); if(requestedPackType == PackType::FTB) {
for(auto pack : packs) { auto packs = doc.object().value("packs").toArray();
auto packId = pack.toInt(); for(auto pack : packs) {
remainingPacks.append(packId); auto packId = pack.toInt();
remainingPacks.append({ModpacksCH::PackType::FTB, packId});
}
}
if(requestedPackType == PackType::CurseForge) {
auto cfpacks = doc.object().value("curseforge").toArray();
for(auto pack : cfpacks) {
auto packId = pack.toInt();
remainingPacks.append({ModpacksCH::PackType::CurseForge, packId});
}
} }
if(!remainingPacks.isEmpty()) { if(!remainingPacks.isEmpty()) {
@@ -151,8 +193,17 @@ void ListModel::requestFailed(QString reason)
void ListModel::requestPack() void ListModel::requestPack()
{ {
auto *netJob = new NetJob("Ftb::Search", APPLICATION->network()); auto *netJob = new NetJob("Ftb::Search", APPLICATION->network());
auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1").arg(currentPack); QString requestUrl;
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); switch(currentPack.type) {
case ModpacksCH::PackType::FTB: {
requestUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1").arg(currentPack.identifier);
break;
}
case ModpacksCH::PackType::CurseForge: {
requestUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/curseforge/%1").arg(currentPack.identifier);
}
}
netJob->addNetAction(Net::Download::makeByteArray(QUrl(requestUrl), &response));
jobPtr = netJob; jobPtr = netJob;
jobPtr->start(); jobPtr->start();
@@ -163,6 +214,7 @@ void ListModel::requestPack()
void ListModel::packRequestFinished() void ListModel::packRequestFinished()
{ {
jobPtr.reset(); jobPtr.reset();
auto type = currentPack.type;
remainingPacks.removeOne(currentPack); remainingPacks.removeOne(currentPack);
QJsonParseError parse_error; QJsonParseError parse_error;
@@ -176,10 +228,14 @@ void ListModel::packRequestFinished()
auto obj = doc.object(); auto obj = doc.object();
ModpacksCH::Modpack pack; Modpack pack;
try try
{ {
ModpacksCH::loadModpack(pack, obj); ModpacksCH::loadModpack(pack, obj);
pack.packType = type;
if(type == ModpacksCH::PackType::CurseForge) {
std::reverse(pack.versions.begin(), pack.versions.end());
}
} }
catch (const JSONValidationError &e) catch (const JSONValidationError &e)
{ {

View File

@@ -19,10 +19,11 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include "modplatform/modpacksch/FTBPackManifest.h" #include "modplatform/modpacksch/FTBPackManifest.h"
#include "modplatform/modpacksch/MCHPackType.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include <QIcon> #include <QIcon>
namespace Ftb { namespace ModpacksCH {
struct Logo { struct Logo {
QString fullpath; QString fullpath;
@@ -34,6 +35,14 @@ struct Logo {
typedef QMap<QString, Logo> LogoMap; typedef QMap<QString, Logo> LogoMap;
typedef std::function<void(QString)> LogoCallback; typedef std::function<void(QString)> LogoCallback;
struct PackCoord {
bool operator==(const PackCoord& other) {
return type == other.type && identifier == other.identifier;
}
PackType type;
int identifier;
};
class ListModel : public QAbstractListModel class ListModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
@@ -47,6 +56,7 @@ public:
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
void request(); void request();
void requestCurse(const QString & searchTerm);
void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
@@ -65,12 +75,13 @@ private:
void requestLogo(QString file, QString url); void requestLogo(QString file, QString url);
private: private:
QList<ModpacksCH::Modpack> modpacks; PackType requestedPackType = PackType::FTB;
QList<Modpack> modpacks;
LogoMap m_logoMap; LogoMap m_logoMap;
NetJob::Ptr jobPtr; NetJob::Ptr jobPtr;
int currentPack; PackCoord currentPack;
QList<int> remainingPacks; QList<PackCoord> remainingPacks;
QByteArray response; QByteArray response;
}; };