GH-2859 remove twitch page and modpack import from URL
The functionality was broken, beyond repair and an ongoing maintenance nightmare.
This commit is contained in:
parent
47ed2f48d4
commit
af5120c828
@ -455,8 +455,6 @@ set(FLAME_SOURCES
|
|||||||
modplatform/flame/PackManifest.cpp
|
modplatform/flame/PackManifest.cpp
|
||||||
modplatform/flame/FileResolvingTask.h
|
modplatform/flame/FileResolvingTask.h
|
||||||
modplatform/flame/FileResolvingTask.cpp
|
modplatform/flame/FileResolvingTask.cpp
|
||||||
modplatform/flame/UrlResolvingTask.h
|
|
||||||
modplatform/flame/UrlResolvingTask.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_unit_test(Index
|
add_unit_test(Index
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
#include "UrlResolvingTask.h"
|
|
||||||
#include <QtXml>
|
|
||||||
#include <Json.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
const char * metabase = "https://cursemeta.dries007.net";
|
|
||||||
}
|
|
||||||
|
|
||||||
Flame::UrlResolvingTask::UrlResolvingTask(const QString& toProcess)
|
|
||||||
: m_url(toProcess)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::executeTask()
|
|
||||||
{
|
|
||||||
resolveUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::resolveUrl()
|
|
||||||
{
|
|
||||||
setStatus(tr("Resolving URL..."));
|
|
||||||
setProgress(0, 1);
|
|
||||||
QUrl actualUrl(m_url);
|
|
||||||
if(actualUrl.host() != "www.curseforge.com") {
|
|
||||||
emitFailed(tr("Not a Twitch URL."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_dljob.reset(new NetJob("URL resolver"));
|
|
||||||
|
|
||||||
bool weAreDigging = false;
|
|
||||||
needle = QString();
|
|
||||||
|
|
||||||
if(m_url.startsWith("https://")) {
|
|
||||||
if(m_url.endsWith("?client=y")) {
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download?client=y
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088?client=y
|
|
||||||
m_url.chop(9);
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088
|
|
||||||
}
|
|
||||||
if(m_url.endsWith("/download")) {
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download -> need to dig inside html...
|
|
||||||
weAreDigging = true;
|
|
||||||
needle = m_url;
|
|
||||||
needle.replace("https://", "twitch://");
|
|
||||||
needle.replace("/download", "/download-client/");
|
|
||||||
m_url.append("?client=y");
|
|
||||||
} else if (m_url.contains("/download/")) {
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088
|
|
||||||
m_url.replace("/download/", "/download-client/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(m_url.startsWith("twitch://")) {
|
|
||||||
// twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
|
|
||||||
m_url.replace(0, 9, "https://");
|
|
||||||
// https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
|
|
||||||
}
|
|
||||||
auto dl = Net::Download::makeByteArray(QUrl(m_url), &results);
|
|
||||||
m_dljob->addNetAction(dl);
|
|
||||||
if(weAreDigging) {
|
|
||||||
connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processHTML);
|
|
||||||
} else {
|
|
||||||
connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCCIP);
|
|
||||||
}
|
|
||||||
m_dljob->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::processHTML()
|
|
||||||
{
|
|
||||||
QString htmlDoc = QString::fromUtf8(results);
|
|
||||||
auto index = htmlDoc.indexOf(needle);
|
|
||||||
if(index < 0) {
|
|
||||||
emitFailed(tr("Couldn't find the needle in the haystack..."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto indexStart = index;
|
|
||||||
int indexEnd = -1;
|
|
||||||
while((index + 1) < htmlDoc.size() && htmlDoc[index] != '"') {
|
|
||||||
index ++;
|
|
||||||
if(htmlDoc[index] == '"') {
|
|
||||||
indexEnd = index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(indexEnd > 0) {
|
|
||||||
QString found = htmlDoc.mid(indexStart, indexEnd - indexStart);
|
|
||||||
qDebug() << "Found needle: " << found;
|
|
||||||
// twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
|
|
||||||
m_url = found;
|
|
||||||
resolveUrl();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emitFailed(tr("Couldn't find the end of the needle in the haystack..."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::processCCIP()
|
|
||||||
{
|
|
||||||
QDomDocument doc;
|
|
||||||
if (!doc.setContent(results)) {
|
|
||||||
qDebug() << results;
|
|
||||||
emitFailed(tr("Resolving failed."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto packageNode = doc.namedItem("package");
|
|
||||||
if(!packageNode.isElement()) {
|
|
||||||
emitFailed(tr("Resolving failed: missing package root element."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto projectNode = packageNode.namedItem("project");
|
|
||||||
if(!projectNode.isElement()) {
|
|
||||||
emitFailed(tr("Resolving failed: missing project element."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto attribs = projectNode.attributes();
|
|
||||||
|
|
||||||
auto projectIdNode = attribs.namedItem("id");
|
|
||||||
if(!projectIdNode.isAttr()) {
|
|
||||||
emitFailed(tr("Resolving failed: missing id attribute."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto fileIdNode = attribs.namedItem("file");
|
|
||||||
if(!fileIdNode.isAttr()) {
|
|
||||||
emitFailed(tr("Resolving failed: missing file attribute."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto projectId = projectIdNode.nodeValue();
|
|
||||||
auto fileId = fileIdNode.nodeValue();
|
|
||||||
bool success = true;
|
|
||||||
m_result.projectId = projectId.toInt(&success);
|
|
||||||
if(!success) {
|
|
||||||
emitFailed(tr("Failed to resolve projectId as a number."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_result.fileId = fileId.toInt(&success);
|
|
||||||
if(!success) {
|
|
||||||
emitFailed(tr("Failed to resolve fileId as a number."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qDebug() << "Resolved" << m_url << "as" << m_result.projectId << "/" << m_result.fileId;
|
|
||||||
resolveIDs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::resolveIDs()
|
|
||||||
{
|
|
||||||
setStatus(tr("Resolving mod IDs..."));
|
|
||||||
m_dljob.reset(new NetJob("Mod id resolver"));
|
|
||||||
auto projectIdStr = QString::number(m_result.projectId);
|
|
||||||
auto fileIdStr = QString::number(m_result.fileId);
|
|
||||||
QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr);
|
|
||||||
auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results);
|
|
||||||
m_dljob->addNetAction(dl);
|
|
||||||
connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCursemeta);
|
|
||||||
m_dljob->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flame::UrlResolvingTask::processCursemeta()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if(m_result.parseFromBytes(results)) {
|
|
||||||
emitSucceeded();
|
|
||||||
qDebug() << results;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (const JSONValidationError &e) {
|
|
||||||
|
|
||||||
qCritical() << "Resolving of" << m_result.projectId << m_result.fileId << "failed because of a parsing error:";
|
|
||||||
qCritical() << e.cause();
|
|
||||||
qCritical() << "JSON:";
|
|
||||||
qCritical() << results;
|
|
||||||
}
|
|
||||||
emitFailed(tr("Failed to resolve the modpack file."));
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "tasks/Task.h"
|
|
||||||
#include "net/NetJob.h"
|
|
||||||
#include "PackManifest.h"
|
|
||||||
|
|
||||||
#include "multimc_logic_export.h"
|
|
||||||
|
|
||||||
namespace Flame
|
|
||||||
{
|
|
||||||
class MULTIMC_LOGIC_EXPORT UrlResolvingTask : public Task
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit UrlResolvingTask(const QString &toProcess);
|
|
||||||
virtual ~UrlResolvingTask() {};
|
|
||||||
|
|
||||||
const Flame::File &getResults() const
|
|
||||||
{
|
|
||||||
return m_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void executeTask() override;
|
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void processCCIP();
|
|
||||||
void processHTML();
|
|
||||||
void processCursemeta();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void resolveUrl();
|
|
||||||
void resolveIDs();
|
|
||||||
|
|
||||||
private: /* data */
|
|
||||||
QString m_url;
|
|
||||||
QString needle;
|
|
||||||
Flame::File m_result;
|
|
||||||
QByteArray results;
|
|
||||||
NetJobPtr m_dljob;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -133,8 +133,6 @@ SET(MULTIMC_SOURCES
|
|||||||
pages/modplatform/legacy_ftb/Page.h
|
pages/modplatform/legacy_ftb/Page.h
|
||||||
pages/modplatform/legacy_ftb/ListModel.h
|
pages/modplatform/legacy_ftb/ListModel.h
|
||||||
pages/modplatform/legacy_ftb/ListModel.cpp
|
pages/modplatform/legacy_ftb/ListModel.cpp
|
||||||
pages/modplatform/TwitchPage.cpp
|
|
||||||
pages/modplatform/TwitchPage.h
|
|
||||||
pages/modplatform/ImportPage.cpp
|
pages/modplatform/ImportPage.cpp
|
||||||
pages/modplatform/ImportPage.h
|
pages/modplatform/ImportPage.h
|
||||||
|
|
||||||
@ -277,7 +275,6 @@ SET(MULTIMC_UIS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(MULTIMC_QRCS
|
set(MULTIMC_QRCS
|
||||||
resources/assets/assets.qrc
|
|
||||||
resources/backgrounds/backgrounds.qrc
|
resources/backgrounds/backgrounds.qrc
|
||||||
resources/multimc/multimc.qrc
|
resources/multimc/multimc.qrc
|
||||||
resources/pe_dark/pe_dark.qrc
|
resources/pe_dark/pe_dark.qrc
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include "widgets/PageContainer.h"
|
#include "widgets/PageContainer.h"
|
||||||
#include <pages/modplatform/VanillaPage.h>
|
#include <pages/modplatform/VanillaPage.h>
|
||||||
#include <pages/modplatform/legacy_ftb/Page.h>
|
#include <pages/modplatform/legacy_ftb/Page.h>
|
||||||
#include <pages/modplatform/TwitchPage.h>
|
|
||||||
#include <pages/modplatform/ImportPage.h>
|
#include <pages/modplatform/ImportPage.h>
|
||||||
|
|
||||||
|
|
||||||
@ -95,15 +94,9 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
|
|||||||
if(!url.isEmpty())
|
if(!url.isEmpty())
|
||||||
{
|
{
|
||||||
QUrl actualUrl(url);
|
QUrl actualUrl(url);
|
||||||
if(actualUrl.host() == "www.curseforge.com") {
|
|
||||||
m_container->selectPage("twitch");
|
|
||||||
twitchPage->setUrl(url);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_container->selectPage("import");
|
m_container->selectPage("import");
|
||||||
importPage->setUrl(url);
|
importPage->setUrl(url);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
updateDialogState();
|
updateDialogState();
|
||||||
|
|
||||||
@ -126,13 +119,11 @@ void NewInstanceDialog::accept()
|
|||||||
QList<BasePage *> NewInstanceDialog::getPages()
|
QList<BasePage *> NewInstanceDialog::getPages()
|
||||||
{
|
{
|
||||||
importPage = new ImportPage(this);
|
importPage = new ImportPage(this);
|
||||||
twitchPage = new TwitchPage(this);
|
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
new VanillaPage(this),
|
new VanillaPage(this),
|
||||||
importPage,
|
importPage,
|
||||||
new LegacyFTB::Page(this),
|
new LegacyFTB::Page(this),
|
||||||
twitchPage
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ class NewInstanceDialog;
|
|||||||
class PageContainer;
|
class PageContainer;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class ImportPage;
|
class ImportPage;
|
||||||
class TwitchPage;
|
|
||||||
|
|
||||||
class NewInstanceDialog : public QDialog, public BasePageProvider
|
class NewInstanceDialog : public QDialog, public BasePageProvider
|
||||||
{
|
{
|
||||||
@ -68,7 +67,6 @@ private:
|
|||||||
|
|
||||||
QString InstIconKey;
|
QString InstIconKey;
|
||||||
ImportPage *importPage = nullptr;
|
ImportPage *importPage = nullptr;
|
||||||
TwitchPage *twitchPage = nullptr;
|
|
||||||
std::unique_ptr<InstanceTask> creationTask;
|
std::unique_ptr<InstanceTask> creationTask;
|
||||||
|
|
||||||
bool importIcon = false;
|
bool importIcon = false;
|
||||||
|
@ -43,7 +43,6 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(multimc);
|
Q_INIT_RESOURCE(multimc);
|
||||||
Q_INIT_RESOURCE(backgrounds);
|
Q_INIT_RESOURCE(backgrounds);
|
||||||
Q_INIT_RESOURCE(assets);
|
|
||||||
|
|
||||||
Q_INIT_RESOURCE(pe_dark);
|
Q_INIT_RESOURCE(pe_dark);
|
||||||
Q_INIT_RESOURCE(pe_light);
|
Q_INIT_RESOURCE(pe_light);
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
#include "TwitchPage.h"
|
|
||||||
#include "ui_TwitchPage.h"
|
|
||||||
|
|
||||||
#include "MultiMC.h"
|
|
||||||
#include "dialogs/NewInstanceDialog.h"
|
|
||||||
#include <InstanceImportTask.h>
|
|
||||||
|
|
||||||
TwitchPage::TwitchPage(NewInstanceDialog* dialog, QWidget *parent)
|
|
||||||
: QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
connect(ui->checkButton, &QPushButton::clicked, this, &TwitchPage::triggerCheck);
|
|
||||||
connect(ui->twitchLabel, &DropLabel::droppedURLs, [this](QList<QUrl> urls){
|
|
||||||
if(urls.size()) {
|
|
||||||
setUrl(urls[0].toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
TwitchPage::~TwitchPage()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TwitchPage::shouldDisplay() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwitchPage::openedImpl()
|
|
||||||
{
|
|
||||||
dialog->setSuggestedPack();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwitchPage::triggerCheck(bool)
|
|
||||||
{
|
|
||||||
if(m_modIdResolver) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto task = new Flame::UrlResolvingTask(ui->lineEdit->text());
|
|
||||||
connect(task, &Task::finished, this, &TwitchPage::checkDone);
|
|
||||||
m_modIdResolver.reset(task);
|
|
||||||
task->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwitchPage::setUrl(const QString& url)
|
|
||||||
{
|
|
||||||
ui->lineEdit->setText(url);
|
|
||||||
triggerCheck(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TwitchPage::checkDone()
|
|
||||||
{
|
|
||||||
auto result = m_modIdResolver->getResults();
|
|
||||||
auto formatted = QString("Project %1, File %2").arg(result.projectId).arg(result.fileId);
|
|
||||||
if(result.resolved && result.type == Flame::File::Type::Modpack) {
|
|
||||||
ui->twitchLabel->setText(formatted);
|
|
||||||
QFileInfo fi(result.fileName);
|
|
||||||
dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(result.url));
|
|
||||||
} else {
|
|
||||||
ui->twitchLabel->setPixmap(QPixmap(QString::fromUtf8(":/assets/deadglitch")));
|
|
||||||
dialog->setSuggestedPack();
|
|
||||||
}
|
|
||||||
m_modIdResolver.reset();
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/* Copyright 2013-2019 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 "modplatform/flame/UrlResolvingTask.h"
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class TwitchPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewInstanceDialog;
|
|
||||||
|
|
||||||
class TwitchPage : public QWidget, public BasePage
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit TwitchPage(NewInstanceDialog* dialog, QWidget *parent = 0);
|
|
||||||
virtual ~TwitchPage();
|
|
||||||
virtual QString displayName() const override
|
|
||||||
{
|
|
||||||
return tr("Twitch URL");
|
|
||||||
}
|
|
||||||
virtual QIcon icon() const override
|
|
||||||
{
|
|
||||||
return MMC->getThemedIcon("twitch");
|
|
||||||
}
|
|
||||||
virtual QString id() const override
|
|
||||||
{
|
|
||||||
return "twitch";
|
|
||||||
}
|
|
||||||
virtual QString helpPage() const override
|
|
||||||
{
|
|
||||||
return "Twitch-platform";
|
|
||||||
}
|
|
||||||
virtual bool shouldDisplay() const override;
|
|
||||||
|
|
||||||
void openedImpl() override;
|
|
||||||
|
|
||||||
void setUrl(const QString & url);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void triggerCheck(bool checked);
|
|
||||||
void checkDone();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::TwitchPage *ui = nullptr;
|
|
||||||
NewInstanceDialog* dialog = nullptr;
|
|
||||||
shared_qobject_ptr<Flame::UrlResolvingTask> m_modIdResolver;
|
|
||||||
};
|
|
@ -1,79 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>TwitchPage</class>
|
|
||||||
<widget class="QWidget" name="TwitchPage">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>666</width>
|
|
||||||
<height>424</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="1" column="0" colspan="3">
|
|
||||||
<widget class="DropLabel" name="twitchLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>40</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="pixmap">
|
|
||||||
<pixmap resource="../../resources/assets/assets.qrc">:/assets/deadglitch</pixmap>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="checkButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Check</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Twitch URL:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEdit"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="3">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Drag and drop an Install button from CurseForge into the area above.</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>DropLabel</class>
|
|
||||||
<extends>QLabel</extends>
|
|
||||||
<header>widgets/DropLabel.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>lineEdit</tabstop>
|
|
||||||
<tabstop>checkButton</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources>
|
|
||||||
<include location="../../resources/assets/assets.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@ -1,6 +0,0 @@
|
|||||||
<!DOCTYPE RCC>
|
|
||||||
<RCC version="1.0">
|
|
||||||
<qresource prefix="/assets">
|
|
||||||
<file alias="deadglitch">deadglitch.svg</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
@ -1,66 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
class="tw-svg__asset tw-svg__asset--deadglitch tw-svg__asset--inherit"
|
|
||||||
width="92px"
|
|
||||||
height="96px"
|
|
||||||
version="1.1"
|
|
||||||
viewBox="0 0 30 30"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
id="svg8"
|
|
||||||
sodipodi:docname="deadglitch.svg"
|
|
||||||
inkscape:version="0.92.2 2405546, 2018-03-11">
|
|
||||||
<metadata
|
|
||||||
id="metadata14">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<defs
|
|
||||||
id="defs12" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1353"
|
|
||||||
inkscape:window-height="828"
|
|
||||||
id="namedview10"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="4.9166667"
|
|
||||||
inkscape:cx="44.285787"
|
|
||||||
inkscape:cy="52.833458"
|
|
||||||
inkscape:window-x="2958"
|
|
||||||
inkscape:window-y="702"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="svg8" />
|
|
||||||
<g
|
|
||||||
id="g6"
|
|
||||||
style="fill:#898395;fill-opacity:1">
|
|
||||||
<path
|
|
||||||
d="M26,17.4589613 L26,3 L4,3 L4,22.0601057 L10.0032868,22.0601057 L10.0032868,26 L14.0004537,22.0601057 L21.3322933,22.0601057 L26,17.4589613 L26,17.4589613 Z M21.0896458,26.0850335 L15.1583403,26.0850335 L11.2051771,30 L7.24798611,30 L7.24798611,26.0850335 L0,26.0850335 L0,5.21746493 L1.97773958,0 L29,0 L29,18.2620736 L21.0896458,26.0850335 L21.0896458,26.0850335 Z"
|
|
||||||
id="path2"
|
|
||||||
style="fill:#898395;fill-opacity:1" />
|
|
||||||
<path
|
|
||||||
d="M20.8587626,12.1710126 L22.4052753,13.7175252 L23.7175252,12.4052753 L22.1710126,10.8587626 L23.7175252,9.31224999 L22.4052753,8 L20.8587626,9.54651264 L19.31225,8 L18,9.31224999 L19.5465126,10.8587626 L18,12.4052753 L19.31225,13.7175252 L20.8587626,12.1710126 Z M11.8587626,12.1710126 L13.4052753,13.7175252 L14.7175252,12.4052753 L13.1710126,10.8587626 L14.7175252,9.31224999 L13.4052753,8 L11.8587626,9.54651264 L10.31225,8 L9,9.31224999 L10.5465126,10.8587626 L9,12.4052753 L10.31225,13.7175252 L11.8587626,12.1710126 Z"
|
|
||||||
id="path4"
|
|
||||||
style="fill:#898395;fill-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue
Block a user