85 lines
3.5 KiB
C++
85 lines
3.5 KiB
C++
#include <tommath.h>
|
|
#include <misc/endianness.h>
|
|
#include <algorithm>
|
|
#include <log/LogUtils.h>
|
|
#include "../web/WebClient.h"
|
|
#include "query/command2.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 unique_ptr<ts::protocol::ClientPacket> &) {}
|
|
|
|
//TODO Packet handlers -> move back to voice manager?
|
|
void VoiceClient::handlePacketCommand(const std::unique_ptr<protocol::ClientPacket>& packet) {
|
|
std::unique_ptr<Command> command;
|
|
try {
|
|
command = make_unique<Command>(Command::parse(packet->data(), true, !ts::config::server::strict_ut8_mode));
|
|
} catch(std::invalid_argument& ex) {
|
|
this->notifyError({findError("parameter_convert"), ex.what()});
|
|
return;
|
|
} catch(command_malformed_exception& ex) {
|
|
this->notifyError({findError("parameter_convert"), ex.what()});
|
|
return;
|
|
} catch(std::exception& ex) {
|
|
this->notifyError({findError("parameter_convert"), ex.what()});
|
|
return;
|
|
}
|
|
|
|
if(command->command() == "clientek") {
|
|
auto result = this->handleCommandClientEk(packet, *command);
|
|
if(!result)
|
|
this->notifyError(result);
|
|
} else if(command->command() == "clientinitiv") {
|
|
auto result = this->handleCommandClientInitIv(*command);
|
|
if(!result)
|
|
this->notifyError(result);
|
|
} else this->handleCommandFull(*command, true);
|
|
}
|
|
|
|
void VoiceClient::handlePacketPing(const std::unique_ptr<protocol::ClientPacket>& packet) {
|
|
if (packet->type() == PacketTypeInfo::Pong) {
|
|
uint16_t id = be2le16((char*) packet->data().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 = duration_cast<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->packetId(), buffer);
|
|
auto pkt = make_shared<ServerPacket>(PacketTypeInfo::Pong, pipes::buffer_view{buffer, 2});
|
|
pkt->enable_flag(PacketFlag::Unencrypted);
|
|
this->connection->sendPacket(pkt);
|
|
}
|
|
|
|
void VoiceClient::handlePacketVoice(const std::unique_ptr<protocol::ClientPacket>& packet) {
|
|
if (packet->type() == PacketTypeInfo::Voice) {
|
|
SpeakingClient::handlePacketVoice(packet->data(), packet->has_flag(PacketFlag::Compressed), packet->has_flag(PacketFlag::Fragmented));
|
|
} else if(packet->type() == PacketTypeInfo::VoiceWhisper) {
|
|
SpeakingClient::handlePacketVoiceWhisper(packet->data(), packet->has_flag(PacketFlag::NewProtocol));
|
|
}
|
|
}
|
|
|
|
void VoiceClient::handlePacketAck(const std::unique_ptr<protocol::ClientPacket>& packet) {
|
|
string error;
|
|
if(!this->connection->acknowledge_handler.process_acknowledge(*packet, error))
|
|
debugMessage(this->getServerId(), "{} Failed to handle acknowledge: {}", CLIENT_STR_LOG_PREFIX, error);
|
|
} |