91 lines
3.2 KiB
C++
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();
|
|
} |