Merge pull request #554 from PolyMC/more_paste_services
This commit is contained in:
		@@ -2,6 +2,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
 | 
			
		||||
 *  Copyright (C) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -36,6 +37,7 @@
 | 
			
		||||
#include "Application.h"
 | 
			
		||||
#include "BuildConfig.h"
 | 
			
		||||
 | 
			
		||||
#include "net/PasteUpload.h"
 | 
			
		||||
#include "ui/MainWindow.h"
 | 
			
		||||
#include "ui/InstanceWindow.h"
 | 
			
		||||
 | 
			
		||||
@@ -61,6 +63,7 @@
 | 
			
		||||
#include "ui/setupwizard/SetupWizard.h"
 | 
			
		||||
#include "ui/setupwizard/LanguageWizardPage.h"
 | 
			
		||||
#include "ui/setupwizard/JavaWizardPage.h"
 | 
			
		||||
#include "ui/setupwizard/PasteWizardPage.h"
 | 
			
		||||
 | 
			
		||||
#include "ui/dialogs/CustomMessageBox.h"
 | 
			
		||||
 | 
			
		||||
@@ -671,8 +674,31 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
 | 
			
		||||
 | 
			
		||||
        m_settings->registerSetting("UpdateDialogGeometry", "");
 | 
			
		||||
 | 
			
		||||
        // pastebin URL
 | 
			
		||||
        m_settings->registerSetting("PastebinURL", "https://0x0.st");
 | 
			
		||||
        // HACK: This code feels so stupid is there a less stupid way of doing this?
 | 
			
		||||
        {
 | 
			
		||||
            m_settings->registerSetting("PastebinURL", "");
 | 
			
		||||
            m_settings->registerSetting("PastebinType", PasteUpload::PasteType::Mclogs);
 | 
			
		||||
            m_settings->registerSetting("PastebinCustomAPIBase", "");
 | 
			
		||||
 | 
			
		||||
            QString pastebinURL = m_settings->get("PastebinURL").toString();
 | 
			
		||||
 | 
			
		||||
            bool userHadDefaultPastebin = pastebinURL == "https://0x0.st";
 | 
			
		||||
            if (!pastebinURL.isEmpty() && !userHadDefaultPastebin)
 | 
			
		||||
            {
 | 
			
		||||
                m_settings->set("PastebinType", PasteUpload::PasteType::NullPointer);
 | 
			
		||||
                m_settings->set("PastebinCustomAPIBase", pastebinURL);
 | 
			
		||||
                m_settings->reset("PastebinURL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            bool ok;
 | 
			
		||||
            int pasteType = m_settings->get("PastebinType").toInt(&ok);
 | 
			
		||||
            // If PastebinType is invalid then reset the related settings.
 | 
			
		||||
            if (!ok || !(PasteUpload::PasteType::First <= pasteType && pasteType <= PasteUpload::PasteType::Last))
 | 
			
		||||
            {
 | 
			
		||||
                m_settings->reset("PastebinType");
 | 
			
		||||
                m_settings->reset("PastebinCustomAPIBase");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_settings->registerSetting("CloseAfterLaunch", false);
 | 
			
		||||
        m_settings->registerSetting("QuitAfterGameStop", false);
 | 
			
		||||
@@ -899,7 +925,8 @@ bool Application::createSetupWizard()
 | 
			
		||||
            return true;
 | 
			
		||||
        return false;
 | 
			
		||||
    }();
 | 
			
		||||
    bool wizardRequired = javaRequired || languageRequired;
 | 
			
		||||
    bool pasteInterventionRequired = settings()->get("PastebinURL") != "";
 | 
			
		||||
    bool wizardRequired = javaRequired || languageRequired || pasteInterventionRequired;
 | 
			
		||||
 | 
			
		||||
    if(wizardRequired)
 | 
			
		||||
    {
 | 
			
		||||
@@ -913,6 +940,11 @@ bool Application::createSetupWizard()
 | 
			
		||||
        {
 | 
			
		||||
            m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pasteInterventionRequired)
 | 
			
		||||
        {
 | 
			
		||||
            m_setupWizard->addPage(new PasteWizardPage(m_setupWizard));
 | 
			
		||||
        }
 | 
			
		||||
        connect(m_setupWizard, &QDialog::finished, this, &Application::setupWizardFinished);
 | 
			
		||||
        m_setupWizard->show();
 | 
			
		||||
        return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -661,6 +661,8 @@ SET(LAUNCHER_SOURCES
 | 
			
		||||
    ui/setupwizard/JavaWizardPage.h
 | 
			
		||||
    ui/setupwizard/LanguageWizardPage.cpp
 | 
			
		||||
    ui/setupwizard/LanguageWizardPage.h
 | 
			
		||||
    ui/setupwizard/PasteWizardPage.cpp
 | 
			
		||||
    ui/setupwizard/PasteWizardPage.h
 | 
			
		||||
 | 
			
		||||
    # GUI - themes
 | 
			
		||||
    ui/themes/FusionTheme.cpp
 | 
			
		||||
@@ -890,6 +892,7 @@ SET(LAUNCHER_SOURCES
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
qt5_wrap_ui(LAUNCHER_UI
 | 
			
		||||
    ui/setupwizard/PasteWizardPage.ui
 | 
			
		||||
    ui/pages/global/AccountListPage.ui
 | 
			
		||||
    ui/pages/global/JavaPage.ui
 | 
			
		||||
    ui/pages/global/LauncherPage.ui
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-3.0-only
 | 
			
		||||
/*
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *  Copyright (C) 2022 Swirl <swurl@swurl.xyz>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -42,8 +44,22 @@
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
 | 
			
		||||
PasteUpload::PasteUpload(QWidget *window, QString text, QString url) : m_window(window), m_uploadUrl(url), m_text(text.toUtf8())
 | 
			
		||||
std::array<PasteUpload::PasteTypeInfo, 4> PasteUpload::PasteTypes = {
 | 
			
		||||
    {{"0x0.st", "https://0x0.st", ""},
 | 
			
		||||
     {"hastebin", "https://hst.sh", "/documents"},
 | 
			
		||||
     {"paste.gg", "https://paste.gg", "/api/v1/pastes"},
 | 
			
		||||
     {"mclo.gs", "https://api.mclo.gs", "/1/log"}}};
 | 
			
		||||
 | 
			
		||||
PasteUpload::PasteUpload(QWidget *window, QString text, QString baseUrl, PasteType pasteType) : m_window(window), m_baseUrl(baseUrl), m_pasteType(pasteType), m_text(text.toUtf8())
 | 
			
		||||
{
 | 
			
		||||
    if (m_baseUrl == "")
 | 
			
		||||
        m_baseUrl = PasteTypes.at(pasteType).defaultBase;
 | 
			
		||||
 | 
			
		||||
    // HACK: Paste's docs say the standard API path is at /api/<version> but the official instance paste.gg doesn't follow that??
 | 
			
		||||
    if (pasteType == PasteGG && m_baseUrl == PasteTypes.at(pasteType).defaultBase)
 | 
			
		||||
        m_uploadUrl = "https://api.paste.gg/v1/pastes";
 | 
			
		||||
    else
 | 
			
		||||
        m_uploadUrl = m_baseUrl + PasteTypes.at(pasteType).endpointPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PasteUpload::~PasteUpload()
 | 
			
		||||
@@ -53,26 +69,73 @@ PasteUpload::~PasteUpload()
 | 
			
		||||
void PasteUpload::executeTask()
 | 
			
		||||
{
 | 
			
		||||
    QNetworkRequest request{QUrl(m_uploadUrl)};
 | 
			
		||||
    QNetworkReply *rep{};
 | 
			
		||||
 | 
			
		||||
    request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED);
 | 
			
		||||
 | 
			
		||||
    QHttpMultiPart *multiPart = new QHttpMultiPart{QHttpMultiPart::FormDataType};
 | 
			
		||||
    switch (m_pasteType) {
 | 
			
		||||
    case NullPointer: {
 | 
			
		||||
        QHttpMultiPart *multiPart =
 | 
			
		||||
          new QHttpMultiPart{QHttpMultiPart::FormDataType};
 | 
			
		||||
 | 
			
		||||
    QHttpPart filePart;
 | 
			
		||||
    filePart.setBody(m_text);
 | 
			
		||||
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
 | 
			
		||||
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"file\"; filename=\"log.txt\"");
 | 
			
		||||
        QHttpPart filePart;
 | 
			
		||||
        filePart.setBody(m_text);
 | 
			
		||||
        filePart.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
 | 
			
		||||
        filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
 | 
			
		||||
                         "form-data; name=\"file\"; filename=\"log.txt\"");
 | 
			
		||||
        multiPart->append(filePart);
 | 
			
		||||
 | 
			
		||||
    multiPart->append(filePart);
 | 
			
		||||
        rep = APPLICATION->network()->post(request, multiPart);
 | 
			
		||||
        multiPart->setParent(rep);
 | 
			
		||||
 | 
			
		||||
    QNetworkReply *rep = APPLICATION->network()->post(request, multiPart);
 | 
			
		||||
    multiPart->setParent(rep);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case Hastebin: {
 | 
			
		||||
        request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED);
 | 
			
		||||
        rep = APPLICATION->network()->post(request, m_text);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case Mclogs: {
 | 
			
		||||
        QUrlQuery postData;
 | 
			
		||||
        postData.addQueryItem("content", m_text);
 | 
			
		||||
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
 | 
			
		||||
        rep = APPLICATION->network()->post(request, postData.toString().toUtf8());
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case PasteGG: {
 | 
			
		||||
        QJsonObject obj;
 | 
			
		||||
        QJsonDocument doc;
 | 
			
		||||
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
 | 
			
		||||
 | 
			
		||||
    m_reply = std::shared_ptr<QNetworkReply>(rep);
 | 
			
		||||
    setStatus(tr("Uploading to %1").arg(m_uploadUrl));
 | 
			
		||||
        obj.insert("expires", QDateTime::currentDateTimeUtc().addDays(100).toString(Qt::DateFormat::ISODate));
 | 
			
		||||
 | 
			
		||||
        QJsonArray files;
 | 
			
		||||
        QJsonObject logFileInfo;
 | 
			
		||||
        QJsonObject logFileContentInfo;
 | 
			
		||||
        logFileContentInfo.insert("format", "text");
 | 
			
		||||
        logFileContentInfo.insert("value", QString::fromUtf8(m_text));
 | 
			
		||||
        logFileInfo.insert("name", "log.txt");
 | 
			
		||||
        logFileInfo.insert("content", logFileContentInfo);
 | 
			
		||||
        files.append(logFileInfo);
 | 
			
		||||
 | 
			
		||||
        obj.insert("files", files);
 | 
			
		||||
 | 
			
		||||
        doc.setObject(obj);
 | 
			
		||||
        rep = APPLICATION->network()->post(request, doc.toJson());
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
 | 
			
		||||
    connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
 | 
			
		||||
    connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
 | 
			
		||||
    connect(rep, &QNetworkReply::finished, this, &PasteUpload::downloadFinished);
 | 
			
		||||
    // This function call would be a lot shorter if we were using the latest Qt
 | 
			
		||||
    connect(rep,
 | 
			
		||||
            static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
 | 
			
		||||
            this, &PasteUpload::downloadError);
 | 
			
		||||
 | 
			
		||||
    m_reply = std::shared_ptr<QNetworkReply>(rep);
 | 
			
		||||
 | 
			
		||||
    setStatus(tr("Uploading to %1").arg(m_uploadUrl));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PasteUpload::downloadError(QNetworkReply::NetworkError error)
 | 
			
		||||
@@ -102,6 +165,82 @@ void PasteUpload::downloadFinished()
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_pasteLink = QString::fromUtf8(data).trimmed();
 | 
			
		||||
    switch (m_pasteType)
 | 
			
		||||
    {
 | 
			
		||||
    case NullPointer:
 | 
			
		||||
        m_pasteLink = QString::fromUtf8(data).trimmed();
 | 
			
		||||
        break;
 | 
			
		||||
    case Hastebin: {
 | 
			
		||||
        QJsonDocument jsonDoc{QJsonDocument::fromJson(data)};
 | 
			
		||||
        QJsonObject jsonObj{jsonDoc.object()};
 | 
			
		||||
        if (jsonObj.contains("key") && jsonObj["key"].isString())
 | 
			
		||||
        {
 | 
			
		||||
            QString key = jsonDoc.object()["key"].toString();
 | 
			
		||||
            m_pasteLink = m_baseUrl + "/" + key;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl));
 | 
			
		||||
            qCritical() << m_uploadUrl << " returned malformed response body: " << data;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case Mclogs: {
 | 
			
		||||
        QJsonDocument jsonDoc{QJsonDocument::fromJson(data)};
 | 
			
		||||
        QJsonObject jsonObj{jsonDoc.object()};
 | 
			
		||||
        if (jsonObj.contains("success") && jsonObj["success"].isBool())
 | 
			
		||||
        {
 | 
			
		||||
            bool success = jsonObj["success"].toBool();
 | 
			
		||||
            if (success)
 | 
			
		||||
            {
 | 
			
		||||
                m_pasteLink = jsonObj["url"].toString();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                QString error = jsonObj["error"].toString();
 | 
			
		||||
                emitFailed(tr("Error: %1 returned an error: %2").arg(m_uploadUrl, error));
 | 
			
		||||
                qCritical() << m_uploadUrl << " returned error: " << error;
 | 
			
		||||
                qCritical() << "Response body: " << data;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl));
 | 
			
		||||
            qCritical() << m_uploadUrl << " returned malformed response body: " << data;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case PasteGG:
 | 
			
		||||
        QJsonDocument jsonDoc{QJsonDocument::fromJson(data)};
 | 
			
		||||
        QJsonObject jsonObj{jsonDoc.object()};
 | 
			
		||||
        if (jsonObj.contains("status") && jsonObj["status"].isString())
 | 
			
		||||
        {
 | 
			
		||||
            QString status = jsonObj["status"].toString();
 | 
			
		||||
            if (status == "success")
 | 
			
		||||
            {
 | 
			
		||||
                m_pasteLink = m_baseUrl + "/p/anonymous/" + jsonObj["result"].toObject()["id"].toString();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                QString error = jsonObj["error"].toString();
 | 
			
		||||
                QString message = (jsonObj.contains("message") && jsonObj["message"].isString()) ? jsonObj["message"].toString() : "none";
 | 
			
		||||
                emitFailed(tr("Error: %1 returned an error code: %2\nError message: %3").arg(m_uploadUrl, error, message));
 | 
			
		||||
                qCritical() << m_uploadUrl << " returned error: " << error;
 | 
			
		||||
                qCritical() << "Error message: " << message;
 | 
			
		||||
                qCritical() << "Response body: " << data;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            emitFailed(tr("Error: %1 returned a malformed response body").arg(m_uploadUrl));
 | 
			
		||||
            qCritical() << m_uploadUrl << " returned malformed response body: " << data;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    emitSucceeded();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-3.0-only
 | 
			
		||||
/*
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -36,14 +37,38 @@
 | 
			
		||||
 | 
			
		||||
#include "tasks/Task.h"
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
class PasteUpload : public Task
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    PasteUpload(QWidget *window, QString text, QString url);
 | 
			
		||||
    enum PasteType : int {
 | 
			
		||||
        // 0x0.st
 | 
			
		||||
        NullPointer,
 | 
			
		||||
        // hastebin.com
 | 
			
		||||
        Hastebin,
 | 
			
		||||
        // paste.gg
 | 
			
		||||
        PasteGG,
 | 
			
		||||
        // mclo.gs
 | 
			
		||||
        Mclogs,
 | 
			
		||||
        // Helpful to get the range of valid values on the enum for input sanitisation:
 | 
			
		||||
        First = NullPointer,
 | 
			
		||||
        Last = Mclogs
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct PasteTypeInfo {
 | 
			
		||||
        const QString name;
 | 
			
		||||
        const QString defaultBase;
 | 
			
		||||
        const QString endpointPath;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static std::array<PasteTypeInfo, 4> PasteTypes;
 | 
			
		||||
 | 
			
		||||
    PasteUpload(QWidget *window, QString text, QString url, PasteType pasteType);
 | 
			
		||||
    virtual ~PasteUpload();
 | 
			
		||||
 | 
			
		||||
    QString pasteLink()
 | 
			
		||||
@@ -56,7 +81,9 @@ protected:
 | 
			
		||||
private:
 | 
			
		||||
    QWidget *m_window;
 | 
			
		||||
    QString m_pasteLink;
 | 
			
		||||
    QString m_baseUrl;
 | 
			
		||||
    QString m_uploadUrl;
 | 
			
		||||
    PasteType m_pasteType;
 | 
			
		||||
    QByteArray m_text;
 | 
			
		||||
    std::shared_ptr<QNetworkReply> m_reply;
 | 
			
		||||
public
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,38 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-3.0-only
 | 
			
		||||
/*
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, version 3.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * This file incorporates work covered by the following copyright and
 | 
			
		||||
 * permission notice:
 | 
			
		||||
 *
 | 
			
		||||
 *      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 "GuiUtil.h"
 | 
			
		||||
 | 
			
		||||
#include <QClipboard>
 | 
			
		||||
@@ -16,8 +51,9 @@
 | 
			
		||||
QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget)
 | 
			
		||||
{
 | 
			
		||||
    ProgressDialog dialog(parentWidget);
 | 
			
		||||
    auto pasteUrlSetting = APPLICATION->settings()->get("PastebinURL").toString();
 | 
			
		||||
    std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, pasteUrlSetting));
 | 
			
		||||
    auto pasteTypeSetting = static_cast<PasteUpload::PasteType>(APPLICATION->settings()->get("PastebinType").toInt());
 | 
			
		||||
    auto pasteCustomAPIBaseSetting = APPLICATION->settings()->get("PastebinCustomAPIBase").toString();
 | 
			
		||||
    std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, pasteCustomAPIBaseSetting, pasteTypeSetting));
 | 
			
		||||
 | 
			
		||||
    dialog.execWithTask(paste.get());
 | 
			
		||||
    if (!paste->wasSuccessful())
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
 | 
			
		||||
 *  Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
 | 
			
		||||
 *  Copyright (c) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -46,16 +47,40 @@
 | 
			
		||||
#include "settings/SettingsObject.h"
 | 
			
		||||
#include "tools/BaseProfiler.h"
 | 
			
		||||
#include "Application.h"
 | 
			
		||||
#include "net/PasteUpload.h"
 | 
			
		||||
 | 
			
		||||
APIPage::APIPage(QWidget *parent) :
 | 
			
		||||
    QWidget(parent),
 | 
			
		||||
    ui(new Ui::APIPage)
 | 
			
		||||
{
 | 
			
		||||
    // This is here so you can reorder the entries in the combobox without messing stuff up
 | 
			
		||||
    int comboBoxEntries[] = {
 | 
			
		||||
        PasteUpload::PasteType::Mclogs,
 | 
			
		||||
        PasteUpload::PasteType::NullPointer,
 | 
			
		||||
        PasteUpload::PasteType::PasteGG,
 | 
			
		||||
        PasteUpload::PasteType::Hastebin
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static QRegularExpression validUrlRegExp("https?://.+");
 | 
			
		||||
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
    ui->urlChoices->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->urlChoices));
 | 
			
		||||
    ui->tabWidget->tabBar()->hide();\
 | 
			
		||||
 | 
			
		||||
    for (auto pasteType : comboBoxEntries) {
 | 
			
		||||
        ui->pasteTypeComboBox->addItem(PasteUpload::PasteTypes.at(pasteType).name, pasteType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void (QComboBox::*currentIndexChangedSignal)(int) (&QComboBox::currentIndexChanged);
 | 
			
		||||
    connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLPlaceholder);
 | 
			
		||||
    // This function needs to be called even when the ComboBox's index is still in its default state.
 | 
			
		||||
    updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex());
 | 
			
		||||
    ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry));
 | 
			
		||||
    ui->tabWidget->tabBar()->hide();
 | 
			
		||||
 | 
			
		||||
    loadSettings();
 | 
			
		||||
 | 
			
		||||
    resetBaseURLNote();
 | 
			
		||||
    connect(ui->pasteTypeComboBox, currentIndexChangedSignal, this, &APIPage::updateBaseURLNote);
 | 
			
		||||
    connect(ui->baseURLEntry, &QLineEdit::textEdited, this, &APIPage::resetBaseURLNote);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
APIPage::~APIPage()
 | 
			
		||||
@@ -63,11 +88,48 @@ APIPage::~APIPage()
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIPage::resetBaseURLNote()
 | 
			
		||||
{
 | 
			
		||||
    ui->baseURLNote->hide();
 | 
			
		||||
    baseURLPasteType = ui->pasteTypeComboBox->currentIndex();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIPage::updateBaseURLNote(int index)
 | 
			
		||||
{
 | 
			
		||||
    if (baseURLPasteType == index)
 | 
			
		||||
    {
 | 
			
		||||
        ui->baseURLNote->hide();
 | 
			
		||||
    }
 | 
			
		||||
    else if (!ui->baseURLEntry->text().isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        ui->baseURLNote->show();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIPage::updateBaseURLPlaceholder(int index)
 | 
			
		||||
{
 | 
			
		||||
    int pasteType = ui->pasteTypeComboBox->itemData(index).toInt();
 | 
			
		||||
    QString pasteDefaultURL = PasteUpload::PasteTypes.at(pasteType).defaultBase;
 | 
			
		||||
    ui->baseURLEntry->setPlaceholderText(pasteDefaultURL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIPage::loadSettings()
 | 
			
		||||
{
 | 
			
		||||
    auto s = APPLICATION->settings();
 | 
			
		||||
    QString pastebinURL = s->get("PastebinURL").toString();
 | 
			
		||||
    ui->urlChoices->setCurrentText(pastebinURL);
 | 
			
		||||
 | 
			
		||||
    int pasteType = s->get("PastebinType").toInt();
 | 
			
		||||
    QString pastebinURL = s->get("PastebinCustomAPIBase").toString();
 | 
			
		||||
 | 
			
		||||
    ui->baseURLEntry->setText(pastebinURL);
 | 
			
		||||
    int pasteTypeIndex = ui->pasteTypeComboBox->findData(pasteType);
 | 
			
		||||
    if (pasteTypeIndex == -1)
 | 
			
		||||
    {
 | 
			
		||||
        pasteTypeIndex = ui->pasteTypeComboBox->findData(PasteUpload::PasteType::Mclogs);
 | 
			
		||||
        ui->baseURLEntry->clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ui->pasteTypeComboBox->setCurrentIndex(pasteTypeIndex);
 | 
			
		||||
 | 
			
		||||
    QString msaClientID = s->get("MSAClientIDOverride").toString();
 | 
			
		||||
    ui->msaClientID->setText(msaClientID);
 | 
			
		||||
    QString curseKey = s->get("CFKeyOverride").toString();
 | 
			
		||||
@@ -77,8 +139,10 @@ void APIPage::loadSettings()
 | 
			
		||||
void APIPage::applySettings()
 | 
			
		||||
{
 | 
			
		||||
    auto s = APPLICATION->settings();
 | 
			
		||||
    QString pastebinURL = ui->urlChoices->currentText();
 | 
			
		||||
    s->set("PastebinURL", pastebinURL);
 | 
			
		||||
 | 
			
		||||
    s->set("PastebinType", ui->pasteTypeComboBox->currentData().toInt());
 | 
			
		||||
    s->set("PastebinCustomAPIBase", ui->baseURLEntry->text());
 | 
			
		||||
 | 
			
		||||
    QString msaClientID = ui->msaClientID->text();
 | 
			
		||||
    s->set("MSAClientIDOverride", msaClientID);
 | 
			
		||||
    QString curseKey = ui->curseKey->text();
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
 *  PolyMC - Minecraft Launcher
 | 
			
		||||
 *  Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
 | 
			
		||||
 *  Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
 | 
			
		||||
 *  Copyright (c) 2022 Lenny McLennington <lenny@sneed.church>
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -73,6 +74,10 @@ public:
 | 
			
		||||
    void retranslate() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    int baseURLPasteType;
 | 
			
		||||
    void resetBaseURLNote();
 | 
			
		||||
    void updateBaseURLNote(int index);
 | 
			
		||||
    void updateBaseURLPlaceholder(int index);
 | 
			
		||||
    void loadSettings();
 | 
			
		||||
    void applySettings();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>603</width>
 | 
			
		||||
    <height>530</height>
 | 
			
		||||
    <width>512</width>
 | 
			
		||||
    <height>538</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
@@ -36,60 +36,44 @@
 | 
			
		||||
       <item>
 | 
			
		||||
        <widget class="QGroupBox" name="groupBox_paste">
 | 
			
		||||
         <property name="title">
 | 
			
		||||
          <string>&Pastebin URL</string>
 | 
			
		||||
          <string>Pastebin Service</string>
 | 
			
		||||
         </property>
 | 
			
		||||
         <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="Line" name="line">
 | 
			
		||||
            <property name="orientation">
 | 
			
		||||
             <enum>Qt::Horizontal</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QLabel" name="label_2">
 | 
			
		||||
            <property name="font">
 | 
			
		||||
             <font>
 | 
			
		||||
              <pointsize>10</pointsize>
 | 
			
		||||
             </font>
 | 
			
		||||
            </property>
 | 
			
		||||
           <widget class="QLabel" name="pasteServiceTypeLabel">
 | 
			
		||||
            <property name="text">
 | 
			
		||||
             <string><html><head/><body><p>Note: only input that starts with <span style=" font-weight:600;">http://</span> or <span style=" font-weight:600;">https://</span> will be accepted.</p></body></html></string>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="scaledContents">
 | 
			
		||||
             <bool>false</bool>
 | 
			
		||||
             <string>Paste Service Type</string>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QComboBox" name="urlChoices">
 | 
			
		||||
            <property name="editable">
 | 
			
		||||
           <widget class="QComboBox" name="pasteTypeComboBox"/>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QLabel" name="baseURLLabel">
 | 
			
		||||
            <property name="text">
 | 
			
		||||
             <string>Base URL</string>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QLineEdit" name="baseURLEntry">
 | 
			
		||||
            <property name="placeholderText">
 | 
			
		||||
             <string/>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="clearButtonEnabled">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="insertPolicy">
 | 
			
		||||
             <enum>QComboBox::NoInsert</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <item>
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string notr="true">https://0x0.st</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </item>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QLabel" name="label">
 | 
			
		||||
           <widget class="QLabel" name="baseURLNote">
 | 
			
		||||
            <property name="text">
 | 
			
		||||
             <string><html><head/><body><p>Here you can choose from a predefined list of paste services, or input the URL of a different paste service of your choice, provided it supports the same protocol as 0x0.st, that is POST a file parameter to the URL and return a link in the response body.</p></body></html></string>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="textFormat">
 | 
			
		||||
             <enum>Qt::RichText</enum>
 | 
			
		||||
             <string>Note: you probably want to change or clear the Base URL after changing the paste service type.</string>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="wordWrap">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="openExternalLinks">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
         </layout>
 | 
			
		||||
@@ -101,13 +85,6 @@
 | 
			
		||||
          <string>&Microsoft Authentication</string>
 | 
			
		||||
         </property>
 | 
			
		||||
         <layout class="QVBoxLayout" name="verticalLayout_4">
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="Line" name="line_2">
 | 
			
		||||
            <property name="orientation">
 | 
			
		||||
             <enum>Qt::Horizontal</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QLabel" name="label_3">
 | 
			
		||||
            <property name="text">
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								launcher/ui/setupwizard/PasteWizardPage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								launcher/ui/setupwizard/PasteWizardPage.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#include "PasteWizardPage.h"
 | 
			
		||||
#include "ui_PasteWizardPage.h"
 | 
			
		||||
 | 
			
		||||
#include "Application.h"
 | 
			
		||||
#include "net/PasteUpload.h"
 | 
			
		||||
 | 
			
		||||
PasteWizardPage::PasteWizardPage(QWidget *parent) :
 | 
			
		||||
    BaseWizardPage(parent),
 | 
			
		||||
    ui(new Ui::PasteWizardPage)
 | 
			
		||||
{
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PasteWizardPage::~PasteWizardPage()
 | 
			
		||||
{
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PasteWizardPage::initializePage()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PasteWizardPage::validatePage()
 | 
			
		||||
{
 | 
			
		||||
    auto s = APPLICATION->settings();
 | 
			
		||||
    QString prevPasteURL = s->get("PastebinURL").toString();
 | 
			
		||||
    s->reset("PastebinURL");
 | 
			
		||||
    if (ui->previousSettingsRadioButton->isChecked())
 | 
			
		||||
    {
 | 
			
		||||
        bool usingDefaultBase = prevPasteURL == PasteUpload::PasteTypes.at(PasteUpload::PasteType::NullPointer).defaultBase;
 | 
			
		||||
        s->set("PastebinType", PasteUpload::PasteType::NullPointer);
 | 
			
		||||
        if (!usingDefaultBase)
 | 
			
		||||
            s->set("PastebinCustomAPIBase", prevPasteURL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PasteWizardPage::retranslate()
 | 
			
		||||
{
 | 
			
		||||
    ui->retranslateUi(this);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								launcher/ui/setupwizard/PasteWizardPage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								launcher/ui/setupwizard/PasteWizardPage.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
#ifndef PASTEDEFAULTSCONFIRMATIONWIZARD_H
 | 
			
		||||
#define PASTEDEFAULTSCONFIRMATIONWIZARD_H
 | 
			
		||||
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include "BaseWizardPage.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class PasteWizardPage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PasteWizardPage : public BaseWizardPage
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit PasteWizardPage(QWidget *parent = nullptr);
 | 
			
		||||
    ~PasteWizardPage();
 | 
			
		||||
 | 
			
		||||
    void initializePage() override;
 | 
			
		||||
    bool validatePage() override;
 | 
			
		||||
    void retranslate() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Ui::PasteWizardPage *ui;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // PASTEDEFAULTSCONFIRMATIONWIZARD_H
 | 
			
		||||
							
								
								
									
										80
									
								
								launcher/ui/setupwizard/PasteWizardPage.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								launcher/ui/setupwizard/PasteWizardPage.ui
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>PasteWizardPage</class>
 | 
			
		||||
 <widget class="QWidget" name="PasteWizardPage">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>400</width>
 | 
			
		||||
    <height>300</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Form</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="label">
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>The default paste service has changed to mclo.gs, please choose what you want to do with your settings.</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="wordWrap">
 | 
			
		||||
      <bool>true</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="Line" name="line">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QRadioButton" name="defaultSettingsRadioButton">
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>Use new default service</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checked">
 | 
			
		||||
      <bool>true</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <attribute name="buttonGroup">
 | 
			
		||||
      <string notr="true">buttonGroup</string>
 | 
			
		||||
     </attribute>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QRadioButton" name="previousSettingsRadioButton">
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>Keep previous settings</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checked">
 | 
			
		||||
      <bool>false</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <attribute name="buttonGroup">
 | 
			
		||||
      <string notr="true">buttonGroup</string>
 | 
			
		||||
     </attribute>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <spacer name="verticalSpacer">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Vertical</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="sizeHint" stdset="0">
 | 
			
		||||
      <size>
 | 
			
		||||
       <width>20</width>
 | 
			
		||||
       <height>156</height>
 | 
			
		||||
      </size>
 | 
			
		||||
     </property>
 | 
			
		||||
    </spacer>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
 <buttongroups>
 | 
			
		||||
  <buttongroup name="buttonGroup"/>
 | 
			
		||||
 </buttongroups>
 | 
			
		||||
</ui>
 | 
			
		||||
		Reference in New Issue
	
	Block a user