aboutsummaryrefslogtreecommitdiff
path: root/application/pages/modplatform/technic
diff options
context:
space:
mode:
Diffstat (limited to 'application/pages/modplatform/technic')
-rw-r--r--application/pages/modplatform/technic/TechnicData.h42
-rw-r--r--application/pages/modplatform/technic/TechnicModel.cpp238
-rw-r--r--application/pages/modplatform/technic/TechnicModel.h70
-rw-r--r--application/pages/modplatform/technic/TechnicPage.cpp198
-rw-r--r--application/pages/modplatform/technic/TechnicPage.h78
-rw-r--r--application/pages/modplatform/technic/TechnicPage.ui95
6 files changed, 0 insertions, 721 deletions
diff --git a/application/pages/modplatform/technic/TechnicData.h b/application/pages/modplatform/technic/TechnicData.h
deleted file mode 100644
index 50fd75e8..00000000
--- a/application/pages/modplatform/technic/TechnicData.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2020-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 <QList>
-#include <QString>
-
-namespace Technic {
-struct Modpack {
- QString slug;
-
- QString name;
- QString logoUrl;
- QString logoName;
-
- bool broken = true;
-
- QString url;
- bool isSolder = false;
- QString minecraftVersion;
-
- bool metadataLoaded = false;
- QString websiteUrl;
- QString author;
- QString description;
-};
-}
-
-Q_DECLARE_METATYPE(Technic::Modpack)
diff --git a/application/pages/modplatform/technic/TechnicModel.cpp b/application/pages/modplatform/technic/TechnicModel.cpp
deleted file mode 100644
index def30783..00000000
--- a/application/pages/modplatform/technic/TechnicModel.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Copyright 2020-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.
- */
-
-#include "TechnicModel.h"
-#include "Env.h"
-#include "MultiMC.h"
-#include "Json.h"
-
-#include <QIcon>
-
-Technic::ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-Technic::ListModel::~ListModel()
-{
-}
-
-QVariant Technic::ListModel::data(const QModelIndex& index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- Modpack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name;
- }
- else if(role == Qt::DecorationRole)
- {
- if(m_logoMap.contains(pack.logoName))
- {
- return (m_logoMap.value(pack.logoName));
- }
- QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
- ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl);
- return icon;
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
- return QVariant();
-}
-
-int Technic::ListModel::columnCount(const QModelIndex&) const
-{
- return 1;
-}
-
-int Technic::ListModel::rowCount(const QModelIndex&) const
-{
- return modpacks.size();
-}
-
-void Technic::ListModel::searchWithTerm(const QString& term)
-{
- if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) {
- return;
- }
- currentSearchTerm = term;
- if(jobPtr) {
- jobPtr->abort();
- searchState = ResetRequested;
- return;
- }
- else {
- beginResetModel();
- modpacks.clear();
- endResetModel();
- searchState = None;
- }
- performSearch();
-}
-
-void Technic::ListModel::performSearch()
-{
- NetJob *netJob = new NetJob("Technic::Search");
- QString searchUrl = "";
- if (currentSearchTerm.isEmpty()) {
- searchUrl = "https://api.technicpack.net/trending?build=multimc";
- }
- else
- {
- searchUrl = QString(
- "https://api.technicpack.net/search?build=multimc&q=%1"
- ).arg(currentSearchTerm);
- }
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
-}
-
-void Technic::ListModel::searchRequestFinished()
-{
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError)
- {
- qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- QList<Modpack> newList;
- try {
- auto root = Json::requireObject(doc);
- auto objs = Json::requireArray(root, "modpacks");
- for (auto technicPack: objs) {
- Modpack pack;
- auto technicPackObject = Json::requireObject(technicPack);
- pack.name = Json::requireString(technicPackObject, "name");
- pack.slug = Json::requireString(technicPackObject, "slug");
- if (pack.slug == "vanilla")
- continue;
-
- auto rawURL = Json::ensureString(technicPackObject, "iconUrl", "null");
- if(rawURL == "null") {
- pack.logoUrl = "null";
- pack.logoName = "null";
- }
- else {
- pack.logoUrl = rawURL;
- pack.logoName = rawURL.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0);
- }
- pack.broken = false;
- newList.append(pack);
- }
- }
- catch (const JSONValidationError &err)
- {
- qCritical() << "Couldn't parse technic search results:" << err.cause() ;
- return;
- }
- searchState = Finished;
- beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1);
- modpacks.append(newList);
- endInsertRows();
-}
-
-void Technic::ListModel::getLogo(const QString& logo, const QString& logoUrl, Technic::LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath());
- }
- else
- {
- requestLogo(logo, logoUrl);
- }
-}
-
-void Technic::ListModel::searchRequestFailed()
-{
- jobPtr.reset();
-
- if(searchState == ResetRequested)
- {
- beginResetModel();
- modpacks.clear();
- endResetModel();
-
- performSearch();
- }
- else
- {
- searchState = Finished;
- }
-}
-
-
-void Technic::ListModel::logoLoaded(QString logo, QString out)
-{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, QIcon(out));
- for(int i = 0; i < modpacks.size(); i++)
- {
- if(modpacks[i].logoName == logo)
- {
- emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole});
- }
- }
-}
-
-void Technic::ListModel::logoFailed(QString logo)
-{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
-}
-
-void Technic::ListModel::requestLogo(QString logo, QString url)
-{
- if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || logo == "null")
- {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo));
- NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo));
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
-
- auto fullPath = entry->getFullPath();
-
- QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath]
- {
- logoLoaded(logo, fullPath);
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, logo]
- {
- logoFailed(logo);
- });
-
- job->start();
-
- m_loadingLogos.append(logo);
-}
diff --git a/application/pages/modplatform/technic/TechnicModel.h b/application/pages/modplatform/technic/TechnicModel.h
deleted file mode 100644
index 82a03842..00000000
--- a/application/pages/modplatform/technic/TechnicModel.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2020-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 <QModelIndex>
-
-#include "TechnicData.h"
-#include "net/NetJob.h"
-
-namespace Technic {
-
-typedef std::function<void(QString)> LogoCallback;
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- ListModel(QObject *parent);
- virtual ~ListModel();
-
- virtual QVariant data(const QModelIndex& index, int role) const;
- virtual int columnCount(const QModelIndex& parent) const;
- virtual int rowCount(const QModelIndex& parent) const;
-
- void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
- void searchWithTerm(const QString & term);
-
-private slots:
- void searchRequestFinished();
- void searchRequestFailed();
-
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QString out);
-
-private:
- void performSearch();
- void requestLogo(QString logo, QString url);
-
-private:
- QList<Modpack> modpacks;
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- QMap<QString, QIcon> m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
-
- QString currentSearchTerm;
- enum SearchState {
- None,
- ResetRequested,
- Finished
- } searchState = None;
- NetJobPtr jobPtr;
- QByteArray response;
-};
-
-}
diff --git a/application/pages/modplatform/technic/TechnicPage.cpp b/application/pages/modplatform/technic/TechnicPage.cpp
deleted file mode 100644
index e836f767..00000000
--- a/application/pages/modplatform/technic/TechnicPage.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* 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.
- */
-
-#include "TechnicPage.h"
-#include "ui_TechnicPage.h"
-
-#include "MultiMC.h"
-#include "dialogs/NewInstanceDialog.h"
-#include "TechnicModel.h"
-#include <QKeyEvent>
-#include "modplatform/technic/SingleZipPackInstallTask.h"
-#include "modplatform/technic/SolderPackInstallTask.h"
-#include "Json.h"
-
-TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog)
-{
- ui->setupUi(this);
- connect(ui->searchButton, &QPushButton::clicked, this, &TechnicPage::triggerSearch);
- ui->searchEdit->installEventFilter(this);
- model = new Technic::ListModel(this);
- ui->packView->setModel(model);
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TechnicPage::onSelectionChanged);
-}
-
-bool TechnicPage::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);
-}
-
-TechnicPage::~TechnicPage()
-{
- delete ui;
-}
-
-bool TechnicPage::shouldDisplay() const
-{
- return true;
-}
-
-void TechnicPage::openedImpl()
-{
- suggestCurrent();
- triggerSearch();
-}
-
-void TechnicPage::triggerSearch() {
- model->searchWithTerm(ui->searchEdit->text());
-}
-
-void TechnicPage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- //ui->frame->clear();
- return;
- }
-
- current = model->data(first, Qt::UserRole).value<Technic::Modpack>();
- suggestCurrent();
-}
-
-void TechnicPage::suggestCurrent()
-{
- if (!isOpened)
- {
- return;
- }
- if (current.broken)
- {
- dialog->setSuggestedPack();
- return;
- }
-
- QString editedLogoName = "technic_" + current.logoName.section(".", 0, 0);
- model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
-
- if (current.metadataLoaded)
- {
- metadataLoaded();
- return;
- }
-
- NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
- std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
- QString slug = current.slug;
- netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.technicpack.net/modpack/%1?build=multimc").arg(slug), response.get()));
- QObject::connect(netJob, &NetJob::succeeded, this, [this, response, slug]
- {
- if (current.slug != slug)
- {
- return;
- }
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
- QJsonObject obj = doc.object();
- if(parse_error.error != QJsonParseError::NoError)
- {
- qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << *response;
- return;
- }
- if (!obj.contains("url"))
- {
- qWarning() << "Json doesn't contain an url key";
- return;
- }
- QJsonValueRef url = obj["url"];
- if (url.isString())
- {
- current.url = url.toString();
- }
- else
- {
- if (!obj.contains("solder"))
- {
- qWarning() << "Json doesn't contain a valid url or solder key";
- return;
- }
- QJsonValueRef solderUrl = obj["solder"];
- if (solderUrl.isString())
- {
- current.url = solderUrl.toString();
- current.isSolder = true;
- }
- else
- {
- qWarning() << "Json doesn't contain a valid url or solder key";
- return;
- }
- }
-
- current.minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
- current.websiteUrl = Json::ensureString(obj, "platformUrl", QString(), "__placeholder__");
- current.author = Json::ensureString(obj, "user", QString(), "__placeholder__");
- current.description = Json::ensureString(obj, "description", QString(), "__placeholder__");
- current.metadataLoaded = true;
- metadataLoaded();
- });
- netJob->start();
-}
-
-// expects current.metadataLoaded to be true
-void TechnicPage::metadataLoaded()
-{
- QString text = "";
- QString name = current.name;
-
- if (current.websiteUrl.isEmpty())
- // This allows injecting HTML here.
- text = name;
- else
- // URL not properly escaped for inclusion in HTML. The name allows for injecting HTML.
- text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>";
- if (!current.author.isEmpty()) {
- // This allows injecting HTML here
- text += tr(" by ") + current.author;
- }
-
- ui->frame->setModText(text);
- ui->frame->setModDescription(current.description);
- if (!current.isSolder)
- {
- dialog->setSuggestedPack(current.name, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion));
- }
- else
- {
- while (current.url.endsWith('/')) current.url.chop(1);
- dialog->setSuggestedPack(current.name, new Technic::SolderPackInstallTask(current.url + "/modpack/" + current.slug, current.minecraftVersion));
- }
-}
diff --git a/application/pages/modplatform/technic/TechnicPage.h b/application/pages/modplatform/technic/TechnicPage.h
deleted file mode 100644
index 27e1258a..00000000
--- a/application/pages/modplatform/technic/TechnicPage.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-#include "TechnicData.h"
-
-namespace Ui
-{
-class TechnicPage;
-}
-
-class NewInstanceDialog;
-
-namespace Technic {
- class ListModel;
-}
-
-class TechnicPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~TechnicPage();
- virtual QString displayName() const override
- {
- return tr("Technic");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("technic");
- }
- virtual QString id() const override
- {
- return "technic";
- }
- virtual QString helpPage() const override
- {
- return "Technic-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
-
- bool eventFilter(QObject* watched, QEvent* event) override;
-
-private:
- void suggestCurrent();
- void metadataLoaded();
-
-private slots:
- void triggerSearch();
- void onSelectionChanged(QModelIndex first, QModelIndex second);
-
-private:
- Ui::TechnicPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
- Technic::ListModel* model = nullptr;
- Technic::Modpack current;
-};
diff --git a/application/pages/modplatform/technic/TechnicPage.ui b/application/pages/modplatform/technic/TechnicPage.ui
deleted file mode 100644
index 2ca45dd2..00000000
--- a/application/pages/modplatform/technic/TechnicPage.ui
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>TechnicPage</class>
- <widget class="QWidget" name="TechnicPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>546</width>
- <height>405</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QWidget" name="widget" native="true">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter ...</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="searchButton">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="packView">
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="iconSize">
- <size>
- <width>48</width>
- <height>48</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <widget class="MCModInfoFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>MCModInfoFrame</class>
- <extends>QFrame</extends>
- <header>widgets/MCModInfoFrame.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>searchButton</tabstop>
- <tabstop>packView</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>