aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/aoapplication.h2
-rw-r--r--src/ext_distribution.cpp51
-rw-r--r--src/network/websocketconnection.cpp16
-rw-r--r--src/network/websocketconnection.h3
-rw-r--r--src/networkmanager.cpp30
-rw-r--r--src/networkmanager.h2
-rw-r--r--src/packet_distribution.cpp5
8 files changed, 110 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5930f7..cdd5952 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -119,6 +119,7 @@ qt_add_executable(Attorney_Online
src/keyring.cpp
src/ext_packet.h
src/ext_packet.cpp
+ src/ext_distribution.cpp
src/vli.h
src/vli.c
src/auth_flow.h
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);