2#include <asio/connect.hpp>
3#include <asio/write.hpp>
4#include <asio/ip/udp.hpp>
21 std::function<
void(
const std::vector<unsigned char>&)> callback)
22 : socket(io_context), initialized(false)
29 asio::ip::tcp::resolver::results_type results = resolver.resolve(
ip, std::to_string(
port));
31 asio::async_connect(
socket, results,
33 std::placeholders::_1));
55 std::vector<unsigned char> sized_packet;
56 sized_packet.reserve(bytes.size() + 5);
57 ProtocolCraft::WriteData<ProtocolCraft::VarInt>(
static_cast<int>(bytes.size()), sized_packet);
58 sized_packet.insert(sized_packet.end(), bytes.begin(), bytes.end());
63 std::vector<unsigned char> encrypted =
encrypter->Encrypt(sized_packet);
101 LOG_INFO(
"Connection to server established.");
105 std::placeholders::_1, std::placeholders::_2));
109 LOG_ERROR(
"Error when connecting to server. Error code :" << error);
120 std::vector<unsigned char> decrypted(bytes_transferred);
121 std::copy_n(
read_packet.begin(), bytes_transferred, decrypted.data());
122 decrypted =
encrypter->Decrypt(decrypted);
123 for (
int i = 0; i < decrypted.size(); ++i)
130 for (
int i = 0; i < bytes_transferred; ++i)
136 for (
int i = 0; i < bytes_transferred; ++i)
144 std::vector<unsigned char>::const_iterator read_iter =
input_packet.begin();
149 packet_length = ProtocolCraft::ReadData<ProtocolCraft::VarInt>(read_iter, max_length);
151 catch (
const std::runtime_error)
155 const int bytes_read =
static_cast<int>(std::distance<std::vector<unsigned char>::const_iterator>(
input_packet.begin(), read_iter));
156 std::vector<unsigned char> data_packet;
158 if (packet_length > 0 &&
input_packet.size() >= bytes_read + packet_length)
160 data_packet = std::vector<unsigned char>(
input_packet.begin() + bytes_read,
input_packet.begin() + bytes_read + packet_length);
173 std::placeholders::_1, std::placeholders::_2));
188 if (!write_in_progress)
194 std::placeholders::_1));
212 std::placeholders::_1));
228 std::string addressOnly;
232 if (splitted_port.size() > 1)
236 port = std::stoi(splitted_port[1]);
237 ip = splitted_port[0];
240 catch (
const std::exception&)
244 addressOnly = splitted_port[0];
249 addressOnly = address;
254 LOG_INFO(
"Performing SRV DNS lookup on " <<
"_minecraft._tcp." << address <<
" to find an endpoint");
281 std::vector<unsigned char> encoded_query;
282 query.
Write(encoded_query);
283 udp_socket.open(asio::ip::udp::v4());
284 asio::ip::udp::endpoint endpoint(asio::ip::make_address(
"8.8.8.8"), 53);
285 udp_socket.send_to(asio::buffer(encoded_query), endpoint);
288 std::vector<unsigned char> answer_buffer(512);
289 asio::ip::udp::endpoint sender_endpoint;
290 const size_t len = udp_socket.receive_from(asio::buffer(answer_buffer), sender_endpoint);
293 size_t remaining = len;
297 answer.
Read(iter, remaining);
301 && answer.
GetAnswers()[0].GetTypeCode() == 0x21)
304 auto iter2 = answer.
GetAnswers()[0].GetRData().begin();
305 size_t len2 = answer.
GetAnswers()[0].GetRDLength();
306 data.
Read(iter2, len2);
314 LOG_INFO(
"SRV DNS lookup successful!");
317 LOG_WARNING(
"SRV DNS lookup failed to find an address");
#define LOG_ERROR(osstream)
#define LOG_WARNING(osstream)
#define LOG_INFO(osstream)
void SetIdentification(const std::vector< unsigned char > &identification_)
void SetFlagOPCode(const char opcode_)
void SetQuestions(const std::vector< DNSQuestion > &questions_)
void SetFlagRA(const char ra_)
void SetFlagQR(const char qr_)
void SetFlagRCode(const char rcode_)
short GetNumberAnswer() const
void SetNumberAdditionalRR(const short number_additional_rr_)
void SetFlagAA(const char aa_)
void SetNumberAnswer(const short number_answer_)
void SetFlagZ(const char z_)
void SetFlagRD(const char rd_)
const std::vector< DNSResourceRecord > & GetAnswers() const
void SetFlagTC(const char tc_)
void SetNumberQuestion(const short number_question_)
void SetNumberAuthority(const short number_authority_)
void SetClassCode(const unsigned short class_code_)
void SetNameLabels(const std::vector< std::string > &name_labels_)
void SetTypeCode(const unsigned short type_code_)
const unsigned short GetPort() const
const std::vector< std::string > & GetNameLabels() const
void UnregisterThread(const std::thread::id id)
Remove a thread from the map.
void RegisterThread(const std::string &name)
Register the current thread in the map.
static Logger & GetInstance()
void do_write(const std::vector< unsigned char > &bytes)
void SendPacket(const std::vector< unsigned char > &bytes)
asio::ip::tcp::socket socket
std::function< void(const std::vector< unsigned char > &)> NewPacketCallback
std::shared_ptr< AESEncrypter > encrypter
std::vector< unsigned char > input_packet
TCP_Com(const std::string &address, std::function< void(const std::vector< unsigned char > &)> callback)
void SetEncrypter(const std::shared_ptr< AESEncrypter > encrypter_)
void handle_write(const asio::error_code &error)
void SetIPAndPortFromAddress(const std::string &address)
asio::io_context io_context
void handle_connect(const asio::error_code &error)
void handle_read(const asio::error_code &error, std::size_t bytes_transferred)
bool IsInitialized() const
const std::string & GetIp() const
std::atomic< bool > initialized
const unsigned short GetPort() const
std::deque< std::vector< unsigned char > > output_packet
std::array< unsigned char, 512 > read_packet
virtual void Write(WriteContainer &container) const
virtual void Read(ReadIterator &iter, size_t &length)
std::vector< std::string > SplitString(const std::string &s, const char delimiter)
std::vector< unsigned char >::const_iterator ReadIterator