Teaspeak-Server/client/src/protocol/ConnectionPacketHandler.cpp

158 lines
6.4 KiB
C++

#include <protocol/Packet.h>
#include <arpa/inet.h>
#include "Connection.h"
#include "misc/base64.h"
#include "misc/endianness.h"
using namespace std;
using namespace ts;
using namespace ts::connection;
using namespace ts::protocol;
//notifystatusfiletransfer clientftfid=4093 status=2063 msg=lost\sfile\stransfer\sconnection size=16384
extern void hexdump(std::ostream& outs, const std::string& s, size_t line_len = 16);
inline void downloadStuff(std::string key, uint16_t port, uint64_t size){
threads::Thread([key, port, size](){
int socketId = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
assert(socketId > 1);
sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( port );
//Connect to remote server
if (connect(socketId , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return;
}
uint32_t readed = 0;
assert(send(socketId, key.data(), key.length(), 0) > 0);
while(readed < size + 3){
char buffer[size];
auto readedBytes = recv(socketId, buffer, size - readed, MSG_DONTWAIT);
if(readedBytes < 0) {
//cerr << "Invalid ft read" << endl;
continue;
}
if(readedBytes == 0){
continue;
}
hexdump(cout, string(buffer, readedBytes));
readed += readedBytes;
}
cout << "File downloaded!" << endl;
}).detach();
}
void ServerConnection::handlePacketAck(std::shared_ptr<protocol::ServerPacket> packet) {
auto packetId = be2le16((const char*) packet->data().data_ptr());
#if defined(DEBUG_PACKET_LOG) || defined(LOG_ACK)
cout << "Got ack for " << packetId << endl;
#endif
}
void ServerConnection::handlePacketCommand(std::shared_ptr<protocol::ServerPacket> packet) {
auto command = packet->asCommand();
#if defined(DEBUG_PACKET_LOG) || defined(LOG_CMD)
cout << "[Server -> Client][" << packet->type().name() << "] " << packet->data() << endl;
#endif
if (command.getCommand().compare("notifyconnectioninforequest") == 0) { //TODO
cout << "Send response" << endl;
Command cmd(
string("setconnectioninfo"), {
{"connection_ping", 10000000},
{"connection_ping_deviation", 10000000},
{"connection_packets_sent_speech", 0},
{"connection_packets_sent_keepalive", 0},
{"connection_packets_sent_control", rand()},
{"connection_bytes_sent_speech", 0},
{"connection_bytes_sent_keepalive", 0},
{"connection_bytes_sent_control", 0},
{"connection_packets_received_speech", 0},
{"connection_packets_received_keepalive", 0},
{"connection_packets_received_control", 0},
{"connection_bytes_received_speech", 0},
{"connection_bytes_received_keepalive", 0},
{"connection_bytes_received_control", 0},
{"connection_server2client_packetloss_speech", 10000000},
{"connection_server2client_packetloss_keepalive", 10000000},
{"connection_server2client_packetloss_control", 10000000},
{"connection_server2client_packetloss_total", 10000000},
{"connection_bandwidth_sent_last_second_speech", 0},
{"connection_bandwidth_sent_last_second_keepalive", 0},
{"connection_bandwidth_sent_last_second_control", 0},
{"connection_bandwidth_sent_last_minute_speech", 0},
{"connection_bandwidth_sent_last_minute_keepalive", 0},
{"connection_bandwidth_sent_last_minute_control", 0},
{"connection_bandwidth_received_last_second_speech", 0},
{"connection_bandwidth_received_last_second_keepalive", 0},
{"connection_bandwidth_received_last_second_control", 0},
{"connection_bandwidth_received_last_minute_speech", 0},
{"connection_bandwidth_received_last_minute_keepalive", 0},
{"connection_bandwidth_received_last_minute_control", 0}
}
);
sendCommand(cmd, true);
} else if (command.command() == "notifyserverupdated") {
#if defined(DEBUG_PACKET_LOG) || defined(LOG_CMD)
cout << "notifyserverupdated -> " << endl;
cout << "Last data: " << packet->data().string().substr(packet->data().length() - 10) << endl;
#endif
} else if (command.command() == "notifystartdownload") {
cout << "Client download: " << command.build() << endl;
auto port = command["port"].as<uint16_t>();
auto key = command["ftkey"].string();
auto size = command["size"].as<uint64_t>();
downloadStuff(key, port, size);
} else if (command.command() == "channellist") {
cout << "Breaking ack" << endl;
for (int index = 0; index < command.bulkCount(); index++) {
this->channels.push_back(command[index]["cid"].as<ChannelId>());
}
}
}
void ServerConnection::handlePacketVoice(std::shared_ptr<protocol::ServerPacket> packet) {}
static int pingIndex = 0;
void ServerConnection::handlePacketPing(std::shared_ptr<protocol::ServerPacket> packet) {
if(packet->type() == PacketTypeInfo::Pong){
//cout << "[PING] gota " << be2le16(packet->data().data()) << endl;
return;
}
char buffer[2];
le2be16(packet->packetId(), buffer);
ClientPacket pkt(PacketTypeInfo::Pong, pipes::buffer_view{buffer, 2});
pkt.enableFlag(PacketFlag::Unencrypted);
sendPacket(pkt);
ClientPacket ping(PacketTypeInfo::Ping, pipes::buffer_view{buffer, 0});
ping.enableFlag(PacketFlag::Unencrypted);
sendPacket(ping);
//cout << "[PING] Reqe " << ping.packetId() << endl;
//cout << "[PONG] Send " << packet->packetId() << endl;
if(this->clientId > 0 && this->channels.size() > 0) {
Command command("clientmove");
command["clid"] = this->clientId;
auto idx = rand() % this->channels.size();
command["cid"] = this->channels[idx];
this->sendCommand(command);
std::thread([&] {
threads::self::sleep_for(chrono::seconds(1));
Command cmd("channelcreate");
cmd["channel_name"] = to_string(rand()) + "_" + to_string(rand());
//this->sendCommand(cmd);
}).detach();
}
}