Teaspeak-Server/server/src/client/voice/VoiceClientPacketHandler.cpp
2020-04-24 22:04:07 +02:00

90 lines
3.7 KiB
C++

#include <tommath.h>
#include <misc/endianness.h>
#include <algorithm>
#include <log/LogUtils.h>
#include "../web/WebClient.h"
#include "VoiceClient.h"
using namespace std;
using namespace std::chrono;
using namespace ts::server;
using namespace ts::protocol;
//#define PKT_LOG_PING
/* should never happen! */
void VoiceClient::handlePacketInit(const ts::protocol::ClientPacketParser &) {}
//TODO Packet handlers -> move back to voice client?
void VoiceClient::handlePacketCommand(const pipes::buffer_view& command_string) {
std::unique_ptr<Command> command;
command_result result{};
try {
command = make_unique<Command>(Command::parse(command_string, true, !ts::config::server::strict_ut8_mode));
} catch(std::invalid_argument& ex) {
result = command_result{error::parameter_convert, std::string{ex.what()}};
goto handle_error;
} catch(std::exception& ex) {
result = command_result{error::parameter_convert, std::string{ex.what()}};
goto handle_error;
}
if(command->command() == "clientek") {
result = this->handleCommandClientEk(*command);
if(result.error_code()) goto handle_error;
} else if(command->command() == "clientinitiv") {
result = this->handleCommandClientInitIv(*command);
if(result.error_code()) goto handle_error;
} else this->handleCommandFull(*command, true);
return;
handle_error:
this->notifyError(result);
result.release_details();
}
void VoiceClient::handlePacketPing(const protocol::ClientPacketParser& packet) {
if (packet.type() == protocol::PONG) {
if(packet.payload_length() < 2) return;
uint16_t id = be2le16((char*) packet.payload().data_ptr());
if (this->lastPingId == id) {
#ifdef PKT_LOG_PING
logMessage(this->getServerId(), "{}[Ping] Got a valid pong for ping {}. Required time: {}", CLIENT_STR_LOG_PREFIX, id, duration_cast<microseconds>(system_clock::now() - this->lastPingRequest).count() / 1000.f);
#endif
this->lastPingResponse = system_clock::now();
this->ping = std::chrono::duration_cast<std::chrono::milliseconds>(this->lastPingResponse - this->lastPingRequest);
}
#ifdef PKT_LOG_PING
else {
logMessage(this->getServerId(), "{}[Ping] Got invalid pong. (Responded pong id {} but expected {})", CLIENT_STR_LOG_PREFIX, packet->packetId(), this->lastPingId);
}
#endif
return;
}
#ifdef PKT_LOG_PING
logMessage(this->getServerId(), "{}[Ping] Sending pong for client requested ping {}", CLIENT_STR_LOG_PREFIX, packet->packetId());
#endif
char buffer[2];
le2be16(packet.packet_id(), buffer);
this->connection->send_packet(PacketType::PONG, PacketFlag::Unencrypted, buffer, 2);
}
void VoiceClient::handlePacketVoice(const protocol::ClientPacketParser& packet) {
SpeakingClient::handlePacketVoice(packet.payload(), (packet.flags() & PacketFlag::Compressed) > 0, (packet.flags() & PacketFlag::Fragmented) > 0);
}
void VoiceClient::handlePacketVoiceWhisper(const ts::protocol::ClientPacketParser &packet) {
SpeakingClient::handlePacketVoiceWhisper(packet.payload(), (packet.flags() & PacketFlag::NewProtocol) > 0);
}
void VoiceClient::handlePacketAck(const protocol::ClientPacketParser& packet) {
if(packet.payload_length() < 2) return;
uint16_t target_id{be2le16(packet.payload().data_ptr<char>())};
this->connection->packet_statistics().received_acknowledge((protocol::PacketType) packet.type(), target_id | (packet.estimated_generation() << 16U));
string error{};
if(!this->connection->acknowledge_handler.process_acknowledge(packet.type(), target_id, error))
debugMessage(this->getServerId(), "{} Failed to handle acknowledge: {}", CLIENT_STR_LOG_PREFIX, error);
}