2021-11-01 09:54:58 -04:00
# include <QPushButton>
# include <QProcess>
# include <QNetworkAccessManager>
# include <QNetworkReply>
# include <QUrlQuery>
# include <QDir>
# include <QFormLayout>
# include <QLineEdit>
# include <QRegularExpression>
# include <QComboBox>
# include <QJsonObject>
# include <QJsonDocument>
# include <QCheckBox>
# include <keychain.h>
# include <QMessageBox>
2021-11-01 13:14:00 -04:00
# include <QMenuBar>
2021-11-10 05:18:59 -05:00
# include <QCoreApplication>
2021-11-23 14:37:37 -05:00
# include <QStandardPaths>
# include <QRegularExpressionMatch>
2021-11-01 09:54:58 -04:00
2021-11-09 15:02:17 -05:00
# if defined(Q_OS_MAC)
# include <sys/sysctl.h>
# include <mach/mach_time.h>
# endif
2021-11-09 20:57:10 -05:00
# if defined(Q_OS_WIN)
# include <windows.h>
# endif
2021-11-23 15:34:23 -05:00
# include "launchercore.h"
2021-11-01 09:54:58 -04:00
# include "sapphirelauncher.h"
# include "squarelauncher.h"
# include "squareboot.h"
2021-11-01 13:14:00 -04:00
# include "settingswindow.h"
2021-11-09 15:02:17 -05:00
# include "blowfish.h"
2021-11-23 14:37:37 -05:00
# include "assetupdater.h"
2021-11-01 09:54:58 -04:00
2021-11-23 15:34:23 -05:00
void LauncherCore : : setSSL ( QNetworkRequest & request ) {
2021-11-01 09:54:58 -04:00
QSslConfiguration config ;
config . setProtocol ( QSsl : : AnyProtocol ) ;
config . setPeerVerifyMode ( QSslSocket : : VerifyNone ) ;
request . setSslConfiguration ( config ) ;
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : buildRequest ( QNetworkRequest & request ) {
2021-11-01 09:54:58 -04:00
setSSL ( request ) ;
request . setHeader ( QNetworkRequest : : UserAgentHeader ,
2021-11-18 07:30:38 -05:00
QString ( " SQEXAuthor/2.0.0(Windows 6.2; ja-jp; %1) " ) . arg ( QString ( QSysInfo : : bootUniqueId ( ) ) ) ) ;
2021-11-01 09:54:58 -04:00
request . setRawHeader ( " Accept " ,
" image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */* " ) ;
request . setRawHeader ( " Accept-Encoding " , " gzip, deflate " ) ;
request . setRawHeader ( " Accept-Language " , " en-us " ) ;
}
2021-11-09 15:02:17 -05:00
// from xivdev
char ChecksumTable [ ] = {
' f ' , ' X ' , ' 1 ' , ' p ' , ' G ' , ' t ' , ' d ' , ' S ' ,
' 5 ' , ' C ' , ' A ' , ' P ' , ' 4 ' , ' _ ' , ' V ' , ' L '
} ;
char GetChecksum ( unsigned int key ) {
auto value = key & 0x000F0000 ;
return ChecksumTable [ value > > 16 ] ;
}
# if defined(Q_OS_MAC)
// this is pretty much what wine does :-0
uint32_t TickCount ( ) {
struct mach_timebase_info convfact ;
mach_timebase_info ( & convfact ) ;
2021-11-10 05:26:21 -05:00
return ( mach_absolute_time ( ) * convfact . numer ) / ( convfact . denom * 1000000 ) ;
2021-11-09 15:02:17 -05:00
}
# endif
2021-11-09 20:59:39 -05:00
# if defined(Q_OS_LINUX)
uint32_t TickCount ( ) {
struct timespec ts ;
clock_gettime ( CLOCK_MONOTONIC , & ts ) ;
return ( ts . tv_sec * 1000 + ts . tv_nsec / 1000000 ) ;
}
# endif
2021-11-09 20:57:10 -05:00
# if defined(Q_OS_WIN)
uint32_t TickCount ( ) {
return GetTickCount ( ) ;
}
# endif
2021-11-09 15:02:17 -05:00
QString encryptGameArg ( QString arg ) {
2021-11-09 20:57:10 -05:00
unsigned int rawTicks = TickCount ( ) ;
2021-11-09 15:02:17 -05:00
unsigned int ticks = rawTicks & 0xFFFFFFFFu ;
2021-11-09 21:32:01 -05:00
unsigned int key = ticks & 0xFFFF0000u ;
2021-11-09 15:02:17 -05:00
2021-11-09 20:57:10 -05:00
char buffer [ 9 ] = { } ;
2021-11-09 21:32:01 -05:00
sprintf ( buffer , " %08x " , key ) ;
2021-11-09 15:02:17 -05:00
2021-11-09 20:57:10 -05:00
Blowfish session ( QByteArray ( buffer , 8 ) ) ;
QByteArray encryptedArg = session . Encrypt ( ( QString ( " /T =%1 " ) . arg ( ticks ) + arg ) . toUtf8 ( ) ) ;
QString base64 = encryptedArg . toBase64 ( QByteArray : : Base64Option : : Base64UrlEncoding | QByteArray : : Base64Option : : OmitTrailingEquals ) ;
2021-11-09 21:32:01 -05:00
char checksum = GetChecksum ( key ) ;
2021-11-09 20:57:10 -05:00
2021-11-09 21:32:01 -05:00
return QString ( " //**sqex0003%1%2**// " ) . arg ( base64 , QString ( checksum ) ) ;
2021-11-09 15:02:17 -05:00
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : launchGame ( const ProfileSettings & profile , const LoginAuth auth ) {
2021-11-02 08:36:30 -04:00
QList < QString > arguments ;
2021-11-23 14:37:37 -05:00
QString dataDir = QStandardPaths : : writableLocation ( QStandardPaths : : AppDataLocation ) ;
2021-11-23 15:34:23 -05:00
if ( profile . enableDalamud ) {
2021-11-23 14:37:37 -05:00
arguments . push_back ( dataDir + " /NativeLauncher.exe " ) ;
}
2021-11-02 08:36:30 -04:00
// now for the actual game...
2021-11-23 15:34:23 -05:00
if ( profile . useDX9 ) {
arguments . push_back ( profile . gamePath + " \\ game \\ ffxiv.exe " ) ;
2021-11-02 08:49:06 -04:00
} else {
2021-11-23 15:34:23 -05:00
arguments . push_back ( profile . gamePath + " \\ game \\ ffxiv_dx11.exe " ) ;
2021-11-02 08:49:06 -04:00
}
2021-11-09 21:26:16 -05:00
struct Argument {
QString key , value ;
} ;
2021-11-02 08:36:30 -04:00
2021-11-09 21:26:16 -05:00
QList < Argument > gameArgs ;
gameArgs . push_back ( { " DEV.DataPathType " , QString : : number ( 1 ) } ) ;
gameArgs . push_back ( { " DEV.UseSqPack " , QString : : number ( 1 ) } ) ;
gameArgs . push_back ( { " DEV.MaxEntitledExpansionID " , QString : : number ( auth . maxExpansion ) } ) ;
gameArgs . push_back ( { " DEV.TestSID " , auth . SID } ) ;
gameArgs . push_back ( { " SYS.Region " , QString : : number ( auth . region ) } ) ;
2021-11-23 15:34:23 -05:00
gameArgs . push_back ( { " language " , QString : : number ( profile . language ) } ) ;
gameArgs . push_back ( { " ver " , profile . gameVersion } ) ;
2021-11-02 08:36:30 -04:00
if ( ! auth . lobbyhost . isEmpty ( ) ) {
2021-11-09 21:26:16 -05:00
gameArgs . push_back ( { " DEV.GMServerHost " , auth . frontierHost } ) ;
for ( int i = 1 ; i < 9 ; i + + ) {
gameArgs . push_back ( { QString ( " DEV.LobbyHost0%1 " ) . arg ( QString : : number ( i ) ) , auth . lobbyhost } ) ;
gameArgs . push_back ( { QString ( " DEV.LobbyPort0%1 " ) . arg ( QString : : number ( i ) ) , QString : : number ( 54994 ) } ) ;
}
2021-11-02 08:36:30 -04:00
}
2021-11-23 14:37:37 -05:00
auto gameProcess = new QProcess ( this ) ;
2021-11-23 15:34:23 -05:00
if ( profile . enableDalamud ) {
connect ( gameProcess , & QProcess : : readyReadStandardOutput , [ this , gameProcess , profile ] {
2021-11-23 14:37:37 -05:00
QString output = gameProcess - > readAllStandardOutput ( ) ;
auto dalamudProcess = new QProcess ( ) ;
QStringList dalamudEnv = gameProcess - > environment ( ) ;
2021-11-23 14:39:49 -05:00
# if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
2021-11-23 14:37:37 -05:00
dalamudEnv < < " XL_WINEONLINUX=true " ;
2021-11-23 14:39:49 -05:00
# endif
2021-11-23 14:37:37 -05:00
dalamudProcess - > setEnvironment ( dalamudEnv ) ;
QString dataDir = QStandardPaths : : writableLocation ( QStandardPaths : : AppDataLocation ) ;
2021-11-23 15:34:23 -05:00
dalamudProcess - > start ( profile . winePath , { dataDir + " /Dalamud/ " + " Dalamud.Injector.exe " , output } ) ;
2021-11-23 14:37:37 -05:00
} ) ;
}
2021-11-23 15:34:23 -05:00
if ( profile . encryptArguments ) {
2021-11-09 15:02:17 -05:00
QString argJoined ;
2021-11-09 21:26:16 -05:00
for ( auto arg : gameArgs ) {
argJoined + = QString ( " /%1 =%2 " ) . arg ( arg . key , arg . value ) ;
}
2021-11-09 15:02:17 -05:00
auto earg = encryptGameArg ( argJoined ) ;
2021-11-09 21:26:16 -05:00
arguments . append ( earg ) ;
2021-11-23 15:34:23 -05:00
launchExecutable ( profile , gameProcess , arguments ) ;
2021-11-09 15:02:17 -05:00
} else {
2021-11-09 21:26:16 -05:00
for ( auto arg : gameArgs ) {
arguments . push_back ( QString ( " %1=%2 " ) . arg ( arg . key , arg . value ) ) ;
}
2021-11-23 15:34:23 -05:00
launchExecutable ( profile , gameProcess , arguments ) ;
2021-11-09 15:02:17 -05:00
}
2021-11-02 08:36:30 -04:00
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : launchExecutable ( const ProfileSettings & profile , const QStringList args ) {
2021-11-01 09:54:58 -04:00
auto process = new QProcess ( this ) ;
2021-11-23 15:34:23 -05:00
launchExecutable ( profile , process , args ) ;
2021-11-23 14:37:37 -05:00
}
2021-11-01 09:54:58 -04:00
2021-11-23 15:34:23 -05:00
void LauncherCore : : launchExecutable ( const ProfileSettings & profile , QProcess * process , const QStringList args ) {
2021-11-01 14:35:32 -04:00
QList < QString > arguments ;
2021-11-02 20:04:53 -04:00
QStringList env = QProcess : : systemEnvironment ( ) ;
2021-11-01 09:54:58 -04:00
# if defined(Q_OS_LINUX)
2021-11-23 15:34:23 -05:00
if ( profile . useGamescope ) {
2021-11-01 14:35:32 -04:00
arguments . push_back ( " gamescope " ) ;
arguments . push_back ( " -f " ) ;
arguments . push_back ( " -b " ) ;
}
2021-11-01 09:54:58 -04:00
2021-11-23 15:34:23 -05:00
if ( profile . useGamemode )
2021-11-01 14:35:32 -04:00
arguments . push_back ( " gamemoderun " ) ;
2021-11-01 09:54:58 -04:00
2021-11-23 15:34:23 -05:00
if ( profile . useEsync )
2021-11-01 14:35:32 -04:00
env < < " WINEESYNC=1 " ;
2021-11-03 06:18:31 -04:00
# endif
2021-11-01 09:54:58 -04:00
2021-11-03 06:31:02 -04:00
# if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
2021-11-23 15:34:23 -05:00
env < < " WINEPREFIX= " + profile . winePrefixPath ;
2021-11-01 14:35:32 -04:00
2021-11-23 15:34:23 -05:00
if ( profile . enableDXVKhud )
2021-11-03 06:18:31 -04:00
env < < " DXVK_HUD=full " ;
2021-11-23 15:34:23 -05:00
arguments . push_back ( profile . winePath ) ;
2021-11-03 06:31:02 -04:00
# endif
2021-11-02 08:36:30 -04:00
arguments . append ( args ) ;
2021-11-01 09:54:58 -04:00
2021-11-01 14:35:32 -04:00
auto executable = arguments [ 0 ] ;
arguments . removeFirst ( ) ;
2021-11-03 06:18:31 -04:00
2021-11-23 15:34:23 -05:00
process - > setWorkingDirectory ( profile . gamePath + " /game/ " ) ;
2021-11-03 06:18:31 -04:00
process - > setEnvironment ( env ) ;
2021-11-23 14:37:37 -05:00
2021-11-01 14:35:32 -04:00
process - > start ( executable , arguments ) ;
2021-11-01 09:54:58 -04:00
}
2021-11-23 15:34:23 -05:00
QString LauncherCore : : readVersion ( QString path ) {
2021-11-01 09:54:58 -04:00
QFile file ( path ) ;
file . open ( QFile : : OpenModeFlag : : ReadOnly ) ;
return file . readAll ( ) ;
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : readInitialInformation ( ) {
2021-11-09 12:25:54 -05:00
defaultProfileIndex = settings . value ( " defaultProfile " , 0 ) . toInt ( ) ;
2021-11-09 11:25:15 -05:00
auto profiles = settings . childGroups ( ) ;
// create the Default profile if it doesnt exist
if ( profiles . empty ( ) )
2021-11-09 13:26:59 -05:00
profiles . append ( QUuid : : createUuid ( ) . toString ( QUuid : : StringFormat : : WithoutBraces ) ) ;
2021-11-09 11:25:15 -05:00
2021-11-09 13:24:38 -05:00
profileSettings . resize ( profiles . size ( ) ) ;
for ( const auto & uuid : profiles ) {
2021-11-09 11:25:15 -05:00
ProfileSettings profile ;
2021-11-09 13:24:38 -05:00
profile . uuid = QUuid ( uuid ) ;
settings . beginGroup ( uuid ) ;
2021-11-09 11:25:15 -05:00
2021-11-09 13:26:59 -05:00
profile . name = settings . value ( " name " , " Default " ) . toString ( ) ;
2021-11-09 11:25:15 -05:00
2021-11-10 05:18:59 -05:00
# if defined(Q_OS_MAC)
profile . wineVersion = settings . value ( " wineVersion " , 2 ) . toInt ( ) ;
# else
2021-11-09 13:04:22 -05:00
profile . wineVersion = settings . value ( " wineVersion " , 0 ) . toInt ( ) ;
2021-11-10 05:18:59 -05:00
# endif
2021-11-10 04:30:01 -05:00
readWineInfo ( profile ) ;
2021-11-03 06:18:31 -04:00
2021-11-09 11:25:15 -05:00
if ( settings . contains ( " gamePath " ) & & settings . value ( " gamePath " ) . canConvert < QString > ( ) & & ! settings . value ( " gamePath " ) . toString ( ) . isEmpty ( ) ) {
profile . gamePath = settings . value ( " gamePath " ) . toString ( ) ;
} else {
2021-11-01 09:54:58 -04:00
# if defined(Q_OS_WIN)
2021-11-09 11:25:15 -05:00
profile . gamePath = " C: \\ Program Files (x86) \\ SquareEnix \\ FINAL FANTASY XIV - A Realm Reborn " ;
2021-11-01 09:54:58 -04:00
# endif
2021-11-10 05:18:59 -05:00
# if defined(Q_OS_MAC)
2021-11-09 11:25:15 -05:00
profile . gamePath = QDir : : homePath ( ) + " /Library/Application Support/FINAL FANTASY XIV ONLINE/Bottles/published_Final_Fantasy/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn " ;
2021-11-01 09:54:58 -04:00
# endif
# if defined(Q_OS_LINUX)
2021-11-09 11:25:15 -05:00
profile . gamePath = QDir : : homePath ( ) + " /.wine/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn " ;
2021-11-01 09:54:58 -04:00
# endif
2021-11-09 11:25:15 -05:00
}
2021-11-01 09:54:58 -04:00
2021-11-09 13:04:22 -05:00
if ( settings . contains ( " winePrefixPath " ) & & settings . value ( " winePrefixPath " ) . canConvert < QString > ( ) & & ! settings . value ( " winePrefixPath " ) . toString ( ) . isEmpty ( ) ) {
profile . winePrefixPath = settings . value ( " winePrefixPath " ) . toString ( ) ;
2021-11-09 11:25:15 -05:00
} else {
2021-11-03 06:31:02 -04:00
# if defined(Q_OS_MACOS)
2021-11-09 11:25:15 -05:00
profile . winePrefixPath = QDir : : homePath ( ) + " /Library/Application Support/FINAL FANTASY XIV ONLINE/Bottles/published_Final_Fantasy " ;
2021-11-03 06:31:02 -04:00
# endif
# if defined(Q_OS_LINUX)
2021-11-09 11:25:15 -05:00
profile . winePrefixPath = QDir : : homePath ( ) + " /.wine " ;
2021-11-03 06:31:02 -04:00
# endif
2021-11-09 11:25:15 -05:00
}
2021-11-09 21:13:21 -05:00
// login
profile . encryptArguments = settings . value ( " encryptArguments " , false ) . toBool ( ) ;
2021-11-09 12:40:44 -05:00
profile . isSapphire = settings . value ( " isSapphire " , false ) . toBool ( ) ;
2021-11-09 12:50:37 -05:00
profile . lobbyURL = settings . value ( " lobbyURL " , " " ) . toString ( ) ;
2021-11-09 12:32:18 -05:00
profile . rememberUsername = settings . value ( " rememberUsername " , false ) . toBool ( ) ;
profile . rememberPassword = settings . value ( " rememberPassword " , false ) . toBool ( ) ;
2021-11-09 12:16:14 -05:00
profile . useDX9 = settings . value ( " useDX9 " , false ) . toBool ( ) ;
2021-11-09 11:25:15 -05:00
profile . useEsync = settings . value ( " useEsync " , false ) . toBool ( ) ;
profile . useGamemode = settings . value ( " useGamemode " , false ) . toBool ( ) ;
profile . useGamescope = settings . value ( " useGamescope " , false ) . toBool ( ) ;
profile . enableDXVKhud = settings . value ( " enableDXVKhud " , false ) . toBool ( ) ;
2021-11-03 06:31:02 -04:00
2021-11-23 14:37:37 -05:00
profile . enableDalamud = settings . value ( " enableDalamud " , false ) . toBool ( ) ;
2021-11-09 13:24:38 -05:00
profileSettings [ settings . value ( " index " ) . toInt ( ) ] = profile ;
2021-11-02 08:50:14 -04:00
2021-11-09 13:24:38 -05:00
settings . endGroup ( ) ;
2021-11-09 11:25:15 -05:00
}
2021-11-09 13:11:21 -05:00
readGameVersion ( ) ;
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : readWineInfo ( ProfileSettings & profile ) {
2021-11-10 04:30:01 -05:00
# if defined(Q_OS_MAC)
switch ( profile . wineVersion ) {
case 0 : // system wine
profile . winePath = " /usr/local/bin/wine64 " ;
break ;
case 1 : // custom path
profile . winePath = profile . winePath ;
break ;
case 2 : // ffxiv built-in (for mac users)
profile . winePath = " /Applications/FINAL FANTASY XIV ONLINE.app/Contents/SharedSupport/finalfantasyxiv/FINAL FANTASY XIV ONLINE/wine " ;
break ;
}
# endif
# if defined(Q_OS_LINUX)
switch ( profile . wineVersion ) {
case 0 : // system wine (should be in $PATH)
profile . winePath = " wine " ;
break ;
case 1 : // custom pth
profile . winePath = profile . winePath ;
break ;
}
# endif
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : readGameVersion ( ) {
2021-11-09 13:11:21 -05:00
for ( auto & profile : profileSettings ) {
profile . bootVersion = readVersion ( profile . gamePath + " /boot/ffxivboot.ver " ) ;
profile . gameVersion = readVersion ( profile . gamePath + " /game/ffxivgame.ver " ) ;
}
2021-11-01 09:54:58 -04:00
}
2021-11-23 15:34:23 -05:00
LauncherCore : : LauncherCore ( ) : settings ( QSettings : : IniFormat , QSettings : : UserScope , QCoreApplication : : applicationName ( ) ) {
2021-11-01 09:54:58 -04:00
mgr = new QNetworkAccessManager ( ) ;
sapphireLauncher = new SapphireLauncher ( * this ) ;
squareLauncher = new SquareLauncher ( * this ) ;
squareBoot = new SquareBoot ( * this , * squareLauncher ) ;
2021-11-23 14:37:37 -05:00
assetUpdater = new AssetUpdater ( * this ) ;
2021-11-01 09:54:58 -04:00
2021-11-09 11:25:15 -05:00
readInitialInformation ( ) ;
2021-11-09 12:06:30 -05:00
}
2021-11-23 15:34:23 -05:00
ProfileSettings LauncherCore : : getProfile ( int index ) const {
2021-11-09 12:06:30 -05:00
return profileSettings [ index ] ;
}
2021-11-23 15:34:23 -05:00
ProfileSettings & LauncherCore : : getProfile ( int index ) {
2021-11-09 12:06:30 -05:00
return profileSettings [ index ] ;
2021-11-09 11:03:44 -05:00
}
2021-11-23 15:34:23 -05:00
int LauncherCore : : getProfileIndex ( QString name ) {
2021-11-09 11:25:15 -05:00
for ( int i = 0 ; i < profileSettings . size ( ) ; i + + ) {
if ( profileSettings [ i ] . name = = name )
return i ;
2021-11-09 11:03:44 -05:00
}
2021-11-09 11:25:15 -05:00
return - 1 ;
2021-11-09 11:03:44 -05:00
}
2021-11-23 15:34:23 -05:00
QList < QString > LauncherCore : : profileList ( ) const {
2021-11-09 11:03:44 -05:00
QList < QString > list ;
for ( auto profile : profileSettings ) {
2021-11-09 11:25:15 -05:00
list . append ( profile . name ) ;
2021-11-09 11:03:44 -05:00
}
return list ;
2021-11-09 11:44:27 -05:00
}
2021-11-23 15:34:23 -05:00
int LauncherCore : : addProfile ( ) {
2021-11-09 11:44:27 -05:00
ProfileSettings newProfile ;
2021-11-09 13:24:38 -05:00
newProfile . uuid = QUuid : : createUuid ( ) ;
2021-11-09 11:44:27 -05:00
newProfile . name = " New Profile " ;
profileSettings . append ( newProfile ) ;
settingsChanged ( ) ;
return profileSettings . size ( ) - 1 ;
2021-11-09 12:16:14 -05:00
}
2021-11-23 15:34:23 -05:00
int LauncherCore : : deleteProfile ( QString name ) {
2021-11-09 13:44:37 -05:00
int index = 0 ;
for ( int i = 0 ; i < profileSettings . size ( ) ; i + + ) {
if ( profileSettings [ i ] . name = = name )
index = i ;
}
// remove group so it doesnt stay
settings . beginGroup ( profileSettings [ index ] . uuid . toString ( QUuid : : StringFormat : : WithoutBraces ) ) ;
settings . remove ( " " ) ;
settings . endGroup ( ) ;
profileSettings . removeAt ( index ) ;
return index - 1 ;
}
2021-11-23 15:34:23 -05:00
void LauncherCore : : saveSettings ( ) {
2021-11-09 13:24:38 -05:00
settings . setValue ( " defaultProfile " , defaultProfileIndex ) ;
for ( int i = 0 ; i < profileSettings . size ( ) ; i + + ) {
const auto & profile = profileSettings [ i ] ;
2021-11-09 13:26:59 -05:00
settings . beginGroup ( profile . uuid . toString ( QUuid : : StringFormat : : WithoutBraces ) ) ;
2021-11-09 13:24:38 -05:00
settings . setValue ( " name " , profile . name ) ;
settings . setValue ( " index " , i ) ;
2021-11-09 12:16:14 -05:00
2021-11-09 13:04:22 -05:00
// game
2021-11-09 12:16:14 -05:00
settings . setValue ( " useDX9 " , profile . useDX9 ) ;
2021-11-09 12:46:27 -05:00
settings . setValue ( " gamePath " , profile . gamePath ) ;
2021-11-09 12:40:44 -05:00
2021-11-09 13:04:22 -05:00
// wine
settings . setValue ( " wineVersion " , profile . wineVersion ) ;
settings . setValue ( " winePath " , profile . winePath ) ;
settings . setValue ( " winePrefixPath " , profile . winePrefixPath ) ;
2021-11-09 13:08:25 -05:00
settings . setValue ( " useEsync " , profile . useEsync ) ;
settings . setValue ( " useGamescope " , profile . useGamescope ) ;
settings . setValue ( " useGamemode " , profile . useGamemode ) ;
2021-11-09 13:04:22 -05:00
// login
2021-11-09 21:13:21 -05:00
settings . setValue ( " encryptArguments " , profile . encryptArguments ) ;
2021-11-09 12:40:44 -05:00
settings . setValue ( " isSapphire " , profile . isSapphire ) ;
2021-11-09 12:50:37 -05:00
settings . setValue ( " lobbyURL " , profile . lobbyURL ) ;
2021-11-09 12:32:18 -05:00
settings . setValue ( " rememberUsername " , profile . rememberUsername ) ;
settings . setValue ( " rememberPassword " , profile . rememberPassword ) ;
2021-11-09 12:16:14 -05:00
2021-11-23 14:37:37 -05:00
settings . setValue ( " enableDalamud " , profile . enableDalamud ) ;
2021-11-09 12:16:14 -05:00
settings . endGroup ( ) ;
}
2021-11-09 11:03:44 -05:00
}