From 3d84635b24e52c35b70e044bed67060adb1dcfd6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 26 Oct 2023 20:09:12 +0300 Subject: [PATCH 01/76] Remove file on mod duplication Signed-off-by: Trial97 --- launcher/InstanceList.cpp | 12 ++++++------ launcher/InstanceList.h | 2 +- launcher/minecraft/mod/Resource.cpp | 10 +++++----- launcher/minecraft/mod/ResourceFolderModel.cpp | 3 --- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 756ff93dd..e245fc2c6 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -371,13 +371,13 @@ void InstanceList::undoTrashInstance() auto top = m_trashHistory.pop(); - while (QDir(top.polyPath).exists()) { + while (QDir(top.rootPath).exists()) { top.id += "1"; - top.polyPath += "1"; + top.rootPath += "1"; } - qDebug() << "Moving" << top.trashPath << "back to" << top.polyPath; - QFile(top.trashPath).rename(top.polyPath); + qDebug() << "Moving" << top.trashPath << "back to" << top.rootPath; + QFile(top.trashPath).rename(top.rootPath); m_instanceGroupIndex[top.id] = top.groupName; increaseGroupCount(top.groupName); @@ -634,8 +634,8 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) QString inst_type = instanceSettings->get("InstanceType").toString(); - // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix - // instance + // NOTE: Some PrismLauncher versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a + // OneSix instance if (inst_type == "OneSix" || inst_type.isEmpty()) { inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); } else { diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h index 6b0bcd810..1a70b57b9 100644 --- a/launcher/InstanceList.h +++ b/launcher/InstanceList.h @@ -58,7 +58,7 @@ enum class GroupsState { NotLoaded, Steady, Dirty }; struct TrashHistoryItem { QString id; - QString polyPath; + QString rootPath; QString trashPath; QString groupName; }; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index da806f0f4..05940fcb4 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -130,15 +130,15 @@ bool Resource::enable(EnableAction action) if (!path.endsWith(".disabled")) return false; path.chop(9); - - if (!file.rename(path)) - return false; } else { path += ".disabled"; - - if (!file.rename(path)) + } + if (QFileInfo::exists(path)) { // the path exists so just remove the file at path + if (!QFile::remove(path)) return false; } + if (!file.rename(path)) + return false; setFile(QFileInfo(path)); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 0503b660b..8f2c87747 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -213,9 +213,6 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena } auto new_id = resource->internal_id(); - if (m_resources_index.contains(new_id)) { - // FIXME: https://github.com/PolyMC/PolyMC/issues/550 - } m_resources_index.remove(old_id); m_resources_index[new_id] = row; From 60a7628dbbf21c27cdc8021b01278b173f56dedb Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 26 Oct 2023 20:43:26 +0300 Subject: [PATCH 02/76] delete duplicate mods Signed-off-by: Trial97 --- launcher/minecraft/mod/tasks/BasicFolderLoadTask.h | 10 ++++++++-- launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h index 23a2b649a..6e8b8ed43 100644 --- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h +++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h @@ -49,10 +49,16 @@ class BasicFolderLoadTask : public Task { connect(this, &Task::finished, this->thread(), &QThread::quit); m_dir.refresh(); + QStringList names; for (auto entry : m_dir.entryInfoList()) { auto resource = m_create_func(entry); - resource->moveToThread(m_thread_to_spawn_into); - m_result->resources.insert(resource->internal_id(), resource); + if (names.contains(resource->name())) { + resource->destroy(); + } else { + names << resource->name(); + resource->moveToThread(m_thread_to_spawn_into); + m_result->resources.insert(resource->internal_id(), resource); + } } if (m_aborted) diff --git a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp index 2094df4fc..c11759dd2 100644 --- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp +++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp @@ -62,9 +62,15 @@ void ModFolderLoadTask::executeTask() // Read JAR files that don't have metadata m_mods_dir.refresh(); + QStringList names; for (auto entry : m_mods_dir.entryInfoList()) { Mod* mod(new Mod(entry)); + if (names.contains(mod->name())) { + mod->destroy(m_index_dir, true); + continue; + } + names << mod->name(); if (mod->enabled()) { if (m_result->mods.contains(mod->internal_id())) { m_result->mods[mod->internal_id()]->setStatus(ModStatus::Installed); From 41d52dc34717aa2cad0537abb255a5a475bd4bca Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 29 Feb 2024 00:06:28 +0200 Subject: [PATCH 03/76] Remove dependencies if review mods is rejected Signed-off-by: Trial97 --- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 1431ea92c..11833c438 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -133,6 +133,7 @@ void ResourceDownloadDialog::confirm() confirm_dialog->retranslateUi(resourcesString()); QHash getRequiredBy; + QStringList depNames; if (auto task = getModDependenciesTask(); task) { connect(task.get(), &Task::failed, this, [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }); @@ -155,8 +156,10 @@ void ResourceDownloadDialog::confirm() QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); return; } else { - for (auto dep : task->getDependecies()) + for (auto dep : task->getDependecies()) { addResource(dep->pack, dep->version); + depNames << dep->pack->name; + } getRequiredBy = task->getRequiredBy(); } } @@ -180,6 +183,9 @@ void ResourceDownloadDialog::confirm() } this->accept(); + } else { + for (auto name : depNames) + removeResource(name); } } From 6078a771c18fd749f38d7c1a2f80ed3c7ec7ad28 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 18 May 2024 21:46:05 +0300 Subject: [PATCH 04/76] add config for transfer timeout Signed-off-by: Trial97 --- launcher/Application.cpp | 10 ++++----- launcher/net/NetRequest.cpp | 4 ++++ launcher/ui/pages/global/LauncherPage.cpp | 2 ++ launcher/ui/pages/global/LauncherPage.ui | 27 ++++++++++++++++++----- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 96a50f2ba..ffa49ee11 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -559,6 +559,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("NumberOfConcurrentTasks", 10); m_settings->registerSetting("NumberOfConcurrentDownloads", 6); + m_settings->registerSetting("DownlodTransferTimeout", 60); QString defaultMonospace; int defaultSize = 11; @@ -949,8 +950,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod( - this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -982,8 +982,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod( - this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -1671,8 +1670,7 @@ QString Application::getJarPath(QString jarFile) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME), #endif - FS::PathCombine(m_rootPath, "jars"), - FS::PathCombine(applicationDirPath(), "jars"), + FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging }; for (QString p : potentialPaths) { diff --git a/launcher/net/NetRequest.cpp b/launcher/net/NetRequest.cpp index abecc0cf3..6ce6a9bfc 100644 --- a/launcher/net/NetRequest.cpp +++ b/launcher/net/NetRequest.cpp @@ -106,7 +106,11 @@ void NetRequest::executeTask() } #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) +#if defined(LAUNCHER_APPLICATION) + request.setTransferTimeout(APPLICATION->settings()->get("DownlodTransferTimeout").toInt() * 1000); +#else request.setTransferTimeout(); +#endif #endif m_last_progress_time = m_clock.now(); diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 78c44380a..4b550a0fd 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -191,6 +191,7 @@ void LauncherPage::applySettings() s->set("NumberOfConcurrentTasks", ui->numberOfConcurrentTasksSpinBox->value()); s->set("NumberOfConcurrentDownloads", ui->numberOfConcurrentDownloadsSpinBox->value()); + s->set("DownlodTransferTimeout", ui->timeoutSecondsSpinBox->value()); // Console settings s->set("ShowConsole", ui->showConsoleCheck->isChecked()); @@ -245,6 +246,7 @@ void LauncherPage::loadSettings() ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt()); ui->numberOfConcurrentDownloadsSpinBox->setValue(s->get("NumberOfConcurrentDownloads").toInt()); + ui->timeoutSecondsSpinBox->setValue(s->get("DownlodTransferTimeout").toInt()); // Console settings ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 928ec8103..20c9d0269 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -7,7 +7,7 @@ 0 0 511 - 629 + 691 @@ -205,6 +205,13 @@ Miscellaneous + + + + 1 + + + @@ -226,10 +233,20 @@ - - - - 1 + + + + Seconds to wait until the requests are terminated + + + Transfer timeout + + + + + + + s From 76a656a017b67453e15c669671b453cfdfd0e7f9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 18 May 2024 22:27:11 +0300 Subject: [PATCH 05/76] retry auth step on fail Signed-off-by: Trial97 --- .../minecraft/auth/steps/EntitlementsStep.cpp | 10 ++++-- .../minecraft/auth/steps/EntitlementsStep.h | 4 ++- launcher/minecraft/auth/steps/GetSkinStep.cpp | 9 +++-- launcher/minecraft/auth/steps/GetSkinStep.h | 4 ++- .../auth/steps/LauncherLoginStep.cpp | 20 ++++++----- .../minecraft/auth/steps/LauncherLoginStep.h | 4 ++- .../auth/steps/MSADeviceCodeStep.cpp | 29 ++++++++------- .../minecraft/auth/steps/MSADeviceCodeStep.h | 4 ++- .../auth/steps/MinecraftProfileStep.cpp | 26 ++++++++------ .../auth/steps/MinecraftProfileStep.h | 4 ++- .../auth/steps/XboxAuthorizationStep.cpp | 23 ++++++------ .../auth/steps/XboxAuthorizationStep.h | 4 ++- .../minecraft/auth/steps/XboxProfileStep.cpp | 19 +++++----- .../minecraft/auth/steps/XboxProfileStep.h | 4 ++- .../minecraft/auth/steps/XboxUserStep.cpp | 19 +++++----- launcher/minecraft/auth/steps/XboxUserStep.h | 4 ++- launcher/net/NetJob.cpp | 35 +++++++++++-------- launcher/net/NetJob.h | 2 ++ 18 files changed, 138 insertions(+), 86 deletions(-) diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.cpp b/launcher/minecraft/auth/steps/EntitlementsStep.cpp index 19cbe6898..4c4809fae 100644 --- a/launcher/minecraft/auth/steps/EntitlementsStep.cpp +++ b/launcher/minecraft/auth/steps/EntitlementsStep.cpp @@ -10,6 +10,7 @@ #include "Logging.h" #include "minecraft/auth/Parsers.h" #include "net/Download.h" +#include "net/NetJob.h" #include "net/StaticHeaderProxy.h" #include "tasks/Task.h" @@ -31,12 +32,15 @@ void EntitlementsStep::perform() { "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } }; m_response.reset(new QByteArray()); - m_task = Net::Download::makeByteArray(url, m_response); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Download::makeByteArray(url, m_response); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("EntitlementsStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &EntitlementsStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); qDebug() << "Getting entitlements..."; } diff --git a/launcher/minecraft/auth/steps/EntitlementsStep.h b/launcher/minecraft/auth/steps/EntitlementsStep.h index dd8ec7aaa..f20fcac08 100644 --- a/launcher/minecraft/auth/steps/EntitlementsStep.h +++ b/launcher/minecraft/auth/steps/EntitlementsStep.h @@ -4,6 +4,7 @@ #include "minecraft/auth/AuthStep.h" #include "net/Download.h" +#include "net/NetJob.h" class EntitlementsStep : public AuthStep { Q_OBJECT @@ -22,5 +23,6 @@ class EntitlementsStep : public AuthStep { private: QString m_entitlements_request_id; std::shared_ptr m_response; - Net::Download::Ptr m_task; + Net::Download::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/GetSkinStep.cpp b/launcher/minecraft/auth/steps/GetSkinStep.cpp index d9785b16a..a0c039cea 100644 --- a/launcher/minecraft/auth/steps/GetSkinStep.cpp +++ b/launcher/minecraft/auth/steps/GetSkinStep.cpp @@ -17,17 +17,20 @@ void GetSkinStep::perform() QUrl url(m_data->minecraftProfile.skin.url); m_response.reset(new QByteArray()); - m_task = Net::Download::makeByteArray(url, m_response); + m_request = Net::Download::makeByteArray(url, m_response); + + m_task.reset(new NetJob("GetSkinStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &GetSkinStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); } void GetSkinStep::onRequestDone() { - if (m_task->error() == QNetworkReply::NoError) + if (m_request->error() == QNetworkReply::NoError) m_data->minecraftProfile.skin.data = *m_response; emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Got skin")); } diff --git a/launcher/minecraft/auth/steps/GetSkinStep.h b/launcher/minecraft/auth/steps/GetSkinStep.h index fffd8be03..c598f05d9 100644 --- a/launcher/minecraft/auth/steps/GetSkinStep.h +++ b/launcher/minecraft/auth/steps/GetSkinStep.h @@ -4,6 +4,7 @@ #include "minecraft/auth/AuthStep.h" #include "net/Download.h" +#include "net/NetJob.h" class GetSkinStep : public AuthStep { Q_OBJECT @@ -21,5 +22,6 @@ class GetSkinStep : public AuthStep { private: std::shared_ptr m_response; - Net::Download::Ptr m_task; + Net::Download::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp index d72346c74..08e1b3b1f 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.cpp +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.cpp @@ -37,12 +37,15 @@ void LauncherLoginStep::perform() }; m_response.reset(new QByteArray()); - m_task = Net::Upload::makeByteArray(url, m_response, requestBody.toUtf8()); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Upload::makeByteArray(url, m_response, requestBody.toUtf8()); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("LauncherLoginStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &LauncherLoginStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); qDebug() << "Getting Minecraft access token..."; } @@ -50,12 +53,13 @@ void LauncherLoginStep::perform() void LauncherLoginStep::onRequestDone() { qCDebug(authCredentials()) << *m_response; - if (m_task->error() != QNetworkReply::NoError) { - qWarning() << "Reply error:" << m_task->error(); - if (Net::isApplicationError(m_task->error())) { - emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to get Minecraft access token: %1").arg(m_task->errorString())); + if (m_request->error() != QNetworkReply::NoError) { + qWarning() << "Reply error:" << m_request->error(); + if (Net::isApplicationError(m_request->error())) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, + tr("Failed to get Minecraft access token: %1").arg(m_request->errorString())); } else { - emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to get Minecraft access token: %1").arg(m_task->errorString())); + emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to get Minecraft access token: %1").arg(m_request->errorString())); } return; } diff --git a/launcher/minecraft/auth/steps/LauncherLoginStep.h b/launcher/minecraft/auth/steps/LauncherLoginStep.h index 21a2a4920..0b5969f2b 100644 --- a/launcher/minecraft/auth/steps/LauncherLoginStep.h +++ b/launcher/minecraft/auth/steps/LauncherLoginStep.h @@ -3,6 +3,7 @@ #include #include "minecraft/auth/AuthStep.h" +#include "net/NetJob.h" #include "net/Upload.h" class LauncherLoginStep : public AuthStep { @@ -21,5 +22,6 @@ class LauncherLoginStep : public AuthStep { private: std::shared_ptr m_response; - Net::Upload::Ptr m_task; + Net::Upload::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp index 22f5d4069..ebb9b6653 100644 --- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp +++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp @@ -65,12 +65,15 @@ void MSADeviceCodeStep::perform() { "Accept", "application/json" }, }; m_response.reset(new QByteArray()); - m_task = Net::Upload::makeByteArray(url, m_response, payload); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Upload::makeByteArray(url, m_response, payload); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("MSADeviceCodeStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &MSADeviceCodeStep::deviceAutorizationFinished); - m_task->setNetwork(APPLICATION->network()); m_task->start(); } @@ -115,7 +118,7 @@ void MSADeviceCodeStep::deviceAutorizationFinished() tr("Device authorization failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description)); return; } - if (!m_task->wasSuccessful() || m_task->error() != QNetworkReply::NoError) { + if (!m_request->wasSuccessful() || m_request->error() != QNetworkReply::NoError) { emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Failed to retrieve device authorization")); qDebug() << *m_response; return; @@ -145,8 +148,8 @@ void MSADeviceCodeStep::abort() { m_expiration_timer.stop(); m_pool_timer.stop(); - if (m_task) { - m_task->abort(); + if (m_request) { + m_request->abort(); } m_is_aborted = true; emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Task aborted")); @@ -175,13 +178,13 @@ void MSADeviceCodeStep::authenticateUser() { "Accept", "application/json" }, }; m_response.reset(new QByteArray()); - m_task = Net::Upload::makeByteArray(url, m_response, payload); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Upload::makeByteArray(url, m_response, payload); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); - connect(m_task.get(), &Task::finished, this, &MSADeviceCodeStep::authenticationFinished); + connect(m_request.get(), &Task::finished, this, &MSADeviceCodeStep::authenticationFinished); - m_task->setNetwork(APPLICATION->network()); - m_task->start(); + m_request->setNetwork(APPLICATION->network()); + m_request->start(); } struct AuthenticationResponse { @@ -221,7 +224,7 @@ AuthenticationResponse parseAuthenticationResponse(const QByteArray& data) void MSADeviceCodeStep::authenticationFinished() { - if (m_task->error() == QNetworkReply::TimeoutError) { + if (m_request->error() == QNetworkReply::TimeoutError) { // rfc8628#section-3.5 // "On encountering a connection timeout, clients MUST unilaterally // reduce their polling frequency before retrying. The use of an @@ -254,7 +257,7 @@ void MSADeviceCodeStep::authenticationFinished() tr("Device Access failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description)); return; } - if (!m_task->wasSuccessful() || m_task->error() != QNetworkReply::NoError) { + if (!m_request->wasSuccessful() || m_request->error() != QNetworkReply::NoError) { startPoolTimer(); // it failed so just try again without increasing the interval return; } diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.h b/launcher/minecraft/auth/steps/MSADeviceCodeStep.h index e53eebc62..87e0ce6e2 100644 --- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.h +++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.h @@ -38,6 +38,7 @@ #include #include "minecraft/auth/AuthStep.h" +#include "net/NetJob.h" #include "net/Upload.h" class MSADeviceCodeStep : public AuthStep { @@ -72,5 +73,6 @@ class MSADeviceCodeStep : public AuthStep { QTimer m_expiration_timer; std::shared_ptr m_response; - Net::Upload::Ptr m_task; + Net::Upload::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp index 305f44320..81b6511f5 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp @@ -22,37 +22,41 @@ void MinecraftProfileStep::perform() { "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } }; m_response.reset(new QByteArray()); - m_task = Net::Download::makeByteArray(url, m_response); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Download::makeByteArray(url, m_response); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("MinecraftProfileStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &MinecraftProfileStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); } void MinecraftProfileStep::onRequestDone() { - if (m_task->error() == QNetworkReply::ContentNotFoundError) { + if (m_request->error() == QNetworkReply::ContentNotFoundError) { // NOTE: Succeed even if we do not have a profile. This is a valid account state. m_data->minecraftProfile = MinecraftProfile(); emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Account has no Minecraft profile.")); return; } - if (m_task->error() != QNetworkReply::NoError) { + if (m_request->error() != QNetworkReply::NoError) { qWarning() << "Error getting profile:"; - qWarning() << " HTTP Status: " << m_task->replyStatusCode(); - qWarning() << " Internal error no.: " << m_task->error(); - qWarning() << " Error string: " << m_task->errorString(); + qWarning() << " HTTP Status: " << m_request->replyStatusCode(); + qWarning() << " Internal error no.: " << m_request->error(); + qWarning() << " Error string: " << m_request->errorString(); qWarning() << " Response:"; qWarning() << QString::fromUtf8(*m_response); - if (Net::isApplicationError(m_task->error())) { + if (Net::isApplicationError(m_request->error())) { emit finished(AccountTaskState::STATE_FAILED_SOFT, - tr("Minecraft Java profile acquisition failed: %1").arg(m_task->errorString())); + tr("Minecraft Java profile acquisition failed: %1").arg(m_request->errorString())); } else { - emit finished(AccountTaskState::STATE_OFFLINE, tr("Minecraft Java profile acquisition failed: %1").arg(m_task->errorString())); + emit finished(AccountTaskState::STATE_OFFLINE, + tr("Minecraft Java profile acquisition failed: %1").arg(m_request->errorString())); } return; } diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.h b/launcher/minecraft/auth/steps/MinecraftProfileStep.h index 831cd52f7..e8b35b875 100644 --- a/launcher/minecraft/auth/steps/MinecraftProfileStep.h +++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.h @@ -4,6 +4,7 @@ #include "minecraft/auth/AuthStep.h" #include "net/Download.h" +#include "net/NetJob.h" class MinecraftProfileStep : public AuthStep { Q_OBJECT @@ -21,5 +22,6 @@ class MinecraftProfileStep : public AuthStep { private: std::shared_ptr m_response; - Net::Download::Ptr m_task; + Net::Download::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp index f07220986..4f5f14a33 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.cpp @@ -42,12 +42,15 @@ void XboxAuthorizationStep::perform() { "Accept", "application/json" }, }; m_response.reset(new QByteArray()); - m_task = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8()); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8()); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("XboxAuthorizationStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &XboxAuthorizationStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); qDebug() << "Getting authorization token for " << m_relyingParty; } @@ -55,19 +58,19 @@ void XboxAuthorizationStep::perform() void XboxAuthorizationStep::onRequestDone() { qCDebug(authCredentials()) << *m_response; - if (m_task->error() != QNetworkReply::NoError) { - qWarning() << "Reply error:" << m_task->error(); - if (Net::isApplicationError(m_task->error())) { + if (m_request->error() != QNetworkReply::NoError) { + qWarning() << "Reply error:" << m_request->error(); + if (Net::isApplicationError(m_request->error())) { if (!processSTSError()) { emit finished(AccountTaskState::STATE_FAILED_SOFT, - tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, m_task->error())); + tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, m_request->error())); } else { emit finished(AccountTaskState::STATE_FAILED_SOFT, - tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, m_task->errorString())); + tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, m_request->errorString())); } } else { emit finished(AccountTaskState::STATE_OFFLINE, - tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, m_task->errorString())); + tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, m_request->errorString())); } return; } @@ -92,7 +95,7 @@ void XboxAuthorizationStep::onRequestDone() bool XboxAuthorizationStep::processSTSError() { - if (m_task->error() == QNetworkReply::AuthenticationRequiredError) { + if (m_request->error() == QNetworkReply::AuthenticationRequiredError) { QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson(*m_response, &jsonError); if (jsonError.error) { diff --git a/launcher/minecraft/auth/steps/XboxAuthorizationStep.h b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h index f6329b7f0..8418727c4 100644 --- a/launcher/minecraft/auth/steps/XboxAuthorizationStep.h +++ b/launcher/minecraft/auth/steps/XboxAuthorizationStep.h @@ -3,6 +3,7 @@ #include #include "minecraft/auth/AuthStep.h" +#include "net/NetJob.h" #include "net/Upload.h" class XboxAuthorizationStep : public AuthStep { @@ -28,5 +29,6 @@ class XboxAuthorizationStep : public AuthStep { QString m_authorizationKind; std::shared_ptr m_response; - Net::Upload::Ptr m_task; + Net::Upload::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.cpp b/launcher/minecraft/auth/steps/XboxProfileStep.cpp index 440a4657c..a784fa195 100644 --- a/launcher/minecraft/auth/steps/XboxProfileStep.cpp +++ b/launcher/minecraft/auth/steps/XboxProfileStep.cpp @@ -34,25 +34,28 @@ void XboxProfileStep::perform() }; m_response.reset(new QByteArray()); - m_task = Net::Download::makeByteArray(url, m_response); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Download::makeByteArray(url, m_response); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("XboxProfileStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &XboxProfileStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); qDebug() << "Getting Xbox profile..."; } void XboxProfileStep::onRequestDone() { - if (m_task->error() != QNetworkReply::NoError) { - qWarning() << "Reply error:" << m_task->error(); + if (m_request->error() != QNetworkReply::NoError) { + qWarning() << "Reply error:" << m_request->error(); qCDebug(authCredentials()) << *m_response; - if (Net::isApplicationError(m_task->error())) { - emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to retrieve the Xbox profile: %1").arg(m_task->errorString())); + if (Net::isApplicationError(m_request->error())) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to retrieve the Xbox profile: %1").arg(m_request->errorString())); } else { - emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to retrieve the Xbox profile: %1").arg(m_task->errorString())); + emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to retrieve the Xbox profile: %1").arg(m_request->errorString())); } return; } diff --git a/launcher/minecraft/auth/steps/XboxProfileStep.h b/launcher/minecraft/auth/steps/XboxProfileStep.h index dfa273d9c..f2ab874f2 100644 --- a/launcher/minecraft/auth/steps/XboxProfileStep.h +++ b/launcher/minecraft/auth/steps/XboxProfileStep.h @@ -4,6 +4,7 @@ #include "minecraft/auth/AuthStep.h" #include "net/Download.h" +#include "net/NetJob.h" class XboxProfileStep : public AuthStep { Q_OBJECT @@ -21,5 +22,6 @@ class XboxProfileStep : public AuthStep { private: std::shared_ptr m_response; - Net::Download::Ptr m_task; + Net::Download::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/minecraft/auth/steps/XboxUserStep.cpp b/launcher/minecraft/auth/steps/XboxUserStep.cpp index c9453dba1..3e697b506 100644 --- a/launcher/minecraft/auth/steps/XboxUserStep.cpp +++ b/launcher/minecraft/auth/steps/XboxUserStep.cpp @@ -38,24 +38,27 @@ void XboxUserStep::perform() { "x-xbl-contract-version", "1" } }; m_response.reset(new QByteArray()); - m_task = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8()); - m_task->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8()); + m_request->addHeaderProxy(new Net::StaticHeaderProxy(headers)); + + m_task.reset(new NetJob("XboxUserStep", APPLICATION->network())); + m_task->setAskRetry(false); + m_task->addNetAction(m_request); connect(m_task.get(), &Task::finished, this, &XboxUserStep::onRequestDone); - m_task->setNetwork(APPLICATION->network()); m_task->start(); qDebug() << "First layer of XBox auth ... commencing."; } void XboxUserStep::onRequestDone() { - if (m_task->error() != QNetworkReply::NoError) { - qWarning() << "Reply error:" << m_task->error(); - if (Net::isApplicationError(m_task->error())) { - emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed: %1").arg(m_task->errorString())); + if (m_request->error() != QNetworkReply::NoError) { + qWarning() << "Reply error:" << m_request->error(); + if (Net::isApplicationError(m_request->error())) { + emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed: %1").arg(m_request->errorString())); } else { - emit finished(AccountTaskState::STATE_OFFLINE, tr("XBox user authentication failed: %1").arg(m_task->errorString())); + emit finished(AccountTaskState::STATE_OFFLINE, tr("XBox user authentication failed: %1").arg(m_request->errorString())); } return; } diff --git a/launcher/minecraft/auth/steps/XboxUserStep.h b/launcher/minecraft/auth/steps/XboxUserStep.h index 934a00c52..f6cc822f2 100644 --- a/launcher/minecraft/auth/steps/XboxUserStep.h +++ b/launcher/minecraft/auth/steps/XboxUserStep.h @@ -3,6 +3,7 @@ #include #include "minecraft/auth/AuthStep.h" +#include "net/NetJob.h" #include "net/Upload.h" class XboxUserStep : public AuthStep { @@ -21,5 +22,6 @@ class XboxUserStep : public AuthStep { private: std::shared_ptr m_response; - Net::Upload::Ptr m_task; + Net::Upload::Ptr m_request; + NetJob::Ptr m_task; }; diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 65d6ec3a4..e8df8c3a8 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -144,21 +144,28 @@ void NetJob::updateState() void NetJob::emitFailed(QString reason) { #if defined(LAUNCHER_APPLICATION) - auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", - "The tasks failed\n" - "Failed urls\n" + - getFailedFiles().join("\n\t") + - "\n" - "If this continues to happen please check the logs of the application" - "Do you want to retry?", - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) - ->exec(); + if (m_ask_retry) { + auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", + "The tasks failed\n" + "Failed urls\n" + + getFailedFiles().join("\n\t") + + "\n" + "If this continues to happen please check the logs of the application" + "Do you want to retry?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); - if (response == QMessageBox::Yes) { - m_try = 0; - executeNextSubTask(); - return; + if (response == QMessageBox::Yes) { + m_try = 0; + executeNextSubTask(); + return; + } } #endif ConcurrentTask::emitFailed(reason); -} \ No newline at end of file +} + +void NetJob::setAskRetry(bool askRetry) +{ + m_ask_retry = askRetry; +} diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h index 09da95771..b421d2450 100644 --- a/launcher/net/NetJob.h +++ b/launcher/net/NetJob.h @@ -62,6 +62,7 @@ class NetJob : public ConcurrentTask { auto getFailedActions() -> QList; auto getFailedFiles() -> QList; + void setAskRetry(bool askRetry); public slots: // Qt can't handle auto at the start for some reason? @@ -78,4 +79,5 @@ class NetJob : public ConcurrentTask { shared_qobject_ptr m_network; int m_try = 1; + bool m_ask_retry = true; }; From d9e2badf71dc5b70e2cdaeac0ddde3a45891f953 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 19 May 2024 08:54:19 +0300 Subject: [PATCH 06/76] Rename timeout option Signed-off-by: Trial97 --- launcher/Application.cpp | 2 +- launcher/net/NetRequest.cpp | 2 +- launcher/ui/pages/global/LauncherPage.cpp | 4 ++-- launcher/ui/pages/global/LauncherPage.ui | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index ffa49ee11..da25f3e3f 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -559,7 +559,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("NumberOfConcurrentTasks", 10); m_settings->registerSetting("NumberOfConcurrentDownloads", 6); - m_settings->registerSetting("DownlodTransferTimeout", 60); + m_settings->registerSetting("RequestTimeout", 60); QString defaultMonospace; int defaultSize = 11; diff --git a/launcher/net/NetRequest.cpp b/launcher/net/NetRequest.cpp index 6ce6a9bfc..dc9bf3b68 100644 --- a/launcher/net/NetRequest.cpp +++ b/launcher/net/NetRequest.cpp @@ -107,7 +107,7 @@ void NetRequest::executeTask() #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) #if defined(LAUNCHER_APPLICATION) - request.setTransferTimeout(APPLICATION->settings()->get("DownlodTransferTimeout").toInt() * 1000); + request.setTransferTimeout(APPLICATION->settings()->get("RequestTimeout").toInt() * 1000); #else request.setTransferTimeout(); #endif diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 4b550a0fd..085c78420 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -191,7 +191,7 @@ void LauncherPage::applySettings() s->set("NumberOfConcurrentTasks", ui->numberOfConcurrentTasksSpinBox->value()); s->set("NumberOfConcurrentDownloads", ui->numberOfConcurrentDownloadsSpinBox->value()); - s->set("DownlodTransferTimeout", ui->timeoutSecondsSpinBox->value()); + s->set("RequestTimeout", ui->timeoutSecondsSpinBox->value()); // Console settings s->set("ShowConsole", ui->showConsoleCheck->isChecked()); @@ -246,7 +246,7 @@ void LauncherPage::loadSettings() ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt()); ui->numberOfConcurrentDownloadsSpinBox->setValue(s->get("NumberOfConcurrentDownloads").toInt()); - ui->timeoutSecondsSpinBox->setValue(s->get("DownlodTransferTimeout").toInt()); + ui->timeoutSecondsSpinBox->setValue(s->get("RequestTimeout").toInt()); // Console settings ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 20c9d0269..62335b467 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -239,7 +239,7 @@ Seconds to wait until the requests are terminated - Transfer timeout + Timeout for HTTP requests From 425a6e09191eda8f732a6e1a6ca2b663d6e6d939 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 19 May 2024 10:09:34 +0300 Subject: [PATCH 07/76] Fix code format Signed-off-by: Trial97 --- launcher/Application.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index da25f3e3f..1781729a1 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -950,7 +950,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod( + this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -982,7 +983,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) [[fallthrough]]; default: { qDebug() << "Exiting because update lockfile is present"; - QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection); + QMetaObject::invokeMethod( + this, []() { exit(1); }, Qt::QueuedConnection); return; } } @@ -1670,7 +1672,8 @@ QString Application::getJarPath(QString jarFile) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME), #endif - FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"), + FS::PathCombine(m_rootPath, "jars"), + FS::PathCombine(applicationDirPath(), "jars"), FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging }; for (QString p : potentialPaths) { From 7a200a337f08cfa1e32102594958f10cb7f000c6 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 26 May 2024 11:04:41 +0300 Subject: [PATCH 08/76] update retry netjob dialog Signed-off-by: Trial97 --- launcher/Application.cpp | 1 + launcher/net/ApiDownload.cpp | 1 - launcher/net/ApiUpload.cpp | 1 - launcher/net/NetJob.cpp | 34 ++++++++++++------- launcher/net/NetJob.h | 3 ++ launcher/ui/pages/global/LauncherPage.cpp | 2 ++ launcher/ui/pages/global/LauncherPage.ui | 16 ++++++++- .../ui/widgets/VariableSizedImageObject.cpp | 3 +- 8 files changed, 44 insertions(+), 17 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 96a50f2ba..06ebf4d71 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -559,6 +559,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("NumberOfConcurrentTasks", 10); m_settings->registerSetting("NumberOfConcurrentDownloads", 6); + m_settings->registerSetting("NumberOfManualRetries", 1); QString defaultMonospace; int defaultSize = 11; diff --git a/launcher/net/ApiDownload.cpp b/launcher/net/ApiDownload.cpp index 8768b63f8..0494d18ad 100644 --- a/launcher/net/ApiDownload.cpp +++ b/launcher/net/ApiDownload.cpp @@ -58,7 +58,6 @@ auto ApiDownload::makeFile(QUrl url, QString path, Options options) -> Download: void ApiDownload::init() { - qDebug() << "Setting up api download"; auto api_headers = new ApiHeaderProxy(); addHeaderProxy(api_headers); } diff --git a/launcher/net/ApiUpload.cpp b/launcher/net/ApiUpload.cpp index 505cbd9f9..01b081dd5 100644 --- a/launcher/net/ApiUpload.cpp +++ b/launcher/net/ApiUpload.cpp @@ -33,7 +33,6 @@ Upload::Ptr ApiUpload::makeByteArray(QUrl url, std::shared_ptr outpu void ApiUpload::init() { - qDebug() << "Setting up api upload"; auto api_headers = new ApiHeaderProxy(); addHeaderProxy(api_headers); } diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 65d6ec3a4..639047e43 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -144,21 +144,29 @@ void NetJob::updateState() void NetJob::emitFailed(QString reason) { #if defined(LAUNCHER_APPLICATION) - auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", - "The tasks failed\n" - "Failed urls\n" + - getFailedFiles().join("\n\t") + - "\n" - "If this continues to happen please check the logs of the application" - "Do you want to retry?", - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) - ->exec(); + if (m_ask_retry || m_manual_try < APPLICATION->settings()->get("NumberOfManualRetries").toInt()) { + m_manual_try++; + auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", + "The tasks failed\n" + "Failed urls\n" + + getFailedFiles().join("\n\t") + + "\n" + "If this continues to happen please check the logs of the application" + "Do you want to retry?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) + ->exec(); - if (response == QMessageBox::Yes) { - m_try = 0; - executeNextSubTask(); - return; + if (response == QMessageBox::Yes) { + m_try = 0; + executeNextSubTask(); + return; + } } #endif ConcurrentTask::emitFailed(reason); +} + +void NetJob::setAskRetry(bool askRetry) +{ + m_ask_retry = askRetry; } \ No newline at end of file diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h index 09da95771..4eaa49df5 100644 --- a/launcher/net/NetJob.h +++ b/launcher/net/NetJob.h @@ -62,6 +62,7 @@ class NetJob : public ConcurrentTask { auto getFailedActions() -> QList; auto getFailedFiles() -> QList; + void setAskRetry(bool askRetry); public slots: // Qt can't handle auto at the start for some reason? @@ -78,4 +79,6 @@ class NetJob : public ConcurrentTask { shared_qobject_ptr m_network; int m_try = 1; + bool m_ask_retry = true; + int m_manual_try = 0; }; diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 78c44380a..711b6674c 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -191,6 +191,7 @@ void LauncherPage::applySettings() s->set("NumberOfConcurrentTasks", ui->numberOfConcurrentTasksSpinBox->value()); s->set("NumberOfConcurrentDownloads", ui->numberOfConcurrentDownloadsSpinBox->value()); + s->set("NumberOfManualRetries", ui->numberOfManualRetriesSpinBox->value()); // Console settings s->set("ShowConsole", ui->showConsoleCheck->isChecked()); @@ -245,6 +246,7 @@ void LauncherPage::loadSettings() ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt()); ui->numberOfConcurrentDownloadsSpinBox->setValue(s->get("NumberOfConcurrentDownloads").toInt()); + ui->numberOfManualRetriesSpinBox->setValue(s->get("NumberOfManualRetries").toInt()); // Console settings ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 928ec8103..8959814bd 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -7,7 +7,7 @@ 0 0 511 - 629 + 691 @@ -233,6 +233,20 @@ + + + + Number of manual retries + + + + + + + 0 + + + diff --git a/launcher/ui/widgets/VariableSizedImageObject.cpp b/launcher/ui/widgets/VariableSizedImageObject.cpp index 3dd9d5634..9723a2c56 100644 --- a/launcher/ui/widgets/VariableSizedImageObject.cpp +++ b/launcher/ui/widgets/VariableSizedImageObject.cpp @@ -80,7 +80,7 @@ void VariableSizedImageObject::drawObject(QPainter* painter, { if (!format.hasProperty(ImageData)) { QUrl image_url{ qvariant_cast(format.property(QTextFormat::ImageName)) }; - if (m_fetching_images.contains(image_url)) + if (m_fetching_images.contains(image_url) || image_url.isEmpty()) return; auto meta = std::make_shared(); @@ -140,6 +140,7 @@ void VariableSizedImageObject::loadImage(QTextDocument* doc, std::shared_ptrurl.toEncoded(), QCryptographicHash::Algorithm::Sha1).toHex()))); auto job = new NetJob(QString("Load Image: %1").arg(meta->url.fileName()), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(meta->url, entry)); auto full_entry_path = entry->getFullPath(); From 694ea654577e920b490769f99926bff6f778d444 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 26 May 2024 11:13:01 +0300 Subject: [PATCH 09/76] disable retry dialog for logo fetching Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ResourceModel.cpp | 4 +++- launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp | 1 + launcher/ui/pages/modplatform/flame/FlameModel.cpp | 1 + launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp | 1 + launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp | 1 + launcher/ui/pages/modplatform/technic/TechnicModel.cpp | 1 + 6 files changed, 8 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index 8a69e910d..581fbf3b1 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -317,8 +317,10 @@ std::optional ResourceModel::getIcon(QModelIndex& index, const QUrl& url) if (QPixmapCache::find(url.toString(), &pixmap)) return { pixmap }; - if (!m_current_icon_job) + if (!m_current_icon_job) { m_current_icon_job.reset(new NetJob("IconJob", APPLICATION->network())); + m_current_icon_job->setAskRetry(false); + } if (m_currently_running_icon_actions.contains(url)) return {}; diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp index d46b97af1..f116ca915 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp @@ -195,6 +195,7 @@ void ListModel::requestLogo(QString file, QString url) MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file)); auto job = new NetJob(QString("ATLauncher Icon Download %1").arg(file), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 3b266bcef..267c5a3af 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -110,6 +110,7 @@ void ListModel::requestLogo(QString logo, QString url) MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo)); auto job = new NetJob(QString("Flame Icon Download %1").arg(logo), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 49666cf6e..98922123c 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -264,6 +264,7 @@ void ListModel::requestLogo(QString file) MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file)); NetJob* job = new NetJob(QString("FTB Icon Download for %1").arg(file), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry)); auto fullPath = entry->getFullPath(); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index ccfe7eccb..b53eea4ef 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -254,6 +254,7 @@ void ModpackListModel::requestLogo(QString logo, QString url) MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo)); auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp index 6f1810d71..4181edab6 100644 --- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp +++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp @@ -292,6 +292,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url) MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo)); auto job = new NetJob(QString("Technic Icon Download %1").arg(logo), APPLICATION->network()); + job->setAskRetry(false); job->addNetAction(Net::ApiDownload::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); From 59a8b912746108a1b083ff8a11f7112c23d06433 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 26 May 2024 16:28:07 +0300 Subject: [PATCH 10/76] add spacing to retry modal Signed-off-by: Trial97 --- launcher/net/NetJob.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 639047e43..66054cc8f 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -147,11 +147,11 @@ void NetJob::emitFailed(QString reason) if (m_ask_retry || m_manual_try < APPLICATION->settings()->get("NumberOfManualRetries").toInt()) { m_manual_try++; auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", - "The tasks failed\n" + "The tasks failed.\n" "Failed urls\n" + getFailedFiles().join("\n\t") + - "\n" - "If this continues to happen please check the logs of the application" + ".\n" + "If this continues to happen please check the logs of the application.\n" "Do you want to retry?", QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ->exec(); From e94243f99bc6840ec85430d3bcb72e748154e4f4 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 30 May 2024 09:56:55 +0300 Subject: [PATCH 11/76] fix blocked mods api Signed-off-by: Trial97 --- launcher/modplatform/flame/FileResolvingTask.cpp | 1 + launcher/net/NetJob.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 8d23896d9..3f9685892 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -74,6 +74,7 @@ void Flame::FileResolvingTask::netJobFinished() setProgress(1, 3); // job to check modrinth for blocked projects m_checkJob.reset(new NetJob("Modrinth check", m_network)); + m_checkJob->setAskRetry(false); blockedProjects = QMap>(); QJsonDocument doc; diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp index 66054cc8f..62c9d4296 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -144,7 +144,7 @@ void NetJob::updateState() void NetJob::emitFailed(QString reason) { #if defined(LAUNCHER_APPLICATION) - if (m_ask_retry || m_manual_try < APPLICATION->settings()->get("NumberOfManualRetries").toInt()) { + if (m_ask_retry && m_manual_try < APPLICATION->settings()->get("NumberOfManualRetries").toInt()) { m_manual_try++; auto response = CustomMessageBox::selectable(nullptr, "Confirm retry", "The tasks failed.\n" From c4a65dd861f0704f09f258c5cc9c5530e5db981a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 12 Jun 2024 00:34:39 +0300 Subject: [PATCH 12/76] update login flow Signed-off-by: Trial97 --- launcher/Application.h | 3 +- launcher/minecraft/auth/AuthFlow.cpp | 10 + launcher/minecraft/auth/AuthFlow.h | 3 + launcher/minecraft/auth/AuthStep.h | 1 + .../minecraft/auth/steps/MSADeviceCodeStep.h | 2 +- launcher/minecraft/auth/steps/MSAStep.cpp | 29 +- launcher/resources/documents/documents.qrc | 1 + launcher/resources/documents/login-qr.png | Bin 0 -> 7616 bytes launcher/ui/MainWindow.cpp | 8 + launcher/ui/dialogs/MSALoginDialog.cpp | 123 +++--- launcher/ui/dialogs/MSALoginDialog.h | 13 +- launcher/ui/dialogs/MSALoginDialog.ui | 383 ++++++++++++++---- launcher/ui/pages/global/AccountListPage.cpp | 5 +- ...org.prismlauncher.PrismLauncher.desktop.in | 2 +- program_info/win_install.nsi.in | 4 + 15 files changed, 421 insertions(+), 166 deletions(-) create mode 100644 launcher/resources/documents/login-qr.png diff --git a/launcher/Application.h b/launcher/Application.h index 7669e08ec..8303c7475 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -48,7 +48,6 @@ #include #include "minecraft/launch/MinecraftServerTarget.h" -#include "ui/themes/CatPack.h" class LaunchController; class LocalPeer; @@ -193,6 +192,8 @@ class Application : public QApplication { void globalSettingsClosed(); int currentCatChanged(int index); + void oauthReplyRecieved(QVariantMap); + #ifdef Q_OS_MACOS void clickedOnDock(); #endif diff --git a/launcher/minecraft/auth/AuthFlow.cpp b/launcher/minecraft/auth/AuthFlow.cpp index 5648fe9f6..45926206c 100644 --- a/launcher/minecraft/auth/AuthFlow.cpp +++ b/launcher/minecraft/auth/AuthFlow.cpp @@ -59,6 +59,9 @@ void AuthFlow::executeTask() void AuthFlow::nextStep() { + if (!Task::isRunning()) { + return; + } if (m_steps.size() == 0) { // we got to the end without an incident... assume this is all. m_currentStep.reset(); @@ -143,4 +146,11 @@ bool AuthFlow::changeState(AccountTaskState newState, QString reason) return false; } } +} +bool AuthFlow::abort() +{ + emitAborted(); + if (m_currentStep) + m_currentStep->abort(); + return true; } \ No newline at end of file diff --git a/launcher/minecraft/auth/AuthFlow.h b/launcher/minecraft/auth/AuthFlow.h index d99deec3c..4d18ac845 100644 --- a/launcher/minecraft/auth/AuthFlow.h +++ b/launcher/minecraft/auth/AuthFlow.h @@ -24,6 +24,9 @@ class AuthFlow : public Task { AccountTaskState taskState() { return m_taskState; } + public slots: + bool abort() override; + signals: void authorizeWithBrowser(const QUrl& url); void authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn); diff --git a/launcher/minecraft/auth/AuthStep.h b/launcher/minecraft/auth/AuthStep.h index 4d2cf69c1..a2b2cf9e5 100644 --- a/launcher/minecraft/auth/AuthStep.h +++ b/launcher/minecraft/auth/AuthStep.h @@ -34,6 +34,7 @@ class AuthStep : public QObject { public slots: virtual void perform() = 0; + virtual void abort() {} signals: void finished(AccountTaskState resultingState, QString message); diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.h b/launcher/minecraft/auth/steps/MSADeviceCodeStep.h index e53eebc62..024927b31 100644 --- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.h +++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.h @@ -51,7 +51,7 @@ class MSADeviceCodeStep : public AuthStep { QString describe() override; public slots: - void abort(); + void abort() override; signals: void authorizeWithBrowser(QString url, QString code, int expiresIn); diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 3f31cdc16..c1eb3a33c 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -35,22 +35,35 @@ #include "MSAStep.h" -#include #include #include +#include #include "Application.h" +#include "BuildConfig.h" + +class CustomOAuthOobReplyHandler : public QOAuthOobReplyHandler { + Q_OBJECT + + public: + explicit CustomOAuthOobReplyHandler(QObject* parent = nullptr) : QOAuthOobReplyHandler(parent) + { + connect(APPLICATION, &Application::oauthReplyRecieved, this, &QOAuthOobReplyHandler::callbackReceived); + } + ~CustomOAuthOobReplyHandler() override + { + disconnect(APPLICATION, &Application::oauthReplyRecieved, this, &QOAuthOobReplyHandler::callbackReceived); + } + QString callback() const override { return BuildConfig.LAUNCHER_APP_BINARY_NAME + "://oauth"; } +}; MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(silent) { m_clientId = APPLICATION->getMSAClientID(); - auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this); - replyHandler->setCallbackText( - "