88 lines
3.5 KiB
C++
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 *);
|
|
};
|
|
}
|
|
} |