1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-21 20:27:45 +00:00

Meh, throw out XIVAPI and fetch avatars from the Lodestone directly

XIVAPI was kind of unnecessary here, and on top of that it's barely
working nowadays. We can grab the image URL directly from the Lodestone,
cutting out the middleman.
This commit is contained in:
Joshua Goins 2024-06-29 20:46:08 -04:00
parent b04a4af954
commit a30b26fa3a
6 changed files with 47 additions and 44 deletions

View file

@ -40,8 +40,8 @@ SPDX-License-Identifier: CC0-1.0
<entry name="SquareEnixLoginServer" type="String"> <entry name="SquareEnixLoginServer" type="String">
<default>square-enix.com</default> <default>square-enix.com</default>
</entry> </entry>
<entry name="XivApiServer" type="String"> <entry name="MainServer" type="String">
<default>xivapi.com</default> <default>finalfantasyxiv.com</default>
</entry> </entry>
<entry name="PreferredProtocol" type="String"> <entry name="PreferredProtocol" type="String">
<default>https</default> <default>https</default>

View file

@ -22,7 +22,7 @@ class LauncherSettings : public QObject
Q_PROPERTY(QString dalamudDistribServer READ dalamudDistribServer WRITE setDalamudDistribServer NOTIFY dalamudDistribServerChanged) Q_PROPERTY(QString dalamudDistribServer READ dalamudDistribServer WRITE setDalamudDistribServer NOTIFY dalamudDistribServerChanged)
Q_PROPERTY(QString squareEnixServer READ squareEnixServer WRITE setSquareEnixServer NOTIFY squareEnixServerChanged) Q_PROPERTY(QString squareEnixServer READ squareEnixServer WRITE setSquareEnixServer NOTIFY squareEnixServerChanged)
Q_PROPERTY(QString squareEnixLoginServer READ squareEnixLoginServer WRITE setSquareEnixLoginServer NOTIFY squareEnixLoginServerChanged) Q_PROPERTY(QString squareEnixLoginServer READ squareEnixLoginServer WRITE setSquareEnixLoginServer NOTIFY squareEnixLoginServerChanged)
Q_PROPERTY(QString xivApiServer READ xivApiServer WRITE setXivApiServer NOTIFY xivApiServerChanged) Q_PROPERTY(QString mainServer READ mainServer WRITE setMainServer NOTIFY mainServerChanged)
Q_PROPERTY(QString preferredProtocol READ preferredProtocol WRITE setPreferredProtocol NOTIFY preferredProtocolChanged) Q_PROPERTY(QString preferredProtocol READ preferredProtocol WRITE setPreferredProtocol NOTIFY preferredProtocolChanged)
Q_PROPERTY(QString screenshotDir READ screenshotDir WRITE setScreenshotDir NOTIFY screenshotDirChanged) Q_PROPERTY(QString screenshotDir READ screenshotDir WRITE setScreenshotDir NOTIFY screenshotDirChanged)
Q_PROPERTY(bool argumentsEncrypted READ argumentsEncrypted WRITE setArgumentsEncrypted NOTIFY encryptedArgumentsChanged) Q_PROPERTY(bool argumentsEncrypted READ argumentsEncrypted WRITE setArgumentsEncrypted NOTIFY encryptedArgumentsChanged)
@ -52,8 +52,8 @@ public:
[[nodiscard]] QString squareEnixLoginServer() const; [[nodiscard]] QString squareEnixLoginServer() const;
void setSquareEnixLoginServer(const QString &value); void setSquareEnixLoginServer(const QString &value);
[[nodiscard]] QString xivApiServer() const; [[nodiscard]] QString mainServer() const;
void setXivApiServer(const QString &value); void setMainServer(const QString &value);
[[nodiscard]] QString preferredProtocol() const; [[nodiscard]] QString preferredProtocol() const;
void setPreferredProtocol(const QString &value); void setPreferredProtocol(const QString &value);
@ -80,7 +80,7 @@ Q_SIGNALS:
void dalamudDistribServerChanged(); void dalamudDistribServerChanged();
void squareEnixServerChanged(); void squareEnixServerChanged();
void squareEnixLoginServerChanged(); void squareEnixLoginServerChanged();
void xivApiServerChanged(); void mainServerChanged();
void preferredProtocolChanged(); void preferredProtocolChanged();
void screenshotDirChanged(); void screenshotDirChanged();
void encryptedArgumentsChanged(); void encryptedArgumentsChanged();

View file

@ -239,38 +239,41 @@ void Account::fetchAvatar()
const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, lodestoneId()); const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, lodestoneId());
if (!QFile(filename).exists()) { if (!QFile(filename).exists()) {
qDebug(ASTRA_LOG) << "Did not find lodestone character " << lodestoneId() << " in cache, fetching from xivapi."; qDebug(ASTRA_LOG) << "Did not find lodestone character " << lodestoneId() << " in cache, fetching from Lodestone.";
QUrl url; QUrl url;
url.setScheme(m_launcher.settings()->preferredProtocol()); url.setScheme(m_launcher.settings()->preferredProtocol());
url.setHost(m_launcher.settings()->xivApiServer()); url.setHost(QStringLiteral("na.%1").arg(m_launcher.settings()->mainServer())); // TODO: NA isnt the only thing in the world...
url.setPath(QStringLiteral("/lodestone/character/%1").arg(lodestoneId()));
url.setPath(QStringLiteral("/character/%1").arg(lodestoneId()));
QNetworkRequest request(url); QNetworkRequest request(url);
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);
connect(reply, &QNetworkReply::finished, [this, filename, reply] { connect(reply, &QNetworkReply::finished, [this, filename, reply] {
auto document = QJsonDocument::fromJson(reply->readAll()); QString document = QString::fromUtf8(reply->readAll());
if (document.isObject()) { if (!document.isEmpty()) {
const QNetworkRequest avatarRequest(QUrl(document.object()["Character"_L1].toObject()["Avatar"_L1].toString())); const static QRegularExpression re(
Utility::printRequest(QStringLiteral("GET"), avatarRequest); QStringLiteral(R"lit(<div\s[^>]*class=["|']frame__chara__face["|'][^>]*>\s*<img\s[&>]*src=["|']([^"']*))lit"));
const QRegularExpressionMatch match = re.match(document);
if (avatarRequest.url().isEmpty()) { if (match.hasCaptured(1)) {
return; const QString newAvatarUrl = match.captured(1);
const QNetworkRequest avatarRequest = QNetworkRequest(QUrl(newAvatarUrl));
Utility::printRequest(QStringLiteral("GET"), avatarRequest);
auto avatarReply = m_launcher.mgr()->get(avatarRequest);
connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
QFile file(filename);
file.open(QIODevice::ReadWrite);
file.write(avatarReply->readAll());
file.close();
m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
Q_EMIT avatarUrlChanged();
});
} }
auto avatarReply = m_launcher.mgr()->get(avatarRequest);
connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
QFile file(filename);
file.open(QIODevice::ReadWrite);
file.write(avatarReply->readAll());
file.close();
m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
Q_EMIT avatarUrlChanged();
});
} }
}); });
} else { } else {

View file

@ -107,17 +107,17 @@ void LauncherSettings::setSquareEnixLoginServer(const QString &value)
} }
} }
QString LauncherSettings::xivApiServer() const QString LauncherSettings::mainServer() const
{ {
return m_config->xivApiServer(); return m_config->mainServer();
} }
void LauncherSettings::setXivApiServer(const QString &value) void LauncherSettings::setMainServer(const QString &value)
{ {
if (value != m_config->xivApiServer()) { if (value != m_config->mainServer()) {
m_config->setXivApiServer(value); m_config->setMainServer(value);
m_config->save(); m_config->save();
Q_EMIT xivApiServerChanged(); Q_EMIT mainServerChanged();
} }
} }

View file

@ -237,7 +237,7 @@ QCoro::Task<std::optional<SquareEnixLogin::StoredInfo>> SquareEnixLogin::getStor
// fetches Steam username // fetches Steam username
if (m_info->profile->account()->license() == Account::GameLicense::WindowsSteam) { if (m_info->profile->account()->license() == Account::GameLicense::WindowsSteam) {
const QRegularExpression re(QStringLiteral(R"lit(<input name=""sqexid"" type=""hidden"" value=""(?<sqexid>.*)""\/>)lit")); const static QRegularExpression re(QStringLiteral(R"lit(<input name=""sqexid"" type=""hidden"" value=""(?<sqexid>.*)""\/>)lit"));
const QRegularExpressionMatch match = re.match(str); const QRegularExpressionMatch match = re.match(str);
if (match.hasMatch()) { if (match.hasMatch()) {
@ -249,7 +249,7 @@ QCoro::Task<std::optional<SquareEnixLogin::StoredInfo>> SquareEnixLogin::getStor
m_username = m_info->username; m_username = m_info->username;
} }
const QRegularExpression re(QStringLiteral(R"lit(\t<\s*input .* name="_STORED_" value="(?<stored>.*)">)lit")); const static QRegularExpression re(QStringLiteral(R"lit(\t<\s*input .* name="_STORED_" value="(?<stored>.*)">)lit"));
const QRegularExpressionMatch match = re.match(str); const QRegularExpressionMatch match = re.match(str);
if (match.hasMatch()) { if (match.hasMatch()) {
co_return StoredInfo{match.captured(1), url}; co_return StoredInfo{match.captured(1), url};
@ -296,7 +296,7 @@ QCoro::Task<bool> SquareEnixLogin::loginOAuth()
const QString str = QString::fromUtf8(reply->readAll()); const QString str = QString::fromUtf8(reply->readAll());
const QRegularExpression re(QStringLiteral(R"lit(window.external.user\("login=auth,ok,(?<launchParams>.*)\);)lit")); const static QRegularExpression re(QStringLiteral(R"lit(window.external.user\("login=auth,ok,(?<launchParams>.*)\);)lit"));
const QRegularExpressionMatch match = re.match(str); const QRegularExpressionMatch match = re.match(str);
if (match.hasMatch()) { if (match.hasMatch()) {
const auto parts = match.captured(1).split(','_L1); const auto parts = match.captured(1).split(','_L1);
@ -320,7 +320,7 @@ QCoro::Task<bool> SquareEnixLogin::loginOAuth()
co_return true; co_return true;
} else { } else {
const QRegularExpression errorRe(QStringLiteral(R"lit(window.external.user\("login=auth,ng,err,(?<launchParams>.*)\);)lit")); const static QRegularExpression errorRe(QStringLiteral(R"lit(window.external.user\("login=auth,ng,err,(?<launchParams>.*)\);)lit"));
const QRegularExpressionMatch errorMatch = errorRe.match(str); const QRegularExpressionMatch errorMatch = errorRe.match(str);
if (errorMatch.hasCaptured(1)) { if (errorMatch.hasCaptured(1)) {

View file

@ -114,7 +114,7 @@ FormCard.FormCardPage {
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: mainServerDelegate id: mainServerDelegate
label: i18n("SE Main Server") label: i18n("SE Main Server (ffxiv.com)")
text: LauncherCore.settings.squareEnixServer text: LauncherCore.settings.squareEnixServer
onTextChanged: LauncherCore.settings.squareEnixServer = text onTextChanged: LauncherCore.settings.squareEnixServer = text
} }
@ -127,22 +127,22 @@ FormCard.FormCardPage {
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: loginServerDelegate id: loginServerDelegate
label: i18n("SE Login Server") label: i18n("SE Login Server (square-enix.com)")
text: LauncherCore.settings.squareEnixLoginServer text: LauncherCore.settings.squareEnixLoginServer
onTextChanged: LauncherCore.settings.squareEnixLoginServer = text onTextChanged: LauncherCore.settings.squareEnixLoginServer = text
} }
FormCard.FormDelegateSeparator { FormCard.FormDelegateSeparator {
above: loginServerDelegate above: loginServerDelegate
below: xivApiServerDelegate below: mainServerDelegate
} }
FormCard.FormTextFieldDelegate { FormCard.FormTextFieldDelegate {
id: xivApiServerDelegate id: mainServerDelegate
label: i18n("XIV Api Server") label: i18n("Main Server (finalfantasyxiv.com)")
text: LauncherCore.settings.xivApiServer text: LauncherCore.settings.mainServer
onTextChanged: LauncherCore.settings.xivApiServer = text onTextChanged: LauncherCore.settings.mainServer = text
} }
} }
} }