TeaSpeak-Client/native/serverconnection/src/connection/ProtocolHandlerPackets.cpp

91 lines
3.2 KiB
C++

#include "ProtocolHandler.h"
#include "ServerConnection.h"
#include "Socket.h"
#include <protocol/buffers.h>
#include <thread>
#include <iostream>
#include <tomcrypt.h>
#include <tommath.h>
#include <misc/endianness.h>
#include <protocol/Packet.h>
#include "audio/VoiceConnection.h"
#include "../logger.h"
using namespace std;
using namespace tc::connection;
using namespace ts::protocol;
using namespace ts;
//#define LOG_PING
void ProtocolHandler::handlePacketAck(const std::shared_ptr<ts::protocol::ServerPacket> &ack) {
string error;
log_trace(category::connection, tr("Handle packet acknowledge for {}"), be2le16(&ack->data()[0]));
this->acknowledge_handler.process_acknowledge(ack->type().type(), ack->data(), error);
}
void ProtocolHandler::handlePacketCommand(const std::shared_ptr<ts::protocol::ServerPacket> &packet) {
std::unique_ptr<Command> command;
try {
command = make_unique<Command>(packet->asCommand());
} catch(const std::invalid_argument& ex) {
log_error(category::connection, tr("Failed to parse command (invalid_argument): {}"), ex.what());
return;
} catch(const std::exception& ex) {
log_error(category::connection, tr("Failed to parse command (exception): {}"), ex.what());
return;
}
log_trace(category::connection, tr("Handing command {}"), command->command());
if(command->command() == "initivexpand") {
this->handleCommandInitIVExpend(*command);
} else if(command->command() == "initivexpand2") {
this->handleCommandInitIVExpend2(*command);
} else if(command->command() == "initserver") {
this->handleCommandInitServer(*command);
}
{
lock_guard lock(this->handle->pending_commands_lock);
this->handle->pending_commands.push_back(move(command));
}
this->handle->execute_pending_commands();
}
void ProtocolHandler::handlePacketVoice(const std::shared_ptr<ts::protocol::ServerPacket> &packet) {
this->handle->voice_connection->process_packet(packet);
}
void ProtocolHandler::handlePacketPing(const std::shared_ptr<ts::protocol::ServerPacket> &packet) {
if(packet->type() == PacketTypeInfo::Pong) {
uint16_t id = be2le16((char*) packet->data().data_ptr());
#ifdef LOG_PING
cout << "Received pong (" << id << "|" << this->ping.ping_id << ")" << endl;
#endif
if(id == this->ping.ping_id) {
this->ping.ping_received_timestamp = chrono::system_clock::now();
this->ping.value = chrono::duration_cast<chrono::microseconds>(this->ping.ping_received_timestamp - this->ping.ping_send_timestamp);
#ifdef LOG_PING
cout << "Updating client ping: " << chrono::duration_cast<chrono::microseconds>(this->ping.value).count() << "us" << endl;
#endif
}
} else {
#ifdef LOG_PING
cout << "Received ping, sending pong" << endl;
#endif
char buffer[2];
le2be16(packet->packetId(), buffer);
this->send_packet(make_shared<ClientPacket>(PacketTypeInfo::Pong, PacketFlag::Unencrypted, pipes::buffer_view{buffer, 2}));
}
}
void ProtocolHandler::ping_send_request() {
auto packet = make_shared<ClientPacket>(PacketTypeInfo::Ping, pipes::buffer_view{});
packet->enable_flag(PacketFlag::Unencrypted);
this->send_packet(packet);
assert(packet->memory_state.id_branded);
this->ping.ping_send_timestamp = chrono::system_clock::now();
this->ping.ping_id = packet->packetId();
}