#pragma once #include #include "ConnectedClient.h" namespace ts { namespace server { class TSServer; class SpeakingClient : public ConnectedClient { public: struct VoicePacketFlags { bool encrypted : 1; bool head : 1; bool fragmented : 1; /* used by MONO. IDK What this is */ bool new_protocol : 1; char _unused : 4; VoicePacketFlags() { *(uint8_t*) this = 0; } }; static_assert(sizeof(VoicePacketFlags) == 1); enum HandshakeState { BEGIN, IDENTITY_PROOF, SUCCEEDED }; enum IdentityType { TEASPEAK_FORUM, TEAMSPEAK, NICKNAME }; SpeakingClient(sql::SqlManager* a, const std::shared_ptr& b) : ConnectedClient(a, b) { speak_begin = std::chrono::system_clock::now(); speak_last_packet = std::chrono::system_clock::now(); }; virtual ~SpeakingClient() = default; //Voice virtual void send_voice_packet(const pipes::buffer_view& /* voice packet data */, const VoicePacketFlags& /* flags */) = 0; virtual bool shouldReceiveVoice(const std::shared_ptr &sender); //Whisper bool shouldReceiveVoiceWhisper(const std::shared_ptr &sender); virtual void send_voice_whisper_packet(const pipes::buffer_view& /* voice packet data */, const VoicePacketFlags& /* flags */) = 0; inline std::chrono::milliseconds takeSpokenTime() { auto time = this->speak_time; this->speak_time = std::chrono::milliseconds(0); return time; } protected: void tick(const std::chrono::system_clock::time_point &time) override; protected: public: void updateChannelClientProperties(bool channel_lock, bool notify) override; protected: CommandResult handleCommand(Command &command) override; public: void handlePacketVoice(const pipes::buffer_view&, bool head, bool fragmented); virtual void handlePacketVoiceWhisper(const pipes::buffer_view&, bool /* new */); void processJoin(); void processLeave(); virtual CommandResult handleCommandHandshakeBegin(Command&); virtual CommandResult handleCommandHandshakeIdentityProof(Command &); virtual CommandResult handleCommandClientInit(Command&); void triggerVoiceEnd(); inline void updateSpeak(bool onlyUpdate, const std::chrono::system_clock::time_point &time); std::chrono::milliseconds speak_accuracy = std::chrono::seconds(1); threads::Mutex speak_lock; std::chrono::milliseconds speak_time = std::chrono::milliseconds(0); std::chrono::system_clock::time_point speak_begin; std::chrono::system_clock::time_point speak_last_packet; permission::PermissionValue max_idle_time = permNotGranted; struct { HandshakeState state = HandshakeState::BEGIN; IdentityType identityType; std::string proof_message; //TeamSpeak std::shared_ptr identityKey; //TeaSpeak std::shared_ptr identityData; } handshake; }; } }