2023-08-05 22:14:05 -04:00
|
|
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <QFuture>
|
|
|
|
#include <QNetworkAccessManager>
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QtQml>
|
2023-09-16 18:37:42 -04:00
|
|
|
#include <qcorotask.h>
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
#include "accountmanager.h"
|
2023-10-08 17:51:18 -04:00
|
|
|
#include "config.h"
|
2023-07-30 08:49:34 -04:00
|
|
|
#include "headline.h"
|
|
|
|
#include "profile.h"
|
|
|
|
#include "profilemanager.h"
|
|
|
|
#include "squareboot.h"
|
|
|
|
#include "steamapi.h"
|
|
|
|
|
|
|
|
class SapphireLauncher;
|
|
|
|
class SquareLauncher;
|
|
|
|
class AssetUpdater;
|
|
|
|
class GameInstaller;
|
2023-08-18 23:27:29 -04:00
|
|
|
class CompatibilityToolInstaller;
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
class LoginInformation : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
Q_PROPERTY(QString username MEMBER username)
|
|
|
|
Q_PROPERTY(QString password MEMBER password)
|
|
|
|
Q_PROPERTY(QString oneTimePassword MEMBER oneTimePassword)
|
|
|
|
Q_PROPERTY(Profile *profile MEMBER profile)
|
|
|
|
|
|
|
|
public:
|
2023-09-17 08:31:24 -04:00
|
|
|
explicit LoginInformation(QObject *parent = nullptr)
|
2023-07-30 10:11:14 -04:00
|
|
|
: QObject(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
Profile *profile = nullptr;
|
|
|
|
|
|
|
|
QString username, password, oneTimePassword;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LoginAuth {
|
|
|
|
QString SID;
|
|
|
|
int region = 2; // america?
|
|
|
|
int maxExpansion = 1;
|
|
|
|
|
2023-10-08 13:19:23 -04:00
|
|
|
// if empty, don't set on the client
|
2023-07-30 08:49:34 -04:00
|
|
|
QString lobbyhost, frontierHost;
|
|
|
|
};
|
|
|
|
|
|
|
|
class LauncherCore : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2023-09-16 18:01:02 -04:00
|
|
|
QML_ELEMENT
|
|
|
|
QML_SINGLETON
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
Q_PROPERTY(bool loadingFinished READ isLoadingFinished NOTIFY loadingFinished)
|
|
|
|
Q_PROPERTY(bool hasAccount READ hasAccount NOTIFY accountChanged)
|
|
|
|
Q_PROPERTY(bool isSteam READ isSteam CONSTANT)
|
2023-07-31 18:58:02 -04:00
|
|
|
Q_PROPERTY(bool isSteamDeck READ isSteamDeck CONSTANT)
|
2023-09-17 08:31:24 -04:00
|
|
|
Q_PROPERTY(SquareBoot *squareBoot MEMBER m_squareBoot)
|
2023-07-30 08:49:34 -04:00
|
|
|
Q_PROPERTY(ProfileManager *profileManager READ profileManager CONSTANT)
|
|
|
|
Q_PROPERTY(AccountManager *accountManager READ accountManager CONSTANT)
|
|
|
|
Q_PROPERTY(bool closeWhenLaunched READ closeWhenLaunched WRITE setCloseWhenLaunched NOTIFY closeWhenLaunchedChanged)
|
2023-07-31 18:59:42 -04:00
|
|
|
Q_PROPERTY(bool showNews READ showNews WRITE setShowNews NOTIFY showNewsChanged)
|
2023-08-19 11:20:47 -04:00
|
|
|
Q_PROPERTY(bool showDevTools READ showDevTools WRITE setShowDevTools NOTIFY showDevToolsChanged)
|
2023-08-18 14:52:06 -04:00
|
|
|
Q_PROPERTY(bool keepPatches READ keepPatches WRITE setKeepPatches NOTIFY keepPatchesChanged)
|
2023-08-18 21:36:29 -04:00
|
|
|
Q_PROPERTY(QString dalamudDistribServer READ dalamudDistribServer WRITE setDalamudDistribServer NOTIFY dalamudDistribServerChanged)
|
|
|
|
Q_PROPERTY(QString squareEnixServer READ squareEnixServer WRITE setSquareEnixServer NOTIFY squareEnixServerChanged)
|
|
|
|
Q_PROPERTY(QString squareEnixLoginServer READ squareEnixLoginServer WRITE setSquareEnixLoginServer NOTIFY squareEnixLoginServerChanged)
|
2023-10-08 13:22:34 -04:00
|
|
|
Q_PROPERTY(QString xivApiServer READ xivApiServer WRITE setXivApiServer NOTIFY xivApiServerChanged)
|
2023-10-06 18:14:32 -04:00
|
|
|
Q_PROPERTY(QString preferredProtocol READ preferredProtocol WRITE setPreferredProtocol NOTIFY preferredProtocolChanged)
|
2023-10-08 13:18:05 -04:00
|
|
|
Q_PROPERTY(bool argumentsEncrypted READ argumentsEncrypted WRITE setArgumentsEncrypted NOTIFY encryptedArgumentsChanged)
|
2023-07-30 08:49:34 -04:00
|
|
|
Q_PROPERTY(Headline *headline READ headline NOTIFY newsChanged)
|
2023-09-16 20:12:01 -04:00
|
|
|
Q_PROPERTY(Profile *currentProfile READ currentProfile WRITE setCurrentProfile NOTIFY currentProfileChanged)
|
2023-09-17 19:20:41 -04:00
|
|
|
Q_PROPERTY(Profile *autoLoginProfile READ autoLoginProfile WRITE setAutoLoginProfile NOTIFY autoLoginProfileChanged)
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
public:
|
2023-09-16 18:01:02 -04:00
|
|
|
LauncherCore();
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
QNetworkAccessManager *mgr;
|
|
|
|
|
|
|
|
ProfileManager *profileManager();
|
|
|
|
AccountManager *accountManager();
|
|
|
|
|
2023-10-08 17:55:13 -04:00
|
|
|
void initializeSteam();
|
2023-09-16 18:01:02 -04:00
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
/*
|
|
|
|
* Begins the login process, and may call SquareBoot or SapphireLauncher depending on the profile type.
|
|
|
|
* It's designed to be opaque as possible to the caller.
|
|
|
|
*
|
|
|
|
* The login process is asynchronous.
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE void login(Profile *profile, const QString &username, const QString &password, const QString &oneTimePassword);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempts to log into a profile without LoginInformation, which may or may not work depending on a combination of
|
|
|
|
* the password failing, OTP not being available to auto-generate, among other things.
|
|
|
|
*
|
|
|
|
* The launcher will still warn the user about any possible errors, however the call site will need to check the
|
|
|
|
* result to see whether they need to "reset" or show a failed state or not.
|
|
|
|
*/
|
2023-10-08 13:21:13 -04:00
|
|
|
Q_INVOKABLE bool autoLogin(Profile *profile);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Launches the game using the provided authentication.
|
|
|
|
*/
|
2023-09-17 19:30:22 -04:00
|
|
|
void launchGame(Profile &settings, const LoginAuth &auth);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This just wraps it in wine if needed.
|
|
|
|
*/
|
|
|
|
void launchExecutable(const Profile &settings, QProcess *process, const QStringList &args, bool isGame, bool needsRegistrySetup);
|
|
|
|
|
|
|
|
void addRegistryKey(const Profile &settings, QString key, QString value, QString data);
|
|
|
|
|
|
|
|
void buildRequest(const Profile &settings, QNetworkRequest &request);
|
|
|
|
void setSSL(QNetworkRequest &request);
|
2023-10-06 18:14:32 -04:00
|
|
|
void setupIgnoreSSL(QNetworkReply *reply);
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
void readInitialInformation();
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] bool closeWhenLaunched() const;
|
2023-07-30 08:49:34 -04:00
|
|
|
void setCloseWhenLaunched(bool value);
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] bool showNews() const;
|
2023-07-31 18:59:42 -04:00
|
|
|
void setShowNews(bool value);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] bool showDevTools() const;
|
2023-08-19 11:20:47 -04:00
|
|
|
void setShowDevTools(bool value);
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] bool keepPatches() const;
|
2023-08-18 14:52:06 -04:00
|
|
|
void setKeepPatches(bool value);
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] QString dalamudDistribServer() const;
|
2023-08-18 21:36:29 -04:00
|
|
|
void setDalamudDistribServer(const QString &value);
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] QString squareEnixServer() const;
|
2023-08-18 21:36:29 -04:00
|
|
|
void setSquareEnixServer(const QString &value);
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] QString squareEnixLoginServer() const;
|
2023-08-18 21:36:29 -04:00
|
|
|
void setSquareEnixLoginServer(const QString &value);
|
|
|
|
|
2023-10-08 13:22:34 -04:00
|
|
|
[[nodiscard]] QString xivApiServer() const;
|
|
|
|
void setXivApiServer(const QString &value);
|
|
|
|
|
2023-10-06 18:14:32 -04:00
|
|
|
[[nodiscard]] QString preferredProtocol() const;
|
|
|
|
void setPreferredProtocol(const QString &value);
|
|
|
|
|
2023-10-08 13:18:05 -04:00
|
|
|
[[nodiscard]] bool argumentsEncrypted() const;
|
|
|
|
void setArgumentsEncrypted(bool value);
|
|
|
|
|
2023-09-17 19:20:41 -04:00
|
|
|
[[nodiscard]] QString autoLoginProfileName() const;
|
|
|
|
[[nodiscard]] Profile *autoLoginProfile() const;
|
|
|
|
void setAutoLoginProfile(Profile *value);
|
|
|
|
|
2023-08-18 12:59:07 -04:00
|
|
|
Q_INVOKABLE GameInstaller *createInstaller(Profile *profile);
|
2023-08-18 23:27:29 -04:00
|
|
|
Q_INVOKABLE CompatibilityToolInstaller *createCompatInstaller();
|
2023-07-30 08:49:34 -04:00
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] bool isLoadingFinished() const;
|
|
|
|
[[nodiscard]] bool hasAccount() const;
|
|
|
|
[[nodiscard]] bool isSteam() const;
|
|
|
|
[[nodiscard]] bool isSteamDeck() const;
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
Q_INVOKABLE void refreshNews();
|
2023-09-17 09:02:11 -04:00
|
|
|
[[nodiscard]] Headline *headline() const;
|
2023-07-30 08:49:34 -04:00
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
[[nodiscard]] Profile *currentProfile() const;
|
2023-09-16 20:12:01 -04:00
|
|
|
void setCurrentProfile(Profile *profile);
|
|
|
|
|
2023-10-08 13:22:49 -04:00
|
|
|
Q_INVOKABLE void clearAvatarCache();
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
signals:
|
|
|
|
void loadingFinished();
|
|
|
|
void gameInstallationChanged();
|
|
|
|
void accountChanged();
|
|
|
|
void settingsChanged();
|
|
|
|
void successfulLaunch();
|
|
|
|
void gameClosed();
|
|
|
|
void closeWhenLaunchedChanged();
|
2023-07-31 18:59:42 -04:00
|
|
|
void showNewsChanged();
|
2023-08-19 11:20:47 -04:00
|
|
|
void showDevToolsChanged();
|
2023-08-18 14:52:06 -04:00
|
|
|
void keepPatchesChanged();
|
2023-08-18 21:36:29 -04:00
|
|
|
void dalamudDistribServerChanged();
|
|
|
|
void squareEnixServerChanged();
|
|
|
|
void squareEnixLoginServerChanged();
|
2023-10-08 13:22:34 -04:00
|
|
|
void xivApiServerChanged();
|
2023-10-06 18:14:32 -04:00
|
|
|
void preferredProtocolChanged();
|
2023-10-08 13:18:05 -04:00
|
|
|
void encryptedArgumentsChanged();
|
2023-07-30 08:49:34 -04:00
|
|
|
void loginError(QString message);
|
|
|
|
void stageChanged(QString message);
|
2023-07-30 14:56:24 -04:00
|
|
|
void stageIndeterminate();
|
|
|
|
void stageDeterminate(int min, int max, int value);
|
2023-07-30 08:49:34 -04:00
|
|
|
void newsChanged();
|
2023-09-16 20:12:01 -04:00
|
|
|
void currentProfileChanged();
|
2023-09-17 19:20:41 -04:00
|
|
|
void autoLoginProfileChanged();
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
private:
|
2023-09-17 18:43:58 -04:00
|
|
|
QCoro::Task<> beginLogin(LoginInformation &info);
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
/*
|
|
|
|
* Begins the game executable, but calls to Dalamud if needed.
|
|
|
|
*/
|
2023-09-17 19:30:22 -04:00
|
|
|
void beginGameExecutable(Profile &settings, const LoginAuth &auth);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Starts a vanilla game session with no Dalamud injection.
|
|
|
|
*/
|
2023-09-17 19:30:22 -04:00
|
|
|
void beginVanillaGame(const QString &gameExecutablePath, Profile &profile, const LoginAuth &auth);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Starts a game session with Dalamud injected.
|
|
|
|
*/
|
2023-09-17 19:30:22 -04:00
|
|
|
void beginDalamudGame(const QString &gameExecutablePath, Profile &profile, const LoginAuth &auth);
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns the game arguments needed to properly launch the game. This encrypts it too if needed, and it's already
|
|
|
|
* joined!
|
|
|
|
*/
|
|
|
|
QString getGameArgs(const Profile &profile, const LoginAuth &auth);
|
|
|
|
|
|
|
|
bool checkIfInPath(const QString &program);
|
|
|
|
|
2023-09-16 18:37:42 -04:00
|
|
|
QCoro::Task<> fetchNews();
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
bool m_isSteam = false;
|
|
|
|
SteamAPI *m_steamApi = nullptr;
|
2023-07-30 08:49:34 -04:00
|
|
|
|
|
|
|
bool m_loadingFinished = false;
|
|
|
|
|
|
|
|
ProfileManager *m_profileManager = nullptr;
|
|
|
|
AccountManager *m_accountManager = nullptr;
|
|
|
|
|
2023-09-17 08:31:24 -04:00
|
|
|
SapphireLauncher *m_sapphireLauncher = nullptr;
|
|
|
|
SquareBoot *m_squareBoot = nullptr;
|
|
|
|
SquareLauncher *m_squareLauncher = nullptr;
|
|
|
|
|
2023-07-30 08:49:34 -04:00
|
|
|
Headline *m_headline = nullptr;
|
2023-10-08 17:51:18 -04:00
|
|
|
Config *m_config = nullptr;
|
2023-09-16 20:12:01 -04:00
|
|
|
|
|
|
|
int m_currentProfileIndex = 0;
|
2023-07-30 08:49:34 -04:00
|
|
|
};
|