mirror of
https://github.com/redstrate/Astra.git
synced 2025-04-20 11:47:46 +00:00
Add better logging
Astra's own logs are now stored in a rotating log, the default message format is improved. The client and DXVK now dump their logs in the same place instead of in the game directory.
This commit is contained in:
parent
2662b0e0bb
commit
c05311fccc
22 changed files with 299 additions and 25 deletions
|
@ -34,6 +34,7 @@ include(ECMPoQmTools)
|
||||||
include(KDEGitCommitHooks)
|
include(KDEGitCommitHooks)
|
||||||
include(KDEClangFormat)
|
include(KDEClangFormat)
|
||||||
include(ECMAddTests)
|
include(ECMAddTests)
|
||||||
|
include(ECMQtDeclareLoggingCategory)
|
||||||
|
|
||||||
ecm_setup_version(${PROJECT_VERSION}
|
ecm_setup_version(${PROJECT_VERSION}
|
||||||
VARIABLE_PREFIX ASTRA
|
VARIABLE_PREFIX ASTRA
|
||||||
|
|
|
@ -3,6 +3,30 @@
|
||||||
|
|
||||||
add_library(astra_static STATIC)
|
add_library(astra_static STATIC)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(astra_static
|
||||||
|
HEADER astra_log.h
|
||||||
|
IDENTIFIER ASTRA_LOG
|
||||||
|
CATEGORY_NAME zone.xiv.astra
|
||||||
|
DESCRIPTION "Astra logs"
|
||||||
|
EXPORT ASTRA
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(astra_static
|
||||||
|
HEADER astra_http_log.h
|
||||||
|
IDENTIFIER ASTRA_HTTP
|
||||||
|
CATEGORY_NAME zone.xiv.astra.http
|
||||||
|
DESCRIPTION "Astra HTTP requests"
|
||||||
|
EXPORT ASTRA
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(astra_static
|
||||||
|
HEADER astra_patcher_log.h
|
||||||
|
IDENTIFIER ASTRA_PATCHER
|
||||||
|
CATEGORY_NAME zone.xiv.astra.patcher
|
||||||
|
DESCRIPTION "Astra patcher"
|
||||||
|
EXPORT ASTRA
|
||||||
|
)
|
||||||
|
|
||||||
target_sources(astra_static PRIVATE
|
target_sources(astra_static PRIVATE
|
||||||
include/patchlist.h
|
include/patchlist.h
|
||||||
src/patchlist.cpp)
|
src/patchlist.cpp)
|
||||||
|
@ -25,7 +49,9 @@ target_sources(astra PRIVATE
|
||||||
include/gameinstaller.h
|
include/gameinstaller.h
|
||||||
include/headline.h
|
include/headline.h
|
||||||
include/launchercore.h
|
include/launchercore.h
|
||||||
|
include/logger.h
|
||||||
include/patcher.h
|
include/patcher.h
|
||||||
|
include/processlogger.h
|
||||||
include/profile.h
|
include/profile.h
|
||||||
include/profilemanager.h
|
include/profilemanager.h
|
||||||
include/sapphirelauncher.h
|
include/sapphirelauncher.h
|
||||||
|
@ -41,8 +67,10 @@ target_sources(astra PRIVATE
|
||||||
src/encryptedarg.cpp
|
src/encryptedarg.cpp
|
||||||
src/gameinstaller.cpp
|
src/gameinstaller.cpp
|
||||||
src/launchercore.cpp
|
src/launchercore.cpp
|
||||||
|
src/logger.cpp
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/patcher.cpp
|
src/patcher.cpp
|
||||||
|
src/processlogger.cpp
|
||||||
src/profile.cpp
|
src/profile.cpp
|
||||||
src/profilemanager.cpp
|
src/profilemanager.cpp
|
||||||
src/sapphirelauncher.cpp
|
src/sapphirelauncher.cpp
|
||||||
|
|
6
launcher/include/logger.h
Normal file
6
launcher/include/logger.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void initializeLogging();
|
17
launcher/include/processlogger.h
Normal file
17
launcher/include/processlogger.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
class ProcessLogger : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ProcessLogger(QProcess *process);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFile file;
|
||||||
|
};
|
|
@ -122,6 +122,7 @@ public:
|
||||||
void readGameData();
|
void readGameData();
|
||||||
Q_INVOKABLE void readGameVersion();
|
Q_INVOKABLE void readGameVersion();
|
||||||
void readWineInfo();
|
void readWineInfo();
|
||||||
|
void readDalamudInfo();
|
||||||
|
|
||||||
[[nodiscard]] QString expansionVersionText() const;
|
[[nodiscard]] QString expansionVersionText() const;
|
||||||
[[nodiscard]] QString dalamudVersionText() const;
|
[[nodiscard]] QString dalamudVersionText() const;
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
|
||||||
namespace Utility
|
namespace Utility
|
||||||
{
|
{
|
||||||
QDir stateDirectory();
|
QDir stateDirectory();
|
||||||
QString toWindowsPath(const QDir &dir);
|
QString toWindowsPath(const QDir &dir);
|
||||||
|
void printRequest(const QString &type, const QNetworkRequest &request);
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
#include <qt6keychain/keychain.h>
|
#include <qt6keychain/keychain.h>
|
||||||
|
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
Account::Account(LauncherCore &launcher, const QString &key, QObject *parent)
|
Account::Account(LauncherCore &launcher, const QString &key, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -234,11 +235,15 @@ void Account::fetchAvatar()
|
||||||
url.setPath(QStringLiteral("/character/%1").arg(lodestoneId()));
|
url.setPath(QStringLiteral("/character/%1").arg(lodestoneId()));
|
||||||
|
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
|
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());
|
auto document = QJsonDocument::fromJson(reply->readAll());
|
||||||
if (document.isObject()) {
|
if (document.isObject()) {
|
||||||
const QNetworkRequest avatarRequest(document.object()[QLatin1String("Character")].toObject()[QLatin1String("Avatar")].toString());
|
const QNetworkRequest avatarRequest(document.object()[QLatin1String("Character")].toObject()[QLatin1String("Avatar")].toString());
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), avatarRequest);
|
||||||
|
|
||||||
auto avatarReply = m_launcher.mgr->get(avatarRequest);
|
auto avatarReply = m_launcher.mgr->get(avatarRequest);
|
||||||
QObject::connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
|
QObject::connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "accountmanager.h"
|
#include "accountmanager.h"
|
||||||
|
#include "astra_log.h"
|
||||||
|
|
||||||
#include <KSharedConfig>
|
#include <KSharedConfig>
|
||||||
|
|
||||||
|
@ -16,7 +17,10 @@ void AccountManager::load()
|
||||||
auto config = KSharedConfig::openStateConfig();
|
auto config = KSharedConfig::openStateConfig();
|
||||||
for (const auto &id : config->groupList()) {
|
for (const auto &id : config->groupList()) {
|
||||||
if (id.contains(QLatin1String("account-"))) {
|
if (id.contains(QLatin1String("account-"))) {
|
||||||
auto account = new Account(m_launcher, QString(id).remove(QLatin1String("account-")), this);
|
const QString uuid = QString(id).remove(QLatin1String("account-"));
|
||||||
|
qInfo(ASTRA_LOG) << "Loading account" << uuid;
|
||||||
|
|
||||||
|
auto account = new Account(m_launcher, uuid, this);
|
||||||
m_accounts.append(account);
|
m_accounts.append(account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "assetupdater.h"
|
#include "assetupdater.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
@ -56,6 +57,7 @@ QCoro::Task<> AssetUpdater::checkRemoteDalamudAssetVersion()
|
||||||
{
|
{
|
||||||
// first we want to fetch the list of assets required
|
// first we want to fetch the list of assets required
|
||||||
const QNetworkRequest request(dalamudAssetManifestUrl());
|
const QNetworkRequest request(dalamudAssetManifestUrl());
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = launcher.mgr->get(request);
|
const auto reply = launcher.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -80,6 +82,7 @@ QCoro::Task<> AssetUpdater::checkRemoteDalamudAssetVersion()
|
||||||
QCoro::Task<> AssetUpdater::checkRemoteDalamudVersion()
|
QCoro::Task<> AssetUpdater::checkRemoteDalamudVersion()
|
||||||
{
|
{
|
||||||
const QNetworkRequest request(dalamudVersionManifestUrl(m_profile.dalamudChannel()));
|
const QNetworkRequest request(dalamudVersionManifestUrl(m_profile.dalamudChannel()));
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
remoteDalamudVersion.clear();
|
remoteDalamudVersion.clear();
|
||||||
remoteRuntimeVersion.clear();
|
remoteRuntimeVersion.clear();
|
||||||
|
@ -132,6 +135,8 @@ QCoro::Task<> AssetUpdater::installDalamudAssets()
|
||||||
|
|
||||||
for (const auto &assetObject : remoteDalamudAssetArray) {
|
for (const auto &assetObject : remoteDalamudAssetArray) {
|
||||||
const QNetworkRequest assetRequest(assetObject.toObject()[QLatin1String("Url")].toString());
|
const QNetworkRequest assetRequest(assetObject.toObject()[QLatin1String("Url")].toString());
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), assetRequest);
|
||||||
|
|
||||||
const auto assetReply = launcher.mgr->get(assetRequest);
|
const auto assetReply = launcher.mgr->get(assetRequest);
|
||||||
|
|
||||||
const auto future = QtFuture::connect(assetReply, &QNetworkReply::finished).then([this, assetReply, assetObject] {
|
const auto future = QtFuture::connect(assetReply, &QNetworkReply::finished).then([this, assetReply, assetObject] {
|
||||||
|
@ -171,6 +176,7 @@ QCoro::Task<> AssetUpdater::installDalamud()
|
||||||
Q_EMIT launcher.stageChanged(i18n("Updating Dalamud..."));
|
Q_EMIT launcher.stageChanged(i18n("Updating Dalamud..."));
|
||||||
|
|
||||||
const QNetworkRequest request(dalamudLatestPackageUrl(chosenChannel));
|
const QNetworkRequest request(dalamudLatestPackageUrl(chosenChannel));
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = launcher.mgr->get(request);
|
const auto reply = launcher.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -200,6 +206,7 @@ QCoro::Task<> AssetUpdater::installRuntime()
|
||||||
// core
|
// core
|
||||||
{
|
{
|
||||||
const QNetworkRequest request(dotnetRuntimePackageURL.arg(remoteRuntimeVersion));
|
const QNetworkRequest request(dotnetRuntimePackageURL.arg(remoteRuntimeVersion));
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = launcher.mgr->get(request);
|
const auto reply = launcher.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -215,6 +222,7 @@ QCoro::Task<> AssetUpdater::installRuntime()
|
||||||
// desktop
|
// desktop
|
||||||
{
|
{
|
||||||
const QNetworkRequest request(dotnetDesktopPackageURL.arg(remoteRuntimeVersion));
|
const QNetworkRequest request(dotnetDesktopPackageURL.arg(remoteRuntimeVersion));
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = launcher.mgr->get(request);
|
const auto reply = launcher.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <physis.hpp>
|
#include <physis.hpp>
|
||||||
|
|
||||||
|
#include "astra_log.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
const QString installerUrl = QStringLiteral("https://download.finalfantasyxiv.com/inst/ffxivsetup.exe");
|
const QString installerUrl = QStringLiteral("https://download.finalfantasyxiv.com/inst/ffxivsetup.exe");
|
||||||
const QByteArray installerSha256 = QByteArray::fromHex("cf70bfaaf4f429794358ef84acbcbdc4193bee109fa1b6aea81bd4de038e500e");
|
const QByteArray installerSha256 = QByteArray::fromHex("cf70bfaaf4f429794358ef84acbcbdc4193bee109fa1b6aea81bd4de038e500e");
|
||||||
|
@ -29,6 +31,8 @@ void GameInstaller::installGame()
|
||||||
QNetworkRequest request((QUrl(installerUrl)));
|
QNetworkRequest request((QUrl(installerUrl)));
|
||||||
|
|
||||||
auto reply = m_launcher.mgr->get(request);
|
auto reply = m_launcher.mgr->get(request);
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::finished, [this, reply, installDirectory] {
|
QObject::connect(reply, &QNetworkReply::finished, [this, reply, installDirectory] {
|
||||||
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||||
Q_EMIT error(i18n("An error has occurred when downloading the installer.\n\n%1", reply->errorString()));
|
Q_EMIT error(i18n("An error has occurred when downloading the installer.\n\n%1", reply->errorString()));
|
||||||
|
@ -55,5 +59,6 @@ void GameInstaller::installGame()
|
||||||
physis_install_game(fileNameStd.c_str(), installDirectoryStd.c_str());
|
physis_install_game(fileNameStd.c_str(), installDirectoryStd.c_str());
|
||||||
|
|
||||||
Q_EMIT installFinished();
|
Q_EMIT installFinished();
|
||||||
|
qInfo(ASTRA_LOG) << "Installed game in" << installDirectory;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "assetupdater.h"
|
#include "assetupdater.h"
|
||||||
|
#include "astra_log.h"
|
||||||
#include "compatibilitytoolinstaller.h"
|
#include "compatibilitytoolinstaller.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "encryptedarg.h"
|
#include "encryptedarg.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
|
#include "processlogger.h"
|
||||||
#include "sapphirelauncher.h"
|
#include "sapphirelauncher.h"
|
||||||
#include "squarelauncher.h"
|
#include "squarelauncher.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
@ -74,8 +76,6 @@ void LauncherCore::launchGame(Profile &profile, const LoginAuth &auth)
|
||||||
|
|
||||||
QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info)
|
QCoro::Task<> LauncherCore::beginLogin(LoginInformation &info)
|
||||||
{
|
{
|
||||||
qDebug() << "Logging in, performing asset update check.";
|
|
||||||
|
|
||||||
auto assetUpdater = new AssetUpdater(*info.profile, *this, this);
|
auto assetUpdater = new AssetUpdater(*info.profile, *this, this);
|
||||||
co_await assetUpdater->update();
|
co_await assetUpdater->update();
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@ void LauncherCore::beginVanillaGame(const QString &gameExecutablePath, Profile &
|
||||||
|
|
||||||
auto args = getGameArgs(profile, auth);
|
auto args = getGameArgs(profile, auth);
|
||||||
|
|
||||||
|
new ProcessLogger(gameProcess);
|
||||||
|
|
||||||
launchExecutable(profile, gameProcess, {gameExecutablePath, args}, true, true);
|
launchExecutable(profile, gameProcess, {gameExecutablePath, args}, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +146,7 @@ void LauncherCore::beginDalamudGame(const QString &gameExecutablePath, Profile &
|
||||||
// so we need to match typical XIVQuickLauncher behavior here. Why? I have no clue.
|
// so we need to match typical XIVQuickLauncher behavior here. Why? I have no clue.
|
||||||
const QDir dalamudPluginDir = dalamudUserPluginDir.absoluteFilePath(QStringLiteral("installedPlugins"));
|
const QDir dalamudPluginDir = dalamudUserPluginDir.absoluteFilePath(QStringLiteral("installedPlugins"));
|
||||||
|
|
||||||
const QString logDir = stateDir.absoluteFilePath(QStringLiteral("logs"));
|
const QString logDir = stateDir.absoluteFilePath(QStringLiteral("log"));
|
||||||
|
|
||||||
if (!QDir().exists(logDir))
|
if (!QDir().exists(logDir))
|
||||||
QDir().mkpath(logDir);
|
QDir().mkpath(logDir);
|
||||||
|
@ -171,6 +173,8 @@ void LauncherCore::beginDalamudGame(const QString &gameExecutablePath, Profile &
|
||||||
#endif
|
#endif
|
||||||
dalamudProcess->setProcessEnvironment(env);
|
dalamudProcess->setProcessEnvironment(env);
|
||||||
|
|
||||||
|
new ProcessLogger(dalamudProcess);
|
||||||
|
|
||||||
const auto args = getGameArgs(profile, auth);
|
const auto args = getGameArgs(profile, auth);
|
||||||
|
|
||||||
launchExecutable(profile,
|
launchExecutable(profile,
|
||||||
|
@ -286,6 +290,10 @@ void LauncherCore::launchExecutable(const Profile &profile, QProcess *process, c
|
||||||
env.insert(QStringLiteral("WINEFSYNC"), QString::number(1));
|
env.insert(QStringLiteral("WINEFSYNC"), QString::number(1));
|
||||||
env.insert(QStringLiteral("WINEFSYNC_FUTEX2"), QString::number(1));
|
env.insert(QStringLiteral("WINEFSYNC_FUTEX2"), QString::number(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString logDir = Utility::stateDirectory().absoluteFilePath(QStringLiteral("log"));
|
||||||
|
|
||||||
|
env.insert(QStringLiteral("DXVK_LOG_PATH"), logDir);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||||
|
@ -371,7 +379,6 @@ void LauncherCore::launchExecutable(const Profile &profile, QProcess *process, c
|
||||||
process->setWorkingDirectory(profile.gamePath() + QStringLiteral("/game/"));
|
process->setWorkingDirectory(profile.gamePath() + QStringLiteral("/game/"));
|
||||||
|
|
||||||
process->setProcessEnvironment(env);
|
process->setProcessEnvironment(env);
|
||||||
process->setProcessChannelMode(QProcess::ProcessChannelMode::ForwardedChannels);
|
|
||||||
|
|
||||||
process->start(executable, arguments);
|
process->start(executable, arguments);
|
||||||
}
|
}
|
||||||
|
@ -457,13 +464,13 @@ bool LauncherCore::autoLogin(Profile *profile)
|
||||||
QString otp;
|
QString otp;
|
||||||
if (profile->account()->useOTP()) {
|
if (profile->account()->useOTP()) {
|
||||||
if (!profile->account()->rememberOTP()) {
|
if (!profile->account()->rememberOTP()) {
|
||||||
Q_EMIT loginError("This account does not have an OTP secret set, but requires it for login.");
|
Q_EMIT loginError(i18n("This account does not have an OTP secret set, but requires it for login."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
otp = profile->account()->getOTP();
|
otp = profile->account()->getOTP();
|
||||||
if (otp.isEmpty()) {
|
if (otp.isEmpty()) {
|
||||||
Q_EMIT loginError("Failed to generate OTP, review the stored secret.");
|
Q_EMIT loginError(i18n("Failed to generate OTP, review the stored secret."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,6 +688,8 @@ void LauncherCore::refreshNews()
|
||||||
|
|
||||||
QCoro::Task<> LauncherCore::fetchNews()
|
QCoro::Task<> LauncherCore::fetchNews()
|
||||||
{
|
{
|
||||||
|
qInfo(ASTRA_LOG) << "Fetching news...";
|
||||||
|
|
||||||
QUrlQuery query;
|
QUrlQuery query;
|
||||||
query.addQueryItem(QStringLiteral("lang"), QStringLiteral("en-us"));
|
query.addQueryItem(QStringLiteral("lang"), QStringLiteral("en-us"));
|
||||||
query.addQueryItem(QStringLiteral("media"), QStringLiteral("pcapp"));
|
query.addQueryItem(QStringLiteral("media"), QStringLiteral("pcapp"));
|
||||||
|
@ -698,6 +707,7 @@ QCoro::Task<> LauncherCore::fetchNews()
|
||||||
QStringLiteral("https://launcher.finalfantasyxiv.com/v600/index.html?rc_lang=%1&time=%2")
|
QStringLiteral("https://launcher.finalfantasyxiv.com/v600/index.html?rc_lang=%1&time=%2")
|
||||||
.arg("en-us", QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd-HH"))
|
.arg("en-us", QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd-HH"))
|
||||||
.toUtf8());
|
.toUtf8());
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
auto reply = mgr->get(request);
|
auto reply = mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -790,7 +800,6 @@ void LauncherCore::setCurrentProfile(Profile *profile)
|
||||||
void LauncherCore::clearAvatarCache()
|
void LauncherCore::clearAvatarCache()
|
||||||
{
|
{
|
||||||
const auto cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
|
const auto cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
|
||||||
qInfo() << cacheLocation;
|
|
||||||
if (QDir(cacheLocation).exists()) {
|
if (QDir(cacheLocation).exists()) {
|
||||||
QDir(cacheLocation).removeRecursively();
|
QDir(cacheLocation).removeRecursively();
|
||||||
}
|
}
|
||||||
|
|
114
launcher/src/logger.cpp
Normal file
114
launcher/src/logger.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QtLogging>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void log(const QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||||
|
{
|
||||||
|
const QString formattedMsg = qFormatLogMessage(type, context, message);
|
||||||
|
|
||||||
|
if (file.isOpen()) {
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
QByteArray buf;
|
||||||
|
QTextStream str(&buf);
|
||||||
|
|
||||||
|
str << formattedMsg << QStringLiteral("\n");
|
||||||
|
str.flush();
|
||||||
|
file.write(buf.constData(), buf.size());
|
||||||
|
file.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << formattedMsg.toStdString() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize()
|
||||||
|
{
|
||||||
|
const QString filename{QStringLiteral("astra.log")};
|
||||||
|
|
||||||
|
const QDir logDirectory = Utility::stateDirectory().absoluteFilePath("log");
|
||||||
|
|
||||||
|
if (!logDirectory.exists()) {
|
||||||
|
QDir().mkpath(logDirectory.absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort them from highest to lowest (4, 3, 2, 1, 0)
|
||||||
|
auto existingLogEntries = logDirectory.entryList({filename + QStringLiteral(".*")});
|
||||||
|
std::sort(existingLogEntries.begin(), existingLogEntries.end(), [](const auto &left, const auto &right) {
|
||||||
|
auto leftIndex = left.split(QStringLiteral(".")).last().toInt();
|
||||||
|
auto rightIndex = right.split(QStringLiteral(".")).last().toInt();
|
||||||
|
return leftIndex > rightIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Iterate through the existing logs, prune them and move the oldest up
|
||||||
|
for (const auto &entry : existingLogEntries) {
|
||||||
|
bool valid = false;
|
||||||
|
const auto index = entry.split(QStringLiteral(".")).last().toInt(&valid);
|
||||||
|
if (!valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString entryFullPath = logDirectory.absoluteFilePath(entry);
|
||||||
|
const QFileInfo info(entryFullPath);
|
||||||
|
if (info.exists()) {
|
||||||
|
QFile existingFile(entryFullPath);
|
||||||
|
if (index > 3) {
|
||||||
|
existingFile.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto &newName = logDirectory.absoluteFilePath(QStringLiteral("%1.%2").arg(filename, QString::number(index + 1)));
|
||||||
|
const auto success = existingFile.copy(newName);
|
||||||
|
if (success) {
|
||||||
|
existingFile.remove();
|
||||||
|
} else {
|
||||||
|
qFatal("Cannot move log file '%s' to '%s': %s",
|
||||||
|
qUtf8Printable(existingFile.fileName()),
|
||||||
|
qUtf8Printable(newName),
|
||||||
|
qUtf8Printable(existingFile.errorString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.setFileName(logDirectory.absoluteFilePath(filename + QStringLiteral(".0")));
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Unbuffered);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex mutex;
|
||||||
|
QFile file;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(Logger, logger)
|
||||||
|
|
||||||
|
void handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
case QtInfoMsg:
|
||||||
|
case QtWarningMsg:
|
||||||
|
case QtCriticalMsg:
|
||||||
|
logger()->log(type, context, message);
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
logger()->log(QtCriticalMsg, context, message);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeLogging()
|
||||||
|
{
|
||||||
|
logger()->initialize();
|
||||||
|
qInstallMessageHandler(handler);
|
||||||
|
}
|
|
@ -15,10 +15,13 @@
|
||||||
#include "compatibilitytoolinstaller.h"
|
#include "compatibilitytoolinstaller.h"
|
||||||
#include "gameinstaller.h"
|
#include "gameinstaller.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "sapphirelauncher.h"
|
#include "sapphirelauncher.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
initializeLogging();
|
||||||
|
|
||||||
QtWebView::initialize();
|
QtWebView::initialize();
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
@ -28,6 +31,11 @@ int main(int argc, char *argv[])
|
||||||
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
|
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default to a sensible message pattern
|
||||||
|
if (qEnvironmentVariableIsEmpty("QT_MESSAGE_PATTERN")) {
|
||||||
|
qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}");
|
||||||
|
}
|
||||||
|
|
||||||
KLocalizedString::setApplicationDomain("astra");
|
KLocalizedString::setApplicationDomain("astra");
|
||||||
|
|
||||||
KAboutData about(QStringLiteral("astra"),
|
KAboutData about(QStringLiteral("astra"),
|
||||||
|
@ -47,7 +55,11 @@ int main(int argc, char *argv[])
|
||||||
physis_get_physis_version(),
|
physis_get_physis_version(),
|
||||||
QStringLiteral("https://xiv.zone/physis"),
|
QStringLiteral("https://xiv.zone/physis"),
|
||||||
KAboutLicense::GPL_V3);
|
KAboutLicense::GPL_V3);
|
||||||
about.addComponent(QStringLiteral("libphysis"), QStringLiteral("C bindings for physis"), physis_get_libphysis_version(), {}, KAboutLicense::GPL_V3);
|
about.addComponent(QStringLiteral("libphysis"),
|
||||||
|
QStringLiteral("C bindings for physis"),
|
||||||
|
physis_get_libphysis_version(),
|
||||||
|
QStringLiteral("https://git.sr.ht/~redstrate/libphysis"),
|
||||||
|
KAboutLicense::GPL_V3);
|
||||||
about.setDesktopFileName(QStringLiteral("zone.xiv.astra"));
|
about.setDesktopFileName(QStringLiteral("zone.xiv.astra"));
|
||||||
about.setBugAddress(QByteArrayLiteral("https://lists.sr.ht/~redstrate/public-inbox"));
|
about.setBugAddress(QByteArrayLiteral("https://lists.sr.ht/~redstrate/public-inbox"));
|
||||||
about.setComponentName(QStringLiteral("astra"));
|
about.setComponentName(QStringLiteral("astra"));
|
||||||
|
@ -58,11 +70,9 @@ int main(int argc, char *argv[])
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(i18n("Linux FFXIV Launcher"));
|
parser.setApplicationDescription(i18n("Linux FFXIV Launcher"));
|
||||||
|
|
||||||
#ifdef ENABLE_STEAM
|
|
||||||
QCommandLineOption steamOption(QStringLiteral("steam"), QStringLiteral("Used for booting the launcher from Steam."), QStringLiteral("verb"));
|
QCommandLineOption steamOption(QStringLiteral("steam"), QStringLiteral("Used for booting the launcher from Steam."), QStringLiteral("verb"));
|
||||||
steamOption.setFlags(QCommandLineOption::HiddenFromHelp);
|
steamOption.setFlags(QCommandLineOption::HiddenFromHelp);
|
||||||
parser.addOption(steamOption);
|
parser.addOption(steamOption);
|
||||||
#endif
|
|
||||||
|
|
||||||
about.setupCommandLine(&parser);
|
about.setupCommandLine(&parser);
|
||||||
parser.parse(QCoreApplication::arguments());
|
parser.parse(QCoreApplication::arguments());
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
#include <physis.hpp>
|
#include <physis.hpp>
|
||||||
#include <qcorofuture.h>
|
#include <qcorofuture.h>
|
||||||
|
|
||||||
|
#include "astra_patcher_log.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
#include "patchlist.h"
|
#include "patchlist.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
Patcher::Patcher(LauncherCore &launcher, const QString &baseDirectory, BootData &bootData, QObject *parent)
|
Patcher::Patcher(LauncherCore &launcher, const QString &baseDirectory, BootData &bootData, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -67,19 +69,22 @@ QCoro::Task<bool> Patcher::patch(const PatchList &patchList)
|
||||||
|
|
||||||
const QueuedPatch queuedPatch{patch.name, patch.repository, patch.version, patchPath, patch.hashes, patch.hashBlockSize, patch.length, isBoot()};
|
const QueuedPatch queuedPatch{patch.name, patch.repository, patch.version, patchPath, patch.hashes, patch.hashBlockSize, patch.length, isBoot()};
|
||||||
|
|
||||||
qDebug() << "Adding a queued patch:";
|
qDebug(ASTRA_PATCHER) << "Adding a queued patch:";
|
||||||
qDebug() << "- Name:" << patch.name;
|
qDebug(ASTRA_PATCHER) << "- Name:" << patch.name;
|
||||||
qDebug() << "- Repository or is boot:" << (isBoot() ? QStringLiteral("boot") : patch.repository);
|
qDebug(ASTRA_PATCHER) << "- Repository or is boot:" << (isBoot() ? QStringLiteral("boot") : patch.repository);
|
||||||
qDebug() << "- Version:" << patch.version;
|
qDebug(ASTRA_PATCHER) << "- Version:" << patch.version;
|
||||||
qDebug() << "- Downloaded Path:" << patchPath;
|
qDebug(ASTRA_PATCHER) << "- Downloaded Path:" << patchPath;
|
||||||
qDebug() << "- Hashes:" << patch.hashes;
|
qDebug(ASTRA_PATCHER) << "- Hashes:" << patch.hashes;
|
||||||
qDebug() << "- Hash Block Size:" << patch.hashBlockSize;
|
qDebug(ASTRA_PATCHER) << "- Hash Block Size:" << patch.hashBlockSize;
|
||||||
qDebug() << "- Length:" << patch.length;
|
qDebug(ASTRA_PATCHER) << "- Length:" << patch.length;
|
||||||
|
|
||||||
m_patchQueue[ourIndex] = queuedPatch;
|
m_patchQueue[ourIndex] = queuedPatch;
|
||||||
|
|
||||||
if (!QFile::exists(patchPath)) {
|
if (!QFile::exists(patchPath)) {
|
||||||
auto patchReply = m_launcher.mgr->get(QNetworkRequest(patch.url));
|
const auto patchRequest = QNetworkRequest(patch.url);
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), patchRequest);
|
||||||
|
|
||||||
|
auto patchReply = m_launcher.mgr->get(patchRequest);
|
||||||
|
|
||||||
connect(patchReply, &QNetworkReply::downloadProgress, this, [this, queuedPatch](int received, int total) {
|
connect(patchReply, &QNetworkReply::downloadProgress, this, [this, queuedPatch](int received, int total) {
|
||||||
Q_EMIT m_launcher.stageChanged(i18n("Updating %1.\nDownloading %2", getBaseString(), queuedPatch.getVersion()));
|
Q_EMIT m_launcher.stageChanged(i18n("Updating %1.\nDownloading %2", getBaseString(), queuedPatch.getVersion()));
|
||||||
|
@ -93,7 +98,7 @@ QCoro::Task<bool> Patcher::patch(const PatchList &patchList)
|
||||||
file.close();
|
file.close();
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Found existing patch: " << patch.name;
|
qDebug(ASTRA_PATCHER) << "Found existing patch: " << patch.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +152,7 @@ void Patcher::processPatch(const QueuedPatch &patch)
|
||||||
physis_gamedata_apply_patch(m_gameData, patch.path.toStdString().c_str());
|
physis_gamedata_apply_patch(m_gameData, patch.path.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Installed" << patch.path << "to" << (isBoot() ? QStringLiteral("boot") : patch.repository);
|
qDebug(ASTRA_PATCHER) << "Installed" << patch.path << "to" << (isBoot() ? QStringLiteral("boot") : patch.repository);
|
||||||
|
|
||||||
QString verFilePath;
|
QString verFilePath;
|
||||||
if (isBoot()) {
|
if (isBoot()) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "patchlist.h"
|
#include "patchlist.h"
|
||||||
|
#include "astra_patcher_log.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ PatchList::PatchList(const QString &patchList)
|
||||||
"PatchList",
|
"PatchList",
|
||||||
"Patch parsing failed, we were given an non-empty patchlist body but nothing were parsed.");
|
"Patch parsing failed, we were given an non-empty patchlist body but nothing were parsed.");
|
||||||
|
|
||||||
qDebug() << "Finished parsing patch list. Num patches:" << m_patches.size();
|
qDebug(ASTRA_PATCHER) << "Finished parsing patch list. # of patches:" << m_patches.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Patch> PatchList::patches() const
|
QVector<Patch> PatchList::patches() const
|
||||||
|
|
30
launcher/src/processlogger.cpp
Normal file
30
launcher/src/processlogger.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "processlogger.h"
|
||||||
|
#include "astra_log.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
ProcessLogger::ProcessLogger(QProcess *process)
|
||||||
|
{
|
||||||
|
const QDir logDirectory = Utility::stateDirectory().absoluteFilePath("log");
|
||||||
|
|
||||||
|
file.setFileName(logDirectory.absoluteFilePath(QStringLiteral("ffxiv.log")));
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Unbuffered);
|
||||||
|
|
||||||
|
connect(process, &QProcess::readyReadStandardOutput, this, [this, process] {
|
||||||
|
file.write(process->readAllStandardOutput());
|
||||||
|
file.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(process, &QProcess::readyReadStandardError, this, [this, process] {
|
||||||
|
file.write(process->readAllStandardError());
|
||||||
|
file.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(process, &QProcess::finished, this, [this] {
|
||||||
|
deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
|
qInfo(ASTRA_LOG) << "Client logs are being written to" << file.fileName().toUtf8().constData();
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
|
#include "astra_log.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
#include "profileconfig.h"
|
#include "profileconfig.h"
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dalamudVersion = versionString.remove(QLatin1String("Dalamud/"));
|
m_dalamudVersion = versionString.remove(QLatin1String("Dalamud/"));
|
||||||
|
qInfo(ASTRA_LOG) << "Dalamud version:" << m_dalamudVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString dalamudAssetsVer = dalamudAssetsDir.absoluteFilePath(QStringLiteral("asset.ver"));
|
const QString dalamudAssetsVer = dalamudAssetsDir.absoluteFilePath(QStringLiteral("asset.ver"));
|
||||||
|
@ -52,6 +54,7 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent)
|
||||||
assetJson.open(QFile::ReadOnly | QFile::Text);
|
assetJson.open(QFile::ReadOnly | QFile::Text);
|
||||||
|
|
||||||
m_dalamudAssetVersion = QString(assetJson.readAll()).toInt();
|
m_dalamudAssetVersion = QString(assetJson.readAll()).toInt();
|
||||||
|
qInfo(ASTRA_LOG) << "Dalamud asset version:" << m_dalamudVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString dalamudRuntimeVer = dalamudRuntimeDir.absoluteFilePath(QStringLiteral("runtime.ver"));
|
const QString dalamudRuntimeVer = dalamudRuntimeDir.absoluteFilePath(QStringLiteral("runtime.ver"));
|
||||||
|
@ -60,6 +63,7 @@ Profile::Profile(LauncherCore &launcher, const QString &key, QObject *parent)
|
||||||
runtimeVer.open(QFile::ReadOnly | QFile::Text);
|
runtimeVer.open(QFile::ReadOnly | QFile::Text);
|
||||||
|
|
||||||
m_runtimeVersion = QString(runtimeVer.readAll());
|
m_runtimeVersion = QString(runtimeVer.readAll());
|
||||||
|
qInfo(ASTRA_LOG) << "Dalamud runtime version:" << m_dalamudVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "profilemanager.h"
|
#include "profilemanager.h"
|
||||||
|
#include "astra_log.h"
|
||||||
|
|
||||||
#include <KSharedConfig>
|
#include <KSharedConfig>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -101,8 +102,9 @@ void ProfileManager::load()
|
||||||
auto config = KSharedConfig::openStateConfig();
|
auto config = KSharedConfig::openStateConfig();
|
||||||
for (const auto &id : config->groupList()) {
|
for (const auto &id : config->groupList()) {
|
||||||
if (id.contains(QLatin1String("profile-"))) {
|
if (id.contains(QLatin1String("profile-"))) {
|
||||||
qInfo() << "Adding profile" << id;
|
const QString uuid = QString(id).remove(QLatin1String("profile-"));
|
||||||
auto profile = new Profile(m_launcher, QString(id).remove(QLatin1String("profile-")), this);
|
qInfo(ASTRA_LOG) << "Loading profile" << uuid;
|
||||||
|
auto profile = new Profile(m_launcher, uuid, this);
|
||||||
insertProfile(profile);
|
insertProfile(profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "sapphirelauncher.h"
|
#include "sapphirelauncher.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
@ -22,8 +23,10 @@ void SapphireLauncher::login(const QString &lobbyUrl, const LoginInformation &in
|
||||||
|
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));
|
||||||
|
Utility::printRequest(QStringLiteral("POST"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->post(request, QJsonDocument(data).toJson(QJsonDocument::JsonFormat::Compact));
|
const auto reply = window.mgr->post(request, QJsonDocument(data).toJson(QJsonDocument::JsonFormat::Compact));
|
||||||
|
|
||||||
connect(reply, &QNetworkReply::finished, [this, reply, &info] {
|
connect(reply, &QNetworkReply::finished, [this, reply, &info] {
|
||||||
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||||
Q_EMIT window.loginError(i18n("Could not contact lobby server.\n\n%1", reply->errorString()));
|
Q_EMIT window.loginError(i18n("Could not contact lobby server.\n\n%1", reply->errorString()));
|
||||||
|
@ -53,6 +56,8 @@ void SapphireLauncher::registerAccount(const QString &lobbyUrl, const LoginInfor
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));
|
||||||
|
|
||||||
|
Utility::printRequest(QStringLiteral("POST"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->post(request, QJsonDocument(data).toJson(QJsonDocument::JsonFormat::Compact));
|
const auto reply = window.mgr->post(request, QJsonDocument(data).toJson(QJsonDocument::JsonFormat::Compact));
|
||||||
connect(reply, &QNetworkReply::finished, [&] {
|
connect(reply, &QNetworkReply::finished, [&] {
|
||||||
const QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
|
const QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "squarelauncher.h"
|
#include "squarelauncher.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
SquareBoot::SquareBoot(LauncherCore &window, SquareLauncher &launcher, QObject *parent)
|
SquareBoot::SquareBoot(LauncherCore &window, SquareLauncher &launcher, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -43,6 +44,7 @@ QCoro::Task<> SquareBoot::bootCheck(const LoginInformation &info)
|
||||||
}
|
}
|
||||||
|
|
||||||
request.setRawHeader(QByteArrayLiteral("Host"), QStringLiteral("patch-bootver.%1").arg(window.squareEnixServer()).toUtf8());
|
request.setRawHeader(QByteArrayLiteral("Host"), QStringLiteral("patch-bootver.%1").arg(window.squareEnixServer()).toUtf8());
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->get(request);
|
const auto reply = window.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -77,6 +79,8 @@ QCoro::Task<> SquareBoot::checkGateStatus(const LoginInformation &info)
|
||||||
// TODO: really?
|
// TODO: really?
|
||||||
window.buildRequest(*info.profile, request);
|
window.buildRequest(*info.profile, request);
|
||||||
|
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->get(request);
|
const auto reply = window.mgr->get(request);
|
||||||
window.setupIgnoreSSL(reply);
|
window.setupIgnoreSSL(reply);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
SquareLauncher::SquareLauncher(LauncherCore &window, QObject *parent)
|
SquareLauncher::SquareLauncher(LauncherCore &window, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -65,6 +66,8 @@ QCoro::Task<std::optional<SquareLauncher::StoredInfo>> SquareLauncher::getStored
|
||||||
auto request = QNetworkRequest(url);
|
auto request = QNetworkRequest(url);
|
||||||
window.buildRequest(*info.profile, request);
|
window.buildRequest(*info.profile, request);
|
||||||
|
|
||||||
|
Utility::printRequest(QStringLiteral("GET"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->get(request);
|
const auto reply = window.mgr->get(request);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
|
||||||
|
@ -123,6 +126,8 @@ QCoro::Task<> SquareLauncher::login(const LoginInformation &info)
|
||||||
request.setRawHeader(QByteArrayLiteral("Referer"), referer.toEncoded());
|
request.setRawHeader(QByteArrayLiteral("Referer"), referer.toEncoded());
|
||||||
request.setRawHeader(QByteArrayLiteral("Cache-Control"), QByteArrayLiteral("no-cache"));
|
request.setRawHeader(QByteArrayLiteral("Cache-Control"), QByteArrayLiteral("no-cache"));
|
||||||
|
|
||||||
|
Utility::printRequest(QStringLiteral("POST"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
|
const auto reply = window.mgr->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
|
||||||
window.setupIgnoreSSL(reply);
|
window.setupIgnoreSSL(reply);
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
@ -183,6 +188,8 @@ QCoro::Task<> SquareLauncher::registerSession(const LoginInformation &info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utility::printRequest(QStringLiteral("POST"), request);
|
||||||
|
|
||||||
const auto reply = window.mgr->post(request, report.toUtf8());
|
const auto reply = window.mgr->post(request, report.toUtf8());
|
||||||
co_await reply;
|
co_await reply;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include "astra_http_log.h"
|
||||||
|
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
@ -21,3 +22,8 @@ QString Utility::toWindowsPath(const QDir &dir)
|
||||||
{
|
{
|
||||||
return QStringLiteral("Z:") + dir.absolutePath().replace(QLatin1Char('/'), QLatin1Char('\\'));
|
return QStringLiteral("Z:") + dir.absolutePath().replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utility::printRequest(const QString &type, const QNetworkRequest &request)
|
||||||
|
{
|
||||||
|
qDebug(ASTRA_HTTP) << type.toUtf8().constData() << request.url().toDisplayString();
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue