Teaspeak-Server/server/src/client/web/WebClient.h

120 lines
4.4 KiB
C++

#pragma once
#ifdef COMPILE_WEB_CLIENT
#include <pipes/ssl.h>
#include <pipes/ws.h>
#include <pipes/rtc/PeerConnection.h>
#include <src/client/SpeakingClient.h>
#include <src/client/ConnectedClient.h>
#include <protocol/buffers.h>
#include "misc/queue.h"
#include <opus/opus.h>
#include <json/json.h>
#include <EventLoop.h>
namespace ts::server {
class WebControlServer;
class WebClient : public SpeakingClient {
friend class WebControlServer;
public:
WebClient(WebControlServer*, int socketFd);
~WebClient() override;
void sendJson(const Json::Value&);
void sendCommand(const ts::Command &command, bool low) override;
void sendCommand(const ts::command_builder &command, bool low) override;
bool disconnect(const std::string &reason) override;
bool close_connection(const std::chrono::system_clock::time_point& timeout = std::chrono::system_clock::time_point()) override;
[[nodiscard]] inline std::chrono::nanoseconds client_ping() const { return this->client_ping_layer_7(); }
[[nodiscard]] inline std::chrono::nanoseconds client_ping_layer_5() const { return this->ping.value; }
[[nodiscard]] inline std::chrono::nanoseconds client_ping_layer_7() const { return this->js_ping.value; }
protected:
void tick(const std::chrono::system_clock::time_point&) override; /* Every 500ms */
void applySelfLock(const std::shared_ptr<WebClient> &cl){ _this = cl; }
private:
WebControlServer* handle;
int file_descriptor;
bool allow_raw_commands{false};
bool ssl_detected{false};
bool ssl_encrypted{true};
pipes::SSL ssl_handler;
pipes::WebSocket ws_handler;
std::mutex event_mutex;
::event* readEvent;
::event* writeEvent;
struct {
uint8_t current_id{0};
std::chrono::system_clock::time_point last_request;
std::chrono::system_clock::time_point last_response;
std::chrono::nanoseconds value{};
std::chrono::nanoseconds timeout{2000};
} ping;
struct {
uint8_t current_id{0};
std::chrono::system_clock::time_point last_request;
std::chrono::system_clock::time_point last_response;
std::chrono::nanoseconds value{};
std::chrono::nanoseconds timeout{2000};
} js_ping;
std::mutex queue_mutex;
std::deque<pipes::buffer> queue_read;
std::deque<pipes::buffer> queue_write;
threads::Mutex execute_mutex; /* needs to be recursive! */
std::thread flush_thread;
std::recursive_mutex close_lock;
struct {
std::mutex mutex{};
pipes::buffer target_header{};
bool is_new_header{false};
bool is_set{false};
} whisper;
private:
void initialize();
void handleMessageRead(int, short, void*);
void handleMessageWrite(int, short, void*);
void enqueue_raw_packet(const pipes::buffer_view& /* buffer */);
void processNextMessage(const std::chrono::system_clock::time_point& /* scheduled */);
void registerMessageProcess();
std::shared_ptr<event::ProxiedEventEntry<WebClient>> event_handle_packet;
//WS events
void onWSConnected();
void onWSDisconnected(const std::string& reason);
void onWSMessage(const pipes::WSMessage&);
protected:
void disconnectFinal();
void handleMessage(const pipes::buffer_view&);
public:
void send_voice_packet(const pipes::buffer_view &view, const VoicePacketFlags &flags) override;
void send_voice_whisper_packet(const pipes::buffer_view &/* teamspeak packet */, const pipes::buffer_view &/* teaspeak packet */, const VoicePacketFlags &flags) override;
protected:
command_result handleCommand(Command &command) override;
command_result handleCommandClientInit(Command &command) override;
command_result handleCommandSetWhisperTarget(Command &command);
command_result handleCommandClearWhisperTarget(Command &command);
};
}
#endif