Teaspeak-Server/client/src/protocol/Connection.h

139 lines
4.1 KiB
C++

#pragma once
#include <ThreadPool/Thread.h>
#include <ThreadPool/Mutex.h>
#include <string>
#include <thread>
#include <netinet/in.h>
#include <deque>
#include <list>
#include <protocol/Packet.h>
#include <protocol/buffers.h>
#include <src/protocol/socket/FilteredUDPSocket.h>
#include <src/Identity.h>
#include <protocol/CryptionHandler.h>
#include <protocol/CompressionHandler.h>
#define NoQt
#ifndef NoQt
#include <QUdpSocket>
#endif
#define DEBUG_PACKET_LOG
//#define LOG_CMD
namespace ts {
namespace connection {
namespace ConnectionState {
enum ConnectionState {
UNCONNECTED,
LLHANDSCHAKE,
HANDSCHAKE,
CONNECTED,
DISCONNECTED
};
}
class ServerConnection
#ifndef NoQt
: public QObject {
Q_OBJECT
#else
{
#endif
public:
ServerConnection();
~ServerConnection();
bool connect(std::string host, std::string port, Identity* identity);
void disconnect();
ConnectionState::ConnectionState getConnectionState(){ return cstate; }
bool handshake(std::string &errorMessage);
bool handshakeNew(Command &cmd, const std::string& alpha, std::string &errorMessage);
void sendPacket(ts::protocol::ClientPacket& packet);
void sendCommand(ts::Command command, bool low = false);
void sendAcknowledge(uint16_t packetId, bool low = false);
std::shared_ptr<protocol::ServerPacket> readNextPacket(bool block = true);
uint16_t getClientId(){
return this->clientId;
}
void setClientId(uint16_t id){
this->clientId = id;
}
#ifndef NoQt
public slots:
void attempDatagramRead();
void bytesWritten(qint64);
#endif
private:
bool encriptAck = false;
bool preProgressPacket(std::shared_ptr<protocol::ServerPacket> packet);
void rwExecutor();
void handleExecutor();
bool handleNextPacket();
bool setupSharedSecret(std::string alpha, std::string beta, std::string sharedKey, std::string& error);
void handlePacketPing(std::shared_ptr<protocol::ServerPacket> packet);
void handlePacketCommand(std::shared_ptr<protocol::ServerPacket> packet);
void handlePacketAck(std::shared_ptr<protocol::ServerPacket> packet);
void handlePacketVoice(std::shared_ptr<protocol::ServerPacket> packet);
bool connected = true;
sockaddr_in remoteAddress;
sockaddr_in localAddress;
UdpSocket* socket;
threads::Thread* rwThread = nullptr;
std::deque<buffer::RawBuffer> writeQueue;
#ifndef NoQt
QUdpSocket* qtSocket = nullptr;
#endif
threads::Mutex bufferQueueLock;
buffer::SortedBufferQueue<protocol::ServerPacket>** readQueue = nullptr;
//std::deque<RawBuffer> readQueue;
std::deque<buffer::RawBuffer> acknowlageQueue;
threads::Mutex acknowlageQueueLock;
protocol::PacketIdManager idManager;
threads::Thread* handleThread = nullptr;
std::list<std::shared_ptr<protocol::ServerPacket>> handleQueue; //Parsed packets
threads::Mutex handleQueueLock;
bool autoHandle = false;
ts::connection::CryptionHandler* cryptionHandler = nullptr;
ts::connection::CompressionHandler* compressionHandler = nullptr;
std::string remoteHost;
uint16_t remotePort;
Identity* clientIdentity;
ConnectionState::ConnectionState cstate = ConnectionState::UNCONNECTED;
bool breakAck = false;
/**
* TS3 Client data
*/
uint16_t clientId = 0;
std::deque<ChannelId> channels;
};
}
}