Cockatrice/cockatrice/src/interface/widgets/server/handle_public_servers.cpp
BruebachL 518c7e6125
[Network] Add a configured QNetworkAccessManager factory (#7628)
* [Network] Add a configured QNetworkAccessManager factory

Every HTTP caller built its own QNetworkAccessManager, so the system proxy
and a transfer timeout were easy to omit. Add NetworkManagerFactory::create()
as the single place that applies the process-wide proxy configuration and a
transfer timeout, and use it at all 14 construction sites.

Per-site settings such as disk caches and manual redirect policies stay with
their callers.

* [Tests] Link libcockatrice_network into the tests that compile its headers

release_channel.cpp and card_picture_loader_worker.cpp now include
libcockatrice/network/network_manager.h, but the test targets that compile
them only linked libcockatrice_settings, so the include directory never
reached them and every platform failed with "file not found":
loader_local_matching_test and picture_loader_benchmark_test.

libcockatrice_network is an INTERFACE library, so linking it costs these
targets nothing but hands over the include path.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
2026-10-25 00:33:43 +02:00

117 lines
4 KiB
C++

#include "handle_public_servers.h"
#include "../../../client/settings/cache_settings.h"
#include <QByteArray>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSharedPointer>
#include <QUrl>
#include <QVariant>
#include <QVariantMap>
#include <libcockatrice/network/network_manager.h>
#include <libcockatrice/settings/servers_settings.h>
#include <qlogging.h>
#define PUBLIC_SERVERS_JSON "https://cockatrice.github.io/public-servers.json"
HandlePublicServers::HandlePublicServers(QObject *parent)
: QObject(parent), nam(NetworkManagerFactory::create(this)), reply(nullptr)
{
}
void HandlePublicServers::downloadPublicServers()
{
QUrl url(QString(PUBLIC_SERVERS_JSON));
reply = nam->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, &HandlePublicServers::actFinishParsingDownloadedData);
}
void HandlePublicServers::actFinishParsingDownloadedData()
{
reply = dynamic_cast<QNetworkReply *>(sender());
QNetworkReply::NetworkError errorCode = reply->error();
if (errorCode == QNetworkReply::NoError) {
// Get current saved hosts
UserConnection_Information uci;
savedHostList = uci.getServerInfo();
// Downloaded data from GitHub
QJsonParseError parseError{};
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
if (parseError.error == QJsonParseError::NoError) {
QVariantMap jsonMap = jsonResponse.toVariant().toMap();
updateServerINISettings(jsonMap);
} else {
qDebug() << "[PUBLIC SERVER HANDLER]" << "JSON Parsing Error:" << parseError.errorString();
emit sigPublicServersDownloadedUnsuccessfully(errorCode);
}
} else {
qDebug() << "[PUBLIC SERVER HANDLER]" << "Error Downloading Public Servers" << errorCode;
emit sigPublicServersDownloadedUnsuccessfully(errorCode);
}
reply->deleteLater(); // After an emit() occurs, this object will be deleted
}
void HandlePublicServers::updateServerINISettings(QMap<QString, QVariant> jsonMap)
{
// Servers available
auto publicServersJSONList = jsonMap["servers"].toList();
for (const auto &server : publicServersJSONList) {
// Data inside one server at a time
// server: [{ ... }, ..., { ... }]
const auto serverMap = server.toMap();
QString serverAddress = serverMap["host"].toString();
if (serverMap["isInactive"].toBool()) {
publicServersToRemove.append(serverAddress);
continue;
}
QString serverName = serverMap["name"].toString();
QString serverPort = serverMap["port"].toString();
QString serverSite = serverMap["site"].toString();
if (serverMap.contains("websocketPort")) {
serverPort = serverMap["websocketPort"].toString();
}
bool serverFound = false;
for (const auto &iter : savedHostList) {
// If the URL/IP matches
if (iter.second.getServer() == serverAddress) {
serverFound = true;
break;
}
}
if (serverFound) {
SettingsCache::instance().servers().updateExistingServerWithoutLoss(serverName, serverAddress, serverPort,
serverSite);
} else {
SettingsCache::instance().servers().addNewServer(serverName, serverAddress, serverPort, "", "", false,
serverSite);
}
}
// If a server was removed from the public list,
// we will delete it from the local system.
// Will not delete "unofficial" servers
for (const auto &pair : savedHostList) {
QString serverAddr = pair.first;
if (publicServersToRemove.indexOf(serverAddr) != -1) {
SettingsCache::instance().servers().removeServer(serverAddr);
}
}
emit sigPublicServersDownloadedSuccessfully();
}