Merge pull request #678 from Scrumplex/improvements-around-proprietary-services

This commit is contained in:
Sefa Eyeoglu 2022-07-11 14:56:09 +02:00 committed by GitHub
commit 8f4d7ac655
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 223 additions and 59 deletions

View File

@ -131,7 +131,7 @@ set(Launcher_MSA_CLIENT_ID "549033b2-1532-4d4e-ae77-1bbaa46f9d74" CACHE STRING "
# By using this key in your builds you accept the terms and conditions laid down in # By using this key in your builds you accept the terms and conditions laid down in
# https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions # https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions
# NOTE: CurseForge requires you to change this if you make any kind of derivative work. # NOTE: CurseForge requires you to change this if you make any kind of derivative work.
set(Launcher_CURSEFORGE_API_KEY "$2a$10$1Oqr2MX3O4n/ilhFGc597u8tfI3L2Hyr9/rtWDAMRjghSQV2QUuxq" CACHE STRING "CurseForge API Key") set(Launcher_CURSEFORGE_API_KEY "$2a$10$1Oqr2MX3O4n/ilhFGc597u8tfI3L2Hyr9/rtWDAMRjghSQV2QUuxq" CACHE STRING "API key for the CurseForge platform")
#### Check the current Git commit and branch #### Check the current Git commit and branch

View File

@ -98,7 +98,7 @@ Config::Config()
HELP_URL = "@Launcher_HELP_URL@"; HELP_URL = "@Launcher_HELP_URL@";
IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@";
MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@"; MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@";
CURSEFORGE_API_KEY = "@Launcher_CURSEFORGE_API_KEY@"; FLAME_API_KEY = "@Launcher_CURSEFORGE_API_KEY@";
META_URL = "@Launcher_META_URL@"; META_URL = "@Launcher_META_URL@";
BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@"; BUG_TRACKER_URL = "@Launcher_BUG_TRACKER_URL@";

View File

@ -124,7 +124,7 @@ class Config {
/** /**
* Client API key for CurseForge * Client API key for CurseForge
*/ */
QString CURSEFORGE_API_KEY; QString FLAME_API_KEY;
/** /**
* Metadata repository URL prefix * Metadata repository URL prefix

View File

@ -711,9 +711,20 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("CloseAfterLaunch", false); m_settings->registerSetting("CloseAfterLaunch", false);
m_settings->registerSetting("QuitAfterGameStop", false); m_settings->registerSetting("QuitAfterGameStop", false);
// Custom MSA credentials // Custom Microsoft Authentication Client ID
m_settings->registerSetting("MSAClientIDOverride", ""); m_settings->registerSetting("MSAClientIDOverride", "");
m_settings->registerSetting("CFKeyOverride", "");
// Custom Flame API Key
{
m_settings->registerSetting("CFKeyOverride", "");
m_settings->registerSetting("FlameKeyOverride", "");
QString flameKey = m_settings->get("CFKeyOverride").toString();
if (!flameKey.isEmpty())
m_settings->set("FlameKeyOverride", flameKey);
m_settings->reset("CFKeyOverride");
}
m_settings->registerSetting("UserAgentOverride", ""); m_settings->registerSetting("UserAgentOverride", "");
// Init page provider // Init page provider
@ -1553,6 +1564,16 @@ shared_qobject_ptr<Meta::Index> Application::metadataIndex()
return m_metadataIndex; return m_metadataIndex;
} }
Application::Capabilities Application::currentCapabilities()
{
Capabilities c;
if (!getMSAClientID().isEmpty())
c |= SupportsMSA;
if (!getFlameAPIKey().isEmpty())
c |= SupportsFlame;
return c;
}
QString Application::getJarPath(QString jarFile) QString Application::getJarPath(QString jarFile)
{ {
QStringList potentialPaths = { QStringList potentialPaths = {
@ -1581,14 +1602,14 @@ QString Application::getMSAClientID()
return BuildConfig.MSA_CLIENT_ID; return BuildConfig.MSA_CLIENT_ID;
} }
QString Application::getCurseKey() QString Application::getFlameAPIKey()
{ {
QString keyOverride = m_settings->get("CFKeyOverride").toString(); QString keyOverride = m_settings->get("FlameKeyOverride").toString();
if (!keyOverride.isEmpty()) { if (!keyOverride.isEmpty()) {
return keyOverride; return keyOverride;
} }
return BuildConfig.CURSEFORGE_API_KEY; return BuildConfig.FLAME_API_KEY;
} }
QString Application::getUserAgent() QString Application::getUserAgent()

View File

@ -90,6 +90,14 @@ public:
Initialized Initialized
}; };
enum Capability {
None = 0,
SupportsMSA = 1 << 0,
SupportsFlame = 1 << 1,
};
Q_DECLARE_FLAGS(Capabilities, Capability)
public: public:
Application(int &argc, char **argv); Application(int &argc, char **argv);
virtual ~Application(); virtual ~Application();
@ -154,6 +162,8 @@ public:
shared_qobject_ptr<Meta::Index> metadataIndex(); shared_qobject_ptr<Meta::Index> metadataIndex();
Capabilities currentCapabilities();
/*! /*!
* Finds and returns the full path to a jar file. * Finds and returns the full path to a jar file.
* Returns a null-string if it could not be found. * Returns a null-string if it could not be found.
@ -161,7 +171,7 @@ public:
QString getJarPath(QString jarFile); QString getJarPath(QString jarFile);
QString getMSAClientID(); QString getMSAClientID();
QString getCurseKey(); QString getFlameAPIKey();
QString getUserAgent(); QString getUserAgent();
QString getUserAgentUncached(); QString getUserAgentUncached();

View File

@ -118,8 +118,9 @@ void Download::executeTask()
} }
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8());
if (request.url().host().contains("api.curseforge.com")) { if (APPLICATION->currentCapabilities() & Application::SupportsFlame
request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); && request.url().host().contains("api.curseforge.com")) {
request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8());
}; };
QNetworkReply* rep = m_network->get(request); QNetworkReply* rep = m_network->get(request);

View File

@ -2,6 +2,7 @@
/* /*
* PolyMC - Minecraft Launcher * PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com> * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,38 @@
// // SPDX-License-Identifier: GPL-3.0-only
// Created by timoreo on 20/05/22. /*
// * PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* 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 "Upload.h" #include "Upload.h"
@ -174,8 +206,9 @@ namespace Net {
} }
request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8());
if (request.url().host().contains("api.curseforge.com")) { if (APPLICATION->currentCapabilities() & Application::SupportsFlame
request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); && request.url().host().contains("api.curseforge.com")) {
request.setRawHeader("x-api-key", APPLICATION->getFlameAPIKey().toUtf8());
} }
//TODO other types of post requests ? //TODO other types of post requests ?
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

View File

@ -1,3 +1,39 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* 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.
*/
#pragma once #pragma once
#include "NetAction.h" #include "NetAction.h"

View File

@ -1,9 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* 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/>.
*/
#include "ModDownloadDialog.h" #include "ModDownloadDialog.h"
#include <BaseVersion.h> #include <BaseVersion.h>
#include <icons/IconList.h> #include <icons/IconList.h>
#include <InstanceList.h> #include <InstanceList.h>
#include "Application.h"
#include "ProgressDialog.h" #include "ProgressDialog.h"
#include "ReviewMessageBox.h" #include "ReviewMessageBox.h"
@ -100,13 +119,13 @@ void ModDownloadDialog::accept()
QList<BasePage *> ModDownloadDialog::getPages() QList<BasePage *> ModDownloadDialog::getPages()
{ {
modrinthPage = new ModrinthModPage(this, m_instance); QList<BasePage *> pages;
flameModPage = new FlameModPage(this, m_instance);
return pages.append(new ModrinthModPage(this, m_instance));
{ if (APPLICATION->currentCapabilities() & Application::SupportsFlame)
modrinthPage, pages.append(new FlameModPage(this, m_instance));
flameModPage
}; return pages;
} }
void ModDownloadDialog::addSelectedMod(const QString& name, ModDownloadTask* task) void ModDownloadDialog::addSelectedMod(const QString& name, ModDownloadTask* task)

View File

@ -1,3 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
*
* 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/>.
*/
#pragma once #pragma once
#include <QDialog> #include <QDialog>
@ -48,9 +66,6 @@ private:
QDialogButtonBox * m_buttons = nullptr; QDialogButtonBox * m_buttons = nullptr;
QVBoxLayout *m_verticalLayout = nullptr; QVBoxLayout *m_verticalLayout = nullptr;
ModrinthModPage *modrinthPage = nullptr;
FlameModPage *flameModPage = nullptr;
QHash<QString, ModDownloadTask*> modTask; QHash<QString, ModDownloadTask*> modTask;
BaseInstance *m_instance; BaseInstance *m_instance;
}; };

View File

@ -150,20 +150,21 @@ void NewInstanceDialog::accept()
QList<BasePage *> NewInstanceDialog::getPages() QList<BasePage *> NewInstanceDialog::getPages()
{ {
QList<BasePage *> pages;
importPage = new ImportPage(this); importPage = new ImportPage(this);
flamePage = new FlamePage(this);
auto technicPage = new TechnicPage(this); pages.append(new VanillaPage(this));
return pages.append(importPage);
{ pages.append(new AtlPage(this));
new VanillaPage(this), if (APPLICATION->currentCapabilities() & Application::SupportsFlame)
importPage, pages.append(new FlamePage(this));
new AtlPage(this), pages.append(new FtbPage(this));
flamePage, pages.append(new LegacyFTB::Page(this));
new FtbPage(this), pages.append(new ModrinthPage(this));
new LegacyFTB::Page(this), pages.append(new TechnicPage(this));
new ModrinthPage(this),
technicPage return pages;
};
} }
QString NewInstanceDialog::dialogTitle() QString NewInstanceDialog::dialogTitle()

View File

@ -1,16 +1,36 @@
/* Copyright 2013-2021 MultiMC Contributors // SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * the Free Software Foundation, version 3.
* *
* http://www.apache.org/licenses/LICENSE-2.0 * 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.
* *
* Unless required by applicable law or agreed to in writing, software * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <https://www.gnu.org/licenses/>.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and * This file incorporates work covered by the following copyright and
* limitations under the License. * 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.
*/ */
#pragma once #pragma once
@ -69,7 +89,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

@ -40,8 +40,10 @@
#include <QMessageBox> #include <QMessageBox>
#include <QFileDialog> #include <QFileDialog>
#include <QRegularExpression>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTabBar> #include <QTabBar>
#include <QValidator>
#include <QVariant> #include <QVariant>
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
@ -63,6 +65,10 @@ APIPage::APIPage(QWidget *parent) :
}; };
static QRegularExpression validUrlRegExp("https?://.+"); static QRegularExpression validUrlRegExp("https?://.+");
static QRegularExpression validMSAClientID(QRegularExpression::anchoredPattern(
"[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"));
static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern(
"\\$2[ayb]\\$.{56}"));
ui->setupUi(this); ui->setupUi(this);
@ -75,6 +81,8 @@ APIPage::APIPage(QWidget *parent) :
// This function needs to be called even when the ComboBox's index is still in its default state. // This function needs to be called even when the ComboBox's index is still in its default state.
updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex());
ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry)); ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry));
ui->msaClientID->setValidator(new QRegularExpressionValidator(validMSAClientID, ui->msaClientID));
ui->flameKey->setValidator(new QRegularExpressionValidator(validFlameKey, ui->flameKey));
ui->metaURL->setPlaceholderText(BuildConfig.META_URL); ui->metaURL->setPlaceholderText(BuildConfig.META_URL);
ui->userAgentLineEdit->setPlaceholderText(BuildConfig.USER_AGENT); ui->userAgentLineEdit->setPlaceholderText(BuildConfig.USER_AGENT);
@ -137,8 +145,8 @@ void APIPage::loadSettings()
ui->msaClientID->setText(msaClientID); ui->msaClientID->setText(msaClientID);
QString metaURL = s->get("MetaURLOverride").toString(); QString metaURL = s->get("MetaURLOverride").toString();
ui->metaURL->setText(metaURL); ui->metaURL->setText(metaURL);
QString curseKey = s->get("CFKeyOverride").toString(); QString flameKey = s->get("FlameKeyOverride").toString();
ui->curseKey->setText(curseKey); ui->flameKey->setText(flameKey);
QString customUserAgent = s->get("UserAgentOverride").toString(); QString customUserAgent = s->get("UserAgentOverride").toString();
ui->userAgentLineEdit->setText(customUserAgent); ui->userAgentLineEdit->setText(customUserAgent);
} }
@ -167,8 +175,8 @@ void APIPage::applySettings()
} }
s->set("MetaURLOverride", metaURL); s->set("MetaURLOverride", metaURL);
QString curseKey = ui->curseKey->text(); QString flameKey = ui->flameKey->text();
s->set("CFKeyOverride", curseKey); s->set("FlameKeyOverride", flameKey);
s->set("UserAgentOverride", ui->userAgentLineEdit->text()); s->set("UserAgentOverride", ui->userAgentLineEdit->text());
} }

View File

@ -196,7 +196,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_curse"> <widget class="QGroupBox" name="groupBox_flame">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -214,7 +214,7 @@
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>Enter a custom API Key for CurseForge here. </string> <string>Enter a custom API Key for CurseForge here.</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>
@ -228,7 +228,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLineEdit" name="curseKey"> <widget class="QLineEdit" name="flameKey">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>

View File

@ -96,7 +96,7 @@ AccountListPage::AccountListPage(QWidget *parent)
updateButtonStates(); updateButtonStates();
// Xbox authentication won't work without a client identifier, so disable the button if it is missing // Xbox authentication won't work without a client identifier, so disable the button if it is missing
if (APPLICATION->getMSAClientID().isEmpty()) { if (~APPLICATION->currentCapabilities() & Application::SupportsMSA) {
ui->actionAddMicrosoft->setVisible(false); ui->actionAddMicrosoft->setVisible(false);
ui->actionAddMicrosoft->setToolTip(tr("No Microsoft Authentication client ID was set.")); ui->actionAddMicrosoft->setToolTip(tr("No Microsoft Authentication client ID was set."));
} }

View File

@ -40,7 +40,7 @@
<item> <item>
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>- Curseforge modpacks (ZIP)</string> <string>- CurseForge modpacks (ZIP)</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>