aboutsummaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/netconnection.cpp5
-rw-r--r--src/net/netconnection.h28
-rw-r--r--src/net/nettcpconnection.cpp102
-rw-r--r--src/net/nettcpconnection.h31
-rw-r--r--src/net/netwebsocketconnection.cpp97
-rw-r--r--src/net/netwebsocketconnection.h32
6 files changed, 295 insertions, 0 deletions
diff --git a/src/net/netconnection.cpp b/src/net/netconnection.cpp
new file mode 100644
index 00000000..63ca7060
--- /dev/null
+++ b/src/net/netconnection.cpp
@@ -0,0 +1,5 @@
+#include "netconnection.h"
+
+NetConnection::NetConnection(QObject *parent)
+ : QObject(parent)
+{}
diff --git a/src/net/netconnection.h b/src/net/netconnection.h
new file mode 100644
index 00000000..0b5d6be3
--- /dev/null
+++ b/src/net/netconnection.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "aopacket.h"
+#include "datatypes.h"
+
+#include <QObject>
+
+class NetConnection : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit NetConnection(QObject *parent = nullptr);
+
+ virtual bool isConnected() = 0;
+
+ virtual void connectToServer(ServerInfo &server) = 0;
+ virtual void disconnectFromServer() = 0;
+
+ virtual void sendPacket(AOPacket packet) = 0;
+
+Q_SIGNALS:
+ void connectedToServer();
+ void disconnectedFromServer();
+ void errorOccurred(QString error);
+
+ void receivedPacket(AOPacket packet);
+};
diff --git a/src/net/nettcpconnection.cpp b/src/net/nettcpconnection.cpp
new file mode 100644
index 00000000..2bc52b71
--- /dev/null
+++ b/src/net/nettcpconnection.cpp
@@ -0,0 +1,102 @@
+#include "nettcpconnection.h"
+
+NetTcpConnection::NetTcpConnection(QObject *parent)
+ : NetConnection(parent)
+ , m_socket(new QTcpSocket(this))
+ , m_last_state(QAbstractSocket::UnconnectedState)
+{
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, &NetTcpConnection::onErrorOccurred);
+#else
+ connect(m_socket, &QTcpSocket::errorOccurred, this, &NetTcpConnection::onErrorOccurred);
+#endif
+ connect(m_socket, &QTcpSocket::stateChanged, this, &NetTcpConnection::onStateChanged);
+ connect(m_socket, &QTcpSocket::readyRead, this, &NetTcpConnection::onReadyRead);
+}
+
+NetTcpConnection::~NetTcpConnection()
+{
+ m_socket->disconnect(this);
+ disconnectFromServer();
+}
+
+bool NetTcpConnection::isConnected()
+{
+ return m_last_state == QAbstractSocket::ConnectedState;
+}
+
+void NetTcpConnection::connectToServer(ServerInfo &server)
+{
+ disconnectedFromServer();
+ m_socket->connectToHost(server.ip, server.port);
+}
+
+void NetTcpConnection::disconnectFromServer()
+{
+ m_socket->abort();
+}
+
+void NetTcpConnection::sendPacket(AOPacket packet)
+{
+ if (!isConnected())
+ {
+ qWarning().noquote() << QObject::tr("Cannot send packet, not connected to server");
+ return;
+ }
+ m_socket->write(packet.toString(true).toUtf8());
+}
+
+void NetTcpConnection::onErrorOccurred()
+{
+ Q_EMIT errorOccurred(m_socket->errorString());
+}
+
+void NetTcpConnection::onStateChanged(QAbstractSocket::SocketState state)
+{
+ m_last_state = state;
+ switch (state)
+ {
+ default:
+ break;
+
+ case QAbstractSocket::ConnectedState:
+ m_cached_data.clear();
+ Q_EMIT connectedToServer();
+ break;
+
+ case QAbstractSocket::UnconnectedState:
+ Q_EMIT disconnectFromServer();
+ break;
+ }
+}
+
+void NetTcpConnection::onReadyRead()
+{
+ m_cached_data += QString::fromUtf8(m_socket->readAll());
+ if (!m_cached_data.endsWith('%'))
+ {
+ return;
+ }
+
+ QStringList raw_packet_list = m_cached_data.split('%', Qt::SkipEmptyParts);
+ m_cached_data.clear();
+ for (QString raw_packet : raw_packet_list)
+ {
+ if (!raw_packet.endsWith('#'))
+ {
+ Q_EMIT errorOccurred(QObject::tr("Malformed packet received %1").arg(raw_packet));
+ continue;
+ }
+ raw_packet.chop(1);
+
+ QStringList raw_content = raw_packet.split('#');
+
+ const QString header = raw_content.takeFirst();
+ for (QString &data : raw_content)
+ {
+ data = AOPacket::decode(data);
+ }
+
+ Q_EMIT receivedPacket(AOPacket(header, raw_content));
+ }
+}
diff --git a/src/net/nettcpconnection.h b/src/net/nettcpconnection.h
new file mode 100644
index 00000000..40dae196
--- /dev/null
+++ b/src/net/nettcpconnection.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "aopacket.h"
+#include "datatypes.h"
+#include "netconnection.h"
+
+#include <QTcpSocket>
+
+class NetTcpConnection : public NetConnection
+{
+public:
+ NetTcpConnection(QObject *parent = nullptr);
+ virtual ~NetTcpConnection();
+
+ bool isConnected() override;
+
+ void connectToServer(ServerInfo &server) override;
+ void disconnectFromServer() override;
+
+ void sendPacket(AOPacket packet) override;
+
+private:
+ QTcpSocket *m_socket;
+ QAbstractSocket::SocketState m_last_state;
+ QString m_cached_data;
+
+private Q_SLOTS:
+ void onErrorOccurred();
+ void onStateChanged(QAbstractSocket::SocketState state);
+ void onReadyRead();
+};
diff --git a/src/net/netwebsocketconnection.cpp b/src/net/netwebsocketconnection.cpp
new file mode 100644
index 00000000..a9d2e10c
--- /dev/null
+++ b/src/net/netwebsocketconnection.cpp
@@ -0,0 +1,97 @@
+#include "netwebsocketconnection.h"
+
+#include "networkmanager.h"
+
+#include <QNetworkRequest>
+#include <QUrl>
+
+NetWebSocketConnection::NetWebSocketConnection(NetworkManager *networkManager)
+ : NetConnection(networkManager)
+ , m_network_manager(networkManager)
+ , m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
+ , m_last_state(QAbstractSocket::UnconnectedState)
+{
+ connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &NetWebSocketConnection::onError);
+ connect(m_socket, &QWebSocket::stateChanged, this, &NetWebSocketConnection::onStateChanged);
+ connect(m_socket, &QWebSocket::textMessageReceived, this, &NetWebSocketConnection::onTextMessageReceived);
+}
+
+NetWebSocketConnection::~NetWebSocketConnection()
+{
+ m_socket->disconnect(this);
+ disconnectFromServer();
+}
+
+bool NetWebSocketConnection::isConnected()
+{
+ return m_last_state == QAbstractSocket::ConnectedState;
+}
+
+void NetWebSocketConnection::connectToServer(ServerInfo &server)
+{
+ disconnectFromServer();
+
+ QUrl url;
+ url.setScheme("ws");
+ url.setHost(server.ip);
+ url.setPort(server.port);
+
+ QNetworkRequest req(url);
+ req.setHeader(QNetworkRequest::UserAgentHeader, m_network_manager->get_user_agent());
+
+ m_socket->open(req);
+}
+
+void NetWebSocketConnection::disconnectFromServer()
+{
+ if (isConnected())
+ {
+ m_socket->close(QWebSocketProtocol::CloseCodeGoingAway);
+ }
+}
+
+void NetWebSocketConnection::sendPacket(AOPacket packet)
+{
+ m_socket->sendTextMessage(packet.toString(true));
+}
+
+void NetWebSocketConnection::onError()
+{
+ Q_EMIT errorOccurred(m_socket->errorString());
+}
+
+void NetWebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
+{
+ m_last_state = state;
+ switch (state)
+ {
+ default:
+ break;
+
+ case QAbstractSocket::ConnectedState:
+ Q_EMIT connectedToServer();
+ break;
+
+ case QAbstractSocket::UnconnectedState:
+ Q_EMIT disconnectFromServer();
+ break;
+ }
+}
+
+void NetWebSocketConnection::onTextMessageReceived(QString message)
+{
+ if (!message.endsWith("#%"))
+ {
+ return;
+ }
+ message.chop(2);
+
+ QStringList raw_content = message.split('#');
+ const QString header = raw_content.takeFirst();
+ for (QString &data : raw_content)
+ {
+ data = AOPacket::decode(data);
+ }
+
+ Q_EMIT receivedPacket(AOPacket(header, raw_content));
+}
diff --git a/src/net/netwebsocketconnection.h b/src/net/netwebsocketconnection.h
new file mode 100644
index 00000000..26f41a6e
--- /dev/null
+++ b/src/net/netwebsocketconnection.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "netconnection.h"
+
+class NetworkManager;
+
+#include <QWebSocket>
+
+class NetWebSocketConnection : public NetConnection
+{
+public:
+ NetWebSocketConnection(NetworkManager *networkManager);
+ virtual ~NetWebSocketConnection();
+
+ bool isConnected() override;
+
+ void connectToServer(ServerInfo &server) override;
+ void disconnectFromServer() override;
+
+ void sendPacket(AOPacket packet) override;
+
+private:
+ NetworkManager *m_network_manager;
+
+ QWebSocket *m_socket;
+ QAbstractSocket::SocketState m_last_state;
+
+private Q_SLOTS:
+ void onError();
+ void onStateChanged(QAbstractSocket::SocketState state);
+ void onTextMessageReceived(QString message);
+};