2021-11-23 15:34:23 -05:00
|
|
|
#include "launcherwindow.h"
|
|
|
|
|
|
|
|
#include <QMenuBar>
|
2022-03-01 17:21:29 -05:00
|
|
|
#include <keychain.h>
|
2021-11-23 15:34:23 -05:00
|
|
|
#include <QFormLayout>
|
2021-12-03 17:19:58 -05:00
|
|
|
#include <QApplication>
|
2022-02-24 09:28:11 -05:00
|
|
|
#include <QDesktopServices>
|
2021-11-23 15:34:23 -05:00
|
|
|
|
|
|
|
#include "settingswindow.h"
|
|
|
|
#include "squareboot.h"
|
|
|
|
#include "squarelauncher.h"
|
|
|
|
#include "sapphirelauncher.h"
|
|
|
|
#include "assetupdater.h"
|
|
|
|
|
|
|
|
LauncherWindow::LauncherWindow(LauncherCore& core, QWidget* parent) : QMainWindow(parent), core(core) {
|
2022-02-23 19:00:17 -05:00
|
|
|
setWindowTitle("Astra");
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
connect(&core, &LauncherCore::settingsChanged, this, &LauncherWindow::reloadControls);
|
|
|
|
|
|
|
|
QMenu* toolsMenu = menuBar()->addMenu("Tools");
|
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
QAction* launchOfficial = toolsMenu->addAction("Open Official Client...");
|
|
|
|
launchOfficial->setIcon(QIcon::fromTheme("application-x-executable"));
|
2021-11-23 15:34:23 -05:00
|
|
|
connect(launchOfficial, &QAction::triggered, [=] {
|
2021-12-02 22:26:08 -05:00
|
|
|
this->core.launchExecutable(currentProfile(), {currentProfile().gamePath + "/boot/ffxivboot.exe"});
|
2021-11-23 15:34:23 -05:00
|
|
|
});
|
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
QAction* launchSysInfo = toolsMenu->addAction("Open System Info...");
|
|
|
|
launchSysInfo->setIcon(QIcon::fromTheme("application-x-executable"));
|
2021-11-23 15:34:23 -05:00
|
|
|
connect(launchSysInfo, &QAction::triggered, [=] {
|
|
|
|
this->core.launchExecutable(currentProfile(), {currentProfile().gamePath + "/boot/ffxivsysinfo64.exe"});
|
|
|
|
});
|
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
QAction* launchCfgBackup = toolsMenu->addAction("Open Config Backup...");
|
|
|
|
launchCfgBackup->setIcon(QIcon::fromTheme("application-x-executable"));
|
2021-11-23 15:34:23 -05:00
|
|
|
connect(launchCfgBackup, &QAction::triggered, [=] {
|
|
|
|
this->core.launchExecutable(currentProfile(), {currentProfile().gamePath + "/boot/ffxivconfig64.exe"});
|
|
|
|
});
|
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
toolsMenu->addSeparator();
|
2021-11-23 15:34:23 -05:00
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
QAction* openGameDir = toolsMenu->addAction("Open Game Directory...");
|
|
|
|
openGameDir->setIcon(QIcon::fromTheme("document-open"));
|
|
|
|
connect(openGameDir, &QAction::triggered, [=] {
|
|
|
|
openPath(currentProfile().gamePath);
|
2021-11-23 15:34:23 -05:00
|
|
|
});
|
|
|
|
|
2022-02-24 09:28:11 -05:00
|
|
|
QMenu* fileMenu = menuBar()->addMenu("Settings");
|
|
|
|
|
|
|
|
QAction* settingsAction = fileMenu->addAction("Configure Astra...");
|
|
|
|
settingsAction->setIcon(QIcon::fromTheme("settings"));
|
|
|
|
connect(settingsAction, &QAction::triggered, [=] {
|
|
|
|
auto window = new SettingsWindow(*this, this->core, this);
|
|
|
|
connect(&this->core, &LauncherCore::settingsChanged, window, &SettingsWindow::reloadControls);
|
|
|
|
window->show();
|
|
|
|
});
|
|
|
|
|
|
|
|
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
|
|
|
QAction* wineCfg = fileMenu->addAction("Configure Wine...");
|
|
|
|
wineCfg->setIcon(QIcon::fromTheme("settings"));
|
|
|
|
connect(wineCfg, &QAction::triggered, [=] {
|
|
|
|
this->core.launchExecutable(currentProfile(), {"winecfg.exe"});
|
2021-11-23 15:34:23 -05:00
|
|
|
});
|
|
|
|
#endif
|
|
|
|
|
2021-12-03 17:19:58 -05:00
|
|
|
QMenu* helpMenu = menuBar()->addMenu("Help");
|
2022-02-23 19:00:17 -05:00
|
|
|
QAction* showAbout = helpMenu->addAction("About Astra");
|
2022-02-24 09:28:11 -05:00
|
|
|
showAbout->setIcon(QIcon::fromTheme("help-about"));
|
2021-12-03 17:19:58 -05:00
|
|
|
connect(showAbout, &QAction::triggered, [=] {
|
2022-02-23 19:00:17 -05:00
|
|
|
QMessageBox::about(this, "About Astra", "The source code is available <a href='https://github.com/redstrate/astra'>here</a>.");
|
2021-12-03 17:19:58 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
QAction* showAboutQt = helpMenu->addAction("About Qt");
|
2022-02-24 09:28:11 -05:00
|
|
|
showAboutQt->setIcon(QIcon::fromTheme("help-about"));
|
2021-12-03 17:19:58 -05:00
|
|
|
connect(showAboutQt, &QAction::triggered, [=] {
|
|
|
|
QApplication::aboutQt();
|
|
|
|
});
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
auto layout = new QFormLayout();
|
|
|
|
|
|
|
|
profileSelect = new QComboBox();
|
|
|
|
connect(profileSelect, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int index) {
|
|
|
|
reloadControls();
|
|
|
|
});
|
|
|
|
|
|
|
|
layout->addRow("Profile", profileSelect);
|
|
|
|
|
|
|
|
usernameEdit = new QLineEdit();
|
|
|
|
layout->addRow("Username", usernameEdit);
|
|
|
|
|
|
|
|
rememberUsernameBox = new QCheckBox();
|
|
|
|
connect(rememberUsernameBox, &QCheckBox::stateChanged, [=](int) {
|
|
|
|
currentProfile().rememberUsername = rememberUsernameBox->isChecked();
|
|
|
|
this->core.saveSettings();
|
|
|
|
});
|
|
|
|
layout->addRow("Remember Username?", rememberUsernameBox);
|
|
|
|
|
|
|
|
passwordEdit = new QLineEdit();
|
|
|
|
passwordEdit->setEchoMode(QLineEdit::EchoMode::Password);
|
|
|
|
layout->addRow("Password", passwordEdit);
|
|
|
|
|
|
|
|
rememberPasswordBox = new QCheckBox();
|
|
|
|
connect(rememberPasswordBox, &QCheckBox::stateChanged, [=](int) {
|
|
|
|
currentProfile().rememberPassword = rememberPasswordBox->isChecked();
|
|
|
|
this->core.saveSettings();
|
|
|
|
});
|
|
|
|
layout->addRow("Remember Password?", rememberPasswordBox);
|
|
|
|
|
|
|
|
otpEdit = new QLineEdit();
|
|
|
|
layout->addRow("One-Time Password", otpEdit);
|
|
|
|
|
2021-12-02 14:17:33 -05:00
|
|
|
loginButton = new QPushButton("Login");
|
2021-11-23 15:34:23 -05:00
|
|
|
layout->addRow(loginButton);
|
|
|
|
|
|
|
|
registerButton = new QPushButton("Register");
|
|
|
|
layout->addRow(registerButton);
|
|
|
|
|
|
|
|
auto emptyWidget = new QWidget();
|
|
|
|
emptyWidget->setLayout(layout);
|
|
|
|
setCentralWidget(emptyWidget);
|
|
|
|
|
|
|
|
connect(core.assetUpdater, &AssetUpdater::finishedUpdating, [=] {
|
|
|
|
auto info = LoginInformation{¤tProfile(), usernameEdit->text(), passwordEdit->text(), otpEdit->text()};
|
|
|
|
|
2022-02-24 09:38:41 -05:00
|
|
|
#ifndef QT_DEBUG
|
2021-11-23 15:34:23 -05:00
|
|
|
if(currentProfile().rememberUsername) {
|
|
|
|
auto job = new QKeychain::WritePasswordJob("LauncherWindow");
|
|
|
|
job->setTextData(usernameEdit->text());
|
|
|
|
job->setKey(currentProfile().name + "-username");
|
|
|
|
job->start();
|
|
|
|
}
|
2022-02-24 09:38:41 -05:00
|
|
|
#endif
|
2021-11-23 15:34:23 -05:00
|
|
|
|
2022-02-24 09:38:41 -05:00
|
|
|
#ifndef QT_DEBUG
|
2021-11-23 15:34:23 -05:00
|
|
|
if(currentProfile().rememberPassword) {
|
|
|
|
auto job = new QKeychain::WritePasswordJob("LauncherWindow");
|
|
|
|
job->setTextData(passwordEdit->text());
|
|
|
|
job->setKey(currentProfile().name + "-password");
|
|
|
|
job->start();
|
|
|
|
}
|
2022-02-24 09:38:41 -05:00
|
|
|
#endif
|
2021-11-23 15:34:23 -05:00
|
|
|
|
|
|
|
if(currentProfile().isSapphire) {
|
|
|
|
this->core.sapphireLauncher->login(currentProfile().lobbyURL, info);
|
|
|
|
} else {
|
|
|
|
this->core.squareBoot->bootCheck(info);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(loginButton, &QPushButton::released, [=] {
|
|
|
|
// update the assets first if needed, then it calls the slot above :-)
|
|
|
|
this->core.assetUpdater->update(currentProfile());
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(registerButton, &QPushButton::released, [=] {
|
|
|
|
if(currentProfile().isSapphire) {
|
|
|
|
auto info = LoginInformation{¤tProfile(), usernameEdit->text(), passwordEdit->text(), otpEdit->text()};
|
|
|
|
this->core.sapphireLauncher->registerAccount(currentProfile().lobbyURL, info);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-02-24 09:10:00 -05:00
|
|
|
connect(&core, &LauncherCore::successfulLaunch, [&] {
|
|
|
|
hide();
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(&core, &LauncherCore::gameClosed, [&] {
|
|
|
|
if(core.appSettings.closeWhenLaunched)
|
|
|
|
QCoreApplication::quit();
|
|
|
|
});
|
|
|
|
|
2021-11-23 15:34:23 -05:00
|
|
|
reloadControls();
|
|
|
|
}
|
|
|
|
|
|
|
|
ProfileSettings LauncherWindow::currentProfile() const {
|
|
|
|
return core.getProfile(profileSelect->currentIndex());
|
|
|
|
}
|
|
|
|
|
|
|
|
ProfileSettings& LauncherWindow::currentProfile() {
|
|
|
|
return core.getProfile(profileSelect->currentIndex());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWindow::reloadControls() {
|
|
|
|
if(currentlyReloadingControls)
|
|
|
|
return;
|
|
|
|
|
|
|
|
currentlyReloadingControls = true;
|
|
|
|
|
|
|
|
const int oldIndex = profileSelect->currentIndex();
|
|
|
|
|
|
|
|
profileSelect->clear();
|
|
|
|
|
|
|
|
for(const auto& profile : core.profileList()) {
|
|
|
|
profileSelect->addItem(profile);
|
|
|
|
}
|
|
|
|
|
|
|
|
profileSelect->setCurrentIndex(oldIndex);
|
|
|
|
|
|
|
|
if(profileSelect->currentIndex() == -1) {
|
|
|
|
profileSelect->setCurrentIndex(core.defaultProfileIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
rememberUsernameBox->setChecked(currentProfile().rememberUsername);
|
2022-02-24 09:38:41 -05:00
|
|
|
#ifndef QT_DEBUG
|
2021-11-23 15:34:23 -05:00
|
|
|
if(currentProfile().rememberUsername) {
|
|
|
|
auto job = new QKeychain::ReadPasswordJob("LauncherWindow");
|
|
|
|
job->setKey(currentProfile().name + "-username");
|
|
|
|
job->start();
|
|
|
|
|
|
|
|
connect(job, &QKeychain::ReadPasswordJob::finished, [=](QKeychain::Job* j) {
|
|
|
|
usernameEdit->setText(job->textData());
|
|
|
|
});
|
|
|
|
}
|
2022-02-24 09:38:41 -05:00
|
|
|
#endif
|
2021-11-23 15:34:23 -05:00
|
|
|
|
|
|
|
rememberPasswordBox->setChecked(currentProfile().rememberPassword);
|
2022-02-24 09:38:41 -05:00
|
|
|
#ifndef QT_DEBUG
|
2021-11-23 15:34:23 -05:00
|
|
|
if(currentProfile().rememberPassword) {
|
|
|
|
auto job = new QKeychain::ReadPasswordJob("LauncherWindow");
|
|
|
|
job->setKey(currentProfile().name + "-password");
|
|
|
|
job->start();
|
|
|
|
|
|
|
|
connect(job, &QKeychain::ReadPasswordJob::finished, [=](QKeychain::Job* j) {
|
|
|
|
passwordEdit->setText(job->textData());
|
|
|
|
});
|
|
|
|
}
|
2022-02-24 09:38:41 -05:00
|
|
|
#endif
|
2021-11-23 15:34:23 -05:00
|
|
|
|
2021-12-02 14:40:04 -05:00
|
|
|
const bool canLogin = currentProfile().isSapphire || (!currentProfile().isSapphire && core.squareLauncher->isGateOpen);
|
2021-12-02 14:17:33 -05:00
|
|
|
|
2021-12-02 14:40:04 -05:00
|
|
|
if(canLogin) {
|
2021-12-02 14:17:33 -05:00
|
|
|
loginButton->setText("Login");
|
|
|
|
} else {
|
|
|
|
loginButton->setText("Login (Maintenance is in progress)");
|
|
|
|
}
|
|
|
|
|
2021-12-02 14:40:04 -05:00
|
|
|
loginButton->setEnabled(canLogin);
|
2021-11-23 15:34:23 -05:00
|
|
|
registerButton->setEnabled(currentProfile().isSapphire);
|
|
|
|
otpEdit->setEnabled(!currentProfile().isSapphire);
|
|
|
|
|
|
|
|
currentlyReloadingControls = false;
|
2022-02-24 09:28:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWindow::openPath(const QString path) {
|
|
|
|
#if defined(Q_OS_WIN)
|
|
|
|
// for some reason, windows requires special treatment (what else is new?)
|
|
|
|
const QFileInfo fileInfo(path);
|
|
|
|
|
|
|
|
QProcess::startDetached("explorer.exe", QStringList(QDir::toNativeSeparators(fileInfo.canonicalFilePath())));
|
|
|
|
#else
|
|
|
|
QDesktopServices::openUrl("file://" + path);
|
|
|
|
#endif
|
|
|
|
}
|