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(
- " ");
- oauth2.setReplyHandler(replyHandler);
+ auto bv = new CustomOAuthOobReplyHandler();
+
+ oauth2.setReplyHandler(bv);
oauth2.setAuthorizationUrl(QUrl("https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize"));
oauth2.setAccessTokenUrl(QUrl("https://login.microsoftonline.com/consumers/oauth2/v2.0/token"));
oauth2.setScope("XboxLive.SignIn XboxLive.offline_access");
@@ -106,3 +119,5 @@ void MSAStep::perform()
oauth2.grant();
}
}
+
+#include "MSAStep.moc"
\ No newline at end of file
diff --git a/launcher/resources/documents/documents.qrc b/launcher/resources/documents/documents.qrc
index 007efcde3..a5ff84390 100644
--- a/launcher/resources/documents/documents.qrc
+++ b/launcher/resources/documents/documents.qrc
@@ -2,6 +2,7 @@
../../../COPYING.md
+ login-qr.png
diff --git a/launcher/resources/documents/login-qr.png b/launcher/resources/documents/login-qr.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bed0a73e2e456fd810cdc997dbf0db24dcafc1c
GIT binary patch
literal 7616
zcmeHMdrVVT7(ZAChJgf^DBYxU5?^tY4a7R2fR52QCg?ync`3|_3Rno(+FrCGNaiGv
zg<4WxB|&5+6tG%QXr&AkwJlX}od{g&bcL>zf)#tUJa%r)k|kz;En9MvrD^X;d(-CY
z_nqJCoZT7CaCd#z6#(GA{qu;g09agrKbI_m?=TM^s)ZNl)F?&-Sim2(iiR=(ypL^<
z*cx}dYGSA>b2xli_u_JRkNOI@-BIg$LB9#*zKib`OKCKMW(k{9@p9Z
z8b#JPhn;m1b_u-be!H=)26~HQhy`=LV%w7;a+0B#niE;B3HH&uO!El?HE-Zy0%92m
z0Bu(w&-`?bX@T&|MfPoGDaJ0N%1$MXxSUUq_L$<~I}+!YK{7M3-JVlQ%`s9{)TCSf
ziJL9O2H$SE3mdJst{f4w2;RZjxOB;YkNlffx54@==+p@-dQ8Oi+wG-h6{%*MI@H8(
zJV4*qdd#0ENJkcX5|i7a-~VI!Tf1YNu)KZIeUvB*{TnSJB)iR~(BRC#tOwuwb1@~l2W
z#5MVTjj{^T-XfJ0>0u7?w8;Ky&%9B2XN$GQr@7W%XtBLroti%SEzKs9l6%N^#Kra
z5JWrFu9nXj{8>e?jmo~E_F|%QSDlsUO@LLk%>f-rNtgT01kL~0x
zw$V_%>lO(SNjf^YDo{Y=3T3uXdUuQrdgP~+k$tUhq6||Aqg>$q_Yx|exj3fD61fOtAY~9+)F@37SQX%_@a!fp1>LxQD5!i=3d6eK
zIxaLBA+SPKmWaSGid0d+egV#eGF=NP8|Oeyq-df)n=gDk55qXQLO~a62V%4O?RI-_
zZ?AC!09eZ3q;z1a8w(?tuY_h&`HL>Tfq`AZqaN&%G%8JD(dOjx2XhXPsn#ZlKYXm}
z{v44J2+E#Q!SN3N@dDN4L$O-ziOW~0$)P$ZOKRuZ4xwa1qtKs;^MDT&1$%N&2cmkv!{guEH
z;a@qvnr)s7S`Lp)fY(zN{ag~$6DT!!EPoW=16ct$4^`r)55r%=BNhEYJO-rUgK$j*
d57Yk1tqImvWx8DuF2sL)`)AP+P22XL{sR(L{Sp8G
literal 0
HcmV?d00001
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 50074f1da..f55e35a8f 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -996,6 +996,14 @@ void MainWindow::processURLs(QList urls)
dlUrlDialod.execWithTask(job.get());
}
+ } else if (url.scheme() == BuildConfig.LAUNCHER_APP_BINARY_NAME) {
+ QVariantMap receivedData;
+ const QUrlQuery query(url.query());
+ const auto items = query.queryItems();
+ for (auto it = items.begin(), end = items.end(); it != end; ++it)
+ receivedData.insert(it->first, it->second);
+ emit APPLICATION->oauthReplyRecieved(receivedData);
+ continue;
} else {
dl_url = url;
}
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index a654c1d29..5f311e625 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -34,6 +34,8 @@
*/
#include "MSALoginDialog.h"
+#include "Application.h"
+
#include "ui_MSALoginDialog.h"
#include "DesktopServices.h"
@@ -41,6 +43,7 @@
#include
#include
+#include
#include
#include
@@ -48,13 +51,18 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
{
ui->setupUi(this);
- ui->cancel->setEnabled(false);
- ui->link->setVisible(false);
- ui->copy->setVisible(false);
- ui->progressBar->setVisible(false);
+ // make font monospace
+ QFont font;
+ font.setPixelSize(ui->code->fontInfo().pixelSize());
+ font.setFamily(APPLICATION->settings()->get("ConsoleFont").toString());
+ font.setStyleHint(QFont::Monospace);
+ font.setFixedPitch(true);
+ ui->code->setFont(font);
- connect(ui->cancel, &QPushButton::pressed, this, &QDialog::reject);
- connect(ui->copy, &QPushButton::pressed, this, &MSALoginDialog::copyUrl);
+ ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false);
+
+ connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
+ ui->qr->setPixmap(QPixmap(":/documents/login-qr.png"));
}
int MSALoginDialog::exec()
@@ -63,12 +71,12 @@ int MSALoginDialog::exec()
m_account = MinecraftAccount::createBlankMSA();
m_task = m_account->login(m_using_device_code);
connect(m_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
- connect(m_task.get(), &Task::succeeded, this, &MSALoginDialog::onTaskSucceeded);
+ connect(m_task.get(), &Task::succeeded, this, &QDialog::accept);
+ connect(m_task.get(), &Task::aborted, this, &MSALoginDialog::reject);
connect(m_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
connect(m_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser);
connect(m_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra);
- connect(ui->cancel, &QPushButton::pressed, m_task.get(), &Task::abort);
- connect(&m_external_timer, &QTimer::timeout, this, &MSALoginDialog::externalLoginTick);
+ connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort);
m_task->start();
return QDialog::exec();
@@ -79,9 +87,10 @@ MSALoginDialog::~MSALoginDialog()
delete ui;
}
-void MSALoginDialog::onTaskFailed(const QString& reason)
+void MSALoginDialog::onTaskFailed(QString reason)
{
// Set message
+ ui->stackedWidget->setCurrentIndex(0);
auto lines = reason.split('\n');
QString processed;
for (auto line : lines) {
@@ -91,91 +100,55 @@ void MSALoginDialog::onTaskFailed(const QString& reason)
processed += " ";
}
}
- ui->message->setText(processed);
-}
-
-void MSALoginDialog::onTaskSucceeded()
-{
- QDialog::accept();
-}
-
-void MSALoginDialog::onTaskStatus(const QString& status)
-{
- ui->message->setText(status);
- ui->cancel->setEnabled(false);
- ui->link->setVisible(false);
- ui->copy->setVisible(false);
- ui->progressBar->setVisible(false);
-}
-
-// Public interface
-MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, QString msg, bool usingDeviceCode)
-{
- MSALoginDialog dlg(parent);
- dlg.m_using_device_code = usingDeviceCode;
- dlg.ui->message->setText(msg);
- if (dlg.exec() == QDialog::Accepted) {
- return dlg.m_account;
- }
- return nullptr;
+ ui->status->setText(processed);
+ ui->loadingLabel->setText(m_task->getStatus());
+ disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort);
+ connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &MSALoginDialog::reject);
}
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
{
- ui->cancel->setEnabled(true);
- ui->link->setVisible(true);
- ui->copy->setVisible(true);
+ ui->stackedWidget->setCurrentIndex(2);
DesktopServices::openUrl(url);
- ui->link->setText(url.toDisplayString());
- ui->message->setText(
+ const auto uri = url.toString();
+ const auto linkString = QString("%2 ").arg(uri, uri);
+ ui->urlInfo->setText(
tr("Browser opened to complete the login process."
" "
- "If your browser hasn't opened, please manually open the below link in your browser:"));
-}
-
-void MSALoginDialog::copyUrl()
-{
- QClipboard* cb = QApplication::clipboard();
- cb->setText(ui->link->text());
+ "If your browser hasn't opened, please manually open the following link and choose your account:
"));
+ ui->url->setText(linkString);
}
void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn)
{
- m_external_elapsed = 0;
- m_external_timeout = expiresIn;
+ ui->stackedWidget->setCurrentIndex(1);
- m_external_timer.setInterval(1000);
- m_external_timer.setSingleShot(false);
- m_external_timer.start();
+ const auto linkString = QString("%2 ").arg(url, url);
+ ui->code->setText(code);
+ ui->codeInfo->setText(tr("Enter this code into %1 and choose your account.
").arg(linkString));
- ui->progressBar->setMaximum(expiresIn);
- ui->progressBar->setValue(m_external_elapsed);
+ const auto isDefaultUrl = url == "https://www.microsoft.com/link";
- QString linkString = QString("%2 ").arg(url, url);
- if (url == "https://www.microsoft.com/link" && !code.isEmpty()) {
+ ui->qr->setVisible(isDefaultUrl);
+ if (isDefaultUrl && !code.isEmpty()) {
url += QString("?otc=%1").arg(code);
- ui->message->setText(tr("Please login in the opened browser. If no browser was opened, please open up %1 in "
- "a browser and put in the code %2 to proceed with login.
")
- .arg(linkString, code));
- } else {
- ui->message->setText(
- tr("Please open up %1 in a browser and put in the code %2 to proceed with login.
").arg(linkString, code));
}
- ui->cancel->setEnabled(true);
- ui->link->setVisible(true);
- ui->copy->setVisible(true);
- ui->progressBar->setVisible(true);
DesktopServices::openUrl(url);
- ui->link->setText(code);
}
-void MSALoginDialog::externalLoginTick()
+void MSALoginDialog::onTaskStatus(QString status)
{
- m_external_elapsed++;
- ui->progressBar->setValue(m_external_elapsed);
- ui->progressBar->repaint();
+ ui->stackedWidget->setCurrentIndex(0);
+ ui->status->setText(status);
+}
- if (m_external_elapsed >= m_external_timeout) {
- m_external_timer.stop();
+// Public interface
+MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, bool usingDeviceCode)
+{
+ MSALoginDialog dlg(parent);
+ dlg.m_using_device_code = usingDeviceCode;
+ if (dlg.exec() == QDialog::Accepted) {
+ return dlg.m_account;
}
+ return nullptr;
}
\ No newline at end of file
diff --git a/launcher/ui/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h
index cef647ee4..cf806d88b 100644
--- a/launcher/ui/dialogs/MSALoginDialog.h
+++ b/launcher/ui/dialogs/MSALoginDialog.h
@@ -32,29 +32,22 @@ class MSALoginDialog : public QDialog {
public:
~MSALoginDialog();
- static MinecraftAccountPtr newAccount(QWidget* parent, QString message, bool usingDeviceCode = false);
+ static MinecraftAccountPtr newAccount(QWidget* parent, bool usingDeviceCode = false);
int exec() override;
private:
explicit MSALoginDialog(QWidget* parent = 0);
protected slots:
- void onTaskFailed(const QString& reason);
- void onTaskSucceeded();
- void onTaskStatus(const QString& status);
+ void onTaskFailed(QString reason);
+ void onTaskStatus(QString status);
void authorizeWithBrowser(const QUrl& url);
void authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn);
- void copyUrl();
- void externalLoginTick();
private:
Ui::MSALoginDialog* ui;
MinecraftAccountPtr m_account;
shared_qobject_ptr m_task;
- int m_external_elapsed;
- int m_external_timeout;
- QTimer m_external_timer;
-
bool m_using_device_code = false;
};
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index df1b32044..afd97e348 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -6,90 +6,337 @@
0
0
- 491
- 208
+ 500
+ 300
-
-
- 0
- 0
-
-
Add Microsoft Account
-
-
-
-
- 0
- 0
-
-
-
-
- 500
- 500
-
-
-
-
-
-
- Qt::RichText
-
-
- true
-
-
- true
-
-
- Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+ 2
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ 16
+ 75
+ true
+
+
+
+ Please wait...
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Status
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 40
+ 75
+ true
+
+
+
+ IBeamCursor
+
+
+ CODE
+
+
+ Qt::AlignCenter
+
+
+ Qt::TextBrowserInteraction
+
+
+
+ -
+
+
+ Copy code to clipboard
+
+
+
+
+
+
+ . .
+
+
+
+ 22
+ 22
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+
+ false
+
+
+
+ Information
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+ Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 100
+ 100
+
+
+
+
+
+
+ :/assets/login-qr.png
+
+
+ true
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ false
+
+
+
+ Information
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+ true
+
+
+ Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
+
+
+
+ -
+
+
+ url
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+ Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
-
-
- -
-
-
- false
-
-
-
- -
-
-
-
-
-
-
- . .
-
-
-
-
-
- -
-
-
- 24
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Help
-
+
false
- -
-
-
- Cancel
-
-
-
diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp
index 8d0b66004..3c77cb97a 100644
--- a/launcher/ui/pages/global/AccountListPage.cpp
+++ b/launcher/ui/pages/global/AccountListPage.cpp
@@ -134,15 +134,14 @@ void AccountListPage::on_actionAddMicrosoft_triggered()
box.setWindowTitle(tr("Add account"));
box.setText(tr("How do you want to login?"));
box.setIcon(QMessageBox::Question);
- auto deviceCode = box.addButton(tr("Legacy"), QMessageBox::ButtonRole::YesRole);
+ auto deviceCode = box.addButton(tr("Remote"), QMessageBox::ButtonRole::YesRole);
auto authCode = box.addButton(tr("Recommended"), QMessageBox::ButtonRole::NoRole);
auto cancel = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::RejectRole);
box.setDefaultButton(authCode);
box.exec();
if ((box.clickedButton() != deviceCode && box.clickedButton() != authCode) || box.clickedButton() == cancel)
return;
- MinecraftAccountPtr account = MSALoginDialog::newAccount(
- this, tr("Please enter your Mojang account email and password to add your account."), box.clickedButton() == deviceCode);
+ MinecraftAccountPtr account = MSALoginDialog::newAccount(this, box.clickedButton() == deviceCode);
if (account) {
m_accounts->addAccount(account);
diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in
index a2846b06e..7d186a2e7 100644
--- a/program_info/org.prismlauncher.PrismLauncher.desktop.in
+++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in
@@ -10,4 +10,4 @@ Icon=org.prismlauncher.PrismLauncher
Categories=Game;ActionGame;AdventureGame;Simulation;
Keywords=game;minecraft;mc;
StartupWMClass=PrismLauncher
-MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;
+MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/prismlauncher;
diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in
index eda85821b..cc56b9bd5 100644
--- a/program_info/win_install.nsi.in
+++ b/program_info/win_install.nsi.in
@@ -368,6 +368,10 @@ Section "@Launcher_DisplayName@"
WriteRegStr HKCU Software\Classes\curseforge "URL Protocol" ""
WriteRegStr HKCU Software\Classes\curseforge\shell\open\command "" '"$INSTDIR\@Launcher_APP_BINARY_NAME@.exe" "%1"'
+; Write the URL Handler into registry for prismlauncher
+ WriteRegStr HKCU Software\Classes\prismlauncher "URL Protocol" ""
+ WriteRegStr HKCU Software\Classes\prismlauncher\shell\open\command "" '"$INSTDIR\@Launcher_APP_BINARY_NAME@.exe" "%1"'
+
; Write the uninstall keys for Windows
${GetParameters} $R0
${GetOptions} $R0 "/NoUninstaller" $R1
From df142550fef0a53e6152f7e0710b7ec86a3049de Mon Sep 17 00:00:00 2001
From: Trial97
Date: Wed, 12 Jun 2024 11:55:56 +0300
Subject: [PATCH 13/76] update Add account question
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.cpp | 9 +--------
launcher/ui/pages/global/AccountListPage.cpp | 6 +++---
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 5f311e625..9c93df264 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -126,14 +126,7 @@ void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, in
const auto linkString = QString("%2 ").arg(url, url);
ui->code->setText(code);
ui->codeInfo->setText(tr("Enter this code into %1 and choose your account.
").arg(linkString));
-
- const auto isDefaultUrl = url == "https://www.microsoft.com/link";
-
- ui->qr->setVisible(isDefaultUrl);
- if (isDefaultUrl && !code.isEmpty()) {
- url += QString("?otc=%1").arg(code);
- }
- DesktopServices::openUrl(url);
+ ui->qr->setVisible(url == "https://www.microsoft.com/link");
}
void MSALoginDialog::onTaskStatus(QString status)
diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp
index 3c77cb97a..d2350fb70 100644
--- a/launcher/ui/pages/global/AccountListPage.cpp
+++ b/launcher/ui/pages/global/AccountListPage.cpp
@@ -132,10 +132,10 @@ void AccountListPage::on_actionAddMicrosoft_triggered()
{
QMessageBox box(this);
box.setWindowTitle(tr("Add account"));
- box.setText(tr("How do you want to login?"));
+ box.setText(tr("Where would you like to login?"));
box.setIcon(QMessageBox::Question);
- auto deviceCode = box.addButton(tr("Remote"), QMessageBox::ButtonRole::YesRole);
- auto authCode = box.addButton(tr("Recommended"), QMessageBox::ButtonRole::NoRole);
+ auto authCode = box.addButton(tr("On this device"), QMessageBox::ButtonRole::NoRole);
+ auto deviceCode = box.addButton(tr("On another device"), QMessageBox::ButtonRole::YesRole);
auto cancel = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::RejectRole);
box.setDefaultButton(authCode);
box.exec();
From bbbe7c879e4497a48eee916730f00dab3aad578c Mon Sep 17 00:00:00 2001
From: Trial97
Date: Wed, 12 Jun 2024 12:35:02 +0300
Subject: [PATCH 14/76] update callback
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index c1eb3a33c..78cb0b8d2 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -54,7 +54,7 @@ class CustomOAuthOobReplyHandler : public QOAuthOobReplyHandler {
{
disconnect(APPLICATION, &Application::oauthReplyRecieved, this, &QOAuthOobReplyHandler::callbackReceived);
}
- QString callback() const override { return BuildConfig.LAUNCHER_APP_BINARY_NAME + "://oauth"; }
+ QString callback() const override { return BuildConfig.LAUNCHER_APP_BINARY_NAME + "://oauth/microsoft"; }
};
MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(silent)
From 5f5296ef5e2ff34d3726c73927c842e2c2a8073e Mon Sep 17 00:00:00 2001
From: Trial97
Date: Wed, 12 Jun 2024 19:34:19 +0300
Subject: [PATCH 15/76] update ui once again
Signed-off-by: Trial97
---
.../auth/steps/MSADeviceCodeStep.cpp | 8 +-
launcher/resources/documents/documents.qrc | 2 +-
launcher/resources/documents/login-qr.svg | 8 +
launcher/ui/dialogs/MSALoginDialog.cpp | 74 ++-
launcher/ui/dialogs/MSALoginDialog.h | 7 +-
launcher/ui/dialogs/MSALoginDialog.ui | 591 ++++++++++--------
launcher/ui/pages/global/AccountListPage.cpp | 14 +-
7 files changed, 415 insertions(+), 289 deletions(-)
create mode 100644 launcher/resources/documents/login-qr.svg
diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
index 22f5d4069..c34351bf2 100644
--- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
+++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
@@ -135,9 +135,9 @@ void MSADeviceCodeStep::deviceAutorizationFinished()
m_expiration_timer.setSingleShot(true);
connect(&m_expiration_timer, &QTimer::timeout, this, &MSADeviceCodeStep::abort);
m_expiration_timer.start();
-
m_pool_timer.setTimerType(Qt::VeryCoarseTimer);
m_pool_timer.setSingleShot(true);
+ connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser);
startPoolTimer();
}
@@ -157,8 +157,12 @@ void MSADeviceCodeStep::startPoolTimer()
if (m_is_aborted) {
return;
}
+ if (m_expiration_timer.remainingTime() < interval * 1000) {
+ perform();
+ return;
+ }
+
m_pool_timer.setInterval(interval * 1000);
- connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser);
m_pool_timer.start();
}
diff --git a/launcher/resources/documents/documents.qrc b/launcher/resources/documents/documents.qrc
index a5ff84390..489d1d5a2 100644
--- a/launcher/resources/documents/documents.qrc
+++ b/launcher/resources/documents/documents.qrc
@@ -2,7 +2,7 @@
../../../COPYING.md
- login-qr.png
+ login-qr.svg
diff --git a/launcher/resources/documents/login-qr.svg b/launcher/resources/documents/login-qr.svg
new file mode 100644
index 000000000..1b88e3c83
--- /dev/null
+++ b/launcher/resources/documents/login-qr.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 9c93df264..0a3bca86b 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -36,6 +36,7 @@
#include "MSALoginDialog.h"
#include "Application.h"
+#include "BuildConfig.h"
#include "ui_MSALoginDialog.h"
#include "DesktopServices.h"
@@ -59,25 +60,40 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
font.setFixedPitch(true);
ui->code->setFont(font);
- ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false);
+ // ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false);
connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
- ui->qr->setPixmap(QPixmap(":/documents/login-qr.png"));
+ ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(75, 75)));
+ ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
+ connect(ui->loginButton, &QPushButton::clicked, this, [this] {
+ if (m_url.isValid())
+ DesktopServices::openUrl(m_url);
+ });
}
int MSALoginDialog::exec()
{
// Setup the login task and start it
m_account = MinecraftAccount::createBlankMSA();
- m_task = m_account->login(m_using_device_code);
- connect(m_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
- connect(m_task.get(), &Task::succeeded, this, &QDialog::accept);
- connect(m_task.get(), &Task::aborted, this, &MSALoginDialog::reject);
- connect(m_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
- connect(m_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser);
- connect(m_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra);
- connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort);
- m_task->start();
+ m_authflow_task = m_account->login(false);
+ connect(m_authflow_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
+ connect(m_authflow_task.get(), &Task::succeeded, this, &QDialog::accept);
+ connect(m_authflow_task.get(), &Task::aborted, this, &MSALoginDialog::reject);
+ connect(m_authflow_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
+ connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser);
+ connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra);
+ connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort);
+
+ m_devicecode_task.reset(new AuthFlow(m_account->accountData(), AuthFlow::Action::DeviceCode, this));
+ connect(m_devicecode_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
+ connect(m_devicecode_task.get(), &Task::succeeded, this, &QDialog::accept);
+ connect(m_devicecode_task.get(), &Task::aborted, this, &MSALoginDialog::reject);
+ connect(m_devicecode_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
+ connect(m_devicecode_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser);
+ connect(m_devicecode_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra);
+ connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_devicecode_task.get(), &Task::abort);
+ QMetaObject::invokeMethod(m_authflow_task.get(), &Task::start, Qt::QueuedConnection);
+ QMetaObject::invokeMethod(m_devicecode_task.get(), &Task::start, Qt::QueuedConnection);
return QDialog::exec();
}
@@ -100,23 +116,29 @@ void MSALoginDialog::onTaskFailed(QString reason)
processed += " ";
}
}
+ auto task = qobject_cast(sender());
ui->status->setText(processed);
- ui->loadingLabel->setText(m_task->getStatus());
- disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort);
+ if (task) {
+ ui->loadingLabel->setText(task->getStatus());
+ }
+ disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort);
+ disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_devicecode_task.get(), &Task::abort);
connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &MSALoginDialog::reject);
}
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
{
- ui->stackedWidget->setCurrentIndex(2);
- DesktopServices::openUrl(url);
+ ui->stackedWidget->setCurrentIndex(1);
+ // DesktopServices::openUrl(url);
const auto uri = url.toString();
const auto linkString = QString("%2 ").arg(uri, uri);
- ui->urlInfo->setText(
- tr("Browser opened to complete the login process."
- " "
- "If your browser hasn't opened, please manually open the following link and choose your account:"));
- ui->url->setText(linkString);
+ m_url = url;
+ ui->link->setText(linkString);
+ // ui->urlInfo->setText(
+ // tr("Browser opened to complete the login process."
+ // " "
+ // "If your browser hasn't opened, please manually open the following link and choose your account:"));
+ // ui->url->setText(linkString);
}
void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn)
@@ -125,8 +147,13 @@ void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, in
const auto linkString = QString("%2 ").arg(url, url);
ui->code->setText(code);
- ui->codeInfo->setText(tr("Enter this code into %1 and choose your account.
").arg(linkString));
- ui->qr->setVisible(url == "https://www.microsoft.com/link");
+ auto isDefaultUrl = url == "https://www.microsoft.com/link";
+ ui->qr->setVisible(isDefaultUrl);
+ if (isDefaultUrl) {
+ ui->qrMessage->setText(tr("Open %1 or scan the QR and enter the above code.").arg(linkString));
+ } else {
+ ui->qrMessage->setText(tr("Open %1 and enter the above code.").arg(linkString));
+ }
}
void MSALoginDialog::onTaskStatus(QString status)
@@ -136,10 +163,9 @@ void MSALoginDialog::onTaskStatus(QString status)
}
// Public interface
-MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, bool usingDeviceCode)
+MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent)
{
MSALoginDialog dlg(parent);
- dlg.m_using_device_code = usingDeviceCode;
if (dlg.exec() == QDialog::Accepted) {
return dlg.m_account;
}
diff --git a/launcher/ui/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h
index cf806d88b..70f480ca9 100644
--- a/launcher/ui/dialogs/MSALoginDialog.h
+++ b/launcher/ui/dialogs/MSALoginDialog.h
@@ -32,7 +32,7 @@ class MSALoginDialog : public QDialog {
public:
~MSALoginDialog();
- static MinecraftAccountPtr newAccount(QWidget* parent, bool usingDeviceCode = false);
+ static MinecraftAccountPtr newAccount(QWidget* parent);
int exec() override;
private:
@@ -47,7 +47,8 @@ class MSALoginDialog : public QDialog {
private:
Ui::MSALoginDialog* ui;
MinecraftAccountPtr m_account;
- shared_qobject_ptr m_task;
+ shared_qobject_ptr m_devicecode_task;
+ shared_qobject_ptr m_authflow_task;
- bool m_using_device_code = false;
+ QUrl m_url;
};
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index afd97e348..b2ad80270 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -6,18 +6,18 @@
0
0
- 500
- 300
+ 772
+ 326
Add Microsoft Account
-
+
-
- 2
+ 1
@@ -49,6 +49,9 @@
Qt::AlignCenter
+
+ true
+
-
@@ -59,6 +62,9 @@
Qt::AlignCenter
+
+ true
+
-
@@ -76,253 +82,349 @@
-
-
+
+
-
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
+
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ 16
+ 75
+ true
+
+
+
+ Login to Prismlauncher
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+ TextLabel
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 250
+ 40
+
+
+
+ Login with Microsoft
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
-
-
-
-
- 40
- 75
- true
-
-
-
- IBeamCursor
-
-
- CODE
-
-
- Qt::AlignCenter
-
-
- Qt::TextBrowserInteraction
-
-
+
+ -
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ Qt::Vertical
+
+
+
+
+
+ -
+
+
+ Or
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ Qt::Vertical
+
+
+
+
+
+
-
-
-
- Copy code to clipboard
-
-
-
-
-
-
- . .
-
-
-
- 22
- 22
-
-
-
- true
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 75
+ 75
+
+
+
+
+ 100
+ 100
+
+
+
+
+
+
+ true
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 30
+ 75
+ true
+
+
+
+ IBeamCursor
+
+
+ CODE
+
+
+ Qt::AlignCenter
+
+
+ Qt::TextBrowserInteraction
+
+
+
+ -
+
+
+ Copy code to clipboard
+
+
+
+
+
+
+ . .
+
+
+
+ 22
+ 22
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ TextLabel
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
- -
-
-
-
- false
-
-
-
- Information
-
-
- Qt::AlignCenter
-
-
- true
-
-
- Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
-
-
-
- -
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 100
- 100
-
-
-
-
-
-
- :/assets/login-qr.png
-
-
- true
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- false
-
-
-
- Information
-
-
- Qt::AlignCenter
-
-
- true
-
-
- true
-
-
- Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
-
-
-
- -
-
-
- url
-
-
- Qt::AlignCenter
-
-
- true
-
-
- Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
@@ -330,10 +432,7 @@
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Help
-
-
- false
+ QDialogButtonBox::Cancel
diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp
index d2350fb70..041b8faff 100644
--- a/launcher/ui/pages/global/AccountListPage.cpp
+++ b/launcher/ui/pages/global/AccountListPage.cpp
@@ -130,19 +130,7 @@ void AccountListPage::listChanged()
void AccountListPage::on_actionAddMicrosoft_triggered()
{
- QMessageBox box(this);
- box.setWindowTitle(tr("Add account"));
- box.setText(tr("Where would you like to login?"));
- box.setIcon(QMessageBox::Question);
- auto authCode = box.addButton(tr("On this device"), QMessageBox::ButtonRole::NoRole);
- auto deviceCode = box.addButton(tr("On another device"), QMessageBox::ButtonRole::YesRole);
- auto cancel = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::RejectRole);
- box.setDefaultButton(authCode);
- box.exec();
- if ((box.clickedButton() != deviceCode && box.clickedButton() != authCode) || box.clickedButton() == cancel)
- return;
- MinecraftAccountPtr account = MSALoginDialog::newAccount(this, box.clickedButton() == deviceCode);
-
+ auto account = MSALoginDialog::newAccount(this);
if (account) {
m_accounts->addAccount(account);
if (m_accounts->count() == 1) {
From 125fb2eaf288cd650ed82ca1f28262594e78932d Mon Sep 17 00:00:00 2001
From: Trial97
Date: Wed, 12 Jun 2024 19:34:58 +0300
Subject: [PATCH 16/76] remove png qr code
Signed-off-by: Trial97
---
launcher/resources/documents/login-qr.png | Bin 7616 -> 0 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 launcher/resources/documents/login-qr.png
diff --git a/launcher/resources/documents/login-qr.png b/launcher/resources/documents/login-qr.png
deleted file mode 100644
index 9bed0a73e2e456fd810cdc997dbf0db24dcafc1c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7616
zcmeHMdrVVT7(ZAChJgf^DBYxU5?^tY4a7R2fR52QCg?ync`3|_3Rno(+FrCGNaiGv
zg<4WxB|&5+6tG%QXr&AkwJlX}od{g&bcL>zf)#tUJa%r)k|kz;En9MvrD^X;d(-CY
z_nqJCoZT7CaCd#z6#(GA{qu;g09agrKbI_m?=TM^s)ZNl)F?&-Sim2(iiR=(ypL^<
z*cx}dYGSA>b2xli_u_JRkNOI@-BIg$LB9#*zKib`OKCKMW(k{9@p9Z
z8b#JPhn;m1b_u-be!H=)26~HQhy`=LV%w7;a+0B#niE;B3HH&uO!El?HE-Zy0%92m
z0Bu(w&-`?bX@T&|MfPoGDaJ0N%1$MXxSUUq_L$<~I}+!YK{7M3-JVlQ%`s9{)TCSf
ziJL9O2H$SE3mdJst{f4w2;RZjxOB;YkNlffx54@==+p@-dQ8Oi+wG-h6{%*MI@H8(
zJV4*qdd#0ENJkcX5|i7a-~VI!Tf1YNu)KZIeUvB*{TnSJB)iR~(BRC#tOwuwb1@~l2W
z#5MVTjj{^T-XfJ0>0u7?w8;Ky&%9B2XN$GQr@7W%XtBLroti%SEzKs9l6%N^#Kra
z5JWrFu9nXj{8>e?jmo~E_F|%QSDlsUO@LLk%>f-rNtgT01kL~0x
zw$V_%>lO(SNjf^YDo{Y=3T3uXdUuQrdgP~+k$tUhq6||Aqg>$q_Yx|exj3fD61fOtAY~9+)F@37SQX%_@a!fp1>LxQD5!i=3d6eK
zIxaLBA+SPKmWaSGid0d+egV#eGF=NP8|Oeyq-df)n=gDk55qXQLO~a62V%4O?RI-_
zZ?AC!09eZ3q;z1a8w(?tuY_h&`HL>Tfq`AZqaN&%G%8JD(dOjx2XhXPsn#ZlKYXm}
z{v44J2+E#Q!SN3N@dDN4L$O-ziOW~0$)P$ZOKRuZ4xwa1qtKs;^MDT&1$%N&2cmkv!{guEH
z;a@qvnr)s7S`Lp)fY(zN{ag~$6DT!!EPoW=16ct$4^`r)55r%=BNhEYJO-rUgK$j*
d57Yk1tqImvWx8DuF2sL)`)AP+P22XL{sR(L{Sp8G
From 80ea67f7cf3fa8d74e595546e4c0828868d3b18a Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 13 Jun 2024 00:00:08 +0300
Subject: [PATCH 17/76] finish login dialog
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.cpp | 11 -----------
launcher/ui/dialogs/MSALoginDialog.ui | 17 ++---------------
2 files changed, 2 insertions(+), 26 deletions(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 0a3bca86b..aebd04f08 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -60,8 +60,6 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
font.setFixedPitch(true);
ui->code->setFont(font);
- // ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false);
-
connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(75, 75)));
ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
@@ -129,16 +127,7 @@ void MSALoginDialog::onTaskFailed(QString reason)
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
{
ui->stackedWidget->setCurrentIndex(1);
- // DesktopServices::openUrl(url);
- const auto uri = url.toString();
- const auto linkString = QString("%2 ").arg(uri, uri);
m_url = url;
- ui->link->setText(linkString);
- // ui->urlInfo->setText(
- // tr("Browser opened to complete the login process."
- // " "
- // "If your browser hasn't opened, please manually open the following link and choose your account:"));
- // ui->url->setText(linkString);
}
void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn)
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index b2ad80270..cac91512e 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -6,8 +6,8 @@
0
0
- 772
- 326
+ 770
+ 256
@@ -121,19 +121,6 @@
- -
-
-
- TextLabel
-
-
- Qt::AlignCenter
-
-
- true
-
-
-
-
-
From 2b229d7326f7460c766a9a4dc7d8685d21a3601e Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 13 Jun 2024 00:20:16 +0300
Subject: [PATCH 18/76] increase qr code size
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.cpp | 2 +-
launcher/ui/dialogs/MSALoginDialog.ui | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index aebd04f08..6f2937335 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -61,7 +61,7 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
ui->code->setFont(font);
connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
- ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(75, 75)));
+ ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150)));
ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
connect(ui->loginButton, &QPushButton::clicked, this, [this] {
if (m_url.isValid())
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index cac91512e..02710e940 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -7,7 +7,7 @@
0
0
770
- 256
+ 331
@@ -270,14 +270,14 @@
- 75
- 75
+ 150
+ 150
- 100
- 100
+ 200
+ 200
From 7fdc65eda8032c677e6b1cc3b50dc7ea3c422ada Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 13 Jun 2024 08:51:11 +0300
Subject: [PATCH 19/76] add tooltip to url button
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp | 4 ++--
launcher/ui/dialogs/MSALoginDialog.cpp | 10 ++++++++--
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
index c34351bf2..7df93d04d 100644
--- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
+++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp
@@ -46,6 +46,8 @@
MSADeviceCodeStep::MSADeviceCodeStep(AccountData* data) : AuthStep(data)
{
m_clientId = APPLICATION->getMSAClientID();
+ connect(&m_expiration_timer, &QTimer::timeout, this, &MSADeviceCodeStep::abort);
+ connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser);
}
QString MSADeviceCodeStep::describe()
@@ -133,11 +135,9 @@ void MSADeviceCodeStep::deviceAutorizationFinished()
m_expiration_timer.setTimerType(Qt::VeryCoarseTimer);
m_expiration_timer.setInterval(rsp.expires_in * 1000);
m_expiration_timer.setSingleShot(true);
- connect(&m_expiration_timer, &QTimer::timeout, this, &MSADeviceCodeStep::abort);
m_expiration_timer.start();
m_pool_timer.setTimerType(Qt::VeryCoarseTimer);
m_pool_timer.setSingleShot(true);
- connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser);
startPoolTimer();
}
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 6f2937335..59b45a0e4 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -64,8 +64,11 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150)));
ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
connect(ui->loginButton, &QPushButton::clicked, this, [this] {
- if (m_url.isValid())
- DesktopServices::openUrl(m_url);
+ if (m_url.isValid()) {
+ if (!DesktopServices::openUrl(m_url)) {
+ QApplication::clipboard()->setText(m_url.toString());
+ }
+ }
});
}
@@ -104,6 +107,8 @@ MSALoginDialog::~MSALoginDialog()
void MSALoginDialog::onTaskFailed(QString reason)
{
// Set message
+ m_authflow_task->disconnect();
+ m_devicecode_task->disconnect();
ui->stackedWidget->setCurrentIndex(0);
auto lines = reason.split('\n');
QString processed;
@@ -127,6 +132,7 @@ void MSALoginDialog::onTaskFailed(QString reason)
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
{
ui->stackedWidget->setCurrentIndex(1);
+ ui->loginButton->setToolTip(QString("%1
").arg(url.toString()));
m_url = url;
}
From f7c3e08ac8a8edf03d0be05257a4ac66cf4b6765 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 13 Jun 2024 18:27:37 +0300
Subject: [PATCH 20/76] add prismlauncher to plist
Signed-off-by: Trial97
---
cmake/MacOSXBundleInfo.plist.in | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in
index c439efe25..6d3845dfc 100644
--- a/cmake/MacOSXBundleInfo.plist.in
+++ b/cmake/MacOSXBundleInfo.plist.in
@@ -79,6 +79,14 @@
curseforge
+
+ CFBundleURLName
+ Prismlauncher
+ CFBundleURLSchemes
+
+ prismlauncher
+
+
From 6e8dc6ccc06ee706d71fd730f055396cd405be11 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 13 Jun 2024 19:20:32 +0300
Subject: [PATCH 21/76] add mouse interaction on microsoft link
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.ui | 3 +++
1 file changed, 3 insertions(+)
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index 02710e940..0d4b9f04a 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -393,6 +393,9 @@
true
+
+ Qt::TextBrowserInteraction
+
-
From 712fbc3a4bde6d8a112074247d330a7b55cd1a07 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 11:15:40 +0300
Subject: [PATCH 22/76] reverse login layout
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 21 +-
launcher/ui/dialogs/MSALoginDialog.cpp | 8 +-
launcher/ui/dialogs/MSALoginDialog.ui | 564 +++++++++-------------
3 files changed, 263 insertions(+), 330 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 78cb0b8d2..97590e273 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -37,10 +37,12 @@
#include
#include
+#include
#include
#include "Application.h"
#include "BuildConfig.h"
+#include "FileSystem.h"
class CustomOAuthOobReplyHandler : public QOAuthOobReplyHandler {
Q_OBJECT
@@ -61,9 +63,24 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
{
m_clientId = APPLICATION->getMSAClientID();
- auto bv = new CustomOAuthOobReplyHandler();
+ if (QCoreApplication::applicationFilePath().startsWith("/tmp/.mount_") ||
+ QFile::exists(FS::PathCombine(APPLICATION->root(), "portable.txt")))
- oauth2.setReplyHandler(bv);
+ {
+ auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
+ replyHandler->setCallbackText(R"XXX(
+
+
+
+ Login Successful, redirecting...
+
+ )XXX");
+ oauth2.setReplyHandler(replyHandler);
+ } else {
+ oauth2.setReplyHandler(new CustomOAuthOobReplyHandler(this));
+ }
oauth2.setAuthorizationUrl(QUrl("https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize"));
oauth2.setAccessTokenUrl(QUrl("https://login.microsoftonline.com/consumers/oauth2/v2.0/token"));
oauth2.setScope("XboxLive.SignIn XboxLive.offline_access");
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 59b45a0e4..04453499d 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -61,8 +61,7 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
ui->code->setFont(font);
connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
- ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150)));
- ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME));
+ ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150), Qt::KeepAspectRatio));
connect(ui->loginButton, &QPushButton::clicked, this, [this] {
if (m_url.isValid()) {
if (!DesktopServices::openUrl(m_url)) {
@@ -119,8 +118,11 @@ void MSALoginDialog::onTaskFailed(QString reason)
processed += " ";
}
}
- auto task = qobject_cast(sender());
ui->status->setText(processed);
+ auto task = m_authflow_task;
+ if (task->failReason().isEmpty()) {
+ task = m_devicecode_task;
+ }
if (task) {
ui->loadingLabel->setText(task->getStatus());
}
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index 0d4b9f04a..bb9157aea 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -6,10 +6,16 @@
0
0
- 770
- 331
+ 440
+ 430
+
+
+ 0
+ 430
+
+
Add Microsoft Account
@@ -83,338 +89,246 @@
-
+
-
-
+
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 16
- 75
- true
-
-
-
- Login to Prismlauncher
-
-
- Qt::AlignCenter
-
-
- true
-
-
-
- -
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 250
- 40
-
-
-
- Login with Microsoft
-
-
- true
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- 1
-
-
- Qt::Vertical
-
-
-
-
-
- -
-
-
- Or
-
-
- Qt::AlignCenter
-
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- 1
-
-
- Qt::Vertical
-
-
-
-
-
-
+
+
+
+ 250
+ 40
+
+
+
+ Login with Microsoft
+
+
+ true
+
+
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 150
- 150
-
-
-
-
- 200
- 200
-
-
-
-
-
-
- true
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 30
- 75
- true
-
-
-
- IBeamCursor
-
-
- CODE
-
-
- Qt::AlignCenter
-
-
- Qt::TextBrowserInteraction
-
-
-
- -
-
-
- Copy code to clipboard
-
-
-
-
-
-
- . .
-
-
-
- 22
- 22
-
-
-
- true
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- TextLabel
-
-
- Qt::AlignCenter
-
-
- true
-
-
- Qt::TextBrowserInteraction
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+ -
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Or
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 150
+ 150
+
+
+
+
+ 150
+ 150
+
+
+
+
+
+
+ true
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 30
+ 75
+ true
+
+
+
+ IBeamCursor
+
+
+ CODE
+
+
+ Qt::AlignCenter
+
+
+ Qt::TextBrowserInteraction
+
+
+
+ -
+
+
+ Copy code to clipboard
+
+
+
+
+
+
+ . .
+
+
+
+ 22
+ 22
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ TextLabel
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+ Qt::TextBrowserInteraction
+
+
+
From 014721ca10d651f299041eb453a9ef221d260cd9 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 11:19:54 +0300
Subject: [PATCH 23/76] remove unused import
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 04453499d..047364714 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -36,7 +36,6 @@
#include "MSALoginDialog.h"
#include "Application.h"
-#include "BuildConfig.h"
#include "ui_MSALoginDialog.h"
#include "DesktopServices.h"
From c35461b314c6283ea32fd29b65a29cfc1cd0fecd Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 11:23:14 +0300
Subject: [PATCH 24/76] remove aspect ratio
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 047364714..799b5b332 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -60,7 +60,7 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS
ui->code->setFont(font);
connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); });
- ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150), Qt::KeepAspectRatio));
+ ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(150, 150)));
connect(ui->loginButton, &QPushButton::clicked, this, [this] {
if (m_url.isValid()) {
if (!DesktopServices::openUrl(m_url)) {
From 74a86df53c3f11c4edc31ccecf428232338a141c Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 12:41:37 +0300
Subject: [PATCH 25/76] update the desktop file
Signed-off-by: Trial97
---
program_info/org.prismlauncher.PrismLauncher.desktop.in | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in
index 7d186a2e7..e33ce1601 100644
--- a/program_info/org.prismlauncher.PrismLauncher.desktop.in
+++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in
@@ -1,13 +1,13 @@
[Desktop Entry]
Version=1.0
-Name=Prism Launcher
+Name=@Launcher_DisplayName@
Comment=Discover, manage, and play Minecraft instances
Type=Application
Terminal=false
Exec=@Launcher_APP_BINARY_NAME@ %U
StartupNotify=true
-Icon=org.prismlauncher.PrismLauncher
+Icon=org.@Launcher_APP_BINARY_NAME@.@Launcher_Name@
Categories=Game;ActionGame;AdventureGame;Simulation;
Keywords=game;minecraft;mc;
-StartupWMClass=PrismLauncher
-MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/prismlauncher;
+StartupWMClass=@Launcher_Name@
+MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/@Launcher_APP_BINARY_NAME@;
From f60d0135f7f357695f5a34a7cb667a770dbe1a15 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 12:47:44 +0300
Subject: [PATCH 26/76] made login link to open browser
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.ui | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index bb9157aea..fe883e915 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -316,7 +316,7 @@
-
- TextLabel
+ Info
Qt::AlignCenter
@@ -324,6 +324,9 @@
true
+
+ true
+
Qt::TextBrowserInteraction
From 8db0b5f421a7f0e917fe2a33076fd07324cefc8e Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 12:48:37 +0300
Subject: [PATCH 27/76] Register mime-type on the fly
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 97 ++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 97590e273..edb3f6559 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -44,6 +44,100 @@
#include "BuildConfig.h"
#include "FileSystem.h"
+#include
+#include
+#include
+
+bool isSchemeHandlerRegistered()
+{
+ QProcess process;
+ process.start("xdg-mime", { "query", "default", "x-scheme-handler/" + BuildConfig.LAUNCHER_APP_BINARY_NAME });
+ process.waitForFinished();
+ QString output = process.readAllStandardOutput().trimmed();
+
+ return output.contains(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+}
+
+bool registerSchemeHandler()
+{
+#ifdef Q_OS_LINUX
+
+ // Paths for user-specific installations
+ QString desktopFilePath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) +
+ QString("/%1.desktop").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ QString mimeFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
+ QString("/mime/packages/x-scheme-handler-%1.xml").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ QFile desktopFile(desktopFilePath);
+ QFile mimeFile(mimeFilePath);
+ if ((desktopFile.exists() && mimeFile.exists()) || isSchemeHandlerRegistered()) {
+ return true;
+ }
+ // Create and write the .desktop file
+ if (desktopFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QTextStream out(&desktopFile);
+ out << QString(R"XXX([Desktop Entry]
+Version=1.0
+Name=%1
+Comment=Discover, manage, and play Minecraft instances
+Type=Application
+Terminal=false
+Exec=%2 %U
+StartupNotify=true
+Icon=org.%2.%3
+Categories=Game;ActionGame;AdventureGame;Simulation;
+Keywords=game;minecraft;mc;
+StartupWMClass=%3
+MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/%2;
+)XXX")
+ .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.LAUNCHER_APP_BINARY_NAME, BuildConfig.LAUNCHER_NAME);
+ desktopFile.close();
+ } else {
+ qDebug() << "Failed to write .desktop file:" << desktopFilePath;
+ return false;
+ }
+
+ // Create and write the MIME type XML file
+ if (mimeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QTextStream out(&mimeFile);
+ out << "\n";
+ out << "\n";
+ out << QString(" \n").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ out << QString(" \n").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ out << " \n";
+ out << " \n";
+ mimeFile.close();
+ } else {
+ qDebug() << "Failed to write MIME type XML file:" << mimeFilePath;
+ return false;
+ }
+
+ // Update the MIME database
+ QProcess::execute("update-mime-database", { QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) });
+
+ // Update the desktop database
+ QProcess::execute("update-desktop-database", { QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) });
+
+ qDebug() << "Custom URL scheme handler registered successfully.";
+
+#elif defined(Q_OS_WIN)
+ QString regPath = QString("HKEY_CURRENT_USER\\Software\\Classes\\%1").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
+ QSettings settings(regPath, QSettings::NativeFormat);
+
+ if (settings.contains("shell/open/command/.")) {
+ return true;
+ }
+ QString appPath = QCoreApplication::applicationFilePath().replace("/", "\\");
+
+ settings.setValue(".", QString("URL:%1 Protocol")).arg(BuildConfig.LAUNCHER_NAME);
+ settings.setValue("URL Protocol", "");
+ settings.setValue("DefaultIcon/.", QString("\"%1\",1").arg(appPath));
+ settings.setValue("shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath).arg("%1"));
+
+ qDebug() << "Custom URL scheme handler registered successfully in Windows Registry.";
+#endif
+ return true;
+}
+
class CustomOAuthOobReplyHandler : public QOAuthOobReplyHandler {
Q_OBJECT
@@ -63,8 +157,7 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
{
m_clientId = APPLICATION->getMSAClientID();
- if (QCoreApplication::applicationFilePath().startsWith("/tmp/.mount_") ||
- QFile::exists(FS::PathCombine(APPLICATION->root(), "portable.txt")))
+ if (!registerSchemeHandler())
{
auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
From 3db4f4dc2be7c51e3838cd4dbca5f813165c3470 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 13:00:59 +0300
Subject: [PATCH 28/76] fix build
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 2 +-
launcher/ui/dialogs/MSALoginDialog.ui | 2 +-
program_info/org.prismlauncher.PrismLauncher.desktop.in | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index edb3f6559..05c25586b 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -42,10 +42,10 @@
#include "Application.h"
#include "BuildConfig.h"
-#include "FileSystem.h"
#include
#include
+#include
#include
bool isSchemeHandlerRegistered()
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index fe883e915..abf4b8876 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -114,7 +114,7 @@
- Login with Microsoft
+ Sign in with Microsoft
true
diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in
index e33ce1601..c0e4e9458 100644
--- a/program_info/org.prismlauncher.PrismLauncher.desktop.in
+++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in
@@ -6,8 +6,8 @@ Type=Application
Terminal=false
Exec=@Launcher_APP_BINARY_NAME@ %U
StartupNotify=true
-Icon=org.@Launcher_APP_BINARY_NAME@.@Launcher_Name@
+Icon=org.@Launcher_APP_BINARY_NAME@.@Launcher_CommonName@
Categories=Game;ActionGame;AdventureGame;Simulation;
Keywords=game;minecraft;mc;
-StartupWMClass=@Launcher_Name@
+StartupWMClass=@Launcher_CommonName@
MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/@Launcher_APP_BINARY_NAME@;
From 164d31dcb1a2c4a9815e321bea8908750927e9db Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 13:09:22 +0300
Subject: [PATCH 29/76] fix win build take#2
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 05c25586b..8f3c2bc5e 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -128,7 +128,7 @@ MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/cur
}
QString appPath = QCoreApplication::applicationFilePath().replace("/", "\\");
- settings.setValue(".", QString("URL:%1 Protocol")).arg(BuildConfig.LAUNCHER_NAME);
+ settings.setValue(".", QString("URL:%1 Protocol").arg(BuildConfig.LAUNCHER_NAME));
settings.setValue("URL Protocol", "");
settings.setValue("DefaultIcon/.", QString("\"%1\",1").arg(appPath));
settings.setValue("shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath).arg("%1"));
From 52490743b4e515f949063d97a3dc061f80b13bad Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 14:16:23 +0300
Subject: [PATCH 30/76] revert desktop file creation
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 81 ++---------------------
1 file changed, 5 insertions(+), 76 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 8f3c2bc5e..b47a10583 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -42,98 +42,27 @@
#include "Application.h"
#include "BuildConfig.h"
+#include "FileSystem.h"
-#include
#include
#include
#include
bool isSchemeHandlerRegistered()
{
+#ifdef Q_OS_LINUX
QProcess process;
process.start("xdg-mime", { "query", "default", "x-scheme-handler/" + BuildConfig.LAUNCHER_APP_BINARY_NAME });
process.waitForFinished();
QString output = process.readAllStandardOutput().trimmed();
return output.contains(BuildConfig.LAUNCHER_APP_BINARY_NAME);
-}
-
-bool registerSchemeHandler()
-{
-#ifdef Q_OS_LINUX
-
- // Paths for user-specific installations
- QString desktopFilePath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) +
- QString("/%1.desktop").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
- QString mimeFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
- QString("/mime/packages/x-scheme-handler-%1.xml").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
- QFile desktopFile(desktopFilePath);
- QFile mimeFile(mimeFilePath);
- if ((desktopFile.exists() && mimeFile.exists()) || isSchemeHandlerRegistered()) {
- return true;
- }
- // Create and write the .desktop file
- if (desktopFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream out(&desktopFile);
- out << QString(R"XXX([Desktop Entry]
-Version=1.0
-Name=%1
-Comment=Discover, manage, and play Minecraft instances
-Type=Application
-Terminal=false
-Exec=%2 %U
-StartupNotify=true
-Icon=org.%2.%3
-Categories=Game;ActionGame;AdventureGame;Simulation;
-Keywords=game;minecraft;mc;
-StartupWMClass=%3
-MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge;x-scheme-handler/%2;
-)XXX")
- .arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.LAUNCHER_APP_BINARY_NAME, BuildConfig.LAUNCHER_NAME);
- desktopFile.close();
- } else {
- qDebug() << "Failed to write .desktop file:" << desktopFilePath;
- return false;
- }
-
- // Create and write the MIME type XML file
- if (mimeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream out(&mimeFile);
- out << "\n";
- out << "\n";
- out << QString(" \n").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
- out << QString(" \n").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
- out << " \n";
- out << " \n";
- mimeFile.close();
- } else {
- qDebug() << "Failed to write MIME type XML file:" << mimeFilePath;
- return false;
- }
-
- // Update the MIME database
- QProcess::execute("update-mime-database", { QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) });
-
- // Update the desktop database
- QProcess::execute("update-desktop-database", { QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) });
-
- qDebug() << "Custom URL scheme handler registered successfully.";
#elif defined(Q_OS_WIN)
QString regPath = QString("HKEY_CURRENT_USER\\Software\\Classes\\%1").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
QSettings settings(regPath, QSettings::NativeFormat);
- if (settings.contains("shell/open/command/.")) {
- return true;
- }
- QString appPath = QCoreApplication::applicationFilePath().replace("/", "\\");
-
- settings.setValue(".", QString("URL:%1 Protocol").arg(BuildConfig.LAUNCHER_NAME));
- settings.setValue("URL Protocol", "");
- settings.setValue("DefaultIcon/.", QString("\"%1\",1").arg(appPath));
- settings.setValue("shell/open/command/.", QString("\"%1\" \"%2\"").arg(appPath).arg("%1"));
-
- qDebug() << "Custom URL scheme handler registered successfully in Windows Registry.";
+ return settings.contains("shell/open/command/.");
#endif
return true;
}
@@ -156,8 +85,8 @@ class CustomOAuthOobReplyHandler : public QOAuthOobReplyHandler {
MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(silent)
{
m_clientId = APPLICATION->getMSAClientID();
-
- if (!registerSchemeHandler())
+ if (QCoreApplication::applicationFilePath().startsWith("/tmp/.mount_") ||
+ QFile::exists(FS::PathCombine(APPLICATION->root(), "portable.txt")) || !isSchemeHandlerRegistered())
{
auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
From 863ebe421cf905bd26427f76124da675a9b89737 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 16:38:41 +0300
Subject: [PATCH 31/76] randomize server port
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index b47a10583..2b8a02186 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -89,7 +89,7 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
QFile::exists(FS::PathCombine(APPLICATION->root(), "portable.txt")) || !isSchemeHandlerRegistered())
{
- auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
+ auto replyHandler = new QOAuthHttpServerReplyHandler(0, this);
replyHandler->setCallbackText(R"XXX(
From 9d16557328b936d23a9e999ab9127d346ecba261 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 16:40:27 +0300
Subject: [PATCH 32/76] simplify constructor
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 2b8a02186..8899b224b 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -89,7 +89,7 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
QFile::exists(FS::PathCombine(APPLICATION->root(), "portable.txt")) || !isSchemeHandlerRegistered())
{
- auto replyHandler = new QOAuthHttpServerReplyHandler(0, this);
+ auto replyHandler = new QOAuthHttpServerReplyHandler(this);
replyHandler->setCallbackText(R"XXX(
From d2510b851ba9576304f89c7e146bbd41215542a6 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 22:45:15 +0300
Subject: [PATCH 33/76] mark files as duplicate
Signed-off-by: Trial97
---
launcher/FileSystem.cpp | 26 +++++++++++++++++++
launcher/FileSystem.h | 2 ++
launcher/minecraft/mod/Resource.cpp | 7 +++--
.../minecraft/mod/tasks/BasicFolderLoadTask.h | 17 ++++++------
.../minecraft/mod/tasks/ModFolderLoadTask.cpp | 13 +++++-----
5 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index cafc4f25a..36410f03e 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -1701,4 +1701,30 @@ QString getPathNameInLocal8bit(const QString& file)
}
#endif
+QString getUniqueResourceName(const QString& filePath)
+{
+ auto newFileName = filePath;
+ if (!newFileName.endsWith(".disabled")) {
+ return newFileName; // prioritize enabled mods
+ }
+ newFileName.chop(9);
+ if (!QFile::exists(newFileName)) {
+ return filePath;
+ }
+ QFileInfo fileInfo(filePath);
+ auto baseName = fileInfo.completeBaseName();
+ auto path = fileInfo.absolutePath();
+
+ int counter = 1;
+ do {
+ if (counter == 1) {
+ newFileName = FS::PathCombine(path, baseName + ".duplicate");
+ } else {
+ newFileName = FS::PathCombine(path, baseName + ".duplicate" + QString::number(counter));
+ }
+ counter++;
+ } while (QFile::exists(newFileName));
+
+ return newFileName;
+}
} // namespace FS
diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h
index 23bf5f16e..66adf7a36 100644
--- a/launcher/FileSystem.h
+++ b/launcher/FileSystem.h
@@ -560,4 +560,6 @@ uintmax_t hardLinkCount(const QString& path);
QString getPathNameInLocal8bit(const QString& file);
#endif
+QString getUniqueResourceName(const QString& filePath);
+
} // namespace FS
diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp
index 62bf6b9a2..6066f02db 100644
--- a/launcher/minecraft/mod/Resource.cpp
+++ b/launcher/minecraft/mod/Resource.cpp
@@ -161,10 +161,13 @@ bool Resource::enable(EnableAction action)
path.chop(9);
} else {
path += ".disabled";
+ auto newFilePath = FS::getUniqueResourceName(path);
+ if (newFilePath != path) {
+ FS::move(path, newFilePath);
+ }
}
if (QFileInfo::exists(path)) { // the path exists so just remove the file at path
- if (!QFile::remove(path))
- return false;
+ return false;
}
if (!file.rename(path))
return false;
diff --git a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h
index 6e8b8ed43..2bce2c137 100644
--- a/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h
+++ b/launcher/minecraft/mod/tasks/BasicFolderLoadTask.h
@@ -7,6 +7,7 @@
#include
+#include "FileSystem.h"
#include "minecraft/mod/Resource.h"
#include "tasks/Task.h"
@@ -49,16 +50,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);
- 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);
+ auto filePath = entry.absoluteFilePath();
+ auto newFilePath = FS::getUniqueResourceName(filePath);
+ if (newFilePath != filePath) {
+ FS::move(filePath, newFilePath);
+ entry = QFileInfo(newFilePath);
}
+ auto resource = m_create_func(entry);
+ 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 c11759dd2..501d5be13 100644
--- a/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp
+++ b/launcher/minecraft/mod/tasks/ModFolderLoadTask.cpp
@@ -36,6 +36,7 @@
#include "ModFolderLoadTask.h"
+#include "FileSystem.h"
#include "minecraft/mod/MetadataHandler.h"
#include
@@ -62,15 +63,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()) {
+ auto filePath = entry.absoluteFilePath();
+ auto newFilePath = FS::getUniqueResourceName(filePath);
+ if (newFilePath != filePath) {
+ FS::move(filePath, newFilePath);
+ entry = QFileInfo(newFilePath);
+ }
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 b872f88617fa282f0b1a23e0a134225d360a000c Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 22:46:39 +0300
Subject: [PATCH 34/76] do not double rename
Signed-off-by: Trial97
---
launcher/minecraft/mod/Resource.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp
index 6066f02db..9228d5165 100644
--- a/launcher/minecraft/mod/Resource.cpp
+++ b/launcher/minecraft/mod/Resource.cpp
@@ -161,10 +161,7 @@ bool Resource::enable(EnableAction action)
path.chop(9);
} else {
path += ".disabled";
- auto newFilePath = FS::getUniqueResourceName(path);
- if (newFilePath != path) {
- FS::move(path, newFilePath);
- }
+ path = FS::getUniqueResourceName(path);
}
if (QFileInfo::exists(path)) { // the path exists so just remove the file at path
return false;
From 1a84dc9bcabbd212d1402d04f3f8a41021bdca8f Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 22:47:42 +0300
Subject: [PATCH 35/76] no need for extra exist check
Signed-off-by: Trial97
---
launcher/minecraft/mod/Resource.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp
index 9228d5165..62871cbf2 100644
--- a/launcher/minecraft/mod/Resource.cpp
+++ b/launcher/minecraft/mod/Resource.cpp
@@ -163,9 +163,6 @@ bool Resource::enable(EnableAction action)
path += ".disabled";
path = FS::getUniqueResourceName(path);
}
- if (QFileInfo::exists(path)) { // the path exists so just remove the file at path
- return false;
- }
if (!file.rename(path))
return false;
From 8cdaf5d05f714fadc899081a1100f594f0e19782 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 14 Jun 2024 23:27:27 +0300
Subject: [PATCH 36/76] fix tests
Signed-off-by: Trial97
---
launcher/minecraft/mod/Resource.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp
index 62871cbf2..2a7626953 100644
--- a/launcher/minecraft/mod/Resource.cpp
+++ b/launcher/minecraft/mod/Resource.cpp
@@ -161,7 +161,9 @@ bool Resource::enable(EnableAction action)
path.chop(9);
} else {
path += ".disabled";
- path = FS::getUniqueResourceName(path);
+ if (QFile::exists(path)) {
+ path = FS::getUniqueResourceName(path);
+ }
}
if (!file.rename(path))
return false;
From 24aa337a64cca509d249f57434d489d459ae9c9d Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sun, 23 Jun 2024 00:27:49 +0300
Subject: [PATCH 37/76] fixed offline accounts
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 8899b224b..62066b572 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -119,9 +119,18 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
emit finished(AccountTaskState::STATE_WORKING, tr("Got "));
});
connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, this, &MSAStep::authorizeWithBrowser);
- connect(&oauth2, &QOAuth2AuthorizationCodeFlow::requestFailed, this, [this](const QAbstractOAuth2::Error err) {
- emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Microsoft user authentication failed."));
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::requestFailed, this, [this, silent](const QAbstractOAuth2::Error err) {
+ auto state = AccountTaskState::STATE_FAILED_HARD;
+ if (oauth2.status() == QAbstractOAuth::Status::Granted || silent) {
+ state = AccountTaskState::STATE_FAILED_SOFT;
+ }
+ emit finished(state, tr("Microsoft user authentication failed."));
});
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::error, this,
+ [this](const QString& error, const QString& errorDescription, const QUrl& uri) {
+ qDebug() << "Failed to login because" << error << errorDescription;
+ emit finished(AccountTaskState::STATE_FAILED_HARD, errorDescription);
+ });
connect(&oauth2, &QOAuth2AuthorizationCodeFlow::extraTokensChanged, this,
[this](const QVariantMap& tokens) { m_data->msaToken.extra = tokens; });
@@ -141,17 +150,18 @@ void MSAStep::perform()
if (m_data->msaClientID != m_clientId) {
emit finished(AccountTaskState::STATE_DISABLED,
tr("Microsoft user authentication failed - client identification has changed."));
+ return;
}
oauth2.setRefreshToken(m_data->msaToken.refresh_token);
oauth2.refreshAccessToken();
} else {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // QMultiMap param changed in 6.0
- oauth2.setModifyParametersFunction([](QAbstractOAuth::Stage stage, QMultiMap* map) {
+ oauth2.setModifyParametersFunction(
+ [](QAbstractOAuth::Stage stage, QMultiMap* map) { map->insert("prompt", "select_account"); });
#else
- oauth2.setModifyParametersFunction([](QAbstractOAuth::Stage stage, QMap* map) {
+ oauth2.setModifyParametersFunction(
+ [](QAbstractOAuth::Stage stage, QMap* map) { map->insert("prompt", "select_account"); });
#endif
- map->insert("prompt", "select_account");
- });
*m_data = AccountData();
m_data->msaClientID = m_clientId;
From b0386a4c2f323631b3b33d877a5a6e31312aa069 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sun, 23 Jun 2024 00:47:48 +0300
Subject: [PATCH 38/76] added better error handling
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 62066b572..665070bd3 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -124,11 +124,16 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
if (oauth2.status() == QAbstractOAuth::Status::Granted || silent) {
state = AccountTaskState::STATE_FAILED_SOFT;
}
- emit finished(state, tr("Microsoft user authentication failed."));
+ auto message = tr("Microsoft user authentication failed.");
+ if (silent) {
+ message = tr("Failed to refresh token.");
+ }
+ qWarning() << message;
+ emit finished(state, message);
});
connect(&oauth2, &QOAuth2AuthorizationCodeFlow::error, this,
[this](const QString& error, const QString& errorDescription, const QUrl& uri) {
- qDebug() << "Failed to login because" << error << errorDescription;
+ qWarning() << "Failed to login because" << error << errorDescription;
emit finished(AccountTaskState::STATE_FAILED_HARD, errorDescription);
});
@@ -152,6 +157,10 @@ void MSAStep::perform()
tr("Microsoft user authentication failed - client identification has changed."));
return;
}
+ if (m_data->msaToken.refresh_token.isEmpty()) {
+ emit finished(AccountTaskState::STATE_DISABLED, tr("Microsoft user authentication failed - refresh token is empty."));
+ return;
+ }
oauth2.setRefreshToken(m_data->msaToken.refresh_token);
oauth2.refreshAccessToken();
} else {
From 2ac89c237857ac38f72406f6e665f97e502b22f4 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sun, 23 Jun 2024 01:49:37 +0300
Subject: [PATCH 39/76] add more states for account refresh fail
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/MSAStep.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp
index 665070bd3..3db04bf2f 100644
--- a/launcher/minecraft/auth/steps/MSAStep.cpp
+++ b/launcher/minecraft/auth/steps/MSAStep.cpp
@@ -122,7 +122,11 @@ MSAStep::MSAStep(AccountData* data, bool silent) : AuthStep(data), m_silent(sile
connect(&oauth2, &QOAuth2AuthorizationCodeFlow::requestFailed, this, [this, silent](const QAbstractOAuth2::Error err) {
auto state = AccountTaskState::STATE_FAILED_HARD;
if (oauth2.status() == QAbstractOAuth::Status::Granted || silent) {
- state = AccountTaskState::STATE_FAILED_SOFT;
+ if (err == QAbstractOAuth2::Error::NetworkError) {
+ state = AccountTaskState::STATE_OFFLINE;
+ } else {
+ state = AccountTaskState::STATE_FAILED_SOFT;
+ }
}
auto message = tr("Microsoft user authentication failed.");
if (silent) {
From bb48d1ec9d4aa023080c43811c91c8959f453b7b Mon Sep 17 00:00:00 2001
From: Trial97
Date: Mon, 24 Jun 2024 00:29:21 +0300
Subject: [PATCH 40/76] made sure that the retry dialog is not displayed
offline
Signed-off-by: Trial97
---
launcher/net/NetJob.cpp | 15 ++++++++++++++-
launcher/net/NetJob.h | 1 +
launcher/news/NewsChecker.cpp | 1 +
launcher/translations/TranslationsModel.cpp | 1 +
4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/launcher/net/NetJob.cpp b/launcher/net/NetJob.cpp
index 074d58aa9..8265a63de 100644
--- a/launcher/net/NetJob.cpp
+++ b/launcher/net/NetJob.cpp
@@ -36,6 +36,7 @@
*/
#include "NetJob.h"
+#include
#include "net/NetRequest.h"
#include "tasks/ConcurrentTask.h"
#if defined(LAUNCHER_APPLICATION)
@@ -145,10 +146,22 @@ void NetJob::updateState()
.arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(totalSize())));
}
+bool NetJob::isOnline()
+{
+ // check some errors that are ussually associated with the lack of internet
+ for (auto job : getFailedActions()) {
+ auto err = job->error();
+ if (err != QNetworkReply::HostNotFoundError && err != QNetworkReply::NetworkSessionFailedError) {
+ return true;
+ }
+ }
+ return false;
+};
+
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() && isOnline()) {
m_manual_try++;
auto response = CustomMessageBox::selectable(nullptr, "Confirm retry",
"The tasks failed.\n"
diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h
index 9d617b209..59213ba15 100644
--- a/launcher/net/NetJob.h
+++ b/launcher/net/NetJob.h
@@ -74,6 +74,7 @@ class NetJob : public ConcurrentTask {
protected:
void updateState() override;
+ bool isOnline();
private:
shared_qobject_ptr m_network;
diff --git a/launcher/news/NewsChecker.cpp b/launcher/news/NewsChecker.cpp
index 33fb7eceb..169589f78 100644
--- a/launcher/news/NewsChecker.cpp
+++ b/launcher/news/NewsChecker.cpp
@@ -58,6 +58,7 @@ void NewsChecker::reloadNews()
NetJob::Ptr job{ new NetJob("News RSS Feed", m_network) };
job->addNetAction(Net::Download::makeByteArray(m_feedUrl, newsData));
+ job->setAskRetry(false);
QObject::connect(job.get(), &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished);
QObject::connect(job.get(), &NetJob::failed, this, &NewsChecker::rssDownloadFailed);
m_newsNetJob.reset(job);
diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp
index 56ade8e32..016428d1c 100644
--- a/launcher/translations/TranslationsModel.cpp
+++ b/launcher/translations/TranslationsModel.cpp
@@ -553,6 +553,7 @@ void TranslationsModel::downloadIndex()
auto task = Net::Download::makeCached(QUrl(BuildConfig.TRANSLATIONS_BASE_URL + "index_v2.json"), entry);
d->m_index_task = task.get();
d->m_index_job->addNetAction(task);
+ d->m_index_job->setAskRetry(false);
connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed);
connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexReceived);
d->m_index_job->start();
From e57c2180da6be232e0c1710bb4aa3060011a85da Mon Sep 17 00:00:00 2001
From: Trial97
Date: Mon, 24 Jun 2024 03:06:10 +0300
Subject: [PATCH 41/76] Resolve issue with multiple loaders during update
Signed-off-by: Trial97
---
launcher/minecraft/PackProfile.cpp | 21 +-
launcher/minecraft/PackProfile.h | 1 +
launcher/modplatform/CheckUpdateTask.h | 10 +-
launcher/modplatform/flame/FlameAPI.cpp | 41 ++-
launcher/modplatform/flame/FlameAPI.h | 21 +-
.../modplatform/flame/FlameCheckUpdate.cpp | 23 +-
launcher/modplatform/flame/FlameCheckUpdate.h | 4 +-
.../modrinth/ModrinthCheckUpdate.cpp | 296 ++++++++++--------
.../modrinth/ModrinthCheckUpdate.h | 15 +-
launcher/ui/dialogs/ModUpdateDialog.cpp | 13 +-
10 files changed, 275 insertions(+), 170 deletions(-)
diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp
index 4b17cdf07..fb866ede1 100644
--- a/launcher/minecraft/PackProfile.cpp
+++ b/launcher/minecraft/PackProfile.cpp
@@ -58,7 +58,6 @@
#include "ComponentUpdateTask.h"
#include "PackProfile.h"
#include "PackProfile_p.h"
-#include "minecraft/mod/Mod.h"
#include "modplatform/ModIndex.h"
static const QMap modloaderMapping{ { "net.neoforged", ModPlatform::NeoForge },
@@ -1022,3 +1021,23 @@ std::optional PackProfile::getSupportedModLoaders()
loaders |= ModPlatform::Forge;
return loaders;
}
+
+QList PackProfile::getModLoadersList()
+{
+ QList result;
+ for (auto c : d->components) {
+ if (c->isEnabled() && modloaderMapping.contains(c->getID())) {
+ result.append(modloaderMapping[c->getID()]);
+ }
+ }
+
+ // TODO: remove this or add version condition once Quilt drops official Fabric support
+ if (result.contains(ModPlatform::Quilt) && !result.contains(ModPlatform::Fabric)) {
+ result.append(ModPlatform::Fabric);
+ }
+ if (getComponentVersion("net.minecraft") == "1.20.1" && result.contains(ModPlatform::NeoForge) &&
+ !result.contains(ModPlatform::Forge)) {
+ result.append(ModPlatform::Forge);
+ }
+ return result;
+}
diff --git a/launcher/minecraft/PackProfile.h b/launcher/minecraft/PackProfile.h
index e58e9ae9a..9b6710cc3 100644
--- a/launcher/minecraft/PackProfile.h
+++ b/launcher/minecraft/PackProfile.h
@@ -146,6 +146,7 @@ class PackProfile : public QAbstractListModel {
std::optional getModLoaders();
// this returns aditional loaders(Quilt supports fabric and NeoForge supports Forge)
std::optional getSupportedModLoaders();
+ QList getModLoadersList();
private:
void scheduleSave();
diff --git a/launcher/modplatform/CheckUpdateTask.h b/launcher/modplatform/CheckUpdateTask.h
index b19b25484..fecb842fd 100644
--- a/launcher/modplatform/CheckUpdateTask.h
+++ b/launcher/modplatform/CheckUpdateTask.h
@@ -3,7 +3,6 @@
#include "minecraft/mod/Mod.h"
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "modplatform/ModIndex.h"
-#include "modplatform/ResourceAPI.h"
#include "tasks/Task.h"
class ResourceDownloadTask;
@@ -16,8 +15,14 @@ class CheckUpdateTask : public Task {
CheckUpdateTask(QList& mods,
std::list& mcVersions,
std::optional loaders,
+ QList loadersList,
std::shared_ptr mods_folder)
- : Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder){};
+ : Task(nullptr)
+ , m_mods(mods)
+ , m_game_versions(mcVersions)
+ , m_loaders(loaders)
+ , m_loaders_list(loadersList)
+ , m_mods_folder(mods_folder){};
struct UpdatableMod {
QString name;
@@ -68,6 +73,7 @@ class CheckUpdateTask : public Task {
QList& m_mods;
std::list& m_game_versions;
std::optional m_loaders;
+ QList m_loaders_list;
std::shared_ptr m_mods_folder;
std::vector m_updatable;
diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp
index a1cfe1a60..72437976d 100644
--- a/launcher/modplatform/flame/FlameAPI.cpp
+++ b/launcher/modplatform/flame/FlameAPI.cpp
@@ -4,6 +4,7 @@
#include "FlameAPI.h"
#include
+#include
#include "FlameModIndex.h"
#include "Application.h"
@@ -12,7 +13,6 @@
#include "net/ApiDownload.h"
#include "net/ApiUpload.h"
#include "net/NetJob.h"
-#include "net/Upload.h"
Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, std::shared_ptr response)
{
@@ -34,7 +34,7 @@ Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, std::shar
return netJob;
}
-auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
+QString FlameAPI::getModFileChangelog(int modId, int fileId)
{
QEventLoop lock;
QString changelog;
@@ -69,7 +69,7 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
return changelog;
}
-auto FlameAPI::getModDescription(int modId) -> QString
+QString FlameAPI::getModDescription(int modId)
{
QEventLoop lock;
QString description;
@@ -102,7 +102,7 @@ auto FlameAPI::getModDescription(int modId) -> QString
return description;
}
-auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion
+QList FlameAPI::getLatestVersions(VersionSearchArgs&& args)
{
auto versions_url_optional = getVersionsURL(args);
if (!versions_url_optional.has_value())
@@ -114,7 +114,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
auto netJob = makeShared(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
auto response = std::make_shared();
- ModPlatform::IndexedVersion ver;
+ QList ver;
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
@@ -134,9 +134,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
for (auto file : arr) {
auto file_obj = Json::requireObject(file);
- auto file_tmp = FlameMod::loadIndexedPackVersion(file_obj);
- if (file_tmp.date > ver.date && (!args.loaders.has_value() || !file_tmp.loaders || args.loaders.value() & file_tmp.loaders))
- ver = file_tmp;
+ ver.append(FlameMod::loadIndexedPackVersion(file_obj));
}
} catch (Json::JsonException& e) {
@@ -146,7 +144,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
}
});
- QObject::connect(netJob.get(), &NetJob::finished, [&loop] { loop.quit(); });
+ QObject::connect(netJob.get(), &NetJob::finished, &loop, &QEventLoop::quit);
netJob->start();
@@ -260,4 +258,27 @@ QList FlameAPI::loadModCategories(std::shared_ptr FlameAPI::getLatestVersion(QList versions,
+ QList instanceLoaders,
+ ModPlatform::ModLoaderTypes modLoaders)
+{
+ // edge case: mod has installed for forge but the instance is fabric => fabric version will be prioritizated on update
+ auto bestVersion = [&versions](ModPlatform::ModLoaderTypes loader) {
+ std::optional ver;
+ for (auto file_tmp : versions) {
+ if (file_tmp.loaders & loader && (!ver.has_value() || file_tmp.date > ver->date)) {
+ ver = file_tmp;
+ }
+ }
+ return ver;
+ };
+ for (auto l : instanceLoaders) {
+ auto ver = bestVersion(l);
+ if (ver.has_value()) {
+ return ver;
+ }
+ }
+ return bestVersion(modLoaders);
+}
diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h
index dfe76f9d5..1160151c5 100644
--- a/launcher/modplatform/flame/FlameAPI.h
+++ b/launcher/modplatform/flame/FlameAPI.h
@@ -5,7 +5,6 @@
#pragma once
#include
-#include
#include
#include "modplatform/ModIndex.h"
#include "modplatform/ResourceAPI.h"
@@ -13,10 +12,13 @@
class FlameAPI : public NetworkResourceAPI {
public:
- auto getModFileChangelog(int modId, int fileId) -> QString;
- auto getModDescription(int modId) -> QString;
+ QString getModFileChangelog(int modId, int fileId);
+ QString getModDescription(int modId);
- auto getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion;
+ QList getLatestVersions(VersionSearchArgs&& args);
+ std::optional getLatestVersion(QList versions,
+ QList instanceLoaders,
+ ModPlatform::ModLoaderTypes fallback);
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr response) const override;
Task::Ptr matchFingerprints(const QList& fingerprints, std::shared_ptr response);
@@ -26,9 +28,9 @@ class FlameAPI : public NetworkResourceAPI {
static Task::Ptr getModCategories(std::shared_ptr response);
static QList loadModCategories(std::shared_ptr response);
- [[nodiscard]] auto getSortingMethods() const -> QList override;
+ [[nodiscard]] QList getSortingMethods() const override;
- static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
+ static inline bool validateModLoaders(ModPlatform::ModLoaderTypes loaders)
{
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt);
}
@@ -67,7 +69,7 @@ class FlameAPI : public NetworkResourceAPI {
return 0;
}
- static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> const QStringList
+ static const QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types)
{
QStringList l;
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt }) {
@@ -78,10 +80,7 @@ class FlameAPI : public NetworkResourceAPI {
return l;
}
- static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> const QString
- {
- return "[" + getModLoaderStrings(types).join(',') + "]";
- }
+ static const QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; }
private:
[[nodiscard]] std::optional getSearchURL(SearchArgs const& args) const override
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp
index b4eb304f0..9deffce54 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.cpp
+++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp
@@ -132,25 +132,26 @@ void FlameCheckUpdate::executeTask()
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
setProgress(i++, m_mods.size());
- auto latest_ver = api.getLatestVersion({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
+ auto latest_vers = api.getLatestVersions({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
// Check if we were aborted while getting the latest version
if (m_was_aborted) {
aborted();
return;
}
+ auto latest_ver = api.getLatestVersion(latest_vers, m_loaders_list, mod->loaders());
setStatus(tr("Parsing the API response from CurseForge for '%1'...").arg(mod->name()));
- if (!latest_ver.addonId.isValid()) {
+ if (!latest_ver.has_value() || !latest_ver->addonId.isValid()) {
emit checkFailed(mod, tr("No valid version found for this mod. It's probably unavailable for the current game "
"version / mod loader."));
continue;
}
- if (latest_ver.downloadUrl.isEmpty() && latest_ver.fileId != mod->metadata()->file_id) {
- auto pack = getProjectInfo(latest_ver);
- auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver.fileId.toString());
+ if (latest_ver->downloadUrl.isEmpty() && latest_ver->fileId != mod->metadata()->file_id) {
+ auto pack = getProjectInfo(latest_ver.value());
+ auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver->fileId.toString());
emit checkFailed(mod, tr("Mod has a new update available, but is not downloadable using CurseForge."), recover_url);
continue;
@@ -166,19 +167,19 @@ void FlameCheckUpdate::executeTask()
pack->authors.append({ author });
pack->description = mod->description();
pack->provider = ModPlatform::ResourceProvider::FLAME;
- if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
+ if (!latest_ver->hash.isEmpty() && (mod->metadata()->hash != latest_ver->hash || mod->status() == ModStatus::NotInstalled)) {
auto old_version = mod->version();
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
- auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
+ auto current_ver = getFileInfo(latest_ver->addonId.toInt(), mod->metadata()->file_id.toInt());
old_version = current_ver.version;
}
- auto download_task = makeShared(pack, latest_ver, m_mods_folder);
- m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver.version, latest_ver.version_type,
- api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
+ auto download_task = makeShared(pack, latest_ver.value(), m_mods_folder);
+ m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver->version, latest_ver->version_type,
+ api.getModFileChangelog(latest_ver->addonId.toInt(), latest_ver->fileId.toInt()),
ModPlatform::ResourceProvider::FLAME, download_task);
}
- m_deps.append(std::make_shared(pack, latest_ver));
+ m_deps.append(std::make_shared(pack, latest_ver.value()));
}
emitSucceeded();
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.h b/launcher/modplatform/flame/FlameCheckUpdate.h
index f5bb1653d..bd6806c60 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.h
+++ b/launcher/modplatform/flame/FlameCheckUpdate.h
@@ -1,6 +1,5 @@
#pragma once
-#include "Application.h"
#include "modplatform/CheckUpdateTask.h"
#include "net/NetJob.h"
@@ -11,8 +10,9 @@ class FlameCheckUpdate : public CheckUpdateTask {
FlameCheckUpdate(QList& mods,
std::list& mcVersions,
std::optional loaders,
+ QList loadersList,
std::shared_ptr mods_folder)
- : CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
+ : CheckUpdateTask(mods, mcVersions, loaders, loadersList, mods_folder)
{}
public slots:
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
index 700bcd2e6..50fb11f05 100644
--- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
+++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
@@ -1,23 +1,32 @@
#include "ModrinthCheckUpdate.h"
+#include "Application.h"
#include "ModrinthAPI.h"
#include "ModrinthPackIndex.h"
#include "Json.h"
+#include "QObjectPtr.h"
#include "ResourceDownloadTask.h"
#include "modplatform/helpers/HashUtils.h"
#include "tasks/ConcurrentTask.h"
-#include "minecraft/mod/ModFolderModel.h"
-
static ModrinthAPI api;
+ModrinthCheckUpdate::ModrinthCheckUpdate(QList& mods,
+ std::list& mcVersions,
+ std::optional loaders,
+ QList loadersList,
+ std::shared_ptr mods_folder)
+ : CheckUpdateTask(mods, mcVersions, loaders, loadersList, mods_folder)
+ , m_hash_type(ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first())
+{}
+
bool ModrinthCheckUpdate::abort()
{
- if (m_net_job)
- return m_net_job->abort();
+ if (m_job)
+ return m_job->abort();
return true;
}
@@ -29,15 +38,10 @@ bool ModrinthCheckUpdate::abort()
void ModrinthCheckUpdate::executeTask()
{
setStatus(tr("Preparing mods for Modrinth..."));
- setProgress(0, 3);
+ setProgress(0, 9);
- QHash mappings;
-
- // Create all hashes
- QStringList hashes;
- auto best_hash_type = ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first();
-
- ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
+ auto hashing_task =
+ makeShared(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
for (auto* mod : m_mods) {
if (!mod->enabled()) {
emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!"));
@@ -49,132 +53,176 @@ void ModrinthCheckUpdate::executeTask()
// Sadly the API can only handle one hash type per call, se we
// need to generate a new hash if the current one is innadequate
// (though it will rarely happen, if at all)
- if (mod->metadata()->hash_format != best_hash_type) {
+ if (mod->metadata()->hash_format != m_hash_type) {
auto hash_task = Hashing::createHasher(mod->fileinfo().absoluteFilePath(), ModPlatform::ResourceProvider::MODRINTH);
- connect(hash_task.get(), &Hashing::Hasher::resultsReady, [&hashes, &mappings, mod](QString hash) {
- hashes.append(hash);
- mappings.insert(hash, mod);
- });
+ connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { m_mappings.insert(hash, mod); });
connect(hash_task.get(), &Task::failed, [this] { failed("Failed to generate hash"); });
- hashing_task.addTask(hash_task);
+ hashing_task->addTask(hash_task);
} else {
- hashes.append(hash);
- mappings.insert(hash, mod);
+ m_mappings.insert(hash, mod);
}
}
- QEventLoop loop;
- connect(&hashing_task, &Task::finished, [&loop] { loop.quit(); });
- hashing_task.start();
- loop.exec();
+ connect(hashing_task.get(), &Task::finished, this, &ModrinthCheckUpdate::checkNextLoader);
+ m_job = hashing_task;
+ hashing_task->start();
+}
- auto response = std::make_shared();
- auto job = api.latestVersions(hashes, best_hash_type, m_game_versions, m_loaders, response);
+void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr response,
+ ModPlatform::ModLoaderTypes loader,
+ bool forceModLoaderCheck)
+{
+ QJsonParseError parse_error{};
+ QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
+ if (parse_error.error != QJsonParseError::NoError) {
+ qWarning() << "Error while parsing JSON response from ModrinthCheckUpdate at " << parse_error.offset
+ << " reason: " << parse_error.errorString();
+ qWarning() << *response;
- connect(job.get(), &Task::succeeded, this, [this, response, mappings, best_hash_type, job] {
- QJsonParseError parse_error{};
- QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
- if (parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from ModrinthCheckUpdate at " << parse_error.offset
- << " reason: " << parse_error.errorString();
- qWarning() << *response;
+ emitFailed(parse_error.errorString());
+ return;
+ }
- emitFailed(parse_error.errorString());
- return;
- }
+ setStatus(tr("Parsing the API response from Modrinth..."));
+ setProgress(m_next_loader_idx * 2, 9);
- setStatus(tr("Parsing the API response from Modrinth..."));
- setProgress(2, 3);
-
- try {
- for (auto hash : mappings.keys()) {
- auto project_obj = doc[hash].toObject();
-
- // If the returned project is empty, but we have Modrinth metadata,
- // it means this specific version is not available
- if (project_obj.isEmpty()) {
- qDebug() << "Mod " << mappings.find(hash).value()->name() << " got an empty response.";
- qDebug() << "Hash: " << hash;
-
- emit checkFailed(
- mappings.find(hash).value(),
- tr("No valid version found for this mod. It's probably unavailable for the current game version / mod loader."));
-
- continue;
- }
-
- // Sometimes a version may have multiple files, one with "forge" and one with "fabric",
- // so we may want to filter it
- QString loader_filter;
- if (m_loaders.has_value()) {
- static auto flags = { ModPlatform::ModLoaderType::NeoForge, ModPlatform::ModLoaderType::Forge,
- ModPlatform::ModLoaderType::Fabric, ModPlatform::ModLoaderType::Quilt };
- for (auto flag : flags) {
- if (m_loaders.value().testFlag(flag)) {
- loader_filter = ModPlatform::getModLoaderAsString(flag);
- break;
- }
- }
- }
-
- // Currently, we rely on a couple heuristics to determine whether an update is actually available or not:
- // - The file needs to be preferred: It is either the primary file, or the one found via (explicit) usage of the
- // loader_filter
- // - The version reported by the JAR is different from the version reported by the indexed version (it's usually the case)
- // Such is the pain of having arbitrary files for a given version .-.
-
- auto project_ver = Modrinth::loadIndexedPackVersion(project_obj, best_hash_type, loader_filter);
- if (project_ver.downloadUrl.isEmpty()) {
- qCritical() << "Modrinth mod without download url!";
- qCritical() << project_ver.fileName;
-
- emit checkFailed(mappings.find(hash).value(), tr("Mod has an empty download URL"));
-
- continue;
- }
-
- auto mod_iter = mappings.find(hash);
- if (mod_iter == mappings.end()) {
- qCritical() << "Failed to remap mod from Modrinth!";
- continue;
- }
- auto mod = *mod_iter;
-
- auto key = project_ver.hash;
-
- // Fake pack with the necessary info to pass to the download task :)
- auto pack = std::make_shared();
- pack->name = mod->name();
- pack->slug = mod->metadata()->slug;
- pack->addonId = mod->metadata()->project_id;
- pack->websiteUrl = mod->homeurl();
- for (auto& author : mod->authors())
- pack->authors.append({ author });
- pack->description = mod->description();
- pack->provider = ModPlatform::ResourceProvider::MODRINTH;
- if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
- if (mod->version() == project_ver.version_number)
- continue;
-
- auto download_task = makeShared(pack, project_ver, m_mods_folder);
-
- m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.version_type,
- project_ver.changelog, ModPlatform::ResourceProvider::MODRINTH, download_task);
- }
- m_deps.append(std::make_shared(pack, project_ver));
+ try {
+ for (auto hash : m_mappings.keys()) {
+ if (forceModLoaderCheck && !m_mappings[hash]->loaders().testAnyFlags(loader)) {
+ continue;
}
- } catch (Json::JsonException& e) {
- emitFailed(e.cause() + " : " + e.what());
- return;
- }
- emitSucceeded();
- });
+ auto project_obj = doc[hash].toObject();
- connect(job.get(), &Task::failed, this, &ModrinthCheckUpdate::emitFailed);
+ // If the returned project is empty, but we have Modrinth metadata,
+ // it means this specific version is not available
+ if (project_obj.isEmpty()) {
+ qDebug() << "Mod " << m_mappings.find(hash).value()->name() << " got an empty response."
+ << "Hash: " << hash;
+
+ continue;
+ }
+
+ // Sometimes a version may have multiple files, one with "forge" and one with "fabric",
+ // so we may want to filter it
+ QString loader_filter;
+ static auto flags = { ModPlatform::ModLoaderType::NeoForge, ModPlatform::ModLoaderType::Forge,
+ ModPlatform::ModLoaderType::Quilt, ModPlatform::ModLoaderType::Fabric };
+ for (auto flag : flags) {
+ if (loader.testFlag(flag)) {
+ loader_filter = ModPlatform::getModLoaderAsString(flag);
+ break;
+ }
+ }
+
+ // Currently, we rely on a couple heuristics to determine whether an update is actually available or not:
+ // - The file needs to be preferred: It is either the primary file, or the one found via (explicit) usage of the
+ // loader_filter
+ // - The version reported by the JAR is different from the version reported by the indexed version (it's usually the case)
+ // Such is the pain of having arbitrary files for a given version .-.
+
+ auto project_ver = Modrinth::loadIndexedPackVersion(project_obj, m_hash_type, loader_filter);
+ if (project_ver.downloadUrl.isEmpty()) {
+ qCritical() << "Modrinth mod without download url!" << project_ver.fileName;
+
+ continue;
+ }
+
+ auto mod_iter = m_mappings.find(hash);
+ if (mod_iter == m_mappings.end()) {
+ qCritical() << "Failed to remap mod from Modrinth!";
+ continue;
+ }
+ auto mod = *mod_iter;
+ m_mappings.remove(hash);
+
+ auto key = project_ver.hash;
+
+ // Fake pack with the necessary info to pass to the download task :)
+ auto pack = std::make_shared();
+ pack->name = mod->name();
+ pack->slug = mod->metadata()->slug;
+ pack->addonId = mod->metadata()->project_id;
+ pack->websiteUrl = mod->homeurl();
+ for (auto& author : mod->authors())
+ pack->authors.append({ author });
+ pack->description = mod->description();
+ pack->provider = ModPlatform::ResourceProvider::MODRINTH;
+ if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
+ if (mod->version() == project_ver.version_number)
+ continue;
+
+ auto download_task = makeShared(pack, project_ver, m_mods_folder);
+
+ m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.version_type,
+ project_ver.changelog, ModPlatform::ResourceProvider::MODRINTH, download_task);
+ }
+ m_deps.append(std::make_shared(pack, project_ver));
+ }
+ } catch (Json::JsonException& e) {
+ emitFailed(e.cause() + " : " + e.what());
+ return;
+ }
+ checkNextLoader();
+}
+
+void ModrinthCheckUpdate::getUpdateModsForLoader(ModPlatform::ModLoaderTypes loader, bool forceModLoaderCheck)
+{
+ auto response = std::make_shared();
+ QStringList hashes;
+ if (forceModLoaderCheck) {
+ for (auto hash : m_mappings.keys()) {
+ if (m_mappings[hash]->loaders().testAnyFlags(loader)) {
+ hashes.append(hash);
+ }
+ }
+ } else {
+ hashes = m_mappings.keys();
+ }
+ auto job = api.latestVersions(hashes, m_hash_type, m_game_versions, loader, response);
+
+ connect(job.get(), &Task::succeeded, this,
+ [this, response, loader, forceModLoaderCheck] { checkVersionsResponse(response, loader, forceModLoaderCheck); });
+
+ connect(job.get(), &Task::failed, this, &ModrinthCheckUpdate::checkNextLoader);
setStatus(tr("Waiting for the API response from Modrinth..."));
- setProgress(1, 3);
+ setProgress(m_next_loader_idx * 2 - 1, 9);
- m_net_job = qSharedPointerObjectCast(job);
+ m_job = job;
job->start();
}
+
+void ModrinthCheckUpdate::checkNextLoader()
+{
+ if (m_mappings.isEmpty()) {
+ emitSucceeded();
+ return;
+ }
+ if (m_next_loader_idx < m_loaders_list.size()) {
+ getUpdateModsForLoader(m_loaders_list.at(m_next_loader_idx));
+ m_next_loader_idx++;
+ return;
+ }
+ static auto flags = { ModPlatform::ModLoaderType::NeoForge, ModPlatform::ModLoaderType::Forge, ModPlatform::ModLoaderType::Quilt,
+ ModPlatform::ModLoaderType::Fabric };
+ for (auto flag : flags) {
+ if (!m_loaders_list.contains(flag)) {
+ m_loaders_list.append(flag);
+ m_next_loader_idx++;
+ setProgress(m_next_loader_idx * 2 - 1, 9);
+ for (auto m : m_mappings) {
+ if (m->loaders().testAnyFlag(flag)) {
+ getUpdateModsForLoader(flag, true);
+ return;
+ }
+ }
+ setProgress(m_next_loader_idx * 2, 9);
+ }
+ }
+ for (auto m : m_mappings) {
+ emit checkFailed(m,
+ tr("No valid version found for this mod. It's probably unavailable for the current game version / mod loader."));
+ }
+ emitSucceeded();
+ return;
+}
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
index f2f2c7e92..2abd51970 100644
--- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
+++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
@@ -1,8 +1,6 @@
#pragma once
-#include "Application.h"
#include "modplatform/CheckUpdateTask.h"
-#include "net/NetJob.h"
class ModrinthCheckUpdate : public CheckUpdateTask {
Q_OBJECT
@@ -11,16 +9,21 @@ class ModrinthCheckUpdate : public CheckUpdateTask {
ModrinthCheckUpdate(QList& mods,
std::list& mcVersions,
std::optional loaders,
- std::shared_ptr mods_folder)
- : CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
- {}
+ QList loadersList,
+ std::shared_ptr mods_folder);
public slots:
bool abort() override;
protected slots:
void executeTask() override;
+ void getUpdateModsForLoader(ModPlatform::ModLoaderTypes loader, bool forceModLoaderCheck = false);
+ void checkVersionsResponse(std::shared_ptr response, ModPlatform::ModLoaderTypes loader, bool forceModLoaderCheck = false);
+ void checkNextLoader();
private:
- NetJob::Ptr m_net_job = nullptr;
+ Task::Ptr m_job = nullptr;
+ QHash m_mappings;
+ QString m_hash_type;
+ int m_next_loader_idx = 0;
};
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index 1583b4f46..5cb25b218 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -1,4 +1,5 @@
#include "ModUpdateDialog.h"
+#include "Application.h"
#include "ChooseProviderDialog.h"
#include "CustomMessageBox.h"
#include "ProgressDialog.h"
@@ -32,7 +33,12 @@ static std::list mcVersions(BaseInstance* inst)
static std::optional mcLoaders(BaseInstance* inst)
{
- return { static_cast(inst)->getPackProfile()->getSupportedModLoaders() };
+ return static_cast(inst)->getPackProfile()->getSupportedModLoaders();
+}
+
+static QList mcLoadersList(BaseInstance* inst)
+{
+ return static_cast(inst)->getPackProfile()->getModLoadersList();
}
ModUpdateDialog::ModUpdateDialog(QWidget* parent,
@@ -87,11 +93,12 @@ void ModUpdateDialog::checkCandidates()
auto versions = mcVersions(m_instance);
auto loaders = mcLoaders(m_instance);
+ auto loadersList = mcLoadersList(m_instance);
SequentialTask check_task(m_parent, tr("Checking for updates"));
if (!m_modrinth_to_update.empty()) {
- m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model));
+ m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, loadersList, m_mod_model));
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
@@ -99,7 +106,7 @@ void ModUpdateDialog::checkCandidates()
}
if (!m_flame_to_update.empty()) {
- m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model));
+ m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, loadersList, m_mod_model));
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
From 00b83efb9a79044d71dc4747e9ffaf1562590759 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Mon, 24 Jun 2024 20:12:40 +0300
Subject: [PATCH 42/76] fix build
Signed-off-by: Trial97
---
.../minecraft/mod/tasks/GetModDependenciesTask.cpp | 1 -
launcher/modplatform/CheckUpdateTask.h | 9 +--------
launcher/modplatform/ModIndex.h | 3 +--
launcher/modplatform/flame/FlameCheckUpdate.cpp | 2 +-
launcher/modplatform/flame/FlameCheckUpdate.h | 3 +--
launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp | 9 ++++-----
launcher/modplatform/modrinth/ModrinthCheckUpdate.h | 1 -
launcher/screenshots/ImgurAlbumCreation.cpp | 4 ++--
launcher/screenshots/ImgurUpload.cpp | 4 ++--
launcher/ui/dialogs/ModUpdateDialog.cpp | 10 ++--------
10 files changed, 14 insertions(+), 32 deletions(-)
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
index cc92328ea..b9288d2b3 100644
--- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
@@ -29,7 +29,6 @@
#include "modplatform/ResourceAPI.h"
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/modrinth/ModrinthAPI.h"
-#include "tasks/ConcurrentTask.h"
#include "tasks/SequentialTask.h"
#include "ui/pages/modplatform/ModModel.h"
#include "ui/pages/modplatform/flame/FlameResourceModels.h"
diff --git a/launcher/modplatform/CheckUpdateTask.h b/launcher/modplatform/CheckUpdateTask.h
index fecb842fd..d411409d1 100644
--- a/launcher/modplatform/CheckUpdateTask.h
+++ b/launcher/modplatform/CheckUpdateTask.h
@@ -14,15 +14,9 @@ class CheckUpdateTask : public Task {
public:
CheckUpdateTask(QList& mods,
std::list& mcVersions,
- std::optional loaders,
QList loadersList,
std::shared_ptr mods_folder)
- : Task(nullptr)
- , m_mods(mods)
- , m_game_versions(mcVersions)
- , m_loaders(loaders)
- , m_loaders_list(loadersList)
- , m_mods_folder(mods_folder){};
+ : Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders_list(loadersList), m_mods_folder(mods_folder){};
struct UpdatableMod {
QString name;
@@ -72,7 +66,6 @@ class CheckUpdateTask : public Task {
protected:
QList& m_mods;
std::list& m_game_versions;
- std::optional m_loaders;
QList m_loaders_list;
std::shared_ptr m_mods_folder;
diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h
index 91c9898a9..e3fe69e0c 100644
--- a/launcher/modplatform/ModIndex.h
+++ b/launcher/modplatform/ModIndex.h
@@ -25,7 +25,6 @@
#include
#include
#include
-#include
class QIODevice;
@@ -44,7 +43,7 @@ namespace ProviderCapabilities {
const char* name(ResourceProvider);
QString readableName(ResourceProvider);
QStringList hashType(ResourceProvider);
-}; // namespace ProviderCapabilities
+} // namespace ProviderCapabilities
struct ModpackAuthor {
QString name;
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp
index 9deffce54..957bc19bc 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.cpp
+++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp
@@ -132,7 +132,7 @@ void FlameCheckUpdate::executeTask()
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
setProgress(i++, m_mods.size());
- auto latest_vers = api.getLatestVersions({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
+ auto latest_vers = api.getLatestVersions({ { mod->metadata()->project_id.toString() }, m_game_versions });
// Check if we were aborted while getting the latest version
if (m_was_aborted) {
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.h b/launcher/modplatform/flame/FlameCheckUpdate.h
index bd6806c60..e30ae35b9 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.h
+++ b/launcher/modplatform/flame/FlameCheckUpdate.h
@@ -9,10 +9,9 @@ class FlameCheckUpdate : public CheckUpdateTask {
public:
FlameCheckUpdate(QList& mods,
std::list& mcVersions,
- std::optional loaders,
QList loadersList,
std::shared_ptr mods_folder)
- : CheckUpdateTask(mods, mcVersions, loaders, loadersList, mods_folder)
+ : CheckUpdateTask(mods, mcVersions, loadersList, mods_folder)
{}
public slots:
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
index 50fb11f05..0e9e349d9 100644
--- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
+++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
@@ -16,10 +16,9 @@ static ModrinthAPI api;
ModrinthCheckUpdate::ModrinthCheckUpdate(QList& mods,
std::list& mcVersions,
- std::optional loaders,
QList loadersList,
std::shared_ptr mods_folder)
- : CheckUpdateTask(mods, mcVersions, loaders, loadersList, mods_folder)
+ : CheckUpdateTask(mods, mcVersions, loadersList, mods_folder)
, m_hash_type(ModPlatform::ProviderCapabilities::hashType(ModPlatform::ResourceProvider::MODRINTH).first())
{}
@@ -88,7 +87,7 @@ void ModrinthCheckUpdate::checkVersionsResponse(std::shared_ptr resp
try {
for (auto hash : m_mappings.keys()) {
- if (forceModLoaderCheck && !m_mappings[hash]->loaders().testAnyFlags(loader)) {
+ if (forceModLoaderCheck && !(m_mappings[hash]->loaders() & loader)) {
continue;
}
auto project_obj = doc[hash].toObject();
@@ -171,7 +170,7 @@ void ModrinthCheckUpdate::getUpdateModsForLoader(ModPlatform::ModLoaderTypes loa
QStringList hashes;
if (forceModLoaderCheck) {
for (auto hash : m_mappings.keys()) {
- if (m_mappings[hash]->loaders().testAnyFlags(loader)) {
+ if (m_mappings[hash]->loaders() & loader) {
hashes.append(hash);
}
}
@@ -211,7 +210,7 @@ void ModrinthCheckUpdate::checkNextLoader()
m_next_loader_idx++;
setProgress(m_next_loader_idx * 2 - 1, 9);
for (auto m : m_mappings) {
- if (m->loaders().testAnyFlag(flag)) {
+ if (m->loaders() & flag) {
getUpdateModsForLoader(flag, true);
return;
}
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
index 2abd51970..dab4bda2f 100644
--- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
+++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.h
@@ -8,7 +8,6 @@ class ModrinthCheckUpdate : public CheckUpdateTask {
public:
ModrinthCheckUpdate(QList& mods,
std::list& mcVersions,
- std::optional loaders,
QList loadersList,
std::shared_ptr mods_folder);
diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp
index c63c8b39b..d19f251ea 100644
--- a/launcher/screenshots/ImgurAlbumCreation.cpp
+++ b/launcher/screenshots/ImgurAlbumCreation.cpp
@@ -65,7 +65,7 @@ QNetworkReply* ImgurAlbumCreation::getReply(QNetworkRequest& request)
}
const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden";
return m_network->post(request, data);
-};
+}
void ImgurAlbumCreation::init()
{
@@ -81,7 +81,7 @@ auto ImgurAlbumCreation::Sink::init(QNetworkRequest& request) -> Task::State
{
m_output.clear();
return Task::State::Running;
-};
+}
auto ImgurAlbumCreation::Sink::write(QByteArray& data) -> Task::State
{
diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp
index 941b92ce6..8f60148bf 100644
--- a/launcher/screenshots/ImgurUpload.cpp
+++ b/launcher/screenshots/ImgurUpload.cpp
@@ -81,13 +81,13 @@ QNetworkReply* ImgurUpload::getReply(QNetworkRequest& request)
multipart->append(namePart);
return m_network->post(request, multipart);
-};
+}
auto ImgurUpload::Sink::init(QNetworkRequest& request) -> Task::State
{
m_output.clear();
return Task::State::Running;
-};
+}
auto ImgurUpload::Sink::write(QByteArray& data) -> Task::State
{
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index 5cb25b218..ed984ccbc 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -31,11 +31,6 @@ static std::list mcVersions(BaseInstance* inst)
return { static_cast(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion() };
}
-static std::optional mcLoaders(BaseInstance* inst)
-{
- return static_cast(inst)->getPackProfile()->getSupportedModLoaders();
-}
-
static QList mcLoadersList(BaseInstance* inst)
{
return static_cast(inst)->getPackProfile()->getModLoadersList();
@@ -92,13 +87,12 @@ void ModUpdateDialog::checkCandidates()
}
auto versions = mcVersions(m_instance);
- auto loaders = mcLoaders(m_instance);
auto loadersList = mcLoadersList(m_instance);
SequentialTask check_task(m_parent, tr("Checking for updates"));
if (!m_modrinth_to_update.empty()) {
- m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, loadersList, m_mod_model));
+ m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loadersList, m_mod_model));
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
@@ -106,7 +100,7 @@ void ModUpdateDialog::checkCandidates()
}
if (!m_flame_to_update.empty()) {
- m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, loadersList, m_mod_model));
+ m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loadersList, m_mod_model));
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
From 14b09549e1fc429b87a5c8345ceda069244b6484 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Tue, 25 Jun 2024 01:50:37 -0700
Subject: [PATCH 43/76] feat(instanceList) persist "ungrouped" hidden state
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/InstanceList.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp
index 0d53c7f25..3f835cfaf 100644
--- a/launcher/InstanceList.cpp
+++ b/launcher/InstanceList.cpp
@@ -710,6 +710,12 @@ void InstanceList::saveGroupList()
groupsArr.insert(name, groupObj);
}
toplevel.insert("groups", groupsArr);
+ // empty string represents ungrouped "group"
+ if (m_collapsedGroups.contains("")) {
+ QJsonObject ungrouped;
+ ungrouped.insert("hidden", QJsonValue(true));
+ toplevel.insert("ungrouped", ungrouped);
+ }
QJsonDocument doc(toplevel);
try {
FS::write(groupFileName, doc.toJson());
@@ -805,6 +811,16 @@ void InstanceList::loadGroupList()
increaseGroupCount(groupName);
}
}
+
+ bool ungroupedHidden = false;
+ if (rootObj.value("ungrouped").isObject()) {
+ QJsonObject ungrouped = rootObj.value("ungrouped").toObject();
+ ungroupedHidden = ungrouped.value("hidden").toBool(false);
+ }
+ if (ungroupedHidden) {
+ // empty string represents ungrouped "group"
+ m_collapsedGroups.insert("");
+ }
m_groupsLoaded = true;
qDebug() << "Group list loaded.";
}
From b1a86bec34cefd8af931ac4c6d495e56ff1280c1 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Wed, 26 Jun 2024 09:50:55 +0300
Subject: [PATCH 44/76] refresh account if it should refresh on instance launch
Signed-off-by: Trial97
---
launcher/LaunchController.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp
index bccc426a9..3866a7672 100644
--- a/launcher/LaunchController.cpp
+++ b/launcher/LaunchController.cpp
@@ -194,7 +194,8 @@ void LaunchController::login()
bool tryagain = true;
unsigned int tries = 0;
- if (m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) {
+ if ((m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) ||
+ m_accountToUse->shouldRefresh()) {
// Force account refresh on the account used to launch the instance updating the AccountState
// only on first try and if it is not meant to be offline
auto accounts = APPLICATION->accounts();
From 9d7c36c2fcdbf6e5c99270e875ef27acaf589f71 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 27 Jun 2024 15:35:44 +0300
Subject: [PATCH 45/76] made identty certain if the login ended
Signed-off-by: Trial97
---
launcher/minecraft/auth/steps/GetSkinStep.cpp | 2 +-
launcher/minecraft/auth/steps/MinecraftProfileStep.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/launcher/minecraft/auth/steps/GetSkinStep.cpp b/launcher/minecraft/auth/steps/GetSkinStep.cpp
index d9785b16a..a54366b50 100644
--- a/launcher/minecraft/auth/steps/GetSkinStep.cpp
+++ b/launcher/minecraft/auth/steps/GetSkinStep.cpp
@@ -29,5 +29,5 @@ void GetSkinStep::onRequestDone()
{
if (m_task->error() == QNetworkReply::NoError)
m_data->minecraftProfile.skin.data = *m_response;
- emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Got skin"));
+ emit finished(AccountTaskState::STATE_WORKING, tr("Got skin"));
}
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
index 305f44320..aef6f43af 100644
--- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
@@ -36,7 +36,7 @@ void MinecraftProfileStep::onRequestDone()
if (m_task->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."));
+ emit finished(AccountTaskState::STATE_WORKING, tr("Account has no Minecraft profile."));
return;
}
if (m_task->error() != QNetworkReply::NoError) {
From 2c02d022142950961df31d8d19e9bcf39999c1ce Mon Sep 17 00:00:00 2001
From: Trial97
Date: Fri, 28 Jun 2024 14:11:27 +0300
Subject: [PATCH 46/76] do not display message that no update is avvailable if
the check was done in the background
Signed-off-by: Trial97
---
launcher/updater/PrismExternalUpdater.cpp | 9 +++++++--
launcher/updater/PrismExternalUpdater.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/launcher/updater/PrismExternalUpdater.cpp b/launcher/updater/PrismExternalUpdater.cpp
index dc1aae872..69774dc04 100644
--- a/launcher/updater/PrismExternalUpdater.cpp
+++ b/launcher/updater/PrismExternalUpdater.cpp
@@ -85,6 +85,11 @@ PrismExternalUpdater::~PrismExternalUpdater()
}
void PrismExternalUpdater::checkForUpdates()
+{
+ checkForUpdates(true);
+}
+
+void PrismExternalUpdater::checkForUpdates(bool triggeredByUser)
{
QProgressDialog progress(tr("Checking for updates..."), "", 0, 0, priv->parent);
progress.setCancelButton(nullptr);
@@ -160,7 +165,7 @@ void PrismExternalUpdater::checkForUpdates()
switch (exit_code) {
case 0:
// no update available
- {
+ if (triggeredByUser) {
qDebug() << "No update available";
auto msgBox = QMessageBox(QMessageBox::Information, tr("No Update Available"), tr("You are running the latest version."),
QMessageBox::Ok, priv->parent);
@@ -288,7 +293,7 @@ void PrismExternalUpdater::disconnectTimer()
void PrismExternalUpdater::autoCheckTimerFired()
{
qDebug() << "Auto update Timer fired";
- checkForUpdates();
+ checkForUpdates(false);
}
void PrismExternalUpdater::offerUpdate(const QString& version_name, const QString& version_tag, const QString& release_notes)
diff --git a/launcher/updater/PrismExternalUpdater.h b/launcher/updater/PrismExternalUpdater.h
index bfe94c149..b88676028 100644
--- a/launcher/updater/PrismExternalUpdater.h
+++ b/launcher/updater/PrismExternalUpdater.h
@@ -41,6 +41,7 @@ class PrismExternalUpdater : public ExternalUpdater {
* Check for updates manually, showing the user a progress bar and an alert if no updates are found.
*/
void checkForUpdates() override;
+ void checkForUpdates(bool triggeredByUser);
/*!
* Indicates whether or not to check for updates automatically.
From f1a4a1e8ee70ce298d745ea225a69d04a58e04da Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sat, 29 Jun 2024 08:41:35 +0300
Subject: [PATCH 47/76] increase 'or' font size for login dialog
Signed-off-by: Trial97
---
launcher/ui/dialogs/MSALoginDialog.ui | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui
index abf4b8876..c6821782f 100644
--- a/launcher/ui/dialogs/MSALoginDialog.ui
+++ b/launcher/ui/dialogs/MSALoginDialog.ui
@@ -153,6 +153,11 @@
-
+
+
+ 16
+
+
Or
From eab53c6e42c86ee1dc80b1b8a082212552b6db7b Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sat, 29 Jun 2024 14:02:09 +0300
Subject: [PATCH 48/76] make sure updater take into consideration UserData
Signed-off-by: Trial97
---
launcher/updater/prismupdater/PrismUpdater.cpp | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index 83d8efa22..03c3d2d8f 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -328,6 +328,9 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar
adjustedBy = "Command line";
m_dataPath = dirParam;
#ifndef Q_OS_MACOS
+ if (QDir(FS::PathCombine(m_rootPath, "UserData")).exists()) {
+ m_isPortable = true;
+ }
if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
m_isPortable = true;
}
@@ -338,7 +341,11 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar
adjustedBy = "Persistent data path";
#ifndef Q_OS_MACOS
- if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
+ if (auto portableUserData = FS::PathCombine(m_rootPath, "UserData"); QDir(portableUserData).exists()) {
+ m_dataPath = portableUserData;
+ adjustedBy = "Portable user data path";
+ m_isPortable = true;
+ } else if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
m_dataPath = m_rootPath;
adjustedBy = "Portable data path";
m_isPortable = true;
From 41bcfb3c07861bf960816927d7f90bea9708d3b9 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 29 Jun 2024 03:44:49 -0700
Subject: [PATCH 49/76] Fix #2586 non portable linux update technically works
even if not genraly a good idea.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/updater/prismupdater/PrismUpdater.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index 83d8efa22..96ef48b12 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -1020,7 +1020,7 @@ void PrismUpdaterApp::performInstall(QFileInfo file)
FS::write(changelog_path, m_install_release.body.toUtf8());
logUpdate(tr("Updating from %1 to %2").arg(m_prismVersion).arg(m_install_release.tag_name));
- if (m_isPortable || file.suffix().toLower() == "zip") {
+ if (m_isPortable || file.fileName().endsWith(".zip") || file.fileName().endsWith(".tar.gz")) {
write_lock_file(update_lock_path, QDateTime::currentDateTime(), m_prismVersion, m_install_release.tag_name, m_rootPath, m_dataPath);
logUpdate(tr("Updating portable install at %1").arg(m_rootPath));
unpackAndInstall(file);
From 9d1fffff27854c3895ab316981d76d61c7e4f3ae Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 29 Jun 2024 03:57:30 -0700
Subject: [PATCH 50/76] reject zsync file as valid build artifact
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/updater/prismupdater/PrismUpdater.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index 96ef48b12..b335a19f9 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -787,6 +787,10 @@ QList PrismUpdaterApp::validReleaseArtifacts(const GitHubRel
if (BuildConfig.BUILD_ARTIFACT.isEmpty())
qWarning() << "Build platform is not set!";
for (auto asset : release.assets) {
+ if (asset.name.endsWith("zsync")) {
+ qDebug() << "Rejecting zsync file" << asset.name;
+ continue;
+ }
if (!m_isAppimage && asset.name.toLower().endsWith("appimage")) {
qDebug() << "Rejecting" << asset.name << "because it is an AppImage";
continue;
From b4f5c3d241c6e9c8525d786c0bbaf860a18032b0 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 29 Jun 2024 04:08:04 -0700
Subject: [PATCH 51/76] Update launcher/updater/prismupdater/PrismUpdater.cpp
Co-authored-by: TheKodeToad
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/updater/prismupdater/PrismUpdater.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index b335a19f9..76ba483f0 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -787,7 +787,7 @@ QList PrismUpdaterApp::validReleaseArtifacts(const GitHubRel
if (BuildConfig.BUILD_ARTIFACT.isEmpty())
qWarning() << "Build platform is not set!";
for (auto asset : release.assets) {
- if (asset.name.endsWith("zsync")) {
+ if (asset.name.endsWith(".zsync")) {
qDebug() << "Rejecting zsync file" << asset.name;
continue;
}
From ae3e4ed528aace5385c99047e9c7c431a26b8506 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Sat, 29 Jun 2024 04:29:19 -0700
Subject: [PATCH 52/76] fix Build Artifact Checks
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/updater/prismupdater/PrismUpdater.cpp | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index 76ba483f0..de862b96e 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -244,8 +244,9 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar
auto updater_executable = QCoreApplication::applicationFilePath();
- if (BuildConfig.BUILD_ARTIFACT.toLower() == "macos")
- showFatalErrorMessage(tr("MacOS Not Supported"), tr("The updater does not support installations on MacOS"));
+#ifdef Q_OS_MACOS
+ showFatalErrorMessage(tr("MacOS Not Supported"), tr("The updater does not support installations on MacOS"));
+#endif
if (updater_executable.startsWith("/tmp/.mount_")) {
m_isAppimage = true;
@@ -580,12 +581,6 @@ void PrismUpdaterApp::run()
return exit(result ? 0 : 1);
}
- if (BuildConfig.BUILD_ARTIFACT.toLower() == "linux" && !m_isPortable) {
- showFatalErrorMessage(tr("Updating Not Supported"),
- tr("Updating non-portable linux installations is not supported. Please use your system package manager"));
- return;
- }
-
if (need_update || m_forceUpdate || !m_userSelectedVersion.isEmpty()) {
GitHubRelease update_release = latest;
if (!m_userSelectedVersion.isEmpty()) {
@@ -1098,7 +1093,7 @@ void PrismUpdaterApp::backupAppDir()
if (file_list.isEmpty()) {
// best guess
- if (BuildConfig.BUILD_ARTIFACT.toLower() == "linux") {
+ if (BuildConfig.BUILD_ARTIFACT.toLower().contains("linux")) {
file_list.append({ "PrismLauncher", "bin", "share", "lib" });
} else { // windows by process of elimination
file_list.append({
From 7a0b299be98b93815e265ba2896e971d0bb8c4f8 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sat, 29 Jun 2024 18:08:28 +0300
Subject: [PATCH 53/76] control Prism data directory via env variable
Signed-off-by: Trial97
---
launcher/Application.cpp | 7 ++++++-
launcher/updater/prismupdater/PrismUpdater.cpp | 10 ++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 6d30d1101..2c0c3fca5 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -292,12 +292,17 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
QString adjustedBy;
QString dataPath;
// change folder
+ QString dataDirEnv;
QString dirParam = parser.value("dir");
if (!dirParam.isEmpty()) {
// the dir param. it makes multimc data path point to whatever the user specified
// on command line
adjustedBy = "Command line";
dataPath = dirParam;
+ } else if (dataDirEnv = QProcessEnvironment::systemEnvironment().value(QString("%1_DATA_DIR").arg(BuildConfig.LAUNCHER_NAME.toUpper()));
+ !dataDirEnv.isEmpty()) {
+ adjustedBy = "System environment";
+ dataPath = dataDirEnv;
} else {
QDir foo;
if (DesktopServices::isSnap()) {
@@ -443,7 +448,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// search the dataPath()
// seach app data standard path
- if (!foundLoggingRules && !isPortable() && dirParam.isEmpty()) {
+ if (!foundLoggingRules && !isPortable() && dirParam.isEmpty() && dataDirEnv.isEmpty()) {
logRulesPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, FS::PathCombine("..", logRulesFile));
if (!logRulesPath.isEmpty()) {
qDebug() << "Found" << logRulesPath << "...";
diff --git a/launcher/updater/prismupdater/PrismUpdater.cpp b/launcher/updater/prismupdater/PrismUpdater.cpp
index 83d8efa22..f49c8a0fb 100644
--- a/launcher/updater/prismupdater/PrismUpdater.cpp
+++ b/launcher/updater/prismupdater/PrismUpdater.cpp
@@ -331,6 +331,16 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar
if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
m_isPortable = true;
}
+#endif
+ } else if (auto dataDirEnv =
+ QProcessEnvironment::systemEnvironment().value(QString("%1_DATA_DIR").arg(BuildConfig.LAUNCHER_NAME.toUpper()));
+ !dataDirEnv.isEmpty()) {
+ adjustedBy = "System environment";
+ m_dataPath = dataDirEnv;
+#ifndef Q_OS_MACOS
+ if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) {
+ m_isPortable = true;
+ }
#endif
} else {
QDir foo(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), ".."));
From 25bae20db4525b8f7e0671605d5927971e6ffab8 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sun, 30 Jun 2024 00:17:25 +0300
Subject: [PATCH 54/76] trim input from import page
Signed-off-by: Trial97
---
launcher/ui/pages/modplatform/ImportPage.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp
index 38208f5b0..1efc6199e 100644
--- a/launcher/ui/pages/modplatform/ImportPage.cpp
+++ b/launcher/ui/pages/modplatform/ImportPage.cpp
@@ -104,7 +104,7 @@ void ImportPage::updateState()
return;
}
if (ui->modpackEdit->hasAcceptableInput()) {
- QString input = ui->modpackEdit->text();
+ QString input = ui->modpackEdit->text().trimmed();
auto url = QUrl::fromUserInput(input);
if (url.isLocalFile()) {
// FIXME: actually do some validation of what's inside here... this is fake AF
From 046e3588afc57df5669e1b9c230275b7a5b44bc0 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 21:35:03 +0200
Subject: [PATCH 55/76] more system themes initial changes
Signed-off-by: Tayou
---
launcher/Application.cpp | 4 ++--
launcher/ui/themes/SystemTheme.cpp | 34 +++++++++++++++++++++--------
launcher/ui/themes/SystemTheme.h | 6 +++--
launcher/ui/themes/ThemeManager.cpp | 30 +++++++++++++++++++++----
launcher/ui/themes/ThemeManager.h | 1 +
5 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 7ae66e13a..327b63b02 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -1073,8 +1073,8 @@ bool Application::createSetupWizard()
// set default theme after going into theme wizard
if (!validIcons)
settings()->set("IconTheme", QString("pe_colored"));
- if (!validWidgets)
- settings()->set("ApplicationTheme", QString("system"));
+ //if (!validWidgets)
+ //settings()->set("ApplicationTheme", QString("system"));
m_themeManager->applyCurrentlySelectedTheme(true);
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index cefe664db..d927d2207 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -43,25 +43,33 @@
SystemTheme::SystemTheme()
{
+ themeName = QObject::tr("System");
themeDebugLog() << "Determining System Theme...";
const auto& style = QApplication::style();
- systemPalette = QApplication::palette();
- QString lowerThemeName = style->objectName();
+ colorPalette = QApplication::palette();
+ QString lowerThemeName = style->name();
themeDebugLog() << "System theme seems to be:" << lowerThemeName;
QStringList styles = QStyleFactory::keys();
for (auto& st : styles) {
themeDebugLog() << "Considering theme from theme factory:" << st.toLower();
if (st.toLower() == lowerThemeName) {
- systemTheme = st;
- themeDebugLog() << "System theme has been determined to be:" << systemTheme;
+ widgetTheme = st;
+ themeDebugLog() << "System theme has been determined to be:" << widgetTheme;
return;
}
}
// fall back to fusion if we can't find the current theme.
- systemTheme = "Fusion";
+ widgetTheme = "Fusion";
themeDebugLog() << "System theme not found, defaulted to Fusion";
}
+SystemTheme::SystemTheme(QString& styleName)
+{
+ themeName = styleName;
+ widgetTheme = styleName;
+ colorPalette = QApplication::palette();
+}
+
void SystemTheme::apply(bool initial)
{
// See https://github.com/MultiMC/Launcher/issues/1790
@@ -76,22 +84,30 @@ void SystemTheme::apply(bool initial)
QString SystemTheme::id()
{
- return "system";
+ return themeName;
}
QString SystemTheme::name()
{
- return QObject::tr("System");
+ if (themeName.toLower() == "windowsvista") {
+ return QObject::tr("Windows Vista");
+ } else if (themeName.toLower() == "windows") {
+ return QObject::tr("Windows 9x");
+ } else if (themeName.toLower() == "windows11") {
+ return QObject::tr("Windows 11");
+ } else {
+ return themeName;
+ }
}
QString SystemTheme::qtTheme()
{
- return systemTheme;
+ return widgetTheme;
}
QPalette SystemTheme::colorScheme()
{
- return systemPalette;
+ return colorPalette;
}
QString SystemTheme::appStyleSheet()
diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h
index 4f7d83e57..a0e77fae1 100644
--- a/launcher/ui/themes/SystemTheme.h
+++ b/launcher/ui/themes/SystemTheme.h
@@ -39,6 +39,7 @@
class SystemTheme : public ITheme {
public:
SystemTheme();
+ explicit SystemTheme(QString& themeName);
virtual ~SystemTheme() {}
void apply(bool initial) override;
@@ -53,6 +54,7 @@ class SystemTheme : public ITheme {
QColor fadeColor() override;
private:
- QPalette systemPalette;
- QString systemTheme;
+ QPalette colorPalette;
+ QString widgetTheme;
+ QString themeName;
};
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 1cb83ca26..601bc66c2 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -23,6 +23,8 @@
#include
#include
#include
+#include
+#include
#include "Exception.h"
#include "ui/themes/BrightTheme.h"
#include "ui/themes/CatPack.h"
@@ -119,14 +121,30 @@ void ThemeManager::initializeIcons()
void ThemeManager::initializeWidgets()
{
+ themeDebugLog() << "Determining System Widget Theme...";
+ const auto& style = QApplication::style();
+ currentlySelectedSystemTheme = style->name();
+ themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
+
themeDebugLog() << "<> Initializing Widget Themes";
- themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ //themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
auto darkThemeId = addTheme(std::make_unique());
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
- // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
- // dropdown?)
+ themeDebugLog() << "<> Initializing System Themes";
+ QStringList styles = QStyleFactory::keys();
+ for (auto& st : styles) {
+#if Q_OS_WINDOWS
+ if (QSysInfo::productVersion() != "11" && st == "windows11") {
+ continue;
+ }
+#endif
+ themeDebugLog() << "Loading System Theme:" << addTheme(std::make_unique(st));
+ }
+
+ // TODO: need some way to differentiate same name themes in different subdirectories
+ // (maybe smaller grey text next to theme name in dropdown?)
if (!m_applicationThemeFolder.mkpath("."))
themeWarningLog() << "Couldn't create theme folder";
@@ -238,7 +256,11 @@ void ThemeManager::applyCurrentlySelectedTheme(bool initial)
auto settings = APPLICATION->settings();
setIconTheme(settings->get("IconTheme").toString());
themeDebugLog() << "<> Icon theme set.";
- setApplicationTheme(settings->get("ApplicationTheme").toString(), initial);
+ auto applicationTheme = settings->get("ApplicationTheme").toString();
+ if (applicationTheme == "") {
+ applicationTheme = currentlySelectedSystemTheme;
+ }
+ setApplicationTheme(applicationTheme, initial);
themeDebugLog() << "<> Application theme set.";
}
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index 47b9589e3..ddf619a80 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -64,6 +64,7 @@ class ThemeManager {
QDir m_applicationThemeFolder{ "themes" };
QDir m_catPacksFolder{ "catpacks" };
std::map> m_cat_packs;
+ QString currentlySelectedSystemTheme;
void initializeThemes();
void initializeCatPacks();
From f0c9b520557e467b99a2547360260c494f9f218d Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 21:41:37 +0200
Subject: [PATCH 56/76] oop
Signed-off-by: Tayou
---
launcher/ui/themes/SystemTheme.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index d927d2207..aa5af95bf 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -47,7 +47,7 @@ SystemTheme::SystemTheme()
themeDebugLog() << "Determining System Theme...";
const auto& style = QApplication::style();
colorPalette = QApplication::palette();
- QString lowerThemeName = style->name();
+ QString lowerThemeName = style->objectName();
themeDebugLog() << "System theme seems to be:" << lowerThemeName;
QStringList styles = QStyleFactory::keys();
for (auto& st : styles) {
From a184b26a00be14c84bc86663de2fedd2c9ca8610 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 21:47:52 +0200
Subject: [PATCH 57/76] #ifdef, not #if... I'm smort
Signed-off-by: Tayou
---
launcher/ui/themes/ThemeManager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 601bc66c2..e4ad49db3 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -135,7 +135,7 @@ void ThemeManager::initializeWidgets()
themeDebugLog() << "<> Initializing System Themes";
QStringList styles = QStyleFactory::keys();
for (auto& st : styles) {
-#if Q_OS_WINDOWS
+#ifdef Q_OS_WINDOWS
if (QSysInfo::productVersion() != "11" && st == "windows11") {
continue;
}
From 7104f8909dace5139dcc75b8f6be75cd9ef063a1 Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 21:52:26 +0200
Subject: [PATCH 58/76] another oop
Signed-off-by: Tayou
---
launcher/ui/themes/ThemeManager.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index e4ad49db3..00b89b780 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -123,7 +123,7 @@ void ThemeManager::initializeWidgets()
{
themeDebugLog() << "Determining System Widget Theme...";
const auto& style = QApplication::style();
- currentlySelectedSystemTheme = style->name();
+ currentlySelectedSystemTheme = style->objectName();
themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
themeDebugLog() << "<> Initializing Widget Themes";
From 4f795eb6efd967e3d38fd6f7417bc8313dd6659a Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 22:06:01 +0200
Subject: [PATCH 59/76] format
Signed-off-by: Tayou
---
launcher/Application.cpp | 4 ++--
launcher/ui/themes/ThemeManager.cpp | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 327b63b02..6254e38fe 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -1073,8 +1073,8 @@ bool Application::createSetupWizard()
// set default theme after going into theme wizard
if (!validIcons)
settings()->set("IconTheme", QString("pe_colored"));
- //if (!validWidgets)
- //settings()->set("ApplicationTheme", QString("system"));
+ // if (!validWidgets)
+ // settings()->set("ApplicationTheme", QString("system"));
m_themeManager->applyCurrentlySelectedTheme(true);
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index 00b89b780..b3461f654 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -23,8 +23,8 @@
#include
#include
#include
-#include
#include
+#include
#include "Exception.h"
#include "ui/themes/BrightTheme.h"
#include "ui/themes/CatPack.h"
@@ -127,7 +127,7 @@ void ThemeManager::initializeWidgets()
themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
themeDebugLog() << "<> Initializing Widget Themes";
- //themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ // themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
auto darkThemeId = addTheme(std::make_unique());
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
From d70be5121c3f67c1fa171116fd183be5b814f60b Mon Sep 17 00:00:00 2001
From: Tayou
Date: Sun, 30 Jun 2024 23:27:45 +0200
Subject: [PATCH 60/76] tooltips
Signed-off-by: Tayou
---
launcher/ui/themes/BrightTheme.cpp | 38 +++++++++++++++++++
launcher/ui/themes/BrightTheme.h | 35 +++++++++++++++++
launcher/ui/themes/CustomTheme.cpp | 6 ++-
launcher/ui/themes/CustomTheme.h | 9 ++++-
launcher/ui/themes/DarkTheme.cpp | 38 +++++++++++++++++++
launcher/ui/themes/DarkTheme.h | 35 +++++++++++++++++
launcher/ui/themes/ITheme.h | 1 +
launcher/ui/themes/SystemTheme.cpp | 20 +++++++++-
launcher/ui/themes/SystemTheme.h | 3 +-
launcher/ui/themes/ThemeManager.cpp | 6 +--
launcher/ui/themes/ThemeManager.h | 2 +-
.../ui/widgets/ThemeCustomizationWidget.cpp | 6 ++-
12 files changed, 189 insertions(+), 10 deletions(-)
diff --git a/launcher/ui/themes/BrightTheme.cpp b/launcher/ui/themes/BrightTheme.cpp
index ffccdaab1..39a5bfd14 100644
--- a/launcher/ui/themes/BrightTheme.cpp
+++ b/launcher/ui/themes/BrightTheme.cpp
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2024 Tayou
+ *
+ * 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 .
+ *
+ * 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 "BrightTheme.h"
#include
@@ -55,3 +89,7 @@ QString BrightTheme::appStyleSheet()
{
return QString();
}
+QString BrightTheme::tooltip()
+{
+ return QString();
+}
diff --git a/launcher/ui/themes/BrightTheme.h b/launcher/ui/themes/BrightTheme.h
index 44a767492..750e7bfc5 100644
--- a/launcher/ui/themes/BrightTheme.h
+++ b/launcher/ui/themes/BrightTheme.h
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2024 Tayou
+ *
+ * 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 .
+ *
+ * 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
#include "FusionTheme.h"
@@ -8,6 +42,7 @@ class BrightTheme : public FusionTheme {
QString id() override;
QString name() override;
+ QString tooltip() override;
bool hasStyleSheet() override;
QString appStyleSheet() override;
bool hasColorScheme() override;
diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp
index 4859983c6..22b366b62 100644
--- a/launcher/ui/themes/CustomTheme.cpp
+++ b/launcher/ui/themes/CustomTheme.cpp
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
*
* 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
@@ -285,3 +285,7 @@ QString CustomTheme::qtTheme()
{
return m_widgets;
}
+QString CustomTheme::tooltip()
+{
+ return m_tooltip;
+}
diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h
index 3ec4cafa2..761a2bd90 100644
--- a/launcher/ui/themes/CustomTheme.h
+++ b/launcher/ui/themes/CustomTheme.h
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
*
* 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
@@ -44,6 +44,7 @@ class CustomTheme : public ITheme {
QString id() override;
QString name() override;
+ QString tooltip() override;
bool hasStyleSheet() override;
QString appStyleSheet() override;
bool hasColorScheme() override;
@@ -62,4 +63,10 @@ class CustomTheme : public ITheme {
QString m_id;
QString m_widgets;
QString m_qssFilePath;
+ /**
+ * The tooltip could be defined in the theme json,
+ * or composed of other fields that could be in there.
+ * like author, license, etc.
+ */
+ QString m_tooltip = "";
};
diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp
index c3a68a2d4..429d046ac 100644
--- a/launcher/ui/themes/DarkTheme.cpp
+++ b/launcher/ui/themes/DarkTheme.cpp
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2024 Tayou
+ *
+ * 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 .
+ *
+ * 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 "DarkTheme.h"
#include
@@ -56,3 +90,7 @@ QString DarkTheme::appStyleSheet()
{
return "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }";
}
+QString DarkTheme::tooltip()
+{
+ return "";
+}
diff --git a/launcher/ui/themes/DarkTheme.h b/launcher/ui/themes/DarkTheme.h
index 431e9a735..819f6a934 100644
--- a/launcher/ui/themes/DarkTheme.h
+++ b/launcher/ui/themes/DarkTheme.h
@@ -1,3 +1,37 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (C) 2024 Tayou
+ *
+ * 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 .
+ *
+ * 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
#include "FusionTheme.h"
@@ -8,6 +42,7 @@ class DarkTheme : public FusionTheme {
QString id() override;
QString name() override;
+ QString tooltip() override;
bool hasStyleSheet() override;
QString appStyleSheet() override;
bool hasColorScheme() override;
diff --git a/launcher/ui/themes/ITheme.h b/launcher/ui/themes/ITheme.h
index d85e7f983..45d3e2739 100644
--- a/launcher/ui/themes/ITheme.h
+++ b/launcher/ui/themes/ITheme.h
@@ -44,6 +44,7 @@ class ITheme {
virtual void apply(bool initial);
virtual QString id() = 0;
virtual QString name() = 0;
+ virtual QString tooltip() = 0;
virtual bool hasStyleSheet() = 0;
virtual QString appStyleSheet() = 0;
virtual QString qtTheme() = 0;
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index aa5af95bf..a46b2002a 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
* Copyright (C) 2024 TheKodeToad
*
* This program is free software: you can redistribute it and/or modify
@@ -35,7 +35,6 @@
*/
#include "SystemTheme.h"
#include
-#include
#include
#include
#include "HintOverrideProxyStyle.h"
@@ -100,6 +99,23 @@ QString SystemTheme::name()
}
}
+QString SystemTheme::tooltip()
+{
+ if (themeName.toLower() == "windowsvista") {
+ return QObject::tr("Widget style trying to look like your win32 theme");
+ } else if (themeName.toLower() == "windows") {
+ return QObject::tr("Windows 9x inspired widget style");
+ } else if (themeName.toLower() == "windows11") {
+ return QObject::tr("WinUI 3 inspired Qt widget style");
+ } else if (themeName.toLower() == "fusion") {
+ return QObject::tr("The default Qt widget style");
+ } else if (themeName.toLower() == "system") {
+ return QObject::tr("Your current system theme") + " (" + widgetTheme + ")";
+ } else {
+ return "";
+ }
+}
+
QString SystemTheme::qtTheme()
{
return widgetTheme;
diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h
index a0e77fae1..bcfe34288 100644
--- a/launcher/ui/themes/SystemTheme.h
+++ b/launcher/ui/themes/SystemTheme.h
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
*
* 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
@@ -45,6 +45,7 @@ class SystemTheme : public ITheme {
QString id() override;
QString name() override;
+ QString tooltip() override;
QString qtTheme() override;
bool hasStyleSheet() override;
QString appStyleSheet() override;
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index b3461f654..ac2bf26dc 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
* Copyright (C) 2023 TheKodeToad
*
* This program is free software: you can redistribute it and/or modify
@@ -127,12 +127,12 @@ void ThemeManager::initializeWidgets()
themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
themeDebugLog() << "<> Initializing Widget Themes";
- // themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
auto darkThemeId = addTheme(std::make_unique());
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
- themeDebugLog() << "<> Initializing System Themes";
+ themeDebugLog() << "<> Initializing System Widget Themes";
QStringList styles = QStyleFactory::keys();
for (auto& st : styles) {
#ifdef Q_OS_WINDOWS
diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h
index ddf619a80..9d01d38e7 100644
--- a/launcher/ui/themes/ThemeManager.h
+++ b/launcher/ui/themes/ThemeManager.h
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
* Copyright (C) 2023 TheKodeToad
*
* This program is free software: you can redistribute it and/or modify
diff --git a/launcher/ui/widgets/ThemeCustomizationWidget.cpp b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
index 9c5df0067..7a54bd390 100644
--- a/launcher/ui/widgets/ThemeCustomizationWidget.cpp
+++ b/launcher/ui/widgets/ThemeCustomizationWidget.cpp
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
- * Copyright (C) 2022 Tayou
+ * Copyright (C) 2024 Tayou
*
* 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
@@ -151,6 +151,10 @@ void ThemeCustomizationWidget::loadSettings()
int idx = 0;
for (auto& theme : themes) {
ui->widgetStyleComboBox->addItem(theme->name(), theme->id());
+ if (theme->tooltip() != "") {
+ int index = ui->widgetStyleComboBox->count() - 1;
+ ui->widgetStyleComboBox->setItemData(index, theme->tooltip(), Qt::ToolTipRole);
+ }
if (currentTheme == theme->id()) {
ui->widgetStyleComboBox->setCurrentIndex(idx);
}
From dbcfefca1b0e537aaec2bfe0ddc091c5f994317d Mon Sep 17 00:00:00 2001
From: Tayou
Date: Mon, 1 Jul 2024 23:05:54 +0200
Subject: [PATCH 61/76] fix system theme
Signed-off-by: Tayou
---
launcher/Application.cpp | 4 ++--
launcher/ui/themes/SystemTheme.cpp | 30 +++++------------------------
launcher/ui/themes/SystemTheme.h | 3 +--
launcher/ui/themes/ThemeManager.cpp | 2 +-
4 files changed, 9 insertions(+), 30 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 6254e38fe..7ae66e13a 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -1073,8 +1073,8 @@ bool Application::createSetupWizard()
// set default theme after going into theme wizard
if (!validIcons)
settings()->set("IconTheme", QString("pe_colored"));
- // if (!validWidgets)
- // settings()->set("ApplicationTheme", QString("system"));
+ if (!validWidgets)
+ settings()->set("ApplicationTheme", QString("system"));
m_themeManager->applyCurrentlySelectedTheme(true);
diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp
index a46b2002a..70de21894 100644
--- a/launcher/ui/themes/SystemTheme.cpp
+++ b/launcher/ui/themes/SystemTheme.cpp
@@ -40,31 +40,9 @@
#include "HintOverrideProxyStyle.h"
#include "ThemeManager.h"
-SystemTheme::SystemTheme()
+SystemTheme::SystemTheme(QString& styleName, bool isSystemTheme)
{
- themeName = QObject::tr("System");
- themeDebugLog() << "Determining System Theme...";
- const auto& style = QApplication::style();
- colorPalette = QApplication::palette();
- QString lowerThemeName = style->objectName();
- themeDebugLog() << "System theme seems to be:" << lowerThemeName;
- QStringList styles = QStyleFactory::keys();
- for (auto& st : styles) {
- themeDebugLog() << "Considering theme from theme factory:" << st.toLower();
- if (st.toLower() == lowerThemeName) {
- widgetTheme = st;
- themeDebugLog() << "System theme has been determined to be:" << widgetTheme;
- return;
- }
- }
- // fall back to fusion if we can't find the current theme.
- widgetTheme = "Fusion";
- themeDebugLog() << "System theme not found, defaulted to Fusion";
-}
-
-SystemTheme::SystemTheme(QString& styleName)
-{
- themeName = styleName;
+ themeName = isSystemTheme ? "system" : styleName;
widgetTheme = styleName;
colorPalette = QApplication::palette();
}
@@ -94,6 +72,8 @@ QString SystemTheme::name()
return QObject::tr("Windows 9x");
} else if (themeName.toLower() == "windows11") {
return QObject::tr("Windows 11");
+ } else if (themeName.toLower() == "system") {
+ return QObject::tr("System");
} else {
return themeName;
}
@@ -110,7 +90,7 @@ QString SystemTheme::tooltip()
} else if (themeName.toLower() == "fusion") {
return QObject::tr("The default Qt widget style");
} else if (themeName.toLower() == "system") {
- return QObject::tr("Your current system theme") + " (" + widgetTheme + ")";
+ return QObject::tr("Your current system theme");
} else {
return "";
}
diff --git a/launcher/ui/themes/SystemTheme.h b/launcher/ui/themes/SystemTheme.h
index bcfe34288..5c58856cb 100644
--- a/launcher/ui/themes/SystemTheme.h
+++ b/launcher/ui/themes/SystemTheme.h
@@ -38,8 +38,7 @@
class SystemTheme : public ITheme {
public:
- SystemTheme();
- explicit SystemTheme(QString& themeName);
+ SystemTheme(QString& themeName, bool isSystemTheme = false);
virtual ~SystemTheme() {}
void apply(bool initial) override;
diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp
index ac2bf26dc..d57e166f4 100644
--- a/launcher/ui/themes/ThemeManager.cpp
+++ b/launcher/ui/themes/ThemeManager.cpp
@@ -127,7 +127,7 @@ void ThemeManager::initializeWidgets()
themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
themeDebugLog() << "<> Initializing Widget Themes";
- themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
+ themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique(currentlySelectedSystemTheme, true));
auto darkThemeId = addTheme(std::make_unique());
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique());
From 9b172278f8ca81f7dbf3b698dbfbbc37c40f8a81 Mon Sep 17 00:00:00 2001
From: Kationor
Date: Wed, 3 Jul 2024 12:39:28 +0200
Subject: [PATCH 62/76] Add ModpackUpdatePromptDisabled setting
When creating an instance of a modpack that's already associated with
another instance, the user gets asked if they want to update that
instance instead. This commit introduces a setting to suppress the
prompt and directly create the new instance.
Signed-off-by: Kationor
---
launcher/Application.cpp | 1 +
launcher/InstanceTask.cpp | 5 +++++
launcher/ui/pages/global/LauncherPage.cpp | 2 ++
launcher/ui/pages/global/LauncherPage.ui | 10 ++++++++++
4 files changed, 18 insertions(+)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 7ae66e13a..b88b72006 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -662,6 +662,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// Minecraft mods
m_settings->registerSetting("ModMetadataDisabled", false);
m_settings->registerSetting("ModDependenciesDisabled", false);
+ m_settings->registerSetting("ModpackUpdatePromptDisabled", false);
// Minecraft offline player name
m_settings->registerSetting("LastOfflinePlayerName", "");
diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp
index 53476897c..ffa875119 100644
--- a/launcher/InstanceTask.cpp
+++ b/launcher/InstanceTask.cpp
@@ -1,5 +1,7 @@
#include "InstanceTask.h"
+#include "Application.h"
+#include "settings/SettingsObject.h"
#include "ui/dialogs/CustomMessageBox.h"
#include
@@ -22,6 +24,9 @@ InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& ol
ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name)
{
+ if (APPLICATION->settings()->get("ModpackUpdatePromptDisabled").toBool())
+ return ShouldUpdate::SkipUpdating;
+
auto info = CustomMessageBox::selectable(
parent, QObject::tr("Similar modpack was found!"),
QObject::tr(
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index 6b32e9849..93ff572c2 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -241,6 +241,7 @@ void LauncherPage::applySettings()
// Mods
s->set("ModMetadataDisabled", ui->metadataDisableBtn->isChecked());
s->set("ModDependenciesDisabled", ui->dependenciesDisableBtn->isChecked());
+ s->set("ModpackUpdatePromptDisabled", ui->modpackUpdatePromptDisableBtn->isChecked());
}
void LauncherPage::loadSettings()
{
@@ -303,6 +304,7 @@ void LauncherPage::loadSettings()
ui->metadataDisableBtn->setChecked(s->get("ModMetadataDisabled").toBool());
ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked());
ui->dependenciesDisableBtn->setChecked(s->get("ModDependenciesDisabled").toBool());
+ ui->modpackUpdatePromptDisableBtn->setChecked(s->get("ModpackUpdatePromptDisabled").toBool());
}
void LauncherPage::refreshFontPreview()
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 1f49a831f..162b5da45 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -243,6 +243,16 @@
+ -
+
+
+ When creating a new modpack instance, do not suggest updating existing instances.
+
+
+ Always create new modpack instance
+
+
+
From 83a5fe198413e70d20fa3d08df808b5b3f932bb2 Mon Sep 17 00:00:00 2001
From: Kationor
Date: Wed, 3 Jul 2024 23:09:59 +0200
Subject: [PATCH 63/76] Rename setting to SkipModpackUpdatePrompt
Was ModpackUpdatePromptDisabled
Signed-off-by: Kationor
---
launcher/Application.cpp | 2 +-
launcher/InstanceTask.cpp | 2 +-
launcher/ui/pages/global/LauncherPage.cpp | 4 ++--
launcher/ui/pages/global/LauncherPage.ui | 6 +++---
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index b88b72006..06fc68575 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -662,7 +662,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
// Minecraft mods
m_settings->registerSetting("ModMetadataDisabled", false);
m_settings->registerSetting("ModDependenciesDisabled", false);
- m_settings->registerSetting("ModpackUpdatePromptDisabled", false);
+ m_settings->registerSetting("SkipModpackUpdatePrompt", false);
// Minecraft offline player name
m_settings->registerSetting("LastOfflinePlayerName", "");
diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp
index ffa875119..be10bbe07 100644
--- a/launcher/InstanceTask.cpp
+++ b/launcher/InstanceTask.cpp
@@ -24,7 +24,7 @@ InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& ol
ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name)
{
- if (APPLICATION->settings()->get("ModpackUpdatePromptDisabled").toBool())
+ if (APPLICATION->settings()->get("SkipModpackUpdatePrompt").toBool())
return ShouldUpdate::SkipUpdating;
auto info = CustomMessageBox::selectable(
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index 93ff572c2..179f06bbf 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -241,7 +241,7 @@ void LauncherPage::applySettings()
// Mods
s->set("ModMetadataDisabled", ui->metadataDisableBtn->isChecked());
s->set("ModDependenciesDisabled", ui->dependenciesDisableBtn->isChecked());
- s->set("ModpackUpdatePromptDisabled", ui->modpackUpdatePromptDisableBtn->isChecked());
+ s->set("SkipModpackUpdatePrompt", ui->skipModpackUpdatePromptBtn->isChecked());
}
void LauncherPage::loadSettings()
{
@@ -304,7 +304,7 @@ void LauncherPage::loadSettings()
ui->metadataDisableBtn->setChecked(s->get("ModMetadataDisabled").toBool());
ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked());
ui->dependenciesDisableBtn->setChecked(s->get("ModDependenciesDisabled").toBool());
- ui->modpackUpdatePromptDisableBtn->setChecked(s->get("ModpackUpdatePromptDisabled").toBool());
+ ui->skipModpackUpdatePromptBtn->setChecked(s->get("SkipModpackUpdatePrompt").toBool());
}
void LauncherPage::refreshFontPreview()
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 162b5da45..b3d677ce2 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -244,12 +244,12 @@
-
-
+
- When creating a new modpack instance, do not suggest updating existing instances.
+ When creating a new modpack instance, do not suggest updating existing instances instead.
- Always create new modpack instance
+ Skip modpack update prompt
From 1dd21a5e4a5360ceac5f549fb613722487bfb4f1 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 4 Jul 2024 16:38:40 +0300
Subject: [PATCH 64/76] fix crash with hash task
Signed-off-by: Trial97
---
launcher/modplatform/helpers/HashUtils.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp
index f20af1f09..51789910c 100644
--- a/launcher/modplatform/helpers/HashUtils.cpp
+++ b/launcher/modplatform/helpers/HashUtils.cpp
@@ -18,8 +18,7 @@ Hasher::Ptr createHasher(QString file_path, ModPlatform::ResourceProvider provid
case ModPlatform::ResourceProvider::FLAME:
return makeShared(file_path, Algorithm::Murmur2);
default:
- qCritical() << "[Hashing]"
- << "Unrecognized mod platform!";
+ qCritical() << "[Hashing]" << "Unrecognized mod platform!";
return nullptr;
}
}
@@ -129,6 +128,10 @@ QString hash(QString fileName, Algorithm type)
QFile file(fileName);
return hash(&file, type);
}
+QString hashFile(QString fileName, Algorithm type)
+{
+ return hash(fileName, type);
+}
QString hash(QByteArray data, Algorithm type)
{
@@ -138,7 +141,7 @@ QString hash(QByteArray data, Algorithm type)
void Hasher::executeTask()
{
- m_future = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { return hash(m_path, m_alg); });
+ m_future = QtConcurrent::run(QThreadPool::globalInstance(), hashFile, m_path, m_alg);
connect(&m_watcher, &QFutureWatcher::finished, this, [this] {
if (m_future.isCanceled()) {
emitAborted();
From 5d8d1c4b90960e3469bb04e566c79afb513da529 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Thu, 4 Jul 2024 16:47:27 +0300
Subject: [PATCH 65/76] transform hashFile to lambda
Signed-off-by: Trial97
---
launcher/modplatform/helpers/HashUtils.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp
index 51789910c..a3b8d904c 100644
--- a/launcher/modplatform/helpers/HashUtils.cpp
+++ b/launcher/modplatform/helpers/HashUtils.cpp
@@ -128,10 +128,6 @@ QString hash(QString fileName, Algorithm type)
QFile file(fileName);
return hash(&file, type);
}
-QString hashFile(QString fileName, Algorithm type)
-{
- return hash(fileName, type);
-}
QString hash(QByteArray data, Algorithm type)
{
@@ -141,7 +137,8 @@ QString hash(QByteArray data, Algorithm type)
void Hasher::executeTask()
{
- m_future = QtConcurrent::run(QThreadPool::globalInstance(), hashFile, m_path, m_alg);
+ m_future = QtConcurrent::run(
+ QThreadPool::globalInstance(), [](QString fileName, Algorithm type) { return hash(fileName, type); }, m_path, m_alg);
connect(&m_watcher, &QFutureWatcher::finished, this, [this] {
if (m_future.isCanceled()) {
emitAborted();
From a6ae078e7e8cd9a9ab46ab3f18e824516766a5e4 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Sat, 6 Jul 2024 09:30:26 +0300
Subject: [PATCH 66/76] add docs to Library.cpp
Signed-off-by: Trial97
---
launcher/minecraft/Library.cpp | 101 +++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/launcher/minecraft/Library.cpp b/launcher/minecraft/Library.cpp
index 4e30f72d1..a20d6c515 100644
--- a/launcher/minecraft/Library.cpp
+++ b/launcher/minecraft/Library.cpp
@@ -42,6 +42,20 @@
#include
#include
+/**
+ * @brief Collect applicable files for the library.
+ *
+ * Depending on whether the library is native or not, it adds paths to the
+ * appropriate lists for jar files, native libraries for 32-bit, and native
+ * libraries for 64-bit.
+ *
+ * @param runtimeContext The current runtime context.
+ * @param jar List to store paths for jar files.
+ * @param native List to store paths for native libraries.
+ * @param native32 List to store paths for 32-bit native libraries.
+ * @param native64 List to store paths for 64-bit native libraries.
+ * @param overridePath Optional path to override the default storage path.
+ */
void Library::getApplicableFiles(const RuntimeContext& runtimeContext,
QStringList& jar,
QStringList& native,
@@ -50,6 +64,7 @@ void Library::getApplicableFiles(const RuntimeContext& runtimeContext,
const QString& overridePath) const
{
bool local = isLocal();
+ // Lambda function to get the absolute file path
auto actualPath = [&](QString relPath) {
relPath = FS::RemoveInvalidPathChars(relPath);
QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
@@ -59,6 +74,7 @@ void Library::getApplicableFiles(const RuntimeContext& runtimeContext,
}
return out.absoluteFilePath();
};
+
QString raw_storage = storageSuffix(runtimeContext);
if (isNative()) {
if (raw_storage.contains("${arch}")) {
@@ -76,6 +92,19 @@ void Library::getApplicableFiles(const RuntimeContext& runtimeContext,
}
}
+/**
+ * @brief Get download requests for the library files.
+ *
+ * Depending on whether the library is native or not, and the current runtime context,
+ * this function prepares download requests for the necessary files. It handles both local
+ * and remote files, checks for stale cache entries, and adds checksummed downloads.
+ *
+ * @param runtimeContext The current runtime context.
+ * @param cache Pointer to the HTTP meta cache.
+ * @param failedLocalFiles List to store paths for failed local files.
+ * @param overridePath Optional path to override the default storage path.
+ * @return QList List of download requests.
+ */
QList Library::getDownloads(const RuntimeContext& runtimeContext,
class HttpMetaCache* cache,
QStringList& failedLocalFiles,
@@ -85,6 +114,7 @@ QList Library::getDownloads(const RuntimeContext& runtimeC
bool stale = isAlwaysStale();
bool local = isLocal();
+ // Lambda function to check if a local file exists
auto check_local_file = [&](QString storage) {
QFileInfo fileinfo(storage);
QString fileName = fileinfo.fileName();
@@ -97,6 +127,7 @@ QList Library::getDownloads(const RuntimeContext& runtimeC
return true;
};
+ // Lambda function to add a download request
auto add_download = [&](QString storage, QString url, QString sha1) {
if (local) {
return check_local_file(storage);
@@ -197,6 +228,15 @@ QList Library::getDownloads(const RuntimeContext& runtimeC
return out;
}
+/**
+ * @brief Check if the library is active in the given runtime context.
+ *
+ * This function evaluates rules to determine if the library should be active,
+ * considering both general rules and native compatibility.
+ *
+ * @param runtimeContext The current runtime context.
+ * @return bool True if the library is active, false otherwise.
+ */
bool Library::isActive(const RuntimeContext& runtimeContext) const
{
bool result = true;
@@ -217,16 +257,35 @@ bool Library::isActive(const RuntimeContext& runtimeContext) const
return result;
}
+/**
+ * @brief Check if the library is considered local.
+ *
+ * @return bool True if the library is local, false otherwise.
+ */
bool Library::isLocal() const
{
return m_hint == "local";
}
+/**
+ * @brief Check if the library is always considered stale.
+ *
+ * @return bool True if the library is always stale, false otherwise.
+ */
bool Library::isAlwaysStale() const
{
return m_hint == "always-stale";
}
+/**
+ * @brief Get the compatible native classifier for the current runtime context.
+ *
+ * This function attempts to match the current runtime context with the appropriate
+ * native classifier.
+ *
+ * @param runtimeContext The current runtime context.
+ * @return QString The compatible native classifier, or an empty string if none is found.
+ */
QString Library::getCompatibleNative(const RuntimeContext& runtimeContext) const
{
// try to match precise classifier "[os]-[arch]"
@@ -241,16 +300,31 @@ QString Library::getCompatibleNative(const RuntimeContext& runtimeContext) const
return entry.value();
}
+/**
+ * @brief Set the storage prefix for the library.
+ *
+ * @param prefix The storage prefix to set.
+ */
void Library::setStoragePrefix(QString prefix)
{
m_storagePrefix = prefix;
}
+/**
+ * @brief Get the default storage prefix for libraries.
+ *
+ * @return QString The default storage prefix.
+ */
QString Library::defaultStoragePrefix()
{
return "libraries/";
}
+/**
+ * @brief Get the current storage prefix for the library.
+ *
+ * @return QString The current storage prefix.
+ */
QString Library::storagePrefix() const
{
if (m_storagePrefix.isEmpty()) {
@@ -259,6 +333,15 @@ QString Library::storagePrefix() const
return m_storagePrefix;
}
+/**
+ * @brief Get the filename for the library in the current runtime context.
+ *
+ * This function determines the appropriate filename for the library, taking into
+ * account native classifiers if applicable.
+ *
+ * @param runtimeContext The current runtime context.
+ * @return QString The filename of the library.
+ */
QString Library::filename(const RuntimeContext& runtimeContext) const
{
if (!m_filename.isEmpty()) {
@@ -280,6 +363,15 @@ QString Library::filename(const RuntimeContext& runtimeContext) const
return nativeSpec.getFileName();
}
+/**
+ * @brief Get the display name for the library in the current runtime context.
+ *
+ * This function returns the display name for the library, defaulting to the filename
+ * if no display name is set.
+ *
+ * @param runtimeContext The current runtime context.
+ * @return QString The display name of the library.
+ */
QString Library::displayName(const RuntimeContext& runtimeContext) const
{
if (!m_displayname.isEmpty())
@@ -287,6 +379,15 @@ QString Library::displayName(const RuntimeContext& runtimeContext) const
return filename(runtimeContext);
}
+/**
+ * @brief Get the storage suffix for the library in the current runtime context.
+ *
+ * This function determines the appropriate storage suffix for the library, taking into
+ * account native classifiers if applicable.
+ *
+ * @param runtimeContext The current runtime context.
+ * @return QString The storage suffix of the library.
+ */
QString Library::storageSuffix(const RuntimeContext& runtimeContext) const
{
// non-native? use only the gradle specifier
From e49e2622fc6ebd3f8061dc13b56a24493ce4019e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sun, 7 Jul 2024 00:21:50 +0000
Subject: [PATCH 67/76] chore(nix): update lockfile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Flake lock file updates:
• Updated input 'flake-parts':
'github:hercules-ci/flake-parts/2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8?narHash=sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw%3D' (2024-06-01)
→ 'github:hercules-ci/flake-parts/9227223f6d922fee3c7b190b2cc238a99527bbb7?narHash=sha256-pQMhCCHyQGRzdfAkdJ4cIWiw%2BJNuWsTX7f0ZYSyz0VY%3D' (2024-07-03)
• Updated input 'nixpkgs':
'github:NixOS/nixpkgs/3f84a279f1a6290ce154c5531378acc827836fbb?narHash=sha256-u1fA0DYQYdeG%2B5kDm1bOoGcHtX0rtC7qs2YA2N1X%2B%2BI%3D' (2024-06-13)
→ 'github:NixOS/nixpkgs/9f4128e00b0ae8ec65918efeba59db998750ead6?narHash=sha256-rwz8NJZV%2B387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ%3D' (2024-07-03)
• Updated input 'pre-commit-hooks':
'github:cachix/pre-commit-hooks.nix/cc4d466cb1254af050ff7bdf47f6d404a7c646d1?narHash=sha256-7XfBuLULizXjXfBYy/VV%2BSpYMHreNRHk9nKMsm1bgb4%3D' (2024-06-06)
→ 'github:cachix/pre-commit-hooks.nix/0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07?narHash=sha256-F1h%2BXIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4%3D' (2024-06-24)
---
flake.lock | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/flake.lock b/flake.lock
index caed1a708..961cb2044 100644
--- a/flake.lock
+++ b/flake.lock
@@ -23,11 +23,11 @@
]
},
"locked": {
- "lastModified": 1717285511,
- "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
+ "lastModified": 1719994518,
+ "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
"owner": "hercules-ci",
"repo": "flake-parts",
- "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
+ "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
"type": "github"
},
"original": {
@@ -75,11 +75,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1718276985,
- "narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=",
+ "lastModified": 1720031269,
+ "narHash": "sha256-rwz8NJZV+387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "3f84a279f1a6290ce154c5531378acc827836fbb",
+ "rev": "9f4128e00b0ae8ec65918efeba59db998750ead6",
"type": "github"
},
"original": {
@@ -103,11 +103,11 @@
]
},
"locked": {
- "lastModified": 1717664902,
- "narHash": "sha256-7XfBuLULizXjXfBYy/VV+SpYMHreNRHk9nKMsm1bgb4=",
+ "lastModified": 1719259945,
+ "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
- "rev": "cc4d466cb1254af050ff7bdf47f6d404a7c646d1",
+ "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
"type": "github"
},
"original": {
From fdcd1068f3e5d859e13eac56964b2eaeb4ac6485 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Mon, 8 Jul 2024 14:53:39 +0300
Subject: [PATCH 68/76] remove some poly mentions from the code
Signed-off-by: Trial97
---
launcher/InstanceList.cpp | 12 ++++++------
launcher/InstanceList.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp
index 3f835cfaf..ab92a6c3c 100644
--- a/launcher/InstanceList.cpp
+++ b/launcher/InstanceList.cpp
@@ -372,13 +372,13 @@ void InstanceList::undoTrashInstance()
auto top = m_trashHistory.pop();
- while (QDir(top.polyPath).exists()) {
+ while (QDir(top.path).exists()) {
top.id += "1";
- top.polyPath += "1";
+ top.path += "1";
}
- qDebug() << "Moving" << top.trashPath << "back to" << top.polyPath;
- QFile(top.trashPath).rename(top.polyPath);
+ qDebug() << "Moving" << top.trashPath << "back to" << top.path;
+ QFile(top.trashPath).rename(top.path);
m_instanceGroupIndex[top.id] = top.groupName;
increaseGroupCount(top.groupName);
@@ -635,8 +635,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 PrismMC 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 5ddddee95..c85fe55c7 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 path;
QString trashPath;
QString groupName;
};
From aeb7f29a5b4a65cccd35d0ff65cfd7101124bb35 Mon Sep 17 00:00:00 2001
From: Alexandru Ionut Tripon
Date: Mon, 8 Jul 2024 15:04:27 +0300
Subject: [PATCH 69/76] Update launcher/InstanceList.cpp
Co-authored-by: Tayou
Signed-off-by: Alexandru Ionut Tripon
---
launcher/InstanceList.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp
index ab92a6c3c..e1fa755dd 100644
--- a/launcher/InstanceList.cpp
+++ b/launcher/InstanceList.cpp
@@ -635,7 +635,7 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
QString inst_type = instanceSettings->get("InstanceType").toString();
- // NOTE: Some PrismMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a
+ // NOTE: Some launcher 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));
From 0a543cb66b24d74595073f905d365dbe23c78431 Mon Sep 17 00:00:00 2001
From: izder456
Date: Thu, 11 Jul 2024 20:30:28 -0500
Subject: [PATCH 70/76] FIX launcher/java/JavaUtils.cpp to properly autodetect
JVM paths on OpenBSD and FreeBSD
Signed-off-by: izder456
---
launcher/java/JavaUtils.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp
index 809d81087..34d893ff2 100644
--- a/launcher/java/JavaUtils.cpp
+++ b/launcher/java/JavaUtils.cpp
@@ -394,7 +394,7 @@ QList JavaUtils::FindJavaPaths()
return javas;
}
-#elif defined(Q_OS_LINUX)
+#elif defined(Q_OS_LINUX) || defined(Q_OS_OPENBSD) || defined(Q_OS_FREEBSD)
QList JavaUtils::FindJavaPaths()
{
QList javas;
@@ -419,6 +419,7 @@ QList JavaUtils::FindJavaPaths()
scanJavaDir(snap + dirPath);
}
};
+#if defined(Q_OS_LINUX)
// oracle RPMs
scanJavaDirs("/usr/java");
// general locations used by distro packaging
@@ -437,7 +438,10 @@ QList JavaUtils::FindJavaPaths()
scanJavaDirs("/opt/ibm"); // IBM Semeru Certified Edition
// flatpak
scanJavaDirs("/app/jdk");
-
+#elif defined(Q_OS_OPENBSD) || defined(Q_OS_FREEBSD)
+ // ports install to /usr/local on OpenBSD & FreeBSD
+ scanJavaDirs("/usr/local");
+#endif
auto home = qEnvironmentVariable("HOME");
// javas downloaded by IntelliJ
From 303f3303f6e97ba3b39bb0f2454e1bad0002e6dc Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sun, 14 Jul 2024 00:22:27 +0000
Subject: [PATCH 71/76] chore(nix): update lockfile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Flake lock file updates:
• Updated input 'nixpkgs':
'github:NixOS/nixpkgs/9f4128e00b0ae8ec65918efeba59db998750ead6?narHash=sha256-rwz8NJZV%2B387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ%3D' (2024-07-03)
→ 'github:NixOS/nixpkgs/7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9?narHash=sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y%3D' (2024-07-12)
• Updated input 'pre-commit-hooks':
'github:cachix/pre-commit-hooks.nix/0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07?narHash=sha256-F1h%2BXIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4%3D' (2024-06-24)
→ 'github:cachix/pre-commit-hooks.nix/8d6a17d0cdf411c55f12602624df6368ad86fac1?narHash=sha256-ni/87oHPZm6Gv0ECYxr1f6uxB0UKBWJ6HvS7lwLU6oY%3D' (2024-07-09)
---
flake.lock | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/flake.lock b/flake.lock
index 961cb2044..38b0d7430 100644
--- a/flake.lock
+++ b/flake.lock
@@ -75,11 +75,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1720031269,
- "narHash": "sha256-rwz8NJZV+387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ=",
+ "lastModified": 1720768451,
+ "narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "9f4128e00b0ae8ec65918efeba59db998750ead6",
+ "rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
"type": "github"
},
"original": {
@@ -103,11 +103,11 @@
]
},
"locked": {
- "lastModified": 1719259945,
- "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
+ "lastModified": 1720524665,
+ "narHash": "sha256-ni/87oHPZm6Gv0ECYxr1f6uxB0UKBWJ6HvS7lwLU6oY=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
- "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
+ "rev": "8d6a17d0cdf411c55f12602624df6368ad86fac1",
"type": "github"
},
"original": {
From 6d425717e952a179b776694ea229532fac9e3801 Mon Sep 17 00:00:00 2001
From: Trial97
Date: Tue, 16 Jul 2024 14:06:26 +0300
Subject: [PATCH 72/76] fix a few missing help pages
Signed-off-by: Trial97
---
launcher/ui/pages/global/AccountListPage.h | 2 +-
launcher/ui/pages/instance/ManagedPackPage.h | 2 ++
launcher/ui/pages/instance/OtherLogsPage.h | 2 +-
launcher/ui/pages/instance/ShaderPackPage.h | 2 +-
launcher/ui/pages/modplatform/ResourcePackPage.h | 2 ++
launcher/ui/pages/modplatform/ShaderPackPage.h | 2 ++
launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h | 2 +-
launcher/ui/pages/modplatform/legacy_ftb/Page.h | 2 +-
8 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h
index dd49a95d6..4f02b7df5 100644
--- a/launcher/ui/pages/global/AccountListPage.h
+++ b/launcher/ui/pages/global/AccountListPage.h
@@ -66,7 +66,7 @@ class AccountListPage : public QMainWindow, public BasePage {
return icon;
}
QString id() const override { return "accounts"; }
- QString helpPage() const override { return "Getting-Started#adding-an-account"; }
+ QString helpPage() const override { return "/getting-started/adding-an-account"; }
void retranslate() override;
public slots:
diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h
index fe5a200de..c44f77070 100644
--- a/launcher/ui/pages/instance/ManagedPackPage.h
+++ b/launcher/ui/pages/instance/ManagedPackPage.h
@@ -119,6 +119,7 @@ class ModrinthManagedPackPage final : public ManagedPackPage {
void parseManagedPack() override;
[[nodiscard]] QString url() const override;
+ [[nodiscard]] QString helpPage() const override { return "modrinth-managed-pack"; }
public slots:
void suggestVersion() override;
@@ -142,6 +143,7 @@ class FlameManagedPackPage final : public ManagedPackPage {
void parseManagedPack() override;
[[nodiscard]] QString url() const override;
+ [[nodiscard]] QString helpPage() const override { return "curseforge-managed-pack"; }
public slots:
void suggestVersion() override;
diff --git a/launcher/ui/pages/instance/OtherLogsPage.h b/launcher/ui/pages/instance/OtherLogsPage.h
index de42f5a23..85a3a2dbc 100644
--- a/launcher/ui/pages/instance/OtherLogsPage.h
+++ b/launcher/ui/pages/instance/OtherLogsPage.h
@@ -57,7 +57,7 @@ class OtherLogsPage : public QWidget, public BasePage {
QString id() const override { return "logs"; }
QString displayName() const override { return tr("Other logs"); }
QIcon icon() const override { return APPLICATION->getThemedIcon("log"); }
- QString helpPage() const override { return "Minecraft-Logs"; }
+ QString helpPage() const override { return "other-Logs"; }
void retranslate() override;
void openedImpl() override;
diff --git a/launcher/ui/pages/instance/ShaderPackPage.h b/launcher/ui/pages/instance/ShaderPackPage.h
index 7c43a3756..d134e67ad 100644
--- a/launcher/ui/pages/instance/ShaderPackPage.h
+++ b/launcher/ui/pages/instance/ShaderPackPage.h
@@ -48,7 +48,7 @@ class ShaderPackPage : public ExternalResourcesPage {
QString displayName() const override { return tr("Shader packs"); }
QIcon icon() const override { return APPLICATION->getThemedIcon("shaderpacks"); }
QString id() const override { return "shaderpacks"; }
- QString helpPage() const override { return "Resource-packs"; }
+ QString helpPage() const override { return "shader-packs"; }
bool shouldDisplay() const override { return true; }
diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.h b/launcher/ui/pages/modplatform/ResourcePackPage.h
index 6015aec0b..440d91ab0 100644
--- a/launcher/ui/pages/modplatform/ResourcePackPage.h
+++ b/launcher/ui/pages/modplatform/ResourcePackPage.h
@@ -40,6 +40,8 @@ class ResourcePackResourcePage : public ResourcePage {
[[nodiscard]] QMap urlHandlers() const override;
+ [[nodiscard]] inline auto helpPage() const -> QString override { return "resourcepack-platform"; }
+
protected:
ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.h b/launcher/ui/pages/modplatform/ShaderPackPage.h
index c29317e15..4b92c33dc 100644
--- a/launcher/ui/pages/modplatform/ShaderPackPage.h
+++ b/launcher/ui/pages/modplatform/ShaderPackPage.h
@@ -42,6 +42,8 @@ class ShaderPackResourcePage : public ResourcePage {
[[nodiscard]] QMap urlHandlers() const override;
+ [[nodiscard]] inline auto helpPage() const -> QString override { return "shaderpack-platform"; }
+
protected:
ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h
index 8e9661272..00f013f6f 100644
--- a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h
+++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.h
@@ -44,7 +44,7 @@ class ImportFTBPage : public QWidget, public BasePage {
QString displayName() const override { return tr("FTB App Import"); }
QIcon icon() const override { return APPLICATION->getThemedIcon("ftb_logo"); }
QString id() const override { return "import_ftb"; }
- QString helpPage() const override { return "FTB-platform"; }
+ QString helpPage() const override { return "FTB-import"; }
bool shouldDisplay() const override { return true; }
void openedImpl() override;
void retranslate() override;
diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.h b/launcher/ui/pages/modplatform/legacy_ftb/Page.h
index 4d317b7c0..daef23342 100644
--- a/launcher/ui/pages/modplatform/legacy_ftb/Page.h
+++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.h
@@ -66,7 +66,7 @@ class Page : public QWidget, public BasePage {
QString displayName() const override { return "FTB Legacy"; }
QIcon icon() const override { return APPLICATION->getThemedIcon("ftb_logo"); }
QString id() const override { return "legacy_ftb"; }
- QString helpPage() const override { return "FTB-platform"; }
+ QString helpPage() const override { return "FTB-legacy"; }
bool shouldDisplay() const override;
void openedImpl() override;
void retranslate() override;
From e6019ab396ff32edb2321e8d04dc793aebaaf2e7 Mon Sep 17 00:00:00 2001
From: UnownPlain <38232575+UnownPlain@users.noreply.github.com>
Date: Wed, 17 Jul 2024 23:04:52 -0400
Subject: [PATCH 73/76] Fix dead link to Modrinth authentication docs
Signed-off-by: UnownPlain <38232575+UnownPlain@users.noreply.github.com>
---
launcher/ui/pages/global/APIPage.ui | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui
index 93591e440..a7f3f3f72 100644
--- a/launcher/ui/pages/global/APIPage.ui
+++ b/launcher/ui/pages/global/APIPage.ui
@@ -207,7 +207,7 @@
-
- <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/api-spec/#section/Authentication">documentation</a> for more information.</p></body></html>
+ <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/#section/Authentication">documentation</a> for more information.</p></body></html>
true
From cb65f6dfb582847d1dc9284379b1b45ac8c53b6e Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Wed, 17 Jul 2024 23:05:45 -0700
Subject: [PATCH 74/76] fix(net/validators): ensure buffers are cleared and
reset;
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/meta/BaseEntity.cpp | 12 ++++++++++--
launcher/net/ChecksumValidator.h | 6 +++++-
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp
index 8a99e3303..cbde3b49d 100644
--- a/launcher/meta/BaseEntity.cpp
+++ b/launcher/meta/BaseEntity.cpp
@@ -30,13 +30,21 @@ class ParsingValidator : public Net::Validator {
virtual ~ParsingValidator(){};
public: /* methods */
- bool init(QNetworkRequest&) override { return true; }
+ bool init(QNetworkRequest&) override
+ {
+ m_data.clear();
+ return true;
+ }
bool write(QByteArray& data) override
{
this->m_data.append(data);
return true;
}
- bool abort() override { return true; }
+ bool abort() override
+ {
+ m_data.clear();
+ return true;
+ }
bool validate(QNetworkReply&) override
{
auto fname = m_entity->localFilename();
diff --git a/launcher/net/ChecksumValidator.h b/launcher/net/ChecksumValidator.h
index dfee0aee5..ab2457202 100644
--- a/launcher/net/ChecksumValidator.h
+++ b/launcher/net/ChecksumValidator.h
@@ -60,7 +60,11 @@ class ChecksumValidator : public Validator {
return true;
}
- auto abort() -> bool override { return true; }
+ auto abort() -> bool override
+ {
+ m_checksum.reset();
+ return true;
+ }
auto validate(QNetworkReply&) -> bool override
{
From fb10cb5fdfe121740ce3a6c24a1c9d3ea0dd429a Mon Sep 17 00:00:00 2001
From: Ben Westover
Date: Thu, 18 Jul 2024 22:08:18 -0400
Subject: [PATCH 75/76] Fix a few typos
As part of packaging Prism Launcher for Debian, I have run a package linter
called lintian which found a few spelling errors throughout the source.
I am not a fan of contributions that only fix cosmetics like spelling errors,
but Debian encourages forwarding this stuff upstream instead of letting it get
fixed naturally over time.
Signed-off-by: Ben Westover
---
launcher/Application.cpp | 2 +-
launcher/minecraft/PackProfile.cpp | 4 ++--
launcher/minecraft/ProfileUtils.cpp | 6 +++---
launcher/net/NetRequest.cpp | 2 +-
launcher/settings/OverrideSetting.h | 2 +-
launcher/settings/PassthroughSetting.h | 2 +-
launcher/ui/pages/modplatform/flame/FlameModel.cpp | 2 +-
7 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 06fc68575..5eb1d58d5 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -817,7 +817,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
m_icons.reset(new IconList(instFolders, setting->get().toString()));
connect(setting.get(), &Setting::SettingChanged,
[&](const Setting&, QVariant value) { m_icons->directoryChanged(value.toString()); });
- qDebug() << "<> Instance icons intialized.";
+ qDebug() << "<> Instance icons initialized.";
}
// Themes
diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp
index 4b17cdf07..63067b191 100644
--- a/launcher/minecraft/PackProfile.cpp
+++ b/launcher/minecraft/PackProfile.cpp
@@ -181,7 +181,7 @@ static bool loadPackProfile(PackProfile* parent,
}
if (!componentsFile.open(QFile::ReadOnly)) {
qCritical() << "Couldn't open" << componentsFile.fileName() << " for reading:" << componentsFile.errorString();
- qWarning() << "Ignoring overriden order";
+ qWarning() << "Ignoring overridden order";
return false;
}
@@ -190,7 +190,7 @@ static bool loadPackProfile(PackProfile* parent,
QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
+ qWarning() << "Ignoring overridden order";
return false;
}
diff --git a/launcher/minecraft/ProfileUtils.cpp b/launcher/minecraft/ProfileUtils.cpp
index f81d6cb7f..08ec0fac3 100644
--- a/launcher/minecraft/ProfileUtils.cpp
+++ b/launcher/minecraft/ProfileUtils.cpp
@@ -57,7 +57,7 @@ bool readOverrideOrders(QString path, PatchOrder& order)
}
if (!orderFile.open(QFile::ReadOnly)) {
qCritical() << "Couldn't open" << orderFile.fileName() << " for reading:" << orderFile.errorString();
- qWarning() << "Ignoring overriden order";
+ qWarning() << "Ignoring overridden order";
return false;
}
@@ -66,7 +66,7 @@ bool readOverrideOrders(QString path, PatchOrder& order)
QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
+ qWarning() << "Ignoring overridden order";
return false;
}
@@ -84,7 +84,7 @@ bool readOverrideOrders(QString path, PatchOrder& order)
}
} catch ([[maybe_unused]] const JSONValidationError& err) {
qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format";
- qWarning() << "Ignoring overriden order";
+ qWarning() << "Ignoring overridden order";
order.clear();
return false;
}
diff --git a/launcher/net/NetRequest.cpp b/launcher/net/NetRequest.cpp
index 203f1f950..f3dbe32d3 100644
--- a/launcher/net/NetRequest.cpp
+++ b/launcher/net/NetRequest.cpp
@@ -86,7 +86,7 @@ void NetRequest::executeTask()
break;
case State::Inactive:
case State::Failed:
- emit failed("Failed to initilize sink");
+ emit failed("Failed to initialize sink");
emit finished();
return;
case State::AbortedByUser:
diff --git a/launcher/settings/OverrideSetting.h b/launcher/settings/OverrideSetting.h
index faa3e7948..3763b5717 100644
--- a/launcher/settings/OverrideSetting.h
+++ b/launcher/settings/OverrideSetting.h
@@ -29,7 +29,7 @@
class OverrideSetting : public Setting {
Q_OBJECT
public:
- explicit OverrideSetting(std::shared_ptr overriden, std::shared_ptr gate);
+ explicit OverrideSetting(std::shared_ptr overridden, std::shared_ptr gate);
virtual QVariant defValue() const;
virtual QVariant get() const;
diff --git a/launcher/settings/PassthroughSetting.h b/launcher/settings/PassthroughSetting.h
index c776ca951..3f3474003 100644
--- a/launcher/settings/PassthroughSetting.h
+++ b/launcher/settings/PassthroughSetting.h
@@ -28,7 +28,7 @@
class PassthroughSetting : public Setting {
Q_OBJECT
public:
- explicit PassthroughSetting(std::shared_ptr overriden, std::shared_ptr gate);
+ explicit PassthroughSetting(std::shared_ptr overridden, std::shared_ptr gate);
virtual QVariant defValue() const;
virtual QVariant get() const;
diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
index 3b266bcef..604a9a38d 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
@@ -172,7 +172,7 @@ void ListModel::performPaginatedSearch()
callbacks.on_succeed = [this](auto& doc, auto& pack) { searchRequestForOneSucceeded(doc); };
callbacks.on_abort = [this] {
qCritical() << "Search task aborted by an unknown reason!";
- searchRequestFailed("Abborted");
+ searchRequestFailed("Aborted");
};
static const FlameAPI api;
if (auto job = api.getProjectInfo({ projectId }, std::move(callbacks)); job) {
From fc2d0134024619c84eda5649df2196e5600c3808 Mon Sep 17 00:00:00 2001
From: Edgars Cirulis
Date: Sat, 20 Jul 2024 01:50:30 +0300
Subject: [PATCH 76/76] ui: swap timeoutSecondsLabel and
numberOfManualRetriesLabel order
fixes: 7a200a337f08cfa1e32102594958f10cb7f000c6
conflicted with 6078a771c18fd749f38d7c1a2f80ed3c7ec7ad28
Signed-off-by: Edgars Cirulis
---
launcher/ui/pages/global/LauncherPage.ui | 30 ++++++++++++------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index b3387ba02..72039488b 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -291,6 +291,20 @@
-
+
+
+ Number of manual retries
+
+
+
+ -
+
+
+ 0
+
+
+
+ -
Seconds to wait until the requests are terminated
@@ -300,27 +314,13 @@
- -
+
-
s
- -
-
-
- Number of manual retries
-
-
-
- -
-
-
- 0
-
-
-