90 lines
3.7 KiB
C++
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);
|
|
} |