diff options
| author | Osmium Sorcerer <os@sof.beauty> | 2026-03-22 18:56:58 +0000 |
|---|---|---|
| committer | Osmium Sorcerer <os@sof.beauty> | 2026-03-29 22:22:25 +0000 |
| commit | d6352bc889638b82a887e0a1a138f2b8086dbbdb (patch) | |
| tree | 35f7bb8b5b6641f69930bd8485260bc8594e5fe9 /src | |
| parent | a124f46861d549ddc13485536962e34d80de939a (diff) | |
Handle extension packets using binary frames
The subprotocol shall use binary frames, and AO protocol stays separated
within the text frames.
Diffstat (limited to 'src')
| -rw-r--r-- | src/aoapplication.h | 2 | ||||
| -rw-r--r-- | src/ext_distribution.cpp | 51 | ||||
| -rw-r--r-- | src/network/websocketconnection.cpp | 16 | ||||
| -rw-r--r-- | src/network/websocketconnection.h | 3 | ||||
| -rw-r--r-- | src/networkmanager.cpp | 30 | ||||
| -rw-r--r-- | src/networkmanager.h | 2 | ||||
| -rw-r--r-- | src/packet_distribution.cpp | 5 |
7 files changed, 109 insertions, 0 deletions
diff --git a/src/aoapplication.h b/src/aoapplication.h index d8d0c00..e3db417 100644 --- a/src/aoapplication.h +++ b/src/aoapplication.h @@ -77,8 +77,10 @@ public: void destruct_courtroom(); void server_packet_received(AOPacket p_packet); + void ex_message_received(QByteArrayView message); void send_server_packet(AOPacket p_packet); + void send_ex_message(const QByteArray &msg); void call_settings_menu(); diff --git a/src/ext_distribution.cpp b/src/ext_distribution.cpp new file mode 100644 index 0000000..42f4156 --- /dev/null +++ b/src/ext_distribution.cpp @@ -0,0 +1,51 @@ +// Copyright 2026 Osmium Sorcerer +// SPDX-License-Identifier: MIT + +#include "ext_packet.h" + +#include "aoapplication.h" +#include "auth_flow.h" +#include "courtroom.h" +#include "networkmanager.h" + +#include <QHeaderView> +#include <QVBoxLayout> + +static void handleAuthChallenge(QByteArrayView body, AOApplication *ao) +{ + if (ao->ex_auth_username.isEmpty()) + { + // We're not authenticating, ignore. + return; + } + + AuthChallenge challenge; + if (!parseAuthChallenge(body, challenge)) + { + qWarning() << "Invalid AuthChallenge message"; + return; + } + + new AuthFlow(ao, challenge); +} + +void AOApplication::ex_message_received(QByteArrayView message) +{ + ExMsgType type = (ExMsgType)message[0]; + QByteArrayView body = message.sliced(1); + switch (type) + { + case ExMsgType::auth_challenge: + handleAuthChallenge(body, this); + break; + default: + qWarning() << "Unknown message type:" << (int)type; + break; + } +} + +void AOApplication::send_ex_message(const QByteArray &msg) +{ + // Why indirection? + net_manager->ship_ex_message(msg); +} diff --git a/src/network/websocketconnection.cpp b/src/network/websocketconnection.cpp index d51cdca..fedbe11 100644 --- a/src/network/websocketconnection.cpp +++ b/src/network/websocketconnection.cpp @@ -14,6 +14,7 @@ WebSocketConnection::WebSocketConnection(AOApplication *ao_app, QObject *parent) connect(m_socket, &QWebSocket::errorOccurred, this, &WebSocketConnection::onError); connect(m_socket, &QWebSocket::stateChanged, this, &WebSocketConnection::onStateChanged); connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketConnection::onTextMessageReceived); + connect(m_socket, &QWebSocket::binaryMessageReceived, this, &WebSocketConnection::onBinaryMessageReceived); } WebSocketConnection::~WebSocketConnection() @@ -55,6 +56,11 @@ void WebSocketConnection::sendPacket(AOPacket packet) m_socket->sendTextMessage(packet.toString(true)); } +void WebSocketConnection::sendExMessage(const QByteArray &msg) +{ + m_socket->sendBinaryMessage(msg); +} + void WebSocketConnection::onError() { Q_EMIT errorOccurred(m_socket->errorString()); @@ -95,3 +101,13 @@ void WebSocketConnection::onTextMessageReceived(QString message) Q_EMIT receivedPacket(AOPacket(header, raw_content)); } + +void WebSocketConnection::onBinaryMessageReceived(const QByteArray message) +{ + if (message.isEmpty()) + { + return; + } + + Q_EMIT receivedExMessage(message); +} diff --git a/src/network/websocketconnection.h b/src/network/websocketconnection.h index 9d9f7d0..1f5a842 100644 --- a/src/network/websocketconnection.h +++ b/src/network/websocketconnection.h @@ -23,6 +23,7 @@ public: void disconnectFromServer(); void sendPacket(AOPacket packet); + void sendExMessage(const QByteArray &msg); Q_SIGNALS: void connectedToServer(); @@ -30,6 +31,7 @@ Q_SIGNALS: void errorOccurred(QString error); void receivedPacket(AOPacket packet); + void receivedExMessage(QByteArray msg); private: AOApplication *ao_app; @@ -41,4 +43,5 @@ private Q_SLOTS: void onError(); void onStateChanged(QAbstractSocket::SocketState state); void onTextMessageReceived(QString message); + void onBinaryMessageReceived(QByteArray message); }; diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp index 779dc1e..fa7aa16 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -159,6 +159,7 @@ void NetworkManager::connect_to_server(ServerInfo server) connect(m_connection, &WebSocketConnection::disconnectedFromServer, ao_app, &AOApplication::server_disconnected); connect(m_connection, &WebSocketConnection::errorOccurred, this, [](QString error) { qCritical() << "Connection error:" << error; }); connect(m_connection, &WebSocketConnection::receivedPacket, this, &NetworkManager::handle_server_packet); + connect(m_connection, &WebSocketConnection::receivedExMessage, this, &NetworkManager::handle_ex_message); m_connection->connectToServer(server); } @@ -192,6 +193,27 @@ void NetworkManager::ship_server_packet(AOPacket packet) m_connection->sendPacket(packet); } +void NetworkManager::ship_ex_message(const QByteArray &msg) +{ + if (!m_connection) + { + qCritical() << "Failed to ship packet; no connection."; + return; + } + + if (!m_connection->isConnected()) + { + qCritical() << "Failed to ship packet; not connected."; + return; + } + + // TODO: Diagnostic notation +#ifdef NETWORK_DEBUG + qInfo().noquote() << "Sending message:" << msg.toHex(' '); +#endif + m_connection->sendExMessage(msg); +} + void NetworkManager::join_to_server() { ship_server_packet(AOPacket("askchaa")); @@ -205,6 +227,14 @@ void NetworkManager::handle_server_packet(AOPacket packet) ao_app->server_packet_received(packet); } +void NetworkManager::handle_ex_message(QByteArray message) +{ +#ifdef NETWORK_DEBUG + qInfo().noquote() << "Received message:" << message.toHex(' '); +#endif + ao_app->ex_message_received(message); +} + QNetworkReply *NetworkManager::get_audio_url(const QUrl &url) { QNetworkRequest req(url); diff --git a/src/networkmanager.h b/src/networkmanager.h index bc542a4..2a1f19a 100644 --- a/src/networkmanager.h +++ b/src/networkmanager.h @@ -34,8 +34,10 @@ public: public Q_SLOTS: void get_server_list(); void ship_server_packet(AOPacket packet); + void ship_ex_message(const QByteArray &msg); void join_to_server(); void handle_server_packet(AOPacket packet); + void handle_ex_message(QByteArray msg); void request_document(MSDocumentType document_type, const std::function<void(QString)> &cb); void send_heartbeat(); diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp index 90a6758..69448d4 100644 --- a/src/packet_distribution.cpp +++ b/src/packet_distribution.cpp @@ -67,8 +67,13 @@ void AOApplication::server_packet_received(AOPacket packet) return; } + // Remove this, the client shouldn't use this packet to get its PID. client_id = content.at(0).toInt(); m_serverdata.set_server_software(content.at(1)); + if (content.at(1) == "CSDWASASH") + { + send_ex_message(serializeIdent(Ident{2})); + } emit net_manager->server_connected(true); |
