Merge branch 'PrismLauncher:develop' into instance-accounts

This commit is contained in:
Aaron Sonin
2023-01-02 11:59:29 -07:00
committed by GitHub
21 changed files with 130 additions and 67 deletions

View File

@ -551,6 +551,24 @@ set(ATLAUNCHER_SOURCES
modplatform/atlauncher/ATLShareCode.h
)
######## Logging categories ########
ecm_qt_declare_logging_category(CORE_SOURCES
HEADER Logging.h
IDENTIFIER authCredentials
CATEGORY_NAME "launcher.auth.credentials"
DEFAULT_SEVERITY Warning
DESCRIPTION "Secrets and credentials for debugging purposes"
EXPORT "${Launcher_Name}"
)
if(KDE_INSTALL_LOGGINGCATEGORIESDIR) # only install if there is a standard path for this
ecm_qt_install_logging_categories(
EXPORT "${Launcher_Name}"
DESTINATION "${KDE_INSTALL_LOGGINGCATEGORIESDIR}"
)
endif()
################################ COMPILE ################################
set(LOGIC_SOURCES

View File

@ -1,5 +1,6 @@
#include "Parsers.h"
#include "Json.h"
#include "Logging.h"
#include <QJsonDocument>
#include <QJsonArray>
@ -75,9 +76,7 @@ bool getBool(QJsonValue value, bool & out) {
bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString name) {
qDebug() << "Parsing" << name <<":";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
if(jsonError.error) {
@ -137,9 +136,7 @@ bool parseXTokenResponse(QByteArray & data, Katabasis::Token &output, QString na
bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) {
qDebug() << "Parsing Minecraft profile...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
@ -275,9 +272,7 @@ decoded base64 "value":
bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) {
qDebug() << "Parsing Minecraft profile...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
@ -389,9 +384,7 @@ bool parseMinecraftProfileMojang(QByteArray & data, MinecraftProfile &output) {
bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output) {
qDebug() << "Parsing Minecraft entitlements...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
@ -424,9 +417,7 @@ bool parseMinecraftEntitlements(QByteArray & data, MinecraftEntitlement &output)
bool parseRolloutResponse(QByteArray & data, bool& result) {
qDebug() << "Parsing Rollout response...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonParseError jsonError;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
@ -455,9 +446,7 @@ bool parseRolloutResponse(QByteArray & data, bool& result) {
bool parseMojangResponse(QByteArray & data, Katabasis::Token &output) {
QJsonParseError jsonError;
qDebug() << "Parsing Mojang response...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
if(jsonError.error) {
qWarning() << "Failed to parse response from api.minecraftservices.com/launcher/login as JSON: " << jsonError.errorString();

View File

@ -3,6 +3,7 @@
#include <QNetworkRequest>
#include <QUuid>
#include "Logging.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
@ -41,9 +42,7 @@ void EntitlementsStep::onRequestDone(
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
requestor->deleteLater();
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
// TODO: check presence of same entitlementsRequestId?
// TODO: validate JWTs?

View File

@ -2,9 +2,10 @@
#include <QNetworkRequest>
#include "Logging.h"
#include "minecraft/auth/AccountTask.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "minecraft/auth/AccountTask.h"
#include "net/NetUtils.h"
LauncherLoginStep::LauncherLoginStep(AccountData* data) : AuthStep(data) {
@ -51,14 +52,10 @@ void LauncherLoginStep::onRequestDone(
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
requestor->deleteLater();
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (error != QNetworkReply::NoError) {
qWarning() << "Reply error:" << error;
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (Net::isApplicationError(error)) {
emit finished(
AccountTaskState::STATE_FAILED_SOFT,
@ -76,9 +73,7 @@ void LauncherLoginStep::onRequestDone(
if(!Parsers::parseMojangResponse(data, m_data->yggdrasilToken)) {
qWarning() << "Could not parse login_with_xbox response...";
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
emit finished(
AccountTaskState::STATE_FAILED_SOFT,
tr("Failed to parse the Minecraft access token response.")

View File

@ -42,6 +42,7 @@
#include "minecraft/auth/Parsers.h"
#include "Application.h"
#include "Logging.h"
using OAuth2 = Katabasis::DeviceFlow;
using Activity = Katabasis::Activity;
@ -117,14 +118,12 @@ void MSAStep::onOAuthActivityChanged(Katabasis::Activity activity) {
// Succeeded or did not invalidate tokens
emit hideVerificationUriAndCode();
QVariantMap extraTokens = m_oauth2->extraTokens();
#ifndef NDEBUG
if (!extraTokens.isEmpty()) {
qDebug() << "Extra tokens in response:";
qCDebug(authCredentials()) << "Extra tokens in response:";
foreach (QString key, extraTokens.keys()) {
qDebug() << "\t" << key << ":" << extraTokens.value(key);
qCDebug(authCredentials()) << "\t" << key << ":" << extraTokens.value(key);
}
}
#endif
emit finished(AccountTaskState::STATE_WORKING, tr("Got "));
return;
}

View File

@ -2,6 +2,7 @@
#include <QNetworkRequest>
#include "Logging.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "net/NetUtils.h"
@ -40,9 +41,7 @@ void MinecraftProfileStep::onRequestDone(
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
requestor->deleteLater();
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (error == QNetworkReply::ContentNotFoundError) {
// NOTE: Succeed even if we do not have a profile. This is a valid account state.
if(m_data->type == AccountType::Mojang) {

View File

@ -2,6 +2,7 @@
#include <QNetworkRequest>
#include "Logging.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "net/NetUtils.h"
@ -43,9 +44,7 @@ void MinecraftProfileStepMojang::onRequestDone(
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
requestor->deleteLater();
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (error == QNetworkReply::ContentNotFoundError) {
// NOTE: Succeed even if we do not have a profile. This is a valid account state.
if(m_data->type == AccountType::Mojang) {

View File

@ -4,6 +4,7 @@
#include <QJsonParseError>
#include <QJsonDocument>
#include "Logging.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "net/NetUtils.h"
@ -58,9 +59,7 @@ void XboxAuthorizationStep::onRequestDone(
auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
requestor->deleteLater();
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (error != QNetworkReply::NoError) {
qWarning() << "Reply error:" << error;
if (Net::isApplicationError(error)) {

View File

@ -3,7 +3,7 @@
#include <QNetworkRequest>
#include <QUrlQuery>
#include "Logging.h"
#include "minecraft/auth/AuthRequest.h"
#include "minecraft/auth/Parsers.h"
#include "net/NetUtils.h"
@ -56,9 +56,7 @@ void XboxProfileStep::onRequestDone(
if (error != QNetworkReply::NoError) {
qWarning() << "Reply error:" << error;
#ifndef NDEBUG
qDebug() << data;
#endif
qCDebug(authCredentials()) << data;
if (Net::isApplicationError(error)) {
emit finished(
AccountTaskState::STATE_FAILED_SOFT,
@ -74,9 +72,7 @@ void XboxProfileStep::onRequestDone(
return;
}
#ifndef NDEBUG
qDebug() << "XBox profile: " << data;
#endif
qCDebug(authCredentials()) << "XBox profile: " << data;
emit finished(AccountTaskState::STATE_WORKING, tr("Got Xbox profile"));
}

View File

@ -44,6 +44,8 @@
#include "MetadataHandler.h"
#include "Version.h"
static ModPlatform::ProviderCapabilities ProviderCaps;
Mod::Mod(const QFileInfo& file) : Resource(file), m_local_details()
{
m_enabled = (file.suffix() != "disabled");
@ -91,6 +93,11 @@ std::pair<int, bool> Mod::compare(const Resource& other, SortType type) const
if (this_ver < other_ver)
return { -1, type == SortType::VERSION };
}
case SortType::PROVIDER: {
auto compare_result = QString::compare(provider().value_or("Unknown"), cast_other->provider().value_or("Unknown"), Qt::CaseInsensitive);
if (compare_result != 0)
return { compare_result, type == SortType::PROVIDER };
}
}
return { 0, false };
}
@ -189,4 +196,11 @@ void Mod::finishResolvingWithDetails(ModDetails&& details)
m_local_details = std::move(details);
if (metadata)
setMetadata(std::move(metadata));
};
auto Mod::provider() const -> std::optional<QString>
{
if (metadata())
return ProviderCaps.readableName(metadata()->provider);
return {};
}

View File

@ -39,6 +39,8 @@
#include <QFileInfo>
#include <QList>
#include <optional>
#include "Resource.h"
#include "ModDetails.h"
@ -61,6 +63,7 @@ public:
auto description() const -> QString;
auto authors() const -> QStringList;
auto status() const -> ModStatus;
auto provider() const -> std::optional<QString>;
auto metadata() -> std::shared_ptr<Metadata::ModStruct>;
auto metadata() const -> const std::shared_ptr<Metadata::ModStruct>;

View File

@ -48,10 +48,11 @@
#include "minecraft/mod/tasks/LocalModParseTask.h"
#include "minecraft/mod/tasks/ModFolderLoadTask.h"
#include "modplatform/ModIndex.h"
ModFolderModel::ModFolderModel(const QString &dir, bool is_indexed) : ResourceFolderModel(QDir(dir)), m_is_indexed(is_indexed)
{
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE };
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER };
}
QVariant ModFolderModel::data(const QModelIndex &index, int role) const
@ -82,7 +83,15 @@ QVariant ModFolderModel::data(const QModelIndex &index, int role) const
}
case DateColumn:
return m_resources[row]->dateTimeChanged();
case ProviderColumn: {
auto provider = at(row)->provider();
if (!provider.has_value()) {
//: Unknown mod provider (i.e. not Modrinth, CurseForge, etc...)
return tr("Unknown");
}
return provider.value();
}
default:
return QVariant();
}
@ -118,6 +127,8 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in
return tr("Version");
case DateColumn:
return tr("Last changed");
case ProviderColumn:
return tr("Provider");
default:
return QVariant();
}
@ -133,6 +144,8 @@ QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, in
return tr("The version of the mod.");
case DateColumn:
return tr("The date and time this mod was last changed (or added).");
case ProviderColumn:
return tr("Where the mod was downloaded from.");
default:
return QVariant();
}

View File

@ -67,6 +67,7 @@ public:
NameColumn,
VersionColumn,
DateColumn,
ProviderColumn,
NUM_COLUMNS
};
enum ModStatusAction {

View File

@ -20,7 +20,8 @@ enum class SortType {
DATE,
VERSION,
ENABLED,
PACK_FORMAT
PACK_FORMAT,
PROVIDER
};
enum class EnableAction {

View File

@ -14,6 +14,9 @@
*/
#include "ModListView.h"
#include "minecraft/mod/ModFolderModel.h"
#include <QHeaderView>
#include <QMouseEvent>
#include <QPainter>
@ -62,4 +65,17 @@ void ModListView::setModel ( QAbstractItemModel* model )
for(int i = 1; i < head->count(); i++)
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
auto real_model = model;
if (auto proxy_model = dynamic_cast<QSortFilterProxyModel*>(model); proxy_model)
real_model = proxy_model->sourceModel();
if (auto mod_model = dynamic_cast<ModFolderModel*>(real_model); mod_model) {
connect(mod_model, &ModFolderModel::updateFinished, this, [this, mod_model]{
auto mods = mod_model->allMods();
// Hide the 'Provider' column if no mod has a defined provider!
setColumnHidden(ModFolderModel::Columns::ProviderColumn,
std::none_of(mods.constBegin(), mods.constEnd(), [](auto const mod){ return mod->provider().has_value(); }));
});
}
}