diff options
| author | TrickyLeifa <date.epoch@gmail.com> | 2024-05-15 00:00:17 +0200 |
|---|---|---|
| committer | TrickyLeifa <date.epoch@gmail.com> | 2024-05-15 00:04:16 +0200 |
| commit | c9f52b7223685d2e7fca925594171f94dd8c6e3b (patch) | |
| tree | 740bb32a40da98a4d52836432f59a16b31333900 /src/networkmanager.cpp | |
| parent | 951766666621fa77e257e6b5616fe4ab1eb2a52f (diff) | |
Ported to CMake, ...
* Ported the project to CMake
* Android and Mac support dropped for the time
being.
* Tests, BASS and Discord-RPC are now options
* Restructured and reformated the project.
* Merged `include` and `src`
* Renamed `resource` to `data`
* Renamed various files
* External libraries headers are no longer included in `src`
* Replaced header guards with #pragma once
* Multiple refactors (keywords, headers)
* Added Qt6 compatibility
* Removed various unused functions and headers
* Reworked AOPacket
* When content is passed to AOPacket, it should be ensured that the content is already decoded.
* Encoding/decoding are now static methods.
* Fixed various memory leaks
* Removed animation code for AOImage
* AOImage is always using static images
* Simplified ChatLogPiece
Diffstat (limited to 'src/networkmanager.cpp')
| -rw-r--r-- | src/networkmanager.cpp | 146 |
1 files changed, 79 insertions, 67 deletions
diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp index b7e2810c..a0b95d8c 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -11,16 +11,17 @@ #include <QJsonObject> #include <QNetworkReply> -NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent) +NetworkManager::NetworkManager(AOApplication *parent) + : QObject(parent) { ao_app = parent; http = new QNetworkAccessManager(this); heartbeat_timer = new QTimer(this); - QString master_config = - Options::getInstance().alternativeMasterserver(); - if (!master_config.isEmpty() && QUrl(master_config).scheme().startsWith("http")) { + QString master_config = Options::getInstance().alternativeMasterserver(); + if (!master_config.isEmpty() && QUrl(master_config).scheme().startsWith("http")) + { qInfo() << "using alternate master server" << master_config; ms_baseurl = master_config; } @@ -35,14 +36,14 @@ void NetworkManager::get_server_list() req.setRawHeader("User-Agent", get_user_agent().toUtf8()); QNetworkReply *reply = http->get(req); - connect(reply, &QNetworkReply::finished, - this, std::bind(&NetworkManager::ms_request_finished, this, reply)); + connect(reply, &QNetworkReply::finished, this, std::bind(&NetworkManager::ms_request_finished, this, reply)); } void NetworkManager::ms_request_finished(QNetworkReply *reply) { QJsonDocument json = QJsonDocument::fromJson(reply->readAll()); - if (json.isNull()) { + if (json.isNull()) + { qCritical().noquote() << "Invalid JSON response from" << reply->url(); reply->deleteLater(); return; @@ -52,27 +53,33 @@ void NetworkManager::ms_request_finished(QNetworkReply *reply) QVector<server_type> server_list; const auto jsonEntries = json.array(); - for (const auto &entryRef : jsonEntries) { + for (const auto &entryRef : jsonEntries) + { const auto entry = entryRef.toObject(); server_type server; server.ip = entry["ip"].toString(); server.name = entry["name"].toString(); server.desc = entry["description"].toString(tr("No description provided.")); - if (entry["ws_port"].isDouble()) { + if (entry["ws_port"].isDouble()) + { server.socket_type = WEBSOCKETS; server.port = entry["ws_port"].toInt(); - } else { + } + else + { server.socket_type = TCP; server.port = entry["port"].toInt(); } - if (server.port != 0) { - server_list.append(server); + if (server.port != 0) + { + server_list.append(server); } } ao_app->set_server_list(server_list); - if (ao_app->lobby_constructed) { - ao_app->w_lobby->list_servers(); + if (ao_app->lobby_constructed) + { + ao_app->w_lobby->list_servers(); } reply->deleteLater(); } @@ -84,7 +91,9 @@ void NetworkManager::send_heartbeat() // that time period can be counted and an accurate player count be displayed. // What do I care about your personal information, I really don't want it. if (Options::getInstance().playerCountOptout()) + { return; + } QNetworkRequest req(QUrl(ms_baseurl + "/playing")); req.setRawHeader("User-Agent", get_user_agent().toUtf8()); @@ -92,38 +101,35 @@ void NetworkManager::send_heartbeat() http->post(req, QByteArray()); } -void NetworkManager::request_document(MSDocumentType document_type, - const std::function<void(QString)> &cb) +void NetworkManager::request_document(MSDocumentType document_type, const std::function<void(QString)> &cb) { - const QMap<MSDocumentType, QString> endpoints { - // I have to balance an evil with a good - { MSDocumentType::PrivacyPolicy, "/privacy" }, - { MSDocumentType::Motd, "/motd" }, - { MSDocumentType::ClientVersion, "/version" } - }; + const QMap<MSDocumentType, QString> endpoints{// I have to balance an evil with a good + {MSDocumentType::PrivacyPolicy, "/privacy"}, + {MSDocumentType::Motd, "/motd"}, + {MSDocumentType::ClientVersion, "/version"}}; const QString &endpoint = endpoints[document_type]; QNetworkRequest req(QUrl(ms_baseurl + endpoint)); req.setRawHeader("User-Agent", get_user_agent().toUtf8()); - QString language = - Options::getInstance().language(); + QString language = Options::getInstance().language(); if (language.trimmed().isEmpty()) + { language = QLocale::system().name(); + } req.setRawHeader("Accept-Language", language.toUtf8()); - qDebug().noquote().nospace() - << "Getting " << endpoint << ", Accept-Language: " << language; + qDebug().noquote().nospace() << "Getting " << endpoint << ", Accept-Language: " << language; QNetworkReply *reply = http->get(req); connect(reply, &QNetworkReply::finished, this, [endpoint, cb, reply] { QString content = QString::fromUtf8(reply->readAll()); int http_status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (content.isEmpty() || http_status != 200) { - qDebug().noquote().nospace() - << "Failed to get " << endpoint << " (" << reply->errorString() << ") " - << "(http status " << http_status << ")"; + if (content.isEmpty() || http_status != 200) + { + qDebug().noquote().nospace() << "Failed to get " << endpoint << " (" << reply->errorString() << ") " + << "(http status " << http_status << ")"; content = QString(); } cb(content); @@ -135,10 +141,10 @@ void NetworkManager::connect_to_server(server_type p_server) { disconnect_from_server(); - qInfo().nospace().noquote() << "connecting to " << p_server.ip << ":" - << p_server.port; + qInfo().nospace().noquote() << "connecting to " << p_server.ip << ":" << p_server.port; - switch (p_server.socket_type) { + switch (p_server.socket_type) + { default: p_server.socket_type = TCP; [[fallthrough]]; @@ -146,14 +152,9 @@ void NetworkManager::connect_to_server(server_type p_server) qInfo() << "using TCP backend"; server_socket.tcp = new QTcpSocket(this); - connect(server_socket.tcp, &QAbstractSocket::connected, this, [] { - qDebug() << "established connection to server"; - }); - connect(server_socket.tcp, &QIODevice::readyRead, this, [this] { - handle_server_packet(QString::fromUtf8(server_socket.tcp->readAll())); - }); - connect(server_socket.tcp, &QAbstractSocket::disconnected, ao_app, - &AOApplication::server_disconnected); + connect(server_socket.tcp, &QAbstractSocket::connected, this, [] { qDebug() << "established connection to server"; }); + connect(server_socket.tcp, &QIODevice::readyRead, this, [this] { handle_server_packet(QString::fromUtf8(server_socket.tcp->readAll())); }); + connect(server_socket.tcp, &QAbstractSocket::disconnected, ao_app, &AOApplication::server_disconnected); #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) connect(server_socket.tcp, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, [this] { #else @@ -168,17 +169,10 @@ void NetworkManager::connect_to_server(server_type p_server) qInfo() << "using WebSockets backend"; server_socket.ws = new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this); - connect(server_socket.ws, &QWebSocket::connected, this, [] { - qDebug() << "established connection to server"; - }); - connect(server_socket.ws, &QWebSocket::textMessageReceived, this, - &NetworkManager::handle_server_packet); - connect(server_socket.ws, &QWebSocket::disconnected, ao_app, - &AOApplication::server_disconnected); - connect(server_socket.ws, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), - this, [this] { - qCritical() << "WebSockets error:" << server_socket.ws->errorString(); - }); + connect(server_socket.ws, &QWebSocket::connected, this, [] { qDebug() << "established connection to server"; }); + connect(server_socket.ws, &QWebSocket::textMessageReceived, this, &NetworkManager::handle_server_packet); + connect(server_socket.ws, &QWebSocket::disconnected, ao_app, &AOApplication::server_disconnected); + connect(server_socket.ws, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, [this] { qCritical() << "WebSockets error:" << server_socket.ws->errorString(); }); QUrl url; url.setScheme("ws"); @@ -196,15 +190,18 @@ void NetworkManager::connect_to_server(server_type p_server) void NetworkManager::join_to_server() { - ship_server_packet(AOPacket("askchaa").to_string()); + ship_server_packet(AOPacket("askchaa").to_string()); } void NetworkManager::disconnect_from_server() { if (!connected) + { return; + } - switch (active_connection_type) { + switch (active_connection_type) + { case TCP: server_socket.tcp->close(); server_socket.tcp->deleteLater(); @@ -218,30 +215,36 @@ void NetworkManager::disconnect_from_server() connected = false; } -void NetworkManager::ship_server_packet(QString p_packet) +void NetworkManager::ship_server_packet(AOPacket p_packet) { - switch (active_connection_type) { + QString message = p_packet.to_string(true); + switch (active_connection_type) + { case TCP: - server_socket.tcp->write(p_packet.toUtf8()); + server_socket.tcp->write(message.toUtf8()); break; + case WEBSOCKETS: - server_socket.ws->sendTextMessage(p_packet); + server_socket.ws->sendTextMessage(message); break; } } -void NetworkManager::handle_server_packet(const QString& p_data) +void NetworkManager::handle_server_packet(const QString &p_data) { QString in_data = p_data; - if (!p_data.endsWith("%")) { + if (!p_data.endsWith("%")) + { partial_packet = true; temp_packet += in_data; return; } - else { - if (partial_packet) { + else + { + if (partial_packet) + { in_data = temp_packet + in_data; temp_packet = ""; partial_packet = false; @@ -253,25 +256,34 @@ void NetworkManager::handle_server_packet(const QString& p_data) const QStringList packet_list = in_data.split("%", Qt::SkipEmptyParts); #endif - for (const QString &packet : packet_list) { + for (const QString &packet : packet_list) + { QStringList f_contents; // Packet should *always* end with # - if (packet.endsWith("#")) { + if (packet.endsWith("#")) + { f_contents = packet.chopped(1).split("#"); } // But, if it somehow doesn't, we should still be able to handle it - else { + else + { f_contents = packet.split("#"); } // Empty packets are suspicious! - if (f_contents.isEmpty()) { + if (f_contents.isEmpty()) + { qWarning() << "WARNING: Empty packet received from server, skipping..."; continue; } // Take the first arg as the command QString command = f_contents.takeFirst(); + for (QString &data : f_contents) + { + data = AOPacket::decode(data); + } + // The rest is contents of the packet - AOPacket *f_packet = new AOPacket(command, f_contents); + AOPacket f_packet(command, f_contents); // Ship it to the server! ao_app->server_packet_received(f_packet); } |
