135 lines
5.4 KiB
C++
135 lines
5.4 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 <src/server/VoiceServer.h>
|
|
#include <EventLoop.h>
|
|
#include "../SpeakingClient.h"
|
|
#include "../ConnectedClient.h"
|
|
#include "protocol/CryptHandler.h"
|
|
#include "VoiceClientConnection.h"
|
|
#include "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 POWHandler;
|
|
friend class ts::connection::VoiceClientConnection;
|
|
friend class ConnectedClient;
|
|
friend class io::IOServerHandler;
|
|
public:
|
|
VoiceClient(const std::shared_ptr<VoiceServer>& 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);
|
|
virtual void sendAcknowledge(uint16_t packetId, bool low = false);
|
|
|
|
connection::VoiceClientConnection* getConnection(){ return connection; }
|
|
std::shared_ptr<VoiceServer> getVoiceServer(){ return voice_server; }
|
|
std::chrono::milliseconds calculatePing(){ return ping; }
|
|
private:
|
|
connection::VoiceClientConnection* connection;
|
|
|
|
protected:
|
|
std::shared_ptr<VoiceServer> voice_server;
|
|
|
|
void initialize();
|
|
virtual void tick(const std::chrono::system_clock::time_point &time) override;
|
|
|
|
void handlePacketCommand(const pipes::buffer_view&);
|
|
void handlePacketAck(const protocol::IncomingClientPacketParser&);
|
|
void handlePacketVoice(const protocol::IncomingClientPacketParser&);
|
|
void handlePacketPing(const protocol::IncomingClientPacketParser&);
|
|
void handlePacketInit(const protocol::IncomingClientPacketParser&);
|
|
|
|
//Handshake helpers
|
|
|
|
|
|
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:
|
|
virtual command_result handleCommand(Command &command) override;
|
|
|
|
//Some helper method
|
|
void sendPingRequest();
|
|
|
|
//Ping/pong
|
|
uint16_t lastPingId = 0;
|
|
std::chrono::milliseconds ping = std::chrono::milliseconds(0);
|
|
std::chrono::system_clock::time_point lastPingResponse;
|
|
std::chrono::system_clock::time_point lastPingRequest;
|
|
|
|
std::chrono::system_clock::time_point last_packet_handshake;
|
|
|
|
private:
|
|
int socket = 0;
|
|
io::pktinfo_storage address_info;
|
|
|
|
void finalDisconnect();
|
|
bool final_disconnected = false;
|
|
|
|
//General TS3 manager commands
|
|
command_result handleCommandClientInitIv(Command&);
|
|
command_result handleCommandClientEk(Command&);
|
|
command_result handleCommandClientInit(Command&) override;
|
|
command_result handleCommandClientDisconnect(Command&);
|
|
|
|
//Locked by finalDisconnect, disconnect and close connection
|
|
std::shared_ptr<threads::Thread> flushing_thread;
|
|
|
|
struct {
|
|
bool client_init = false;
|
|
bool new_protocol = false;
|
|
bool protocol_encrypted = 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;
|
|
|
|
std::shared_ptr<event::ProxiedEventEntry<VoiceClient>> event_handle_packet;
|
|
void execute_handle_packet(const std::chrono::system_clock::time_point& /* scheduled */);
|
|
};
|
|
}
|
|
} |