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);