mirror of
https://github.com/redstrate/Astra.git
synced 2025-06-08 15:07:45 +00:00
Add stubs for new profile-specific settings
This commit is contained in:
parent
3ce0e6ca95
commit
1be913b97b
5 changed files with 107 additions and 63 deletions
|
@ -52,17 +52,17 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
|
||||
connect(directXCombo, &QComboBox::currentIndexChanged, [=](int index) {
|
||||
this->window.settings.setValue("directx", directXCombo->currentIndex());
|
||||
this->window.useDX9 = directXCombo->currentIndex() == 1;
|
||||
this->window.currentProfile().useDX9 = directXCombo->currentIndex() == 1;
|
||||
});
|
||||
|
||||
auto currentGameDirectory = new QLabel(window.gamePath);
|
||||
auto currentGameDirectory = new QLabel(window.currentProfile().gamePath);
|
||||
currentGameDirectory->setWordWrap(true);
|
||||
gameBoxLayout->addRow("Game Directory", currentGameDirectory);
|
||||
|
||||
auto selectDirectoryButton = new QPushButton("Select Game Directory");
|
||||
connect(selectDirectoryButton, &QPushButton::pressed, [this, currentGameDirectory] {
|
||||
this->window.gamePath = QFileDialog::getExistingDirectory(this, "Open Game Directory");
|
||||
currentGameDirectory->setText(this->window.gamePath);
|
||||
this->window.currentProfile().gamePath = QFileDialog::getExistingDirectory(this, "Open Game Directory");
|
||||
currentGameDirectory->setText(this->window.currentProfile().gamePath);
|
||||
|
||||
this->window.readInitialInformation();
|
||||
});
|
||||
|
@ -70,7 +70,7 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
|
||||
auto gameDirectoryButton = new QPushButton("Open Game Directory");
|
||||
connect(gameDirectoryButton, &QPushButton::pressed, [this] {
|
||||
openPath(this->window.gamePath);
|
||||
openPath(this->window.currentProfile().gamePath);
|
||||
});
|
||||
gameBoxLayout->addWidget(gameDirectoryButton);
|
||||
|
||||
|
@ -86,7 +86,7 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
infoLabel->setWordWrap(true);
|
||||
wineBoxLayout->addWidget(infoLabel);
|
||||
|
||||
auto winePathLabel = new QLabel(window.winePath);
|
||||
auto winePathLabel = new QLabel(window.currentProfile().winePath);
|
||||
winePathLabel->setWordWrap(true);
|
||||
wineBoxLayout->addRow("Wine Executable", winePathLabel);
|
||||
|
||||
|
@ -110,25 +110,25 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
selectWineButton->setEnabled(index == 1);
|
||||
|
||||
this->window.readInitialInformation();
|
||||
winePathLabel->setText(this->window.winePath);
|
||||
winePathLabel->setText(this->window.currentProfile().winePath);
|
||||
});
|
||||
|
||||
connect(selectWineButton, &QPushButton::pressed, [this, winePathLabel] {
|
||||
this->window.winePath = QFileDialog::getOpenFileName(this, "Open Wine Executable");
|
||||
this->window.settings.setValue("winePath", this->window.winePath);
|
||||
this->window.currentProfile().winePath = QFileDialog::getOpenFileName(this, "Open Wine Executable");
|
||||
this->window.settings.setValue("winePath", this->window.currentProfile().winePath);
|
||||
|
||||
this->window.readInitialInformation();
|
||||
winePathLabel->setText(this->window.winePath);
|
||||
winePathLabel->setText(this->window.currentProfile().winePath);
|
||||
});
|
||||
|
||||
auto winePrefixDirectory = new QLabel(window.winePrefixPath);
|
||||
auto winePrefixDirectory = new QLabel(window.currentProfile().winePrefixPath);
|
||||
winePrefixDirectory->setWordWrap(true);
|
||||
wineBoxLayout->addRow("Wine Prefix", winePrefixDirectory);
|
||||
|
||||
auto selectPrefixButton = new QPushButton("Select Wine Prefix");
|
||||
connect(selectPrefixButton, &QPushButton::pressed, [this, winePrefixDirectory] {
|
||||
this->window.winePrefixPath = QFileDialog::getExistingDirectory(this, "Open Wine Prefix");
|
||||
winePrefixDirectory->setText(this->window.winePrefixPath);
|
||||
this->window.currentProfile().winePrefixPath = QFileDialog::getExistingDirectory(this, "Open Wine Prefix");
|
||||
winePrefixDirectory->setText(this->window.currentProfile().winePrefixPath);
|
||||
|
||||
this->window.readInitialInformation();
|
||||
});
|
||||
|
@ -136,23 +136,23 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
|
||||
auto openPrefixButton = new QPushButton("Open Wine Prefix");
|
||||
connect(openPrefixButton, &QPushButton::pressed, [this] {
|
||||
openPath(this->window.winePrefixPath);
|
||||
openPath(this->window.currentProfile().winePrefixPath);
|
||||
});
|
||||
wineBoxLayout->addWidget(openPrefixButton);
|
||||
|
||||
auto enableDXVKhud = new QCheckBox("Enable DXVK HUD");
|
||||
enableDXVKhud->setChecked(window.enableDXVKhud);
|
||||
enableDXVKhud->setChecked(window.currentProfile().enableDXVKhud);
|
||||
wineBoxLayout->addWidget(enableDXVKhud);
|
||||
|
||||
connect(enableDXVKhud, &QCheckBox::stateChanged, [this](int state) {
|
||||
this->window.enableDXVKhud = state;
|
||||
this->window.currentProfile().enableDXVKhud = state;
|
||||
this->window.settings.setValue("enableDXVKhud", static_cast<bool>(state));
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
auto useEsync = new QCheckBox("Use Esync");
|
||||
useEsync->setChecked(window.useEsync);
|
||||
useEsync->setChecked(window.currentProfile().useEsync);
|
||||
wineBoxLayout->addWidget(useEsync);
|
||||
|
||||
auto esyncLabel = new QLabel("Improves general game performance, but requires a Wine built with the Esync patches.\n"
|
||||
|
@ -161,12 +161,12 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
wineBoxLayout->addWidget(esyncLabel);
|
||||
|
||||
connect(useEsync, &QCheckBox::stateChanged, [this](int state) {
|
||||
this->window.useEsync = state;
|
||||
this->window.currentProfile().useEsync = state;
|
||||
this->window.settings.setValue("useEsync", static_cast<bool>(state));
|
||||
});
|
||||
|
||||
auto useGamescope = new QCheckBox("Use Gamescope");
|
||||
useGamescope->setChecked(window.useGamescope);
|
||||
useGamescope->setChecked(window.currentProfile().useGamescope);
|
||||
wineBoxLayout->addWidget(useGamescope);
|
||||
|
||||
auto gamescopeLabel = new QLabel("Use the SteamOS compositor that uses Wayland.\n"
|
||||
|
@ -175,12 +175,12 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
wineBoxLayout->addWidget(gamescopeLabel);
|
||||
|
||||
connect(useGamescope, &QCheckBox::stateChanged, [this](int state) {
|
||||
this->window.useGamescope = state;
|
||||
this->window.currentProfile().useGamescope = state;
|
||||
this->window.settings.setValue("useGamescope", static_cast<bool>(state));
|
||||
});
|
||||
|
||||
auto useGamemode = new QCheckBox("Use Gamemode");
|
||||
useGamemode->setChecked(window.useGamemode);
|
||||
useGamemode->setChecked(window.currentProfile().useGamemode);
|
||||
wineBoxLayout->addWidget(useGamemode);
|
||||
|
||||
auto gamemodeLabel = new QLabel("Use Feral Interactive's GameMode, which applies a couple of performance enhancements.\n"
|
||||
|
@ -189,7 +189,7 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, QWidget* parent) : window
|
|||
wineBoxLayout->addWidget(gamemodeLabel);
|
||||
|
||||
connect(useGamemode, &QCheckBox::stateChanged, [this](int state) {
|
||||
this->window.useGamemode = state;
|
||||
this->window.currentProfile().useGamemode = state;
|
||||
this->window.settings.setValue("useGamemode", static_cast<bool>(state));
|
||||
});
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ void SquareBoot::bootCheck(LoginInformation& info) {
|
|||
QUrl url;
|
||||
url.setScheme("http");
|
||||
url.setHost("patch-bootver.ffxiv.com");
|
||||
url.setPath(QString("/http/win32/ffxivneo_release_boot/%1").arg(window.bootVersion));
|
||||
url.setPath(QString("/http/win32/ffxivneo_release_boot/%1").arg(window.currentProfile().bootVersion));
|
||||
url.setQuery(query);
|
||||
|
||||
auto request = QNetworkRequest(url);
|
||||
|
|
|
@ -103,7 +103,7 @@ void SquareLauncher::registerSession(const LoginInformation& info) {
|
|||
QUrl url;
|
||||
url.setScheme("https");
|
||||
url.setHost("patch-gamever.ffxiv.com");
|
||||
url.setPath(QString("/http/win32/ffxivneo_release_game/%1/%2").arg(window.gameVersion, SID));
|
||||
url.setPath(QString("/http/win32/ffxivneo_release_game/%1/%2").arg(window.currentProfile().gameVersion, SID));
|
||||
|
||||
auto request = QNetworkRequest(url);
|
||||
window.setSSL(request);
|
||||
|
@ -111,7 +111,7 @@ void SquareLauncher::registerSession(const LoginInformation& info) {
|
|||
request.setRawHeader("User-Agent", "FFXIV PATCH CLIENT");
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
|
||||
|
||||
QString report = window.bootVersion + "=" + getBootHash();
|
||||
QString report = window.currentProfile().bootVersion + "=" + getBootHash();
|
||||
|
||||
for(int i = 0; i < expansionVersions.size(); i++)
|
||||
report += QString("\nex%1\t%2").arg(QString::number(i + 1), expansionVersions[i]);
|
||||
|
@ -142,7 +142,7 @@ QString SquareLauncher::getBootHash() {
|
|||
|
||||
QString result;
|
||||
for (int i = 0; i < fileList.count(); i++) {
|
||||
result += fileList[i] + "/" + getFileHash(window.gamePath + "/boot/" + fileList[i]);
|
||||
result += fileList[i] + "/" + getFileHash(window.currentProfile().gamePath + "/boot/" + fileList[i]);
|
||||
|
||||
if (i != fileList.length() - 1)
|
||||
result += ",";
|
||||
|
@ -153,5 +153,5 @@ QString SquareLauncher::getBootHash() {
|
|||
|
||||
void SquareLauncher::readExpansionVersions(int max) {
|
||||
for(int i = 0; i < max; i++)
|
||||
expansionVersions.push_back(window.readVersion(QString("%1/game/sqpack/ex%2/ex%2.ver").arg(window.gamePath, QString::number(i + 1))));
|
||||
expansionVersions.push_back(window.readVersion(QString("%1/game/sqpack/ex%2/ex%2.ver").arg(window.currentProfile().gamePath, QString::number(i + 1))));
|
||||
}
|
|
@ -43,10 +43,10 @@ void LauncherWindow::launchGame(const LoginAuth auth) {
|
|||
QList<QString> arguments;
|
||||
|
||||
// now for the actual game...
|
||||
if(useDX9) {
|
||||
arguments.push_back(gamePath + "\\game\\ffxiv.exe");
|
||||
if(currentProfile().useDX9) {
|
||||
arguments.push_back(currentProfile().gamePath + "\\game\\ffxiv.exe");
|
||||
} else {
|
||||
arguments.push_back(gamePath + "\\game\\ffxiv_dx11.exe");
|
||||
arguments.push_back(currentProfile().gamePath + "\\game\\ffxiv_dx11.exe");
|
||||
}
|
||||
|
||||
arguments.push_back("DEV.DataPathType=1");
|
||||
|
@ -55,8 +55,8 @@ void LauncherWindow::launchGame(const LoginAuth auth) {
|
|||
arguments.push_back(QString("DEV.MaxEntitledExpansionID=%1").arg(auth.maxExpansion));
|
||||
arguments.push_back(QString("DEV.TestSID=%1").arg(auth.SID));
|
||||
arguments.push_back(QString("SYS.Region=%1").arg(auth.region));
|
||||
arguments.push_back(QString("language=%1").arg(language));
|
||||
arguments.push_back(QString("ver=%1").arg(gameVersion));
|
||||
arguments.push_back(QString("language=%1").arg(currentProfile().language));
|
||||
arguments.push_back(QString("ver=%1").arg(currentProfile().gameVersion));
|
||||
|
||||
if(!auth.lobbyhost.isEmpty()) {
|
||||
arguments.push_back(QString("DEV.GMServerHost=%1").arg(auth.frontierHost));
|
||||
|
@ -75,27 +75,27 @@ void LauncherWindow::launchExecutable(const QStringList args) {
|
|||
QStringList env = QProcess::systemEnvironment();
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
if(useGamescope) {
|
||||
if(currentProfile().useGamescope) {
|
||||
arguments.push_back("gamescope");
|
||||
arguments.push_back("-f");
|
||||
arguments.push_back("-b");
|
||||
}
|
||||
|
||||
if(useGamemode)
|
||||
if(currentProfile().useGamemode)
|
||||
arguments.push_back("gamemoderun");
|
||||
|
||||
if(useEsync) {
|
||||
if(currentProfile().useEsync) {
|
||||
env << "WINEESYNC=1";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||
env << "WINEPREFIX=" + winePrefixPath;
|
||||
env << "WINEPREFIX=" + currentProfile().winePrefixPath;
|
||||
|
||||
if(enableDXVKhud)
|
||||
if(currentProfile().enableDXVKhud)
|
||||
env << "DXVK_HUD=full";
|
||||
|
||||
arguments.push_back(winePath);
|
||||
arguments.push_back(currentProfile().winePath);
|
||||
#endif
|
||||
|
||||
arguments.append(args);
|
||||
|
@ -103,7 +103,7 @@ void LauncherWindow::launchExecutable(const QStringList args) {
|
|||
auto executable = arguments[0];
|
||||
arguments.removeFirst();
|
||||
|
||||
process->setWorkingDirectory(gamePath + "/game/");
|
||||
process->setWorkingDirectory(currentProfile().gamePath + "/game/");
|
||||
process->setEnvironment(env);
|
||||
process->start(executable, arguments);
|
||||
}
|
||||
|
@ -134,16 +134,16 @@ void LauncherWindow::readInitialInformation() {
|
|||
#if defined(Q_OS_LINUX)
|
||||
switch(wineVersion) {
|
||||
case 0: // system wine (should be in $PATH)
|
||||
winePath = "wine";
|
||||
currentProfile().winePath = "wine";
|
||||
break;
|
||||
case 1: // custom pth
|
||||
winePath = settings.value("winePath").toString();
|
||||
currentProfile().winePath = settings.value("winePath").toString();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(settings.contains("gamePath") && settings.value("gamePath").canConvert<QString>() && !settings.value("gamePath").toString().isEmpty()) {
|
||||
gamePath = settings.value("gamePath").toString();
|
||||
currentProfile().gamePath = settings.value("gamePath").toString();
|
||||
} else {
|
||||
#if defined(Q_OS_WIN)
|
||||
gamePath = "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn";
|
||||
|
@ -154,29 +154,29 @@ void LauncherWindow::readInitialInformation() {
|
|||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
gamePath = QDir::homePath() + "/.wine/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn";
|
||||
currentProfile().gamePath = QDir::homePath() + "/.wine/drive_c/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn";
|
||||
#endif
|
||||
}
|
||||
|
||||
if(settings.contains("winePrefix") && settings.value("winePrefix").canConvert<QString>() && !settings.value("winePrefix").toString().isEmpty()) {
|
||||
winePrefixPath = settings.value("winePrefix").toString();
|
||||
currentProfile().winePrefixPath = settings.value("winePrefix").toString();
|
||||
} else {
|
||||
#if defined(Q_OS_MACOS)
|
||||
winePrefixPath = QDir::homePath() + "/Library/Application Support/FINAL FANTASY XIV ONLINE/Bottles/published_Final_Fantasy";
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
winePrefixPath = QDir::homePath() + "/.wine";
|
||||
currentProfile().winePrefixPath = QDir::homePath() + "/.wine";
|
||||
#endif
|
||||
}
|
||||
|
||||
bootVersion = readVersion(gamePath + "/boot/ffxivboot.ver");
|
||||
gameVersion = readVersion(gamePath + "/game/ffxivgame.ver");
|
||||
currentProfile().bootVersion = readVersion(currentProfile().gamePath + "/boot/ffxivboot.ver");
|
||||
currentProfile().gameVersion = readVersion(currentProfile().gamePath + "/game/ffxivgame.ver");
|
||||
|
||||
useEsync = settings.value("useEsync", false).toBool();
|
||||
useGamemode = settings.value("useGamemode", false).toBool();
|
||||
useGamescope = settings.value("useGamescope", false).toBool();
|
||||
enableDXVKhud = settings.value("enableDXVKhud", false).toBool();
|
||||
currentProfile().useEsync = settings.value("useEsync", false).toBool();
|
||||
currentProfile().useGamemode = settings.value("useGamemode", false).toBool();
|
||||
currentProfile().useGamescope = settings.value("useGamescope", false).toBool();
|
||||
currentProfile().enableDXVKhud = settings.value("enableDXVKhud", false).toBool();
|
||||
}
|
||||
|
||||
LauncherWindow::LauncherWindow(QWidget* parent) :
|
||||
|
@ -186,6 +186,8 @@ LauncherWindow::LauncherWindow(QWidget* parent) :
|
|||
squareLauncher = new SquareLauncher(*this);
|
||||
squareBoot = new SquareBoot(*this, *squareLauncher);
|
||||
|
||||
profileSettings.append(ProfileSettings());
|
||||
|
||||
QMenu* fileMenu = menuBar()->addMenu("File");
|
||||
// sorry linux users, for some reason my global menu does not like qt6 apps right now
|
||||
#if defined(Q_OS_LINUX)
|
||||
|
@ -202,17 +204,17 @@ LauncherWindow::LauncherWindow(QWidget* parent) :
|
|||
|
||||
QAction* launchOfficial = toolsMenu->addAction("Launch Official Client...");
|
||||
connect(launchOfficial, &QAction::triggered, [=] {
|
||||
launchExecutable({gamePath + "/boot/ffxivboot64.exe"});
|
||||
launchExecutable({currentProfile().gamePath + "/boot/ffxivboot64.exe"});
|
||||
});
|
||||
|
||||
QAction* launchSysInfo = toolsMenu->addAction("Launch System Info...");
|
||||
connect(launchSysInfo, &QAction::triggered, [=] {
|
||||
launchExecutable({gamePath + "/boot/ffxivsysinfo64.exe"});
|
||||
launchExecutable({currentProfile().gamePath + "/boot/ffxivsysinfo64.exe"});
|
||||
});
|
||||
|
||||
QAction* launchCfgBackup = toolsMenu->addAction("Launch Config Backup...");
|
||||
connect(launchCfgBackup, &QAction::triggered, [=] {
|
||||
launchExecutable({gamePath + "/boot/ffxivconfig64.exe"});
|
||||
launchExecutable({currentProfile().gamePath + "/boot/ffxivconfig64.exe"});
|
||||
});
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||
|
@ -304,8 +306,8 @@ LauncherWindow::LauncherWindow(QWidget* parent) :
|
|||
connect(loginButton, &QPushButton::released, [=] {
|
||||
auto info = LoginInformation{usernameEdit->text(), passwordEdit->text(), otpEdit->text()};
|
||||
|
||||
settings.setValue("gamePath", gamePath);
|
||||
settings.setValue("winePrefix", winePrefixPath);
|
||||
settings.setValue("gamePath", currentProfile().gamePath);
|
||||
settings.setValue("winePrefix", currentProfile().winePrefixPath);
|
||||
|
||||
settings.setValue("rememberUsername", rememberUsernameBox->checkState() == Qt::CheckState::Checked);
|
||||
if(rememberUsernameBox->checkState() == Qt::CheckState::Checked) {
|
||||
|
@ -343,3 +345,34 @@ LauncherWindow::LauncherWindow(QWidget* parent) :
|
|||
}
|
||||
|
||||
LauncherWindow::~LauncherWindow() = default;
|
||||
|
||||
ProfileSettings LauncherWindow::currentProfile() const {
|
||||
return profileSettings[currentProfileIndex];
|
||||
}
|
||||
|
||||
ProfileSettings& LauncherWindow::currentProfile() {
|
||||
return profileSettings[currentProfileIndex];
|
||||
}
|
||||
|
||||
void LauncherWindow::setProfile(QString name) {
|
||||
for(int i = 0; i < profileSettings.size(); i++) {
|
||||
currentProfileIndex = 0;
|
||||
}
|
||||
|
||||
currentProfileIndex = -1;
|
||||
}
|
||||
|
||||
ProfileSettings LauncherWindow::getProfile(QString name) {
|
||||
for(auto profile : profileSettings) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QString> LauncherWindow::profileList() const {
|
||||
QList<QString> list;
|
||||
for(auto profile : profileSettings) {
|
||||
list.append("Default");
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
|
@ -9,6 +9,16 @@ class SapphireLauncher;
|
|||
class SquareLauncher;
|
||||
class SquareBoot;
|
||||
|
||||
struct ProfileSettings {
|
||||
int language = 1; // 1 is english, thats all i know
|
||||
QString gamePath, winePath, winePrefixPath;
|
||||
QString bootVersion, gameVersion;
|
||||
|
||||
bool useEsync, useGamescope, useGamemode;
|
||||
bool useDX9 = false;
|
||||
bool enableDXVKhud = false;
|
||||
};
|
||||
|
||||
struct LoginInformation {
|
||||
QString username, password, oneTimePassword;
|
||||
};
|
||||
|
@ -31,13 +41,11 @@ public:
|
|||
|
||||
QNetworkAccessManager* mgr;
|
||||
|
||||
int language = 1; // 1 is english, thats all i know
|
||||
QString gamePath, winePath, winePrefixPath;
|
||||
QString bootVersion, gameVersion;
|
||||
|
||||
bool useEsync, useGamescope, useGamemode;
|
||||
bool useDX9 = false;
|
||||
bool enableDXVKhud = false;
|
||||
ProfileSettings currentProfile() const;
|
||||
ProfileSettings& currentProfile();
|
||||
void setProfile(QString name);
|
||||
ProfileSettings getProfile(QString name);
|
||||
QList<QString> profileList() const;
|
||||
|
||||
void launchGame(const LoginAuth auth);
|
||||
void launchExecutable(const QStringList args);
|
||||
|
@ -52,4 +60,7 @@ private:
|
|||
SapphireLauncher* sapphireLauncher;
|
||||
SquareBoot* squareBoot;
|
||||
SquareLauncher* squareLauncher;
|
||||
|
||||
QList<ProfileSettings> profileSettings;
|
||||
int currentProfileIndex = 0;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue