120 lines
4.4 KiB
C++
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 |