Teaspeak-Server/server/src/server/VoiceServer.h

88 lines
3.5 KiB
C++

#pragma once
#include <netinet/in.h>
#include <deque>
#include <ThreadPool/Thread.h>
#include <ThreadPool/Mutex.h>
#include <event.h>
#include <condition_variable>
#include <misc/net.h>
#include <protocol/ringbuffer.h>
#include "VoiceIOManager.h"
#include "./voice/DatagramPacket.h"
#include "Definitions.h"
namespace ts {
namespace protocol {
class PuzzleManager;
}
namespace server {
class VirtualServer;
class ConnectedClient;
class VoiceClient;
class POWHandler;
struct VoiceServerBinding {
sockaddr_storage address{};
int file_descriptor = 0;
[[nodiscard]] inline std::string address_string() const { return net::to_string(address); }
[[nodiscard]] inline uint16_t address_port() const { return net::port(address); }
};
class VoiceServer {
friend class VoiceClient;
friend class io::VoiceIOManager;
friend struct io::IOEventLoopEvents;
friend class POWHandler;
public:
explicit VoiceServer(const std::shared_ptr<VirtualServer>& server);
~VoiceServer();
bool start(const std::deque<std::shared_ptr<VoiceServerBinding>>&, std::string&);
bool stop(const std::chrono::milliseconds& flushTimeout = std::chrono::milliseconds(1000));
std::shared_ptr<VoiceClient> findClient(ClientId);
std::shared_ptr<VoiceClient> findClient(sockaddr_in* addr, bool lock = true);
std::shared_ptr<VoiceClient> findClient(sockaddr_in6* addr, bool lock = true);
inline std::shared_ptr<VoiceClient> findClient(sockaddr_storage* address, bool lock = true) {
return address->ss_family == AF_INET ?
this->findClient((sockaddr_in*) address, lock) :
address->ss_family == AF_INET6 ?
this->findClient((sockaddr_in6*) address, lock) :
nullptr;
}
bool unregisterConnection(std::shared_ptr<VoiceClient>);
inline std::deque<std::shared_ptr<VoiceServerBinding>> activeBindings() {
std::deque<std::shared_ptr<VoiceServerBinding>> result;
for(const auto& entry : this->bindings)
if(entry->file_descriptor > 0) result.push_back(entry);
return result;
}
inline std::shared_ptr<VirtualServer> get_server() { return this->server; }
private:
std::unique_ptr<POWHandler> pow_handler;
std::shared_ptr<VirtualServer> server = nullptr;
bool running = false;
std::deque<std::shared_ptr<VoiceServerBinding>> bindings;
std::recursive_mutex connectionLock;
std::deque<std::shared_ptr<VoiceClient>> activeConnections;
public:
void triggerWrite(const std::shared_ptr<VoiceClient> &);
void tickHandshakingClients();
void execute_resend(const std::chrono::system_clock::time_point& /* now */, std::chrono::system_clock::time_point& /* next resend */);
void send_datagram(int /* socket */, udp::DatagramPacket* /* packet */);
std::shared_ptr<io::IOServerHandler> io;
private:
static void handleMessageRead(int, short, void *);
static void handleMessageWrite(int, short, void *);
};
}
}