1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-26 14:17:45 +00:00

Use KConfig's own class instead of "proxying" it in Profile

This will make it trivial to add more profile settings in the future.
This commit is contained in:
Joshua Goins 2025-03-17 18:44:36 -04:00
parent da3084266c
commit 79bd032322
19 changed files with 171 additions and 477 deletions

View file

@ -92,7 +92,7 @@ target_link_libraries(astra_static PUBLIC
QCoro::Qml) QCoro::Qml)
kconfig_target_kcfg_file(astra_static FILE config.kcfg CLASS_NAME Config MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE USE_ENUM_TYPES) kconfig_target_kcfg_file(astra_static FILE config.kcfg CLASS_NAME Config MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE USE_ENUM_TYPES)
kconfig_target_kcfg_file(astra_static FILE accountconfig.kcfg CLASS_NAME AccountConfig MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE USE_ENUM_TYPES) kconfig_target_kcfg_file(astra_static FILE accountconfig.kcfg CLASS_NAME AccountConfig MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE USE_ENUM_TYPES)
kconfig_target_kcfg_file(astra_static FILE profileconfig.kcfg CLASS_NAME ProfileConfig MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE) kconfig_target_kcfg_file(astra_static FILE profileconfig.kcfg CLASS_NAME ProfileConfig MUTATORS GENERATE_PROPERTIES GENERATE_MOC DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR QML_REGISTRATION QML_UNCREATABLE USE_ENUM_TYPES)
target_include_directories(astra_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}) target_include_directories(astra_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_BINARY_DIR})
if (NOT MSVC) if (NOT MSVC)

View file

@ -16,105 +16,47 @@ class Profile : public QObject
QML_ELEMENT QML_ELEMENT
QML_UNCREATABLE("Use from ProfileManager") QML_UNCREATABLE("Use from ProfileManager")
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString gamePath READ gamePath WRITE setGamePath NOTIFY gamePathChanged)
Q_PROPERTY(QString winePath READ winePath WRITE setWinePath NOTIFY winePathChanged) Q_PROPERTY(QString winePath READ winePath WRITE setWinePath NOTIFY winePathChanged)
Q_PROPERTY(QString winePrefixPath READ winePrefixPath WRITE setWinePrefixPath NOTIFY winePrefixPathChanged) Q_PROPERTY(bool hasDirectx9 READ hasDirectx9 NOTIFY hasDirectx9Changed)
Q_PROPERTY(WineType wineType READ wineType WRITE setWineType NOTIFY wineTypeChanged)
Q_PROPERTY(bool gamescopeEnabled READ gamescopeEnabled WRITE setGamescopeEnabled NOTIFY useGamescopeChanged)
Q_PROPERTY(bool gamemodeEnabled READ gamemodeEnabled WRITE setGamemodeEnabled NOTIFY useGamemodeChanged)
Q_PROPERTY(bool directx9Enabled READ directx9Enabled WRITE setDirectX9Enabled NOTIFY useDX9Changed)
Q_PROPERTY(bool hasDirectx9 READ hasDirectx9 NOTIFY gamePathChanged)
Q_PROPERTY(bool gamescopeFullscreen READ gamescopeFullscreen WRITE setGamescopeFullscreen NOTIFY gamescopeFullscreenChanged)
Q_PROPERTY(bool gamescopeBorderless READ gamescopeBorderless WRITE setGamescopeBorderless NOTIFY gamescopeBorderlessChanged)
Q_PROPERTY(int gamescopeWidth READ gamescopeWidth WRITE setGamescopeWidth NOTIFY gamescopeWidthChanged)
Q_PROPERTY(int gamescopeHeight READ gamescopeHeight WRITE setGamescopeHeight NOTIFY gamescopeHeightChanged)
Q_PROPERTY(int gamescopeRefreshRate READ gamescopeRefreshRate WRITE setGamescopeRefreshRate NOTIFY gamescopeRefreshRateChanged)
Q_PROPERTY(bool dalamudEnabled READ dalamudEnabled WRITE setDalamudEnabled NOTIFY dalamudEnabledChanged)
Q_PROPERTY(DalamudInjectMethod dalamudInjectMethod READ dalamudInjectMethod WRITE setDalamudInjectMethod NOTIFY dalamudInjectMethodChanged)
Q_PROPERTY(int dalamudInjectDelay READ dalamudInjectDelay WRITE setDalamudInjectDelay NOTIFY dalamudInjectDelayChanged)
Q_PROPERTY(DalamudChannel dalamudChannel READ dalamudChannel WRITE setDalamudChannel NOTIFY dalamudChannelChanged)
Q_PROPERTY(bool isGameInstalled READ isGameInstalled NOTIFY gameInstallChanged) Q_PROPERTY(bool isGameInstalled READ isGameInstalled NOTIFY gameInstallChanged)
Q_PROPERTY(Account *account READ account WRITE setAccount NOTIFY accountChanged) Q_PROPERTY(Account *account READ account WRITE setAccount NOTIFY accountChanged)
Q_PROPERTY(QString expansionVersionText READ expansionVersionText NOTIFY gameInstallChanged) Q_PROPERTY(QString expansionVersionText READ expansionVersionText NOTIFY gameInstallChanged)
Q_PROPERTY(QString dalamudVersionText READ dalamudVersionText NOTIFY gameInstallChanged) Q_PROPERTY(QString dalamudVersionText READ dalamudVersionText NOTIFY gameInstallChanged)
Q_PROPERTY(QString wineVersionText READ wineVersionText NOTIFY wineChanged) Q_PROPERTY(QString wineVersionText READ wineVersionText NOTIFY wineChanged)
Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged) Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged)
Q_PROPERTY(bool isBenchmark READ isBenchmark WRITE setIsBenchmark NOTIFY isBenchmarkChanged)
Q_PROPERTY(QString subtitle READ subtitle NOTIFY gameInstallChanged) Q_PROPERTY(QString subtitle READ subtitle NOTIFY gameInstallChanged)
Q_PROPERTY(ProfileConfig *config READ config CONSTANT)
public: public:
explicit Profile(const QString &key, QObject *parent = nullptr); explicit Profile(const QString &key, QObject *parent = nullptr);
enum class WineType { BuiltIn, Custom }; enum WineType {
BuiltIn,
Custom
};
Q_ENUM(WineType) Q_ENUM(WineType)
enum class DalamudChannel { Stable, Staging, Local }; enum DalamudChannel {
Stable,
Staging,
Local
};
Q_ENUM(DalamudChannel) Q_ENUM(DalamudChannel)
enum class DalamudInjectMethod { Entrypoint, DLLInject }; enum DalamudInjectMethod {
Entrypoint,
DLLInject
};
Q_ENUM(DalamudInjectMethod) Q_ENUM(DalamudInjectMethod)
[[nodiscard]] QString uuid() const; [[nodiscard]] QString uuid() const;
[[nodiscard]] QString name() const;
void setName(const QString &name);
[[nodiscard]] QString gamePath() const;
void setGamePath(const QString &path);
[[nodiscard]] QString winePath() const; [[nodiscard]] QString winePath() const;
void setWinePath(const QString &path); void setWinePath(const QString &path);
[[nodiscard]] QString winePrefixPath() const;
void setWinePrefixPath(const QString &path);
[[nodiscard]] WineType wineType() const;
void setWineType(WineType type);
[[nodiscard]] bool gamescopeEnabled() const;
void setGamescopeEnabled(bool value);
[[nodiscard]] bool gamemodeEnabled() const;
void setGamemodeEnabled(bool value);
[[nodiscard]] bool directx9Enabled() const;
void setDirectX9Enabled(bool value);
[[nodiscard]] bool hasDirectx9() const; [[nodiscard]] bool hasDirectx9() const;
[[nodiscard]] bool gamescopeFullscreen() const;
void setGamescopeFullscreen(bool value);
[[nodiscard]] bool gamescopeBorderless() const;
void setGamescopeBorderless(bool value);
[[nodiscard]] int gamescopeWidth() const;
void setGamescopeWidth(int value);
[[nodiscard]] int gamescopeHeight() const;
void setGamescopeHeight(int value);
[[nodiscard]] int gamescopeRefreshRate() const;
void setGamescopeRefreshRate(int value);
[[nodiscard]] bool dalamudEnabled() const;
void setDalamudEnabled(bool value);
[[nodiscard]] DalamudChannel dalamudChannel() const;
void setDalamudChannel(DalamudChannel channel);
[[nodiscard]] DalamudInjectMethod dalamudInjectMethod() const;
void setDalamudInjectMethod(DalamudInjectMethod value);
[[nodiscard]] int dalamudInjectDelay() const;
void setDalamudInjectDelay(int value);
[[nodiscard]] bool isBenchmark() const;
void setIsBenchmark(bool value);
[[nodiscard]] Account *account() const; [[nodiscard]] Account *account() const;
[[nodiscard]] QString accountUuid() const;
void setAccount(Account *account); void setAccount(Account *account);
void readGameVersion(); void readGameVersion();
@ -161,29 +103,15 @@ public:
[[nodiscard]] QString subtitle() const; [[nodiscard]] QString subtitle() const;
ProfileConfig *config() const;
Q_SIGNALS: Q_SIGNALS:
void gameInstallChanged(); void gameInstallChanged();
void nameChanged();
void gamePathChanged();
void winePathChanged(); void winePathChanged();
void winePrefixPathChanged();
void wineTypeChanged();
void useGamescopeChanged();
void useGamemodeChanged();
void useDX9Changed();
void gamescopeFullscreenChanged();
void gamescopeBorderlessChanged();
void gamescopeWidthChanged();
void gamescopeHeightChanged();
void gamescopeRefreshRateChanged();
void dalamudEnabledChanged();
void dalamudChannelChanged();
void dalamudInjectMethodChanged();
void dalamudInjectDelayChanged();
void isBenchmarkChanged();
void accountChanged(); void accountChanged();
void wineChanged(); void wineChanged();
void loggedInChanged(); void loggedInChanged();
void hasDirectx9Changed();
private: private:
void readGameData(); void readGameData();
@ -212,4 +140,4 @@ private:
QString m_frontierUrl; QString m_frontierUrl;
bool m_loggedIn = false; bool m_loggedIn = false;
}; };

View file

@ -11,6 +11,7 @@ SPDX-License-Identifier: CC0-1.0
<kcfgfile name="astrastaterc" stateConfig="true"> <kcfgfile name="astrastaterc" stateConfig="true">
<parameter name="uuid"/> <parameter name="uuid"/>
</kcfgfile> </kcfgfile>
<include>profile.h</include>
<group name="profile-$(uuid)"> <group name="profile-$(uuid)">
<entry key="Name" type="string"> <entry key="Name" type="string">
</entry> </entry>
@ -25,7 +26,7 @@ SPDX-License-Identifier: CC0-1.0
<default code="true">ProfileManager::getDefaultWinePrefixPath(mParamuuid)</default> <default code="true">ProfileManager::getDefaultWinePrefixPath(mParamuuid)</default>
</entry> </entry>
<entry key="WineType" type="Enum"> <entry key="WineType" type="Enum">
<choices> <choices name="Profile::WineType">
<choice name="BuiltIn"> <choice name="BuiltIn">
</choice> </choice>
<choice name="Custom"> <choice name="Custom">
@ -61,7 +62,7 @@ SPDX-License-Identifier: CC0-1.0
<default>false</default> <default>false</default>
</entry> </entry>
<entry key="DalamudChannel" type="Enum"> <entry key="DalamudChannel" type="Enum">
<choices> <choices name="Profile::DalamudChannel">
<choice name="Stable"> <choice name="Stable">
</choice> </choice>
<choice name="Staging"> <choice name="Staging">
@ -72,7 +73,7 @@ SPDX-License-Identifier: CC0-1.0
<default>Stable</default> <default>Stable</default>
</entry> </entry>
<entry key="DalamudInjectMethod" type="Enum"> <entry key="DalamudInjectMethod" type="Enum">
<choices> <choices name="Profile::DalamudInjectMethod">
<choice name="Entrypoint"> <choice name="Entrypoint">
</choice> </choice>
<choice name="DLLInject"> <choice name="DLLInject">

View file

@ -3,6 +3,7 @@
#include "assetupdater.h" #include "assetupdater.h"
#include "astra_log.h" #include "astra_log.h"
#include "profileconfig.h"
#include "utility.h" #include "utility.h"
#include <KLocalizedString> #include <KLocalizedString>
@ -15,8 +16,6 @@
#include <qcorofuture.h> #include <qcorofuture.h>
#include <qcoronetworkreply.h> #include <qcoronetworkreply.h>
#include <QtConcurrentRun>
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
AssetUpdater::AssetUpdater(Profile &profile, LauncherCore &launcher, QObject *parent) AssetUpdater::AssetUpdater(Profile &profile, LauncherCore &launcher, QObject *parent)
@ -40,17 +39,17 @@ QCoro::Task<bool> AssetUpdater::update()
Utility::createPathIfNeeded(m_wineDir); Utility::createPathIfNeeded(m_wineDir);
Utility::createPathIfNeeded(m_dxvkDir); Utility::createPathIfNeeded(m_dxvkDir);
if (m_profile.wineType() == Profile::WineType::BuiltIn && !co_await checkRemoteCompatibilityToolVersion()) { if (m_profile.config()->wineType() == Profile::WineType::BuiltIn && !co_await checkRemoteCompatibilityToolVersion()) {
co_return false; co_return false;
} }
// TODO: should DXVK be tied to this setting...? // TODO: should DXVK be tied to this setting...?
if (m_profile.wineType() == Profile::WineType::BuiltIn && !co_await checkRemoteDxvkVersion()) { if (m_profile.config()->wineType() == Profile::WineType::BuiltIn && !co_await checkRemoteDxvkVersion()) {
co_return false; co_return false;
} }
} }
if (!m_profile.dalamudEnabled()) { if (!m_profile.config()->dalamudEnabled()) {
co_return true; co_return true;
} }
@ -65,7 +64,7 @@ QCoro::Task<bool> AssetUpdater::update()
Utility::createPathIfNeeded(m_dalamudAssetDir); Utility::createPathIfNeeded(m_dalamudAssetDir);
Utility::createPathIfNeeded(m_dalamudRuntimeDir); Utility::createPathIfNeeded(m_dalamudRuntimeDir);
if (m_profile.dalamudChannel() != Profile::DalamudChannel::Local) { if (m_profile.config()->dalamudChannel() != Profile::DalamudChannel::Local) {
if (!co_await checkRemoteDalamudAssetVersion()) { if (!co_await checkRemoteDalamudAssetVersion()) {
co_return false; co_return false;
} }

View file

@ -10,6 +10,7 @@
#include "astra_log.h" #include "astra_log.h"
#include "launchercore.h" #include "launchercore.h"
#include "profile.h" #include "profile.h"
#include "profileconfig.h"
#include "utility.h" #include "utility.h"
// TODO: this should be dynamically grabbed from the webpage to avoid hardcoding it // TODO: this should be dynamically grabbed from the webpage to avoid hardcoding it
@ -62,7 +63,7 @@ void BenchmarkInstaller::start()
void BenchmarkInstaller::installGame() void BenchmarkInstaller::installGame()
{ {
const QDir installDirectory = m_profile.gamePath(); const QDir installDirectory = m_profile.config()->gamePath();
KZip archive(m_localInstallerPath); KZip archive(m_localInstallerPath);
if (!archive.open(QIODevice::ReadOnly)) { if (!archive.open(QIODevice::ReadOnly)) {
@ -83,4 +84,4 @@ void BenchmarkInstaller::installGame()
qInfo(ASTRA_LOG) << "Installed game in" << installDirectory; qInfo(ASTRA_LOG) << "Installed game in" << installDirectory;
} }
#include "moc_benchmarkinstaller.cpp" #include "moc_benchmarkinstaller.cpp"

View file

@ -12,6 +12,7 @@
#include "astra_log.h" #include "astra_log.h"
#include "launchercore.h" #include "launchercore.h"
#include "profile.h" #include "profile.h"
#include "profileconfig.h"
#include "utility.h" #include "utility.h"
const auto installerUrl = QStringLiteral("https://download.finalfantasyxiv.com/inst/ffxivsetup.exe"); const auto installerUrl = QStringLiteral("https://download.finalfantasyxiv.com/inst/ffxivsetup.exe");
@ -70,7 +71,7 @@ void GameInstaller::start()
void GameInstaller::installGame() void GameInstaller::installGame()
{ {
const QDir installDirectory = m_profile.gamePath(); const QDir installDirectory = m_profile.config()->gamePath();
const std::string installDirectoryStd = installDirectory.absolutePath().toStdString(); const std::string installDirectoryStd = installDirectory.absolutePath().toStdString();
const std::string fileNameStd = m_localInstallerPath.toStdString(); const std::string fileNameStd = m_localInstallerPath.toStdString();
@ -83,4 +84,4 @@ void GameInstaller::installGame()
qInfo(ASTRA_LOG) << "Installed game in" << installDirectory; qInfo(ASTRA_LOG) << "Installed game in" << installDirectory;
} }
#include "moc_gameinstaller.cpp" #include "moc_gameinstaller.cpp"

View file

@ -13,6 +13,7 @@
#include "launchercore.h" #include "launchercore.h"
#include "processlogger.h" #include "processlogger.h"
#include "processwatcher.h" #include "processwatcher.h"
#include "profileconfig.h"
#include "utility.h" #include "utility.h"
#include <KProcessList> #include <KProcessList>
@ -28,10 +29,10 @@ GameRunner::GameRunner(LauncherCore &launcher, QObject *parent)
void GameRunner::beginGameExecutable(Profile &profile, const std::optional<LoginAuth> &auth) void GameRunner::beginGameExecutable(Profile &profile, const std::optional<LoginAuth> &auth)
{ {
QString gameExectuable; QString gameExectuable;
if (profile.directx9Enabled() && profile.hasDirectx9()) { if (profile.config()->useDX9() && profile.hasDirectx9()) {
gameExectuable = profile.gamePath() + QStringLiteral("/game/ffxiv.exe"); gameExectuable = profile.config()->gamePath() + QStringLiteral("/game/ffxiv.exe");
} else { } else {
gameExectuable = profile.gamePath() + QStringLiteral("/game/ffxiv_dx11.exe"); gameExectuable = profile.config()->gamePath() + QStringLiteral("/game/ffxiv_dx11.exe");
} }
if (profile.dalamudShouldLaunch()) { if (profile.dalamudShouldLaunch()) {
@ -147,30 +148,31 @@ void GameRunner::beginDalamudGame(const QString &gameExecutablePath, Profile &pr
const auto args = getGameArgs(profile, auth); const auto args = getGameArgs(profile, auth);
launchExecutable(profile, launchExecutable(
dalamudProcess, profile,
{Utility::toWindowsPath(dalamudInjector), dalamudProcess,
QStringLiteral("launch"), {Utility::toWindowsPath(dalamudInjector),
QStringLiteral("-m"), QStringLiteral("launch"),
profile.dalamudInjectMethod() == Profile::DalamudInjectMethod::Entrypoint ? QStringLiteral("entrypoint") : QStringLiteral("inject"), QStringLiteral("-m"),
QStringLiteral("--game=") + Utility::toWindowsPath(gameExecutablePath), profile.config()->dalamudInjectMethod() == Profile::DalamudInjectMethod::Entrypoint ? QStringLiteral("entrypoint") : QStringLiteral("inject"),
QStringLiteral("--dalamud-configuration-path=") + Utility::toWindowsPath(dalamudConfigPath), QStringLiteral("--game=") + Utility::toWindowsPath(gameExecutablePath),
QStringLiteral("--dalamud-plugin-directory=") + Utility::toWindowsPath(dalamudPluginDir), QStringLiteral("--dalamud-configuration-path=") + Utility::toWindowsPath(dalamudConfigPath),
QStringLiteral("--dalamud-asset-directory=") + Utility::toWindowsPath(dalamudAssetDir), QStringLiteral("--dalamud-plugin-directory=") + Utility::toWindowsPath(dalamudPluginDir),
QStringLiteral("--dalamud-client-language=") + QString::number(profile.account()->config()->language()), QStringLiteral("--dalamud-asset-directory=") + Utility::toWindowsPath(dalamudAssetDir),
QStringLiteral("--dalamud-delay-initialize=") + QString::number(profile.dalamudInjectDelay()), QStringLiteral("--dalamud-client-language=") + QString::number(profile.account()->config()->language()),
QStringLiteral("--logpath=") + Utility::toWindowsPath(logDir), QStringLiteral("--dalamud-delay-initialize=") + QString::number(profile.config()->dalamudInjectDelay()),
QStringLiteral("--"), QStringLiteral("--logpath=") + Utility::toWindowsPath(logDir),
args}, QStringLiteral("--"),
true, args},
true); true,
true);
} }
QString GameRunner::getGameArgs(const Profile &profile, const std::optional<LoginAuth> &auth) const QString GameRunner::getGameArgs(const Profile &profile, const std::optional<LoginAuth> &auth) const
{ {
QList<std::pair<QString, QString>> gameArgs; QList<std::pair<QString, QString>> gameArgs;
if (profile.isBenchmark()) { if (profile.config()->isBenchmark()) {
gameArgs.push_back({QStringLiteral("SYS.Language"), QString::number(1)}); gameArgs.push_back({QStringLiteral("SYS.Language"), QString::number(1)});
gameArgs.push_back({QStringLiteral("SYS.Fps"), QString::number(0)}); gameArgs.push_back({QStringLiteral("SYS.Fps"), QString::number(0)});
gameArgs.push_back({QStringLiteral("SYS.WaterWet_DX11"), QString::number(1)}); gameArgs.push_back({QStringLiteral("SYS.WaterWet_DX11"), QString::number(1)});
@ -226,7 +228,7 @@ QString GameRunner::getGameArgs(const Profile &profile, const std::optional<Logi
// FIXME: this should belong somewhere else... // FIXME: this should belong somewhere else...
if (LauncherCore::needsCompatibilityTool()) if (LauncherCore::needsCompatibilityTool())
Utility::createPathIfNeeded(profile.winePrefixPath()); Utility::createPathIfNeeded(profile.config()->winePrefixPath());
if (auth) { if (auth) {
if (!auth->lobbyHost.isEmpty()) { if (!auth->lobbyHost.isEmpty()) {
@ -242,14 +244,15 @@ QString GameRunner::getGameArgs(const Profile &profile, const std::optional<Logi
} }
} }
const QString argFormat = !profile.isBenchmark() && m_launcher.config()->encryptArguments() ? QStringLiteral(" /%1 =%2") : QStringLiteral(" %1=%2"); const QString argFormat =
!profile.config()->isBenchmark() && m_launcher.config()->encryptArguments() ? QStringLiteral(" /%1 =%2") : QStringLiteral(" %1=%2");
QString argJoined; QString argJoined;
for (const auto &[key, value] : gameArgs) { for (const auto &[key, value] : gameArgs) {
argJoined += argFormat.arg(key, value); argJoined += argFormat.arg(key, value);
} }
return !profile.isBenchmark() && m_launcher.config()->encryptArguments() ? encryptGameArg(argJoined) : argJoined; return !profile.config()->isBenchmark() && m_launcher.config()->encryptArguments() ? encryptGameArg(argJoined) : argJoined;
} }
void GameRunner::launchExecutable(const Profile &profile, QProcess *process, const QStringList &args, bool isGame, bool needsRegistrySetup) void GameRunner::launchExecutable(const Profile &profile, QProcess *process, const QStringList &args, bool isGame, bool needsRegistrySetup)
@ -260,7 +263,7 @@ void GameRunner::launchExecutable(const Profile &profile, QProcess *process, con
if (needsRegistrySetup) { if (needsRegistrySetup) {
#if defined(Q_OS_LINUX) || defined(Q_OS_MAC) #if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
// FFXIV detects this as a "macOS" build by checking if Wine shows up // FFXIV detects this as a "macOS" build by checking if Wine shows up
if (!profile.isBenchmark()) { if (!profile.config()->isBenchmark()) {
const int value = profile.account()->config()->license() == Account::GameLicense::macOS ? 0 : 1; const int value = profile.account()->config()->license() == Account::GameLicense::macOS ? 0 : 1;
addRegistryKey(profile, QStringLiteral("HKEY_CURRENT_USER\\Software\\Wine"), QStringLiteral("HideWineExports"), QString::number(value)); addRegistryKey(profile, QStringLiteral("HKEY_CURRENT_USER\\Software\\Wine"), QStringLiteral("HideWineExports"), QString::number(value));
} }
@ -276,7 +279,7 @@ void GameRunner::launchExecutable(const Profile &profile, QProcess *process, con
const QDir dxvkDir = compatibilityToolDir.absoluteFilePath(QStringLiteral("dxvk")); const QDir dxvkDir = compatibilityToolDir.absoluteFilePath(QStringLiteral("dxvk"));
const QDir dxvk64Dir = dxvkDir.absoluteFilePath(QStringLiteral("x64")); const QDir dxvk64Dir = dxvkDir.absoluteFilePath(QStringLiteral("x64"));
const QDir winePrefix = profile.winePrefixPath(); const QDir winePrefix = profile.config()->winePrefixPath();
const QDir driveC = winePrefix.absoluteFilePath(QStringLiteral("drive_c")); const QDir driveC = winePrefix.absoluteFilePath(QStringLiteral("drive_c"));
const QDir windows = driveC.absoluteFilePath(QStringLiteral("windows")); const QDir windows = driveC.absoluteFilePath(QStringLiteral("windows"));
const QDir system32 = windows.absoluteFilePath(QStringLiteral("system32")); const QDir system32 = windows.absoluteFilePath(QStringLiteral("system32"));
@ -290,35 +293,35 @@ void GameRunner::launchExecutable(const Profile &profile, QProcess *process, con
#endif #endif
} }
if (isGame && profile.gamescopeEnabled()) { if (isGame && profile.config()->useGamescope()) {
arguments.push_back(QStringLiteral("gamescope")); arguments.push_back(QStringLiteral("gamescope"));
if (profile.gamescopeFullscreen()) if (profile.config()->gamescopeFullscreen())
arguments.push_back(QStringLiteral("-f")); arguments.push_back(QStringLiteral("-f"));
if (profile.gamescopeBorderless()) if (profile.config()->gamescopeBorderless())
arguments.push_back(QStringLiteral("-b")); arguments.push_back(QStringLiteral("-b"));
if (profile.gamescopeWidth() > 0) { if (profile.config()->gamescopeWidth() > 0) {
arguments.push_back(QStringLiteral("-w")); arguments.push_back(QStringLiteral("-w"));
arguments.push_back(QString::number(profile.gamescopeWidth())); arguments.push_back(QString::number(profile.config()->gamescopeWidth()));
} }
if (profile.gamescopeHeight() > 0) { if (profile.config()->gamescopeHeight() > 0) {
arguments.push_back(QStringLiteral("-h")); arguments.push_back(QStringLiteral("-h"));
arguments.push_back(QString::number(profile.gamescopeHeight())); arguments.push_back(QString::number(profile.config()->gamescopeHeight()));
} }
if (profile.gamescopeRefreshRate() > 0) { if (profile.config()->gamescopeRefreshRate() > 0) {
arguments.push_back(QStringLiteral("-r")); arguments.push_back(QStringLiteral("-r"));
arguments.push_back(QString::number(profile.gamescopeRefreshRate())); arguments.push_back(QString::number(profile.config()->gamescopeRefreshRate()));
} }
arguments.push_back(QStringLiteral("--")); arguments.push_back(QStringLiteral("--"));
} }
#ifdef ENABLE_GAMEMODE #ifdef ENABLE_GAMEMODE
if (isGame && profile.gamemodeEnabled()) { if (isGame && profile.config()->useGamemode()) {
gamemode_request_start(); gamemode_request_start();
} }
#endif #endif
@ -340,16 +343,16 @@ void GameRunner::launchExecutable(const Profile &profile, QProcess *process, con
#endif #endif
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX) #if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
env.insert(QStringLiteral("WINEPREFIX"), profile.winePrefixPath()); env.insert(QStringLiteral("WINEPREFIX"), profile.config()->winePrefixPath());
if (profile.wineType() == Profile::WineType::BuiltIn) { if (profile.config()->wineType() == Profile::WineType::BuiltIn) {
env.insert(QStringLiteral("WINEDLLOVERRIDES"), QStringLiteral("msquic=,mscoree=n,b;d3d9,d3d11,d3d10core,dxgi=n,b")); env.insert(QStringLiteral("WINEDLLOVERRIDES"), QStringLiteral("msquic=,mscoree=n,b;d3d9,d3d11,d3d10core,dxgi=n,b"));
} }
arguments.push_back(profile.winePath()); arguments.push_back(profile.winePath());
#endif #endif
if (!profile.isBenchmark() && profile.account()->config()->license() == Account::GameLicense::WindowsSteam) { if (!profile.config()->isBenchmark() && profile.account()->config()->license() == Account::GameLicense::WindowsSteam) {
env.insert(QStringLiteral("IS_FFXIV_LAUNCH_FROM_STEAM"), QStringLiteral("1")); env.insert(QStringLiteral("IS_FFXIV_LAUNCH_FROM_STEAM"), QStringLiteral("1"));
} }
@ -358,11 +361,11 @@ void GameRunner::launchExecutable(const Profile &profile, QProcess *process, con
const QString executable = arguments.takeFirst(); const QString executable = arguments.takeFirst();
if (isGame) { if (isGame) {
if (profile.isBenchmark()) { if (profile.config()->isBenchmark()) {
// Benchmarks usually have some data located in the root // Benchmarks usually have some data located in the root
process->setWorkingDirectory(profile.gamePath()); process->setWorkingDirectory(profile.config()->gamePath());
} else { } else {
process->setWorkingDirectory(profile.gamePath() + QStringLiteral("/game/")); process->setWorkingDirectory(profile.config()->gamePath() + QStringLiteral("/game/"));
} }
} }

View file

@ -19,6 +19,7 @@
#include "compatibilitytoolinstaller.h" #include "compatibilitytoolinstaller.h"
#include "gamerunner.h" #include "gamerunner.h"
#include "launchercore.h" #include "launchercore.h"
#include "profileconfig.h"
#include "sapphirelogin.h" #include "sapphirelogin.h"
#include "squareenixlogin.h" #include "squareenixlogin.h"
#include "utility.h" #include "utility.h"
@ -61,7 +62,7 @@ LauncherCore::LauncherCore()
// restore profile -> account connections // restore profile -> account connections
for (const auto profile : m_profileManager->profiles()) { for (const auto profile : m_profileManager->profiles()) {
if (const auto account = m_accountManager->getByUuid(profile->accountUuid())) { if (const auto account = m_accountManager->getByUuid(profile->config()->account())) {
profile->setAccount(account); profile->setAccount(account);
} }
} }
@ -96,7 +97,7 @@ void LauncherCore::login(Profile *profile, const QString &username, const QStrin
loginInformation->profile = profile; loginInformation->profile = profile;
// Benchmark never has to login, of course // Benchmark never has to login, of course
if (!profile->isBenchmark()) { if (!profile->config()->isBenchmark()) {
loginInformation->username = username; loginInformation->username = username;
loginInformation->password = password; loginInformation->password = password;
loginInformation->oneTimePassword = oneTimePassword; loginInformation->oneTimePassword = oneTimePassword;
@ -456,7 +457,7 @@ SyncManager *LauncherCore::syncManager() const
QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info) QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info)
{ {
// Hmm, I don't think we're set up for this yet? // Hmm, I don't think we're set up for this yet?
if (!info.profile->isBenchmark()) { if (!info.profile->config()->isBenchmark()) {
updateConfig(info.profile->account()); updateConfig(info.profile->account());
} }
@ -468,7 +469,7 @@ QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info)
#endif #endif
std::optional<LoginAuth> auth; std::optional<LoginAuth> auth;
if (!info.profile->isBenchmark()) { if (!info.profile->config()->isBenchmark()) {
if (info.profile->account()->config()->isSapphire()) { if (info.profile->account()->config()->isSapphire()) {
auth = co_await m_sapphireLogin->login(info.profile->account()->config()->lobbyUrl(), info); auth = co_await m_sapphireLogin->login(info.profile->account()->config()->lobbyUrl(), info);
} else { } else {
@ -479,7 +480,7 @@ QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info)
const auto assetUpdater = new AssetUpdater(*info.profile, *this, this); const auto assetUpdater = new AssetUpdater(*info.profile, *this, this);
if (co_await assetUpdater->update()) { if (co_await assetUpdater->update()) {
// If we expect an auth ticket, don't continue if missing // If we expect an auth ticket, don't continue if missing
if (!info.profile->isBenchmark() && auth == std::nullopt) { if (!info.profile->config()->isBenchmark() && auth == std::nullopt) {
co_return; co_return;
} }

View file

@ -24,6 +24,10 @@ Profile::Profile(const QString &key, QObject *parent)
readGameVersion(); readGameVersion();
readWineInfo(); readWineInfo();
readDalamudInfo(); readDalamudInfo();
connect(m_config, &ProfileConfig::WineTypeChanged, this, &Profile::readWineInfo);
connect(m_config, &ProfileConfig::GamePathChanged, this, &Profile::readGameVersion);
connect(m_config, &ProfileConfig::GamePathChanged, this, &Profile::hasDirectx9Changed);
} }
void Profile::readDalamudInfo() void Profile::readDalamudInfo()
@ -111,38 +115,9 @@ void Profile::readWineInfo()
wineProcess->waitForFinished(); wineProcess->waitForFinished();
} }
QString Profile::name() const
{
return m_config->name();
}
void Profile::setName(const QString &name)
{
if (m_config->name() != name) {
m_config->setName(name);
m_config->save();
Q_EMIT nameChanged();
}
}
QString Profile::gamePath() const
{
return m_config->gamePath();
}
void Profile::setGamePath(const QString &path)
{
if (m_config->gamePath() != path) {
m_config->setGamePath(path);
m_config->save();
readGameVersion();
Q_EMIT gamePathChanged();
}
}
QString Profile::winePath() const QString Profile::winePath() const
{ {
switch (wineType()) { switch (config()->wineType()) {
case WineType::BuiltIn: { case WineType::BuiltIn: {
const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); const QDir dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
const QDir compatibilityToolDir = dataDir.absoluteFilePath(QStringLiteral("tool")); const QDir compatibilityToolDir = dataDir.absoluteFilePath(QStringLiteral("tool"));
@ -162,228 +137,16 @@ void Profile::setWinePath(const QString &path)
{ {
if (m_config->winePath() != path) { if (m_config->winePath() != path) {
m_config->setWinePath(path); m_config->setWinePath(path);
m_config->save();
Q_EMIT winePathChanged(); Q_EMIT winePathChanged();
} }
} }
QString Profile::winePrefixPath() const
{
return m_config->winePrefixPath();
}
void Profile::setWinePrefixPath(const QString &path)
{
if (m_config->winePrefixPath() != path) {
m_config->setWinePrefixPath(path);
m_config->save();
Q_EMIT winePrefixPathChanged();
}
}
Profile::WineType Profile::wineType() const
{
return static_cast<WineType>(m_config->wineType());
}
void Profile::setWineType(const WineType type)
{
if (static_cast<WineType>(m_config->wineType()) != type) {
m_config->setWineType(static_cast<int>(type));
m_config->save();
Q_EMIT wineTypeChanged();
readWineInfo();
}
}
bool Profile::gamescopeEnabled() const
{
return m_config->useGamescope();
}
void Profile::setGamescopeEnabled(const bool value)
{
if (m_config->useGamescope() != value) {
m_config->setUseGamescope(value);
m_config->save();
Q_EMIT useGamescopeChanged();
}
}
bool Profile::gamemodeEnabled() const
{
return m_config->useGamemode();
}
void Profile::setGamemodeEnabled(const bool value)
{
if (m_config->useGamemode() != value) {
m_config->setUseGamemode(value);
m_config->save();
Q_EMIT useGamemodeChanged();
}
}
bool Profile::directx9Enabled() const
{
return m_config->useDX9();
}
void Profile::setDirectX9Enabled(const bool value)
{
if (m_config->useDX9() != value) {
m_config->setUseDX9(value);
m_config->save();
Q_EMIT useDX9Changed();
}
}
bool Profile::hasDirectx9() const bool Profile::hasDirectx9() const
{ {
const QDir gameDir(gamePath()); const QDir gameDir(config()->gamePath());
return QFileInfo::exists(gameDir.absoluteFilePath(QStringLiteral("game/ffxiv.exe"))); return QFileInfo::exists(gameDir.absoluteFilePath(QStringLiteral("game/ffxiv.exe")));
} }
bool Profile::gamescopeFullscreen() const
{
return m_config->gamescopeFullscreen();
}
void Profile::setGamescopeFullscreen(const bool value)
{
if (m_config->gamescopeFullscreen() != value) {
m_config->setGamescopeFullscreen(value);
m_config->save();
Q_EMIT gamescopeFullscreenChanged();
}
}
bool Profile::gamescopeBorderless() const
{
return m_config->gamescopeBorderless();
}
void Profile::setGamescopeBorderless(const bool value)
{
if (m_config->gamescopeBorderless() != value) {
m_config->setGamescopeBorderless(value);
m_config->save();
Q_EMIT gamescopeBorderlessChanged();
}
}
int Profile::gamescopeWidth() const
{
return m_config->gamescopeWidth();
}
void Profile::setGamescopeWidth(const int value)
{
if (m_config->gamescopeWidth() != value) {
m_config->setGamescopeWidth(value);
m_config->save();
Q_EMIT gamescopeWidthChanged();
}
}
int Profile::gamescopeHeight() const
{
return m_config->gamescopeHeight();
}
void Profile::setGamescopeHeight(const int value)
{
if (m_config->gamescopeHeight() != value) {
m_config->setGamescopeHeight(value);
m_config->save();
Q_EMIT gamescopeHeightChanged();
}
}
int Profile::gamescopeRefreshRate() const
{
return m_config->gamescopeRefreshRate();
}
void Profile::setGamescopeRefreshRate(const int value)
{
if (m_config->gamescopeRefreshRate() != value) {
m_config->setGamescopeRefreshRate(value);
m_config->save();
Q_EMIT gamescopeRefreshRateChanged();
}
}
bool Profile::dalamudEnabled() const
{
return m_config->dalamudEnabled();
}
void Profile::setDalamudEnabled(const bool value)
{
if (m_config->dalamudEnabled() != value) {
m_config->setDalamudEnabled(value);
m_config->save();
Q_EMIT dalamudEnabledChanged();
}
}
Profile::DalamudChannel Profile::dalamudChannel() const
{
return static_cast<DalamudChannel>(m_config->dalamudChannel());
}
void Profile::setDalamudChannel(const DalamudChannel channel)
{
if (static_cast<DalamudChannel>(m_config->dalamudChannel()) != channel) {
m_config->setDalamudChannel(static_cast<int>(channel));
m_config->save();
Q_EMIT dalamudChannelChanged();
}
}
Profile::DalamudInjectMethod Profile::dalamudInjectMethod() const
{
return static_cast<DalamudInjectMethod>(m_config->dalamudInjectMethod());
}
void Profile::setDalamudInjectMethod(const Profile::DalamudInjectMethod value)
{
if (static_cast<DalamudInjectMethod>(m_config->dalamudInjectMethod()) != value) {
m_config->setDalamudInjectMethod(static_cast<int>(value));
m_config->save();
Q_EMIT dalamudInjectMethodChanged();
}
}
int Profile::dalamudInjectDelay() const
{
return m_config->dalamudInjectDelay();
}
void Profile::setDalamudInjectDelay(const int value)
{
if (m_config->dalamudInjectDelay() != value) {
m_config->setDalamudInjectDelay(static_cast<int>(value));
m_config->save();
Q_EMIT dalamudInjectDelayChanged();
}
}
bool Profile::isBenchmark() const
{
return m_config->isBenchmark();
}
void Profile::setIsBenchmark(const bool value)
{
if (m_config->isBenchmark() != value) {
m_config->setIsBenchmark(value);
m_config->save();
Q_EMIT isBenchmarkChanged();
}
}
Account *Profile::account() const Account *Profile::account() const
{ {
return m_account; return m_account;
@ -391,24 +154,19 @@ Account *Profile::account() const
void Profile::setAccount(Account *account) void Profile::setAccount(Account *account)
{ {
if (account != m_account) { m_account = account;
m_account = account; m_config->setAccount(account->uuid());
if (account->uuid() != m_config->account()) { Q_EMIT accountChanged();
m_config->setAccount(account->uuid());
m_config->save();
}
Q_EMIT accountChanged();
}
} }
void Profile::readGameVersion() void Profile::readGameVersion()
{ {
if (gamePath().isEmpty()) { if (config()->gamePath().isEmpty()) {
return; return;
} }
m_gameData = physis_gamedata_initialize(QString(gamePath() + QStringLiteral("/game")).toStdString().c_str()); m_gameData = physis_gamedata_initialize(QString(config()->gamePath() + QStringLiteral("/game")).toStdString().c_str());
m_bootData = physis_bootdata_initialize(QString(gamePath() + QStringLiteral("/boot")).toStdString().c_str()); m_bootData = physis_bootdata_initialize(QString(config()->gamePath() + QStringLiteral("/boot")).toStdString().c_str());
if (m_bootData != nullptr) { if (m_bootData != nullptr) {
m_bootVersion = physis_bootdata_get_version(m_bootData); m_bootVersion = physis_bootdata_get_version(m_bootData);
@ -420,7 +178,7 @@ void Profile::readGameVersion()
} }
// Extract frontier url if possible // Extract frontier url if possible
const auto launcherPath = QString(gamePath() + QStringLiteral("/boot/ffxivlauncher64.exe")); const auto launcherPath = QString(config()->gamePath() + QStringLiteral("/boot/ffxivlauncher64.exe"));
if (QFile::exists(launcherPath)) { if (QFile::exists(launcherPath)) {
m_frontierUrl = QString::fromUtf8(physis_extract_frontier_url(launcherPath.toStdString().c_str())); m_frontierUrl = QString::fromUtf8(physis_extract_frontier_url(launcherPath.toStdString().c_str()));
} }
@ -428,11 +186,6 @@ void Profile::readGameVersion()
Q_EMIT gameInstallChanged(); Q_EMIT gameInstallChanged();
} }
QString Profile::accountUuid() const
{
return m_config->account();
}
QString Profile::expansionVersionText() const QString Profile::expansionVersionText() const
{ {
if (!isGameInstalled()) { if (!isGameInstalled()) {
@ -493,7 +246,7 @@ QString Profile::wineVersionText() const
QString Profile::dalamudChannelName() const QString Profile::dalamudChannelName() const
{ {
switch (dalamudChannel()) { switch (config()->dalamudChannel()) {
case DalamudChannel::Stable: case DalamudChannel::Stable:
return QStringLiteral("stable"); return QStringLiteral("stable");
case DalamudChannel::Staging: case DalamudChannel::Staging:
@ -581,7 +334,7 @@ void Profile::setDalamudApplicable(const bool applicable)
bool Profile::dalamudShouldLaunch() const bool Profile::dalamudShouldLaunch() const
{ {
// Local Dalamud installations can always run // Local Dalamud installations can always run
return dalamudEnabled() && (dalamudChannel() != DalamudChannel::Local ? m_dalamudApplicable : true); return config()->dalamudEnabled() && (config()->dalamudChannel() != DalamudChannel::Local ? m_dalamudApplicable : true);
} }
QString Profile::compatibilityToolVersion() const QString Profile::compatibilityToolVersion() const
@ -619,7 +372,7 @@ void Profile::setLoggedIn(const bool value)
QString Profile::subtitle() const QString Profile::subtitle() const
{ {
if (isBenchmark()) { if (config()->isBenchmark()) {
return i18n("Benchmark"); return i18n("Benchmark");
} else if (m_repositories.repositories_count > 0) { } else if (m_repositories.repositories_count > 0) {
const unsigned int latestExpansion = m_repositories.repositories_count - 1; const unsigned int latestExpansion = m_repositories.repositories_count - 1;
@ -634,4 +387,9 @@ QString Profile::subtitle() const
} }
} }
#include "moc_profile.cpp" ProfileConfig *Profile::config() const
{
return m_config;
}
#include "moc_profile.cpp"

View file

@ -3,6 +3,7 @@
#include "profilemanager.h" #include "profilemanager.h"
#include "astra_log.h" #include "astra_log.h"
#include "profileconfig.h"
#include <KSharedConfig> #include <KSharedConfig>
#include <QDir> #include <QDir>
@ -43,7 +44,7 @@ Profile *ProfileManager::getProfileByUUID(const QString &uuid)
Profile *ProfileManager::addProfile() Profile *ProfileManager::addProfile()
{ {
const auto newProfile = new Profile(QUuid::createUuid().toString(), this); const auto newProfile = new Profile(QUuid::createUuid().toString(), this);
newProfile->setName(QStringLiteral("New Profile")); newProfile->config()->setName(QStringLiteral("New Profile"));
insertProfile(newProfile); insertProfile(newProfile);
@ -151,4 +152,4 @@ int ProfileManager::numProfiles() const
return static_cast<int>(m_profiles.count()); return static_cast<int>(m_profiles.count());
} }
#include "moc_profilemanager.cpp" #include "moc_profilemanager.cpp"

View file

@ -17,6 +17,7 @@
#include "accountconfig.h" #include "accountconfig.h"
#include "astra_log.h" #include "astra_log.h"
#include "launchercore.h" #include "launchercore.h"
#include "profileconfig.h"
#include "utility.h" #include "utility.h"
const QString platform = QStringLiteral("win32"); const QString platform = QStringLiteral("win32");
@ -194,7 +195,7 @@ QCoro::Task<bool> SquareEnixLogin::checkBootUpdates()
if (!patchList.isEmpty()) { if (!patchList.isEmpty()) {
qDebug(ASTRA_LOG) << "Boot patch list:" << patchList; qDebug(ASTRA_LOG) << "Boot patch list:" << patchList;
m_patcher = new Patcher(m_launcher, m_info->profile->gamePath() + QStringLiteral("/boot"), *m_info->profile->bootData(), this); m_patcher = new Patcher(m_launcher, m_info->profile->config()->gamePath() + QStringLiteral("/boot"), *m_info->profile->bootData(), this);
const std::string patchListStd = patchList.toStdString(); const std::string patchListStd = patchList.toStdString();
const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Boot, patchListStd.c_str())); const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Boot, patchListStd.c_str()));
if (hasPatched) { if (hasPatched) {
@ -397,7 +398,7 @@ QCoro::Task<bool> SquareEnixLogin::registerSession()
if (!body.isEmpty()) { if (!body.isEmpty()) {
qDebug(ASTRA_LOG) << "Game patch list:" << body; qDebug(ASTRA_LOG) << "Game patch list:" << body;
m_patcher = new Patcher(m_launcher, m_info->profile->gamePath() + QStringLiteral("/game"), *m_info->profile->gameData(), this); m_patcher = new Patcher(m_launcher, m_info->profile->config()->gamePath() + QStringLiteral("/game"), *m_info->profile->gameData(), this);
std::string bodyStd = body.toStdString(); std::string bodyStd = body.toStdString();
const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Game, bodyStd.c_str())); const bool hasPatched = co_await m_patcher->patch(physis_parse_patchlist(PatchListType::Game, bodyStd.c_str()));
m_patcher->deleteLater(); m_patcher->deleteLater();
@ -444,7 +445,7 @@ QCoro::Task<QString> SquareEnixLogin::getBootHash() const
QStringLiteral("ffxivupdater64.exe")}; QStringLiteral("ffxivupdater64.exe")};
const auto hashFuture = QtConcurrent::mapped(fileList, [this](const auto &filename) -> QString { const auto hashFuture = QtConcurrent::mapped(fileList, [this](const auto &filename) -> QString {
return getFileHash(m_info->profile->gamePath() + QStringLiteral("/boot/") + filename); return getFileHash(m_info->profile->config()->gamePath() + QStringLiteral("/boot/") + filename);
}); });
co_await hashFuture; co_await hashFuture;

View file

@ -58,7 +58,7 @@ Kirigami.ApplicationWindow {
pageStack.push(Qt.createComponent("zone.xiv.astra", "SetupPage"), { pageStack.push(Qt.createComponent("zone.xiv.astra", "SetupPage"), {
profile: LauncherCore.currentProfile profile: LauncherCore.currentProfile
}) })
} else if (!LauncherCore.currentProfile.account && !LauncherCore.currentProfile.isBenchmark) { } else if (!LauncherCore.currentProfile.account && !LauncherCore.currentProfile.config.isBenchmark) {
// User must select an account for the profile // User must select an account for the profile
pageStack.push(Qt.createComponent("zone.xiv.astra", "AccountSetup"), { pageStack.push(Qt.createComponent("zone.xiv.astra", "AccountSetup"), {
profile: LauncherCore.currentProfile profile: LauncherCore.currentProfile

View file

@ -122,7 +122,7 @@ QQC2.Control {
FormCard.FormButtonDelegate { FormCard.FormButtonDelegate {
id: currentProfileDelegate id: currentProfileDelegate
text: LauncherCore.currentProfile.name text: LauncherCore.currentProfile.config.name
QQC2.Menu { QQC2.Menu {
id: profileMenu id: profileMenu
@ -138,7 +138,7 @@ QQC2.Control {
required property var profile required property var profile
QQC2.MenuItem { QQC2.MenuItem {
text: profileMenuItem.profile.name text: profileMenuItem.profile.config.name
onClicked: { onClicked: {
LauncherCore.currentProfile = profileMenuItem.profile; LauncherCore.currentProfile = profileMenuItem.profile;
@ -156,7 +156,7 @@ QQC2.Control {
FormCard.FormCard { FormCard.FormCard {
id: regularLoginCard id: regularLoginCard
visible: !LauncherCore.currentProfile.isBenchmark visible: !LauncherCore.currentProfile.config.isBenchmark
maximumWidth: Kirigami.Units.gridUnit * 25 maximumWidth: Kirigami.Units.gridUnit * 25
Layout.fillWidth: true Layout.fillWidth: true
@ -297,7 +297,7 @@ QQC2.Control {
FormCard.FormCard { FormCard.FormCard {
id: benchmarkLaunchCard id: benchmarkLaunchCard
visible: LauncherCore.currentProfile.isBenchmark visible: LauncherCore.currentProfile.config.isBenchmark
maximumWidth: Kirigami.Units.gridUnit * 25 maximumWidth: Kirigami.Units.gridUnit * 25
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -49,7 +49,7 @@ Kirigami.Page {
standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.Cancel standardButtons: Kirigami.Dialog.Yes | Kirigami.Dialog.Cancel
onAccepted: { onAccepted: {
LauncherCore.currentProfile.dalamudEnabled = false; LauncherCore.currentProfile.config.dalamudEnabled = false;
applicationWindow().checkSetup(); applicationWindow().checkSetup();
} }
onRejected: applicationWindow().checkSetup() onRejected: applicationWindow().checkSetup()

View file

@ -68,8 +68,8 @@ FormCard.FormCardPage {
id: nameDelegate id: nameDelegate
label: i18n("Name") label: i18n("Name")
text: page.profile.name text: page.profile.config.name
onTextChanged: page.profile.name = text onTextChanged: page.profile.config.name = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -81,9 +81,9 @@ FormCard.FormCardPage {
id: gamePathDelegate id: gamePathDelegate
text: i18n("Game Folder") text: i18n("Game Folder")
folder: page.profile.gamePath folder: page.profile.config.gamePath
onAccepted: (folder) => page.profile.gamePath = folder onAccepted: (folder) => page.profile.config.gamePath = folder
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -96,8 +96,8 @@ FormCard.FormCardPage {
text: i18n("DirectX Version") text: i18n("DirectX Version")
model: ["DirectX 11", "DirectX 9"] model: ["DirectX 11", "DirectX 9"]
currentIndex: page.profile.directx9Enabled ? 1 : 0 currentIndex: page.profile.config.directx9Enabled ? 1 : 0
onCurrentIndexChanged: page.profile.directx9Enabled = (currentIndex === 1) onCurrentIndexChanged: page.profile.config.directx9Enabled = (currentIndex === 1)
visible: page.profile.hasDirectx9 visible: page.profile.hasDirectx9
} }
@ -122,8 +122,8 @@ FormCard.FormCardPage {
text: i18n("Wine Type") text: i18n("Wine Type")
model: [i18n("Built-in"), i18n("Custom")] model: [i18n("Built-in"), i18n("Custom")]
currentIndex: page.profile.wineType currentIndex: page.profile.config.wineType
onCurrentIndexChanged: page.profile.wineType = currentIndex onCurrentIndexChanged: page.profile.config.wineType = currentIndex
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -136,7 +136,7 @@ FormCard.FormCardPage {
text: i18n("Wine Executable") text: i18n("Wine Executable")
file: page.profile.winePath file: page.profile.winePath
enabled: page.profile.wineType !== Profile.BuiltIn enabled: page.profile.config.wineType !== Profile.BuiltIn
onAccepted: (path) => page.profile.winePath = path onAccepted: (path) => page.profile.winePath = path
} }
@ -150,7 +150,7 @@ FormCard.FormCardPage {
id: winePrefixPathDelegate id: winePrefixPathDelegate
text: i18n("Wine Prefix Folder") text: i18n("Wine Prefix Folder")
folder: page.profile.winePrefixPath folder: page.profile.config.winePrefixPath
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -171,8 +171,8 @@ FormCard.FormCardPage {
FormCard.FormCheckDelegate { FormCard.FormCheckDelegate {
text: i18n("Enable Gamescope") text: i18n("Enable Gamescope")
description: i18n("A micro-compositor that uses Wayland to create a nested session.\nIf you use fullscreen mode, it may improve input handling.") description: i18n("A micro-compositor that uses Wayland to create a nested session.\nIf you use fullscreen mode, it may improve input handling.")
checked: page.profile.gamescopeEnabled checked: page.profile.config.gamescopeEnabled
onCheckedChanged: page.profile.gamescopeEnabled = checked onCheckedChanged: page.profile.config.gamescopeEnabled = checked
} }
FormCard.FormDelegateSeparator {} FormCard.FormDelegateSeparator {}
@ -180,7 +180,7 @@ FormCard.FormCardPage {
FormCard.FormButtonDelegate { FormCard.FormButtonDelegate {
text: i18n("Configure Gamescope...") text: i18n("Configure Gamescope...")
icon.name: "configure" icon.name: "configure"
enabled: page.profile.gamescopeEnabled enabled: page.profile.config.gamescopeEnabled
Kirigami.PromptDialog { Kirigami.PromptDialog {
id: gamescopeSettingsDialog id: gamescopeSettingsDialog
title: i18n("Configure Gamescope") title: i18n("Configure Gamescope")
@ -188,31 +188,31 @@ FormCard.FormCardPage {
Kirigami.FormLayout { Kirigami.FormLayout {
QQC2.CheckBox { QQC2.CheckBox {
Kirigami.FormData.label: "Fullscreen:" Kirigami.FormData.label: "Fullscreen:"
checked: page.profile.gamescopeFullscreen checked: page.profile.config.gamescopeFullscreen
onCheckedChanged: page.profile.gamescopeFullscreen = checked onCheckedChanged: page.profile.config.gamescopeFullscreen = checked
} }
QQC2.CheckBox { QQC2.CheckBox {
Kirigami.FormData.label: "Borderless:" Kirigami.FormData.label: "Borderless:"
checked: page.profile.gamescopeBorderless checked: page.profile.config.gamescopeBorderless
onCheckedChanged: page.profile.gamescopeBorderless = checked onCheckedChanged: page.profile.config.gamescopeBorderless = checked
} }
QQC2.SpinBox { QQC2.SpinBox {
Kirigami.FormData.label: "Width:" Kirigami.FormData.label: "Width:"
to: 4096 to: 4096
value: page.profile.gamescopeWidth value: page.profile.config.gamescopeWidth
onValueModified: page.profile.gamescopeWidth = value onValueModified: page.profile.config.gamescopeWidth = value
} }
QQC2.SpinBox { QQC2.SpinBox {
Kirigami.FormData.label: "Height:" Kirigami.FormData.label: "Height:"
to: 4096 to: 4096
value: page.profile.gamescopeHeight value: page.profile.config.gamescopeHeight
onValueModified: page.profile.gamescopeHeight = value onValueModified: page.profile.config.gamescopeHeight = value
} }
QQC2.SpinBox { QQC2.SpinBox {
Kirigami.FormData.label: "Refresh Rate:" Kirigami.FormData.label: "Refresh Rate:"
to: 512 to: 512
value: page.profile.gamescopeRefreshRate value: page.profile.config.gamescopeRefreshRate
onValueModified: page.profile.gamescopeRefreshRate = value onValueModified: page.profile.config.gamescopeRefreshRate = value
} }
} }
} }
@ -227,8 +227,8 @@ FormCard.FormCardPage {
text: i18n("Enable Gamemode") text: i18n("Enable Gamemode")
description: i18n("A special game performance tool, that tunes your CPU scheduler among other things.") description: i18n("A special game performance tool, that tunes your CPU scheduler among other things.")
checked: page.profile.gamemodeEnabled checked: page.profile.config.gamemodeEnabled
onCheckedChanged: page.profile.gamemodeEnabled = checked onCheckedChanged: page.profile.config.gamemodeEnabled = checked
} }
} }
@ -243,8 +243,8 @@ FormCard.FormCardPage {
text: i18n("Enable Dalamud") text: i18n("Enable Dalamud")
description: i18n("Dalamud extends the game with useful plugins, but use at your own risk.") description: i18n("Dalamud extends the game with useful plugins, but use at your own risk.")
checked: page.profile.dalamudEnabled checked: page.profile.config.dalamudEnabled
onCheckedChanged: page.profile.dalamudEnabled = checked onCheckedChanged: page.profile.config.dalamudEnabled = checked
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -257,9 +257,9 @@ FormCard.FormCardPage {
text: i18n("Update Channel") text: i18n("Update Channel")
model: LauncherCore.config.showDevTools ? [i18n("Stable"), i18n("Staging"), i18n("Local")] : [i18n("Stable"), i18n("Staging")] model: LauncherCore.config.showDevTools ? [i18n("Stable"), i18n("Staging"), i18n("Local")] : [i18n("Stable"), i18n("Staging")]
currentIndex: page.profile.dalamudChannel currentIndex: page.profile.config.dalamudChannel
onCurrentIndexChanged: page.profile.dalamudChannel = currentIndex onCurrentIndexChanged: page.profile.config.dalamudChannel = currentIndex
enabled: page.profile.dalamudEnabled enabled: page.profile.config.dalamudEnabled
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -275,9 +275,9 @@ FormCard.FormCardPage {
text: i18n("Injection Method") text: i18n("Injection Method")
description: "It shouldn't be nessecary to change this setting, unless you're running into issues injecting Dalamud." description: "It shouldn't be nessecary to change this setting, unless you're running into issues injecting Dalamud."
model: ["Entrypoint", "DLL Injection"] model: ["Entrypoint", "DLL Injection"]
currentIndex: page.profile.dalamudInjectMethod currentIndex: page.profile.config.dalamudInjectMethod
onCurrentIndexChanged: page.profile.dalamudInjectMethod = currentIndex onCurrentIndexChanged: page.profile.config.dalamudInjectMethod = currentIndex
enabled: page.profile.dalamudEnabled enabled: page.profile.config.dalamudEnabled
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -290,9 +290,9 @@ FormCard.FormCardPage {
visible: LauncherCore.config.showDevTools visible: LauncherCore.config.showDevTools
label: i18n("Injection Delay") label: i18n("Injection Delay")
value: page.profile.dalamudInjectDelay value: page.profile.config.dalamudInjectDelay
onValueChanged: page.profile.dalamudInjectDelay = value onValueChanged: page.profile.config.dalamudInjectDelay = value
enabled: page.profile.dalamudEnabled enabled: page.profile.config.dalamudEnabled
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -300,7 +300,7 @@ FormCard.FormCardPage {
} }
FormCard.FormTextDelegate { FormCard.FormTextDelegate {
description: page.profile.dalamudVersionText description: page.profile.config.dalamudVersionText
} }
} }

View file

@ -35,7 +35,7 @@ FormCard.FormCardPage {
FormCard.FormButtonDelegate { FormCard.FormButtonDelegate {
text: i18n("Auto-login Profile") text: i18n("Auto-login Profile")
description: LauncherCore.autoLoginProfile ? LauncherCore.autoLoginProfile.name : i18n("Disabled") description: LauncherCore.autoLoginProfile ? LauncherCore.autoLoginProfile.config.name : i18n("Disabled")
QQC2.Menu { QQC2.Menu {
id: profileMenu id: profileMenu
@ -55,7 +55,7 @@ FormCard.FormCardPage {
QQC2.MenuItem { QQC2.MenuItem {
required property var profile required property var profile
text: profile.name text: profile.config.name
onClicked: { onClicked: {
LauncherCore.autoLoginProfile = profile; LauncherCore.autoLoginProfile = profile;
@ -87,7 +87,7 @@ FormCard.FormCardPage {
FormCard.FormButtonDelegate { FormCard.FormButtonDelegate {
id: buttonDelegate id: buttonDelegate
text: layout.profile.name text: layout.profile.config.name
description: layout.profile.subtitle description: layout.profile.subtitle
onClicked: page.Window.window.pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "ProfileSettings"), { onClicked: page.Window.window.pageStack.layers.push(Qt.createComponent("zone.xiv.astra", "ProfileSettings"), {
profile: layout.profile profile: layout.profile

View file

@ -25,7 +25,7 @@ FormCard.FormCardPage {
FormCard.FormTextDelegate { FormCard.FormTextDelegate {
id: helpTextDelegate id: helpTextDelegate
text: i18n("Select an account to use for '%1'.", LauncherCore.currentProfile.name) text: i18n("Select an account to use for '%1'.", LauncherCore.currentProfile.config.name)
} }
} }

View file

@ -23,7 +23,7 @@ FormCard.FormCardPage {
id: dialog id: dialog
onAccepted: { onAccepted: {
page.profile.gamePath = decodeURIComponent(selectedFolder.toString().replace("file://", "")); page.profile.config.gamePath = decodeURIComponent(selectedFolder.toString().replace("file://", ""));
applicationWindow().checkSetup(); applicationWindow().checkSetup();
} }
} }
@ -43,7 +43,7 @@ FormCard.FormCardPage {
description: type description: type
onClicked: { onClicked: {
page.profile.gamePath = path; page.profile.config.gamePath = path;
applicationWindow().checkSetup(); applicationWindow().checkSetup();
} }
} }

View file

@ -22,7 +22,7 @@ FormCard.FormCardPage {
data: FolderDialog { data: FolderDialog {
id: installFolderDialog id: installFolderDialog
onAccepted: page.profile.gamePath = decodeURIComponent(selectedFolder.toString().replace("file://", "")) onAccepted: page.profile.config.gamePath = decodeURIComponent(selectedFolder.toString().replace("file://", ""))
} }
Image { Image {
@ -47,7 +47,7 @@ FormCard.FormCardPage {
if (page.isInitialSetup) { if (page.isInitialSetup) {
return i18n("You must have a legitimate installation of FFXIV to continue."); return i18n("You must have a legitimate installation of FFXIV to continue.");
} else { } else {
return i18n("Select a game installation for '%1'.", page.profile.name); return i18n("Select a game installation for '%1'.", page.profile.config.name);
} }
} }
} }
@ -62,7 +62,7 @@ FormCard.FormCardPage {
icon.name: "document-open-folder" icon.name: "document-open-folder"
text: i18n("Select Install Folder") text: i18n("Select Install Folder")
description: profile.gamePath description: profile.config.gamePath
onClicked: installFolderDialog.open() onClicked: installFolderDialog.open()
} }
@ -94,12 +94,12 @@ FormCard.FormCardPage {
FormCard.FormButtonDelegate { FormCard.FormButtonDelegate {
required property var profile required property var profile
text: profile.name text: profile.config.name
description: profile.gamePath description: profile.config.gamePath
visible: profile.isGameInstalled visible: profile.isGameInstalled
onClicked: { onClicked: {
LauncherCore.currentProfile.gamePath = profile.gamePath; LauncherCore.currentProfile.config.gamePath = profile.config.gamePath;
applicationWindow().checkSetup(); applicationWindow().checkSetup();
} }
} }
@ -218,4 +218,4 @@ FormCard.FormCardPage {
onClicked: benchmarkDialog.open() onClicked: benchmarkDialog.open()
} }
} }
} }