Teaspeak-Server/server/src/client/voice/VoiceClient.h

108 lines
4.2 KiB
C++

#pragma once
#include <cstdint>
#include <ThreadPool/Thread.h>
#include <ThreadPool/Mutex.h>
#include <protocol/buffers.h>
#include <netinet/in.h>
#include <deque>
#include <cstdint>
#include <EventLoop.h>
#include "../SpeakingClient.h"
#include "../ConnectedClient.h"
#include "protocol/CryptHandler.h"
#include "VoiceClientConnection.h"
#include "src/server/udp-server/PrecomputedPuzzles.h"
#include "../../lincense/TeamSpeakLicense.h"
//#define LOG_INCOMPING_PACKET_FRAGMENTS
//#define LOG_AUTO_ACK_AUTORESPONSE
//#define LOG_AUTO_ACK_REQUEST
//#define LOG_AUTO_ACK_RESPONSE
//#define LOG_PKT_RESEND
#define PKT_LOG_CMD
//#define PKT_LOG_VOICE
//#define PKT_LOG_WHISPER
//#define PKT_LOG_PING
//For CLion
#ifndef CLIENT_LOG_PREFIX
#define CLIENT_LOG_PREFIX "Undefined CLIENT_LOG_PREFIX"
#endif
namespace ts {
namespace connection {
class VoiceClientConnection;
}
namespace server {
class VirtualServer;
class VoiceClient : public SpeakingClient {
friend class VirtualServer;
friend class VoiceServer;
friend class ts::connection::VoiceClientConnection;
friend class ConnectedClient;
public:
VoiceClient(const std::shared_ptr<VirtualServer>& server,const sockaddr_storage*);
~VoiceClient();
bool close_connection(const std::chrono::system_clock::time_point &timeout) override;
bool disconnect(const std::string&) override;
bool disconnect(ViewReasonId /* reason type */, const std::string& /* reason */, const std::shared_ptr<ts::server::ConnectedClient>& /* invoker */, bool /* notify viewer */);
virtual void sendCommand(const ts::Command &command, bool low = false) { return this->sendCommand0(command.build(), low); }
virtual void sendCommand(const ts::command_builder &command, bool low) { return this->sendCommand0(command.build(), low); }
/* Note: Order is only guaranteed if progressDirectly is on! */
virtual void sendCommand0(const std::string_view& /* data */, bool low = false, bool progressDirectly = false, std::unique_ptr<threads::Future<bool>> listener = nullptr);
/* the connection might be null! */
[[nodiscard]] inline auto connection() { return this->connection_; }
[[nodiscard]] std::chrono::milliseconds calculatePing();
private:
std::shared_ptr<connection::VoiceClientConnection> connection_{nullptr};
protected:
void initialize(const std::shared_ptr<connection::VoiceClientConnection>& /* connection */);
void finalize();
virtual void tick(const std::chrono::system_clock::time_point &time) override;
public:
void send_voice_packet(const pipes::buffer_view &packet, const VoicePacketFlags &flags) override;
void send_voice_whisper_packet(const pipes::buffer_view &packet, const VoicePacketFlags &flags) override;
protected:
void handlePacketCommand(const pipes::buffer_view&);
virtual command_result handleCommand(Command &command) override;
std::chrono::system_clock::time_point last_packet_handshake;
private:
//General TS3 manager commands
command_result handleCommandClientInitIv(Command&);
command_result handleCommandClientEk(Command&);
command_result handleCommandClientInit(Command&) override;
command_result handleCommandClientDisconnect(Command&);
struct {
bool client_init = false;
bool new_protocol = false;
uint32_t client_time = 0;
std::string alpha;
std::string beta;
std::shared_ptr<LicenseChainData> chain_data;
std::shared_ptr<ecc_key> remote_key;
} crypto;
enum struct CryptoHandshakeState {
INITEV,
CLIENT_EK,
DONE
} crypto_handshake_state{CryptoHandshakeState::INITEV};
};
}
}