1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-05-06 10:47:44 +00:00

Overhaul custom server settings, allow configuring more servers

You can now configure the frontier server, the save data bank server and
the data center travel server. The names of the existing settings should
be clearer now, too.
This commit is contained in:
Joshua Goins 2025-05-02 15:17:32 -04:00
parent c80beea353
commit 02a44b0247
6 changed files with 130 additions and 62 deletions

View file

@ -61,23 +61,35 @@ SPDX-License-Identifier: CC0-1.0
<entry name="PreferredProtocol" type="String"> <entry name="PreferredProtocol" type="String">
<default>https</default> <default>https</default>
</entry> </entry>
<entry name="GMServerHost" type="String"> <entry name="GMServer" type="String">
<default></default> <default></default>
</entry> </entry>
<entry name="LobbyHost" type="String"> <entry name="LobbyServer" type="String">
<default></default> <default></default>
</entry> </entry>
<entry name="LobbyHostPort" type="int"> <entry name="LobbyPort" type="int">
<default>7000</default> <default></default>
</entry> </entry>
<entry name="SquareEnixServer" type="String"> <entry name="OldServer" type="String">
<default>ffxiv.com</default> <default>ffxiv.com</default>
</entry> </entry>
<entry name="SquareEnixLoginServer" type="String"> <entry name="LoginServer" type="String">
<default>square-enix.com</default> <default>square-enix.com</default>
</entry> </entry>
<entry name="MainServer" type="String"> <entry name="NewServer" type="String">
<default>finalfantasyxiv.com</default> <default>finalfantasyxiv.com</default>
</entry> </entry>
<entry name="FrontierServer" type="String">
<default></default>
</entry>
<entry name="SaveDataBankServer" type="String">
<default></default>
</entry>
<entry name="SaveDataBankPort" type="int">
<default></default>
</entry>
<entry name="DataCenterTravelServer" type="String">
<default></default>
</entry>
</group> </group>
</kcfg> </kcfg>

View file

@ -46,10 +46,7 @@ struct LoginAuth {
QString SID; QString SID;
int region = 2; // america? int region = 2; // america?
int maxExpansion = 1; int maxExpansion = 1;
Account *account = nullptr;
// if empty, don't set on the client
QString lobbyHost, frontierHost;
int lobbyHostPort;
}; };
class LauncherCore : public QObject class LauncherCore : public QObject

View file

@ -250,12 +250,29 @@ QString GameRunner::getGameArgs(const Profile &profile, const std::optional<Logi
Utility::createPathIfNeeded(profile.config()->winePrefixPath()); Utility::createPathIfNeeded(profile.config()->winePrefixPath());
if (auth) { if (auth) {
if (!auth->lobbyHost.isEmpty()) { auto config = auth->account->config();
gameArgs.push_back({QStringLiteral("DEV.GMServerHost"), auth->frontierHost}); if (!config->frontierServer().isEmpty()) {
for (int i = 1; i < 9; i++) { gameArgs.push_back({QStringLiteral("DEV.GMServerHost"), config->frontierServer()});
gameArgs.push_back({QStringLiteral("DEV.LobbyHost0%1").arg(QString::number(i)), auth->lobbyHost}); }
gameArgs.push_back({QStringLiteral("DEV.LobbyPort0%1").arg(QString::number(i)), QString::number(auth->lobbyHostPort)});
if (!config->lobbyServer().isEmpty()) {
for (int i = 1; i < 13; i++) {
gameArgs.push_back({QStringLiteral("DEV.LobbyHost%1").arg(QString::number(i), 2, '0'_L1), config->lobbyServer()});
gameArgs.push_back({QStringLiteral("DEV.LobbyPort%1").arg(QString::number(i), 2, '0'_L1), QString::number(config->lobbyPort())});
} }
// the special server!!
gameArgs.push_back({QStringLiteral("DEV.LobbyHost98"), config->lobbyServer()});
gameArgs.push_back({QStringLiteral("DEV.LobbyPort98"), QString::number(config->lobbyPort())});
}
if (!config->saveDataBankServer().isEmpty()) {
gameArgs.push_back({QStringLiteral("DEV.SaveDataBankHost"), config->saveDataBankServer()});
gameArgs.push_back({QStringLiteral("DEV.SaveDataBankPort"), QString::number(config->saveDataBankPort())});
}
if (!config->dataCenterTravelServer().isEmpty()) {
gameArgs.push_back({QStringLiteral("DEV.DktWebHost"), config->dataCenterTravelServer()});
} }
if (profile.account()->config()->license() == Account::GameLicense::WindowsSteam) { if (profile.account()->config()->license() == Account::GameLicense::WindowsSteam) {

View file

@ -185,7 +185,7 @@ void LauncherCore::fetchAvatar(Account *account)
QUrl url; QUrl url;
url.setScheme(account->config()->preferredProtocol()); url.setScheme(account->config()->preferredProtocol());
url.setHost(QStringLiteral("na.%1").arg(account->config()->mainServer())); // TODO: NA isnt the only thing in the world... url.setHost(QStringLiteral("na.%1").arg(account->config()->newServer()));
url.setPath(QStringLiteral("/lodestone/character/%1").arg(account->config()->lodestoneId())); url.setPath(QStringLiteral("/lodestone/character/%1").arg(account->config()->lodestoneId()));
const QNetworkRequest request(url); const QNetworkRequest request(url);
@ -500,7 +500,7 @@ QCoro::Task<> LauncherCore::fetchNews()
QUrl headlineUrl; QUrl headlineUrl;
headlineUrl.setScheme(currentProfile()->account()->config()->preferredProtocol()); headlineUrl.setScheme(currentProfile()->account()->config()->preferredProtocol());
headlineUrl.setHost(QStringLiteral("frontier.%1").arg(currentProfile()->account()->config()->squareEnixServer())); headlineUrl.setHost(QStringLiteral("frontier.%1").arg(currentProfile()->account()->config()->oldServer()));
headlineUrl.setPath(QStringLiteral("/news/headline.json")); headlineUrl.setPath(QStringLiteral("/news/headline.json"));
headlineUrl.setQuery(query); headlineUrl.setQuery(query);
@ -519,7 +519,7 @@ QCoro::Task<> LauncherCore::fetchNews()
QUrl bannerUrl; QUrl bannerUrl;
bannerUrl.setScheme(currentProfile()->account()->config()->preferredProtocol()); bannerUrl.setScheme(currentProfile()->account()->config()->preferredProtocol());
bannerUrl.setHost(QStringLiteral("frontier.%1").arg(currentProfile()->account()->config()->squareEnixServer())); bannerUrl.setHost(QStringLiteral("frontier.%1").arg(currentProfile()->account()->config()->oldServer()));
bannerUrl.setPath(QStringLiteral("/v2/topics/%1/banner.json").arg(QStringLiteral("en-us"))); bannerUrl.setPath(QStringLiteral("/v2/topics/%1/banner.json").arg(QStringLiteral("en-us")));
bannerUrl.setQuery(query); bannerUrl.setQuery(query);

View file

@ -73,13 +73,7 @@ QCoro::Task<std::optional<LoginAuth>> SquareEnixLogin::login(LoginInformation *i
co_return std::nullopt; co_return std::nullopt;
} }
// Inject custom game server if set m_auth.account = info->profile->account();
if (!info->profile->account()->config()->lobbyHost().isEmpty()) {
m_auth.frontierHost = info->profile->account()->config()->gMServerHost();
m_auth.lobbyHost = info->profile->account()->config()->lobbyHost();
m_auth.lobbyHostPort = info->profile->account()->config()->lobbyHostPort();
}
co_return m_auth; co_return m_auth;
} }
@ -90,7 +84,7 @@ QCoro::Task<bool> SquareEnixLogin::checkGateStatus() const
QUrl url; QUrl url;
url.setScheme(m_info->profile->account()->config()->preferredProtocol()); url.setScheme(m_info->profile->account()->config()->preferredProtocol());
url.setHost(QStringLiteral("frontier.%1").arg(m_info->profile->account()->config()->squareEnixServer())); url.setHost(QStringLiteral("frontier.%1").arg(m_info->profile->account()->config()->oldServer()));
url.setPath(QStringLiteral("/worldStatus/gate_status.json")); url.setPath(QStringLiteral("/worldStatus/gate_status.json"));
url.setQuery(QString::number(QDateTime::currentMSecsSinceEpoch())); url.setQuery(QString::number(QDateTime::currentMSecsSinceEpoch()));
@ -131,7 +125,7 @@ QCoro::Task<bool> SquareEnixLogin::checkLoginStatus() const
QUrl url; QUrl url;
url.setScheme(m_info->profile->account()->config()->preferredProtocol()); url.setScheme(m_info->profile->account()->config()->preferredProtocol());
url.setHost(QStringLiteral("frontier.%1").arg(m_info->profile->account()->config()->squareEnixServer())); url.setHost(QStringLiteral("frontier.%1").arg(m_info->profile->account()->config()->oldServer()));
url.setPath(QStringLiteral("/worldStatus/login_status.json")); url.setPath(QStringLiteral("/worldStatus/login_status.json"));
url.setQuery(QString::number(QDateTime::currentMSecsSinceEpoch())); url.setQuery(QString::number(QDateTime::currentMSecsSinceEpoch()));
@ -173,7 +167,7 @@ QCoro::Task<bool> SquareEnixLogin::checkBootUpdates()
QUrl url; QUrl url;
url.setScheme(QStringLiteral("http")); url.setScheme(QStringLiteral("http"));
url.setHost(QStringLiteral("patch-bootver.%1").arg(m_info->profile->account()->config()->squareEnixServer())); url.setHost(QStringLiteral("patch-bootver.%1").arg(m_info->profile->account()->config()->oldServer()));
url.setPath(QStringLiteral("/http/%1/%2/%3/").arg(platform, bootUpdateChannel, m_info->profile->bootVersion())); url.setPath(QStringLiteral("/http/%1/%2/%3/").arg(platform, bootUpdateChannel, m_info->profile->bootVersion()));
url.setQuery(query); url.setQuery(query);
@ -184,7 +178,7 @@ QCoro::Task<bool> SquareEnixLogin::checkBootUpdates()
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, patchUserAgent); request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, patchUserAgent);
} }
request.setRawHeader(QByteArrayLiteral("Host"), QStringLiteral("patch-bootver.%1").arg(m_info->profile->account()->config()->squareEnixServer()).toUtf8()); request.setRawHeader(QByteArrayLiteral("Host"), QStringLiteral("patch-bootver.%1").arg(m_info->profile->account()->config()->oldServer()).toUtf8());
Utility::printRequest(QStringLiteral("GET"), request); Utility::printRequest(QStringLiteral("GET"), request);
const auto reply = m_launcher.mgr()->get(request); const auto reply = m_launcher.mgr()->get(request);
@ -248,7 +242,7 @@ QCoro::Task<std::optional<SquareEnixLogin::StoredInfo>> SquareEnixLogin::getStor
QUrl url; QUrl url;
url.setScheme(m_info->profile->account()->config()->preferredProtocol()); url.setScheme(m_info->profile->account()->config()->preferredProtocol());
url.setHost(QStringLiteral("ffxiv-login.%1").arg(m_info->profile->account()->config()->squareEnixLoginServer())); url.setHost(QStringLiteral("ffxiv-login.%1").arg(m_info->profile->account()->config()->loginServer()));
url.setPath(QStringLiteral("/oauth/ffxivarr/login/top")); url.setPath(QStringLiteral("/oauth/ffxivarr/login/top"));
url.setQuery(query); url.setQuery(query);
@ -306,7 +300,7 @@ QCoro::Task<bool> SquareEnixLogin::loginOAuth()
QUrl url; QUrl url;
url.setScheme(m_info->profile->account()->config()->preferredProtocol()); url.setScheme(m_info->profile->account()->config()->preferredProtocol());
url.setHost(QStringLiteral("ffxiv-login.%1").arg(m_info->profile->account()->config()->squareEnixLoginServer())); url.setHost(QStringLiteral("ffxiv-login.%1").arg(m_info->profile->account()->config()->loginServer()));
url.setPath(QStringLiteral("/oauth/ffxivarr/login/login.send")); url.setPath(QStringLiteral("/oauth/ffxivarr/login/login.send"));
QNetworkRequest request(url); QNetworkRequest request(url);
@ -367,7 +361,7 @@ QCoro::Task<bool> SquareEnixLogin::registerSession()
QUrl url; QUrl url;
url.setScheme(m_info->profile->account()->config()->preferredProtocol()); url.setScheme(m_info->profile->account()->config()->preferredProtocol());
url.setHost(QStringLiteral("patch-gamever.%1").arg(m_info->profile->account()->config()->squareEnixServer())); url.setHost(QStringLiteral("patch-gamever.%1").arg(m_info->profile->account()->config()->oldServer()));
url.setPath(QStringLiteral("/http/%1/%2/%3/%4").arg(platform, gameUpdateChannel, m_info->profile->baseGameVersion(), m_SID)); url.setPath(QStringLiteral("/http/%1/%2/%3/%4").arg(platform, gameUpdateChannel, m_info->profile->baseGameVersion(), m_SID));
auto request = QNetworkRequest(url); auto request = QNetworkRequest(url);

View file

@ -250,9 +250,10 @@ FormCard.FormCardPage {
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: squareMainServerDelegate id: squareMainServerDelegate
label: i18n("SE Main Server (ffxiv.com)") label: i18n("Old Server")
text: page.account.config.squareEnixServer text: page.account.config.oldServer
onTextChanged: page.account.config.squareEnixServer = text placeholderText: "ffxiv.com"
onTextChanged: page.account.config.oldServer = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -263,9 +264,10 @@ FormCard.FormCardPage {
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: loginServerDelegate id: loginServerDelegate
label: i18n("SE Login Server (square-enix.com)") label: i18n("Login Server")
text: page.account.config.squareEnixLoginServer text: page.account.config.loginServer
onTextChanged: page.account.config.squareEnixLoginServer = text placeholderText: "square-enix.com"
onTextChanged: page.account.config.loginServer = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -276,35 +278,24 @@ FormCard.FormCardPage {
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: mainServerDelegate id: mainServerDelegate
label: i18n("Main Server (finalfantasyxiv.com)") label: i18n("New Server")
text: page.account.config.mainServer text: page.account.config.newServer
onTextChanged: page.account.config.mainServer = text placeholderText: "finalfantasyxiv.com"
onTextChanged: page.account.config.newServer = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
above: mainServerDelegate above: mainServerDelegate
below: gmServerDelegate
}
FormCard.FormTextFieldDelegate {
id: gmServerDelegate
label: i18n("GM Server (leave blank for default)")
text: page.account.config.gMServerHost
onTextChanged: page.account.config.gMServerHost = text
}
FormCard.FormDelegateSeparator {
above: gmServerDelegate
below: gameServerDelegate below: gameServerDelegate
} }
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: gameServerDelegate id: gameServerDelegate
label: i18n("Lobby Server (leave blank for default)") label: i18n("Lobby Server")
text: page.account.config.lobbyHost text: page.account.config.lobbyServer
onTextChanged: page.account.config.lobbyHost = text placeholderText: i18nc("@info:placeholder", "(Default value in client)")
onTextChanged: page.account.config.lobbyServer = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
@ -315,12 +306,69 @@ FormCard.FormCardPage {
FormCard.FormSpinBoxDelegate { FormCard.FormSpinBoxDelegate {
id: gameServerPortDelegate id: gameServerPortDelegate
label: i18n("Lobby Server Port") label: i18n("Lobby Port")
value: page.account.config.lobbyHostPort value: page.account.config.lobbyPort
onValueChanged: page.account.config.lobbyHostPort = value onValueChanged: page.account.config.lobbyPort = value
from: 1 from: 0
to: 999999 to: 999999
} }
FormCard.FormDelegateSeparator {
above: gameServerPortDelegate
below: frontierServerDelegate
}
FormCard.FormTextFieldDelegate {
id: frontierServerDelegate
label: i18n("Frontier Server")
text: page.account.config.frontierServer
placeholderText: i18nc("@info:placeholder", "(Default value in client)")
onTextChanged: page.account.config.frontierServer = text
}
FormCard.FormDelegateSeparator {
above: frontierServerDelegate
below: saveDataBankServerDelegate
}
FormCard.FormTextFieldDelegate {
id: saveDataBankServerDelegate
label: i18n("Save Data Bank Server")
text: page.account.config.saveDataBankServer
placeholderText: i18nc("@info:placeholder", "(Default value in client)")
onTextChanged: page.account.config.saveDataBankServer = text
}
FormCard.FormDelegateSeparator {
above: saveDataBankServerDelegate
below: saveDataBankPortDelegate
}
FormCard.FormSpinBoxDelegate {
id: saveDataBankPortDelegate
label: i18n("Save Data Bank Port")
value: page.account.config.saveDataBankPort
onValueChanged: page.account.config.saveDataBankPort = value
from: 0
to: 999999
}
FormCard.FormDelegateSeparator {
above: saveDataBankPortDelegate
below: dataCenterTravelServerDelegate
}
FormCard.FormTextFieldDelegate {
id: dataCenterTravelServerDelegate
label: i18n("Data Center Travel Server")
text: page.account.config.dataCenterTravelServer
placeholderText: i18nc("@info:placeholder", "(Default value in client)")
onTextChanged: page.account.config.dataCenterTravelServer = text
}
} }
Kirigami.PromptDialog { Kirigami.PromptDialog {