diff --git a/akashi.pro b/akashi.pro index 14c0246..c3ed942 100644 --- a/akashi.pro +++ b/akashi.pro @@ -17,7 +17,8 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += $$files($$PWD/src/*.cpp) -HEADERS += $$files($$PWD/include/*.h) +HEADERS += $$files($$PWD/include/*.h) \ + include/aoclient.h FORMS += $$files($$PWD/resource/forms/*.ui) diff --git a/include/advertiser.h b/include/advertiser.h index f479348..34807c1 100644 --- a/include/advertiser.h +++ b/include/advertiser.h @@ -1,7 +1,7 @@ #ifndef MASTER_H #define MASTER_H -#include +#include "include/aopacket.h" #include #include diff --git a/include/akashimain.h b/include/akashimain.h index 749f690..def37ed 100644 --- a/include/akashimain.h +++ b/include/akashimain.h @@ -1,9 +1,9 @@ #ifndef AKASHIMAIN_H #define AKASHIMAIN_H -#include -#include -#include +#include "include/advertiser.h" +#include "include/config_manager.h" +#include "include/server.h" #include #include diff --git a/include/aoclient.h b/include/aoclient.h new file mode 100644 index 0000000..6dbf3c7 --- /dev/null +++ b/include/aoclient.h @@ -0,0 +1,15 @@ +#ifndef AOCLIENT_H +#define AOCLIENT_H + +#include + +class AOClient +{ +public: + AOClient(); + +private: + +}; + +#endif // AOCLIENT_H diff --git a/include/aopacket.h b/include/aopacket.h index 4f9f3d7..cc02f20 100644 --- a/include/aopacket.h +++ b/include/aopacket.h @@ -2,16 +2,17 @@ #define PACKET_MANAGER_H #include +#include #include #include class AOPacket { public: AOPacket(QString p_header, QStringList p_contents); + AOPacket(QString packet); QString toString(); QByteArray toUtf8(); -private: QString header; QStringList contents; }; diff --git a/include/server.h b/include/server.h index c30dba9..c2d11be 100644 --- a/include/server.h +++ b/include/server.h @@ -1,19 +1,37 @@ #ifndef SERVER_H #define SERVER_H +#include "include/aopacket.h" +#include "include/aoclient.h" + #include #include +#include +#include class Server : public QObject { Q_OBJECT public: - Server(int p_port, int p_ws_port); + Server(int p_port, int p_ws_port, QObject* parent = nullptr); void start(); +signals: + +public slots: + void clientConnected(); + void clientDisconnected(); + void clientData(); + private: + QTcpServer* server; + int port; int ws_port; + + QMap clients; + QString partial_packet; + bool is_partial; }; #endif // SERVER_H diff --git a/src/akashimain.cpp b/src/akashimain.cpp index 10ef1e0..363bfa9 100644 --- a/src/akashimain.cpp +++ b/src/akashimain.cpp @@ -19,6 +19,7 @@ AkashiMain::AkashiMain(QWidget *parent) } else { if (settings.advertise_server) { + // TODO: send signal advertiser started advertiser = new Advertiser(settings.ms_ip, settings.port, settings.ws_port, settings.local_port, settings.name, settings.description, this); diff --git a/src/aoclient.cpp b/src/aoclient.cpp new file mode 100644 index 0000000..0d82eff --- /dev/null +++ b/src/aoclient.cpp @@ -0,0 +1,6 @@ +#include "include/aoclient.h" + +AOClient::AOClient() +{ + +} diff --git a/src/aopacket.cpp b/src/aopacket.cpp index 357efa2..76499d1 100644 --- a/src/aopacket.cpp +++ b/src/aopacket.cpp @@ -1,4 +1,4 @@ -#include +#include "include/aopacket.h" AOPacket::AOPacket(QString p_header, QStringList p_contents) { @@ -6,6 +6,24 @@ AOPacket::AOPacket(QString p_header, QStringList p_contents) contents = p_contents; } +AOPacket::AOPacket(QString p_packet) +{ + QStringList packet_contents = p_packet.split("#"); + if(p_packet.at(0) == '#') { + // The header is encrypted with FantaCrypt + // The server always uses the same key for FantaCrypt + // That way, we can just hardcode FantaCrypted headers + packet_contents.removeFirst(); + if(packet_contents[0] == "48E0") + header = "HI"; + } + else { + header = packet_contents[0]; + } + packet_contents.removeFirst(); + contents = packet_contents; +} + QString AOPacket::toString() { QString ao_packet = header; diff --git a/src/config_manager.cpp b/src/config_manager.cpp index 2709cf8..6252263 100644 --- a/src/config_manager.cpp +++ b/src/config_manager.cpp @@ -1,4 +1,4 @@ -#include +#include "include/config_manager.h" ConfigManager::ConfigManager() { diff --git a/src/server.cpp b/src/server.cpp index b5a3a6e..d91dacb 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,9 +1,71 @@ #include "include/server.h" -Server::Server(int p_port, int p_ws_port) +Server::Server(int p_port, int p_ws_port, QObject* parent) + : QObject(parent) { + server = new QTcpServer(this); + connect(server, SIGNAL(newConnection()), this, SLOT(clientConnected())); + port = p_port; ws_port = p_ws_port; } -void Server::start() {} +void Server::start() +{ + // TODO: websockets lul + // Maybe websockets should be handled by a separate intermediate part of the code? + // The idea being that it is a websocket server, and all it does is create a + // local connection to the raw tcp server. + // The main issue with this is that it will cause problems with bans, ipids, etc + // But perhaps this can be negotiated by sending some extra data over? + // No idea. I'll wait for long to read this massive comment and DM me on discord + if(!server->listen(QHostAddress::Any, port)) + { + // TODO: signal server start failed + qDebug() << "Server error:" << server->errorString(); + } + else + { + // TODO: signal server start success + qDebug() << "Server listening on" << port; + } +} + +void Server::clientConnected() +{ + QTcpSocket* client = server->nextPendingConnection(); + AOClient ao_client; + clients.insert(client, ao_client); + connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected())); + connect(client, SIGNAL(readyRead()), this, SLOT(clientData())); + + AOPacket decryptor("decryptor", {"34"}); + client->write(decryptor.toUtf8()); + + qDebug() << client->peerAddress().toString() << "connected"; +} + +void Server::clientDisconnected() +{ + if(QTcpSocket* client = dynamic_cast(sender())){ + qDebug() << client->peerAddress() << "disconnected"; + clients.remove(client); + } +} + +void Server::clientData() +{ + if(QTcpSocket* client = dynamic_cast(sender())){ + QString data = QString::fromUtf8(client->readAll()); + qDebug() << "From" << client->peerAddress() << ":" << data; + + if(is_partial) { + data = partial_packet + data; + } + if(!data.endsWith("%")){ + is_partial = true; + } + + AOPacket packet(data); + } +}