2021-11-01 09:54:58 -04:00
|
|
|
#pragma once
|
|
|
|
|
2022-08-15 11:14:37 -04:00
|
|
|
#include <QFuture>
|
2021-11-01 09:54:58 -04:00
|
|
|
#include <QMainWindow>
|
2022-08-15 11:14:37 -04:00
|
|
|
#include <QMessageBox>
|
2021-11-01 09:54:58 -04:00
|
|
|
#include <QNetworkAccessManager>
|
2022-08-15 11:14:37 -04:00
|
|
|
#include <QProcess>
|
2021-11-01 09:54:58 -04:00
|
|
|
#include <QSettings>
|
2021-11-09 13:24:38 -05:00
|
|
|
#include <QUuid>
|
2022-06-08 13:55:15 -04:00
|
|
|
#include <QtQml>
|
|
|
|
|
|
|
|
#include "squareboot.h"
|
2022-09-05 15:43:15 -04:00
|
|
|
#include "steamapi.h"
|
2021-11-01 09:54:58 -04:00
|
|
|
|
|
|
|
class SapphireLauncher;
|
|
|
|
class SquareLauncher;
|
2021-11-23 14:37:37 -05:00
|
|
|
class AssetUpdater;
|
2021-12-06 21:15:31 -05:00
|
|
|
class Watchdog;
|
2021-11-01 09:54:58 -04:00
|
|
|
|
2022-03-16 09:59:27 -04:00
|
|
|
enum class GameLicense {
|
|
|
|
WindowsStandalone,
|
|
|
|
WindowsSteam,
|
2022-05-09 16:02:07 -04:00
|
|
|
macOS
|
2022-03-16 09:59:27 -04:00
|
|
|
};
|
|
|
|
|
2022-04-09 17:28:24 -04:00
|
|
|
enum class WineType {
|
|
|
|
System,
|
|
|
|
Custom,
|
2022-04-14 16:29:23 -04:00
|
|
|
Builtin, // macos only
|
|
|
|
XIVOnMac // macos only
|
2022-04-09 17:28:24 -04:00
|
|
|
};
|
|
|
|
|
2022-04-13 10:45:00 -04:00
|
|
|
enum class DalamudChannel {
|
|
|
|
Stable,
|
|
|
|
Staging,
|
|
|
|
Net5
|
|
|
|
};
|
|
|
|
|
2022-06-08 13:55:15 -04:00
|
|
|
class ProfileSettings : public QObject {
|
|
|
|
Q_OBJECT
|
|
|
|
QML_ELEMENT
|
|
|
|
public:
|
2021-11-09 13:24:38 -05:00
|
|
|
QUuid uuid;
|
2021-11-09 11:25:15 -05:00
|
|
|
QString name;
|
|
|
|
|
2021-11-09 21:13:21 -05:00
|
|
|
// game
|
2021-11-09 11:03:44 -05:00
|
|
|
int language = 1; // 1 is english, thats all i know
|
|
|
|
QString gamePath, winePath, winePrefixPath;
|
2022-08-09 23:18:18 -04:00
|
|
|
QString wineVersion;
|
2021-12-06 21:15:31 -05:00
|
|
|
bool enableWatchdog = false;
|
2021-11-09 13:04:22 -05:00
|
|
|
|
2022-08-09 22:44:10 -04:00
|
|
|
BootData* bootData;
|
|
|
|
GameData* gameData;
|
|
|
|
|
2022-08-09 23:18:18 -04:00
|
|
|
physis_Repositories repositories;
|
|
|
|
const char* bootVersion;
|
|
|
|
|
2022-04-09 16:56:17 -04:00
|
|
|
bool isGameInstalled() const {
|
2022-08-09 23:18:18 -04:00
|
|
|
return repositories.repositories_count > 0;
|
2022-04-09 16:56:17 -04:00
|
|
|
}
|
|
|
|
|
2022-04-09 17:28:24 -04:00
|
|
|
bool isWineInstalled() const {
|
|
|
|
return !wineVersion.isEmpty();
|
|
|
|
}
|
|
|
|
|
2021-11-10 05:18:59 -05:00
|
|
|
#if defined(Q_OS_MAC)
|
2022-04-09 17:28:24 -04:00
|
|
|
WineType wineType = WineType::Builtin;
|
2021-11-10 05:18:59 -05:00
|
|
|
#else
|
2022-04-09 17:28:24 -04:00
|
|
|
WineType wineType = WineType::System;
|
2021-11-10 05:18:59 -05:00
|
|
|
#endif
|
2022-04-09 17:28:24 -04:00
|
|
|
|
2021-11-09 13:52:36 -05:00
|
|
|
bool useEsync = false, useGamescope = false, useGamemode = false;
|
2021-11-09 11:03:44 -05:00
|
|
|
bool useDX9 = false;
|
|
|
|
bool enableDXVKhud = false;
|
2021-11-09 11:25:15 -05:00
|
|
|
|
2022-02-23 21:18:53 -05:00
|
|
|
struct GamescopeOptions {
|
|
|
|
bool fullscreen = true;
|
|
|
|
bool borderless = true;
|
|
|
|
int width = 0;
|
|
|
|
int height = 0;
|
|
|
|
int refreshRate = 0;
|
|
|
|
} gamescope;
|
|
|
|
|
2022-03-13 19:58:58 -04:00
|
|
|
struct DalamudOptions {
|
|
|
|
bool enabled = false;
|
|
|
|
bool optOutOfMbCollection = false;
|
2022-04-13 10:45:00 -04:00
|
|
|
DalamudChannel channel = DalamudChannel::Stable;
|
2022-03-13 19:58:58 -04:00
|
|
|
} dalamud;
|
|
|
|
|
2021-11-09 21:13:21 -05:00
|
|
|
// login
|
2022-01-27 11:17:45 -05:00
|
|
|
bool encryptArguments = true;
|
2021-11-09 11:25:15 -05:00
|
|
|
bool isSapphire = false;
|
|
|
|
QString lobbyURL;
|
2021-11-09 13:52:36 -05:00
|
|
|
bool rememberUsername = false, rememberPassword = false;
|
2022-08-31 17:27:30 -04:00
|
|
|
bool rememberOTPSecret = false;
|
2022-04-10 17:43:05 -04:00
|
|
|
bool useOneTimePassword = false;
|
2022-08-31 17:14:54 -04:00
|
|
|
bool autoLogin = false;
|
2022-03-16 09:59:27 -04:00
|
|
|
|
|
|
|
GameLicense license = GameLicense::WindowsStandalone;
|
2022-05-09 16:02:07 -04:00
|
|
|
bool isFreeTrial = false;
|
2021-11-09 11:03:44 -05:00
|
|
|
};
|
|
|
|
|
2022-02-24 09:10:00 -05:00
|
|
|
struct AppSettings {
|
|
|
|
bool closeWhenLaunched = true;
|
2022-04-10 16:58:29 -04:00
|
|
|
bool showBanners = true;
|
|
|
|
bool showNewsList = true;
|
2022-02-24 09:10:00 -05:00
|
|
|
};
|
|
|
|
|
2022-06-08 13:55:15 -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(ProfileSettings* settings MEMBER settings)
|
|
|
|
QML_ELEMENT
|
|
|
|
public:
|
2022-03-17 11:41:02 -04:00
|
|
|
ProfileSettings* settings = nullptr;
|
2021-11-23 15:34:23 -05:00
|
|
|
|
2021-11-01 09:54:58 -04:00
|
|
|
QString username, password, oneTimePassword;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LoginAuth {
|
|
|
|
QString SID;
|
|
|
|
int region = 2; // america?
|
|
|
|
int maxExpansion = 1;
|
|
|
|
|
|
|
|
// if empty, dont set on the client
|
|
|
|
QString lobbyhost, frontierHost;
|
|
|
|
};
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
class LauncherCore : public QObject {
|
2022-06-08 13:55:15 -04:00
|
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(SquareBoot* squareBoot MEMBER squareBoot)
|
2021-11-01 09:54:58 -04:00
|
|
|
public:
|
2021-11-23 15:34:23 -05:00
|
|
|
LauncherCore();
|
2021-11-01 09:54:58 -04:00
|
|
|
|
2022-06-08 13:55:15 -04:00
|
|
|
// used for qml only, TODO: move this to a dedicated factory
|
|
|
|
Q_INVOKABLE LoginInformation* createNewLoginInfo() {
|
|
|
|
return new LoginInformation();
|
|
|
|
}
|
|
|
|
|
2021-11-01 09:54:58 -04:00
|
|
|
QNetworkAccessManager* mgr;
|
|
|
|
|
2021-11-09 12:06:30 -05:00
|
|
|
ProfileSettings& getProfile(int index);
|
|
|
|
|
2022-06-08 13:55:15 -04:00
|
|
|
// used for qml only
|
|
|
|
Q_INVOKABLE ProfileSettings* getProfileQML(int index) {
|
|
|
|
return profileSettings[index];
|
|
|
|
}
|
|
|
|
|
2021-11-09 11:25:15 -05:00
|
|
|
int getProfileIndex(QString name);
|
2022-06-08 13:55:15 -04:00
|
|
|
Q_INVOKABLE QList<QString> profileList() const;
|
2021-11-09 11:44:27 -05:00
|
|
|
int addProfile();
|
2021-11-09 13:44:37 -05:00
|
|
|
int deleteProfile(QString name);
|
2021-11-01 14:35:32 -04:00
|
|
|
|
2022-09-05 16:05:39 -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.
|
|
|
|
*/
|
|
|
|
void login(LoginInformation& loginInformation);
|
|
|
|
|
2022-09-05 16:14:07 -04:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
bool autoLogin(ProfileSettings& settings);
|
|
|
|
|
2022-09-05 15:59:00 -04:00
|
|
|
/*
|
|
|
|
* Launches the game using the provided authentication.
|
|
|
|
*/
|
|
|
|
void launchGame(const ProfileSettings& settings, const LoginAuth& auth);
|
2022-02-25 20:20:52 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This just wraps it in wine if needed.
|
|
|
|
*/
|
2022-08-15 11:14:37 -04:00
|
|
|
void launchExecutable(
|
|
|
|
const ProfileSettings& settings,
|
|
|
|
QProcess* process,
|
|
|
|
QStringList args,
|
|
|
|
bool isGame,
|
|
|
|
bool needsRegistrySetup);
|
2022-04-09 17:53:43 -04:00
|
|
|
|
2022-04-14 17:48:06 -04:00
|
|
|
void addRegistryKey(const ProfileSettings& settings, QString key, QString value, QString data);
|
|
|
|
|
2022-03-16 15:03:35 -04:00
|
|
|
void buildRequest(const ProfileSettings& settings, QNetworkRequest& request);
|
2021-11-01 09:54:58 -04:00
|
|
|
void setSSL(QNetworkRequest& request);
|
2021-11-02 08:27:00 -04:00
|
|
|
void readInitialInformation();
|
2021-11-09 13:11:21 -05:00
|
|
|
void readGameVersion();
|
2021-11-10 04:30:01 -05:00
|
|
|
void readWineInfo(ProfileSettings& settings);
|
2021-11-09 12:16:14 -05:00
|
|
|
void saveSettings();
|
2021-11-01 09:54:58 -04:00
|
|
|
|
2021-11-01 14:35:32 -04:00
|
|
|
QSettings settings;
|
|
|
|
|
2021-11-01 09:54:58 -04:00
|
|
|
SapphireLauncher* sapphireLauncher;
|
|
|
|
SquareBoot* squareBoot;
|
|
|
|
SquareLauncher* squareLauncher;
|
2021-11-23 14:37:37 -05:00
|
|
|
AssetUpdater* assetUpdater;
|
2021-12-06 21:15:31 -05:00
|
|
|
Watchdog* watchdog;
|
2021-11-09 11:03:44 -05:00
|
|
|
|
2022-02-24 08:35:31 -05:00
|
|
|
bool gamescopeAvailable = false;
|
|
|
|
bool gamemodeAvailable = false;
|
|
|
|
|
2022-02-24 09:10:00 -05:00
|
|
|
AppSettings appSettings;
|
|
|
|
|
2022-02-25 22:25:21 -05:00
|
|
|
QString dalamudVersion;
|
|
|
|
int dalamudAssetVersion = -1;
|
|
|
|
QString runtimeVersion;
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
int defaultProfileIndex = 0;
|
2022-05-09 15:04:56 -04:00
|
|
|
|
|
|
|
QVector<QString> expansionNames;
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
signals:
|
|
|
|
void settingsChanged();
|
2022-02-24 09:10:00 -05:00
|
|
|
void successfulLaunch();
|
|
|
|
void gameClosed();
|
2021-11-09 12:25:54 -05:00
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
private:
|
2022-09-05 16:51:46 -04:00
|
|
|
/*
|
|
|
|
* Begins the game executable, but calls to Dalamud if needed.
|
|
|
|
*/
|
2022-09-05 15:59:00 -04:00
|
|
|
void beginGameExecutable(const ProfileSettings& settings, const LoginAuth& auth);
|
2022-09-05 16:51:46 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Starts a vanilla game session with no Dalamud injection.
|
|
|
|
*/
|
|
|
|
void beginVanillaGame(const QString& gameExecutablePath, const ProfileSettings& profile, const LoginAuth& auth);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Starts a game session with Dalamud injected.
|
|
|
|
*/
|
|
|
|
void beginDalamudGame(const QString& gameExecutablePath, const ProfileSettings& profile, const LoginAuth& auth);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns the game arguments needed to properly launch the game. This encrypts it too if needed, and it's already
|
|
|
|
* joined!
|
|
|
|
*/
|
|
|
|
QString getGameArgs(const ProfileSettings& profile, const LoginAuth& auth);
|
|
|
|
|
2022-02-24 08:35:31 -05:00
|
|
|
bool checkIfInPath(QString program);
|
2022-05-09 15:04:56 -04:00
|
|
|
void readGameData(ProfileSettings& profile);
|
2021-12-02 15:02:59 -05:00
|
|
|
|
2022-02-25 20:37:38 -05:00
|
|
|
QString getDefaultGamePath();
|
|
|
|
QString getDefaultWinePrefixPath();
|
|
|
|
|
2022-06-08 13:55:15 -04:00
|
|
|
QVector<ProfileSettings*> profileSettings;
|
2022-09-05 15:43:15 -04:00
|
|
|
|
|
|
|
SteamAPI* steamApi = nullptr;
|
2021-11-01 09:54:58 -04:00
|
|
|
};
|