diff --git a/src/network/Buffer.cpp b/src/network/Buffer.cpp deleted file mode 100644 index d7521ad..0000000 --- a/src/network/Buffer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "Buffer.h" - -#include - -using byte = uint8_t; - -namespace Feather::Network -{ - - int Buffer::WriteVarInt(int value) - { - int size = 0; - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - WriteByte(temp); - size++; - } while (value != 0); - - return size; - } - - void Buffer::WriteString(const char* str) - { - WriteString(str, strlen(str)); - } - - void Buffer::WriteString(const char *str, size_t length) - { - WriteVarInt(length); - for (int i = 0; i < length; i++) - WriteByte(str[i]); - } -} \ No newline at end of file diff --git a/src/network/Buffer.h b/src/network/Buffer.h deleted file mode 100644 index 0652ca3..0000000 --- a/src/network/Buffer.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - -using std::vector; - -namespace Feather::Network -{ - class Buffer - { - public: - inline void WriteByte(uint8_t byte) { m_data.push_back(byte); } - - // Returns the number of bytes written. - int WriteVarInt(int i); - - // Write a null terminated string to the buffer. - void WriteString(const char *str); - - // Write a string with known size to the buffer - void WriteString(const char *str, size_t length); - - inline vector GetData() { return m_data; } - inline size_t Size() { return m_data.size(); } - - private: - vector m_data; - }; -} \ No newline at end of file diff --git a/src/network/NetworkMessage.h b/src/network/NetworkMessage.h new file mode 100644 index 0000000..42a924b --- /dev/null +++ b/src/network/NetworkMessage.h @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include + +namespace Feather::Network +{ + class NetworkMessageCounter + { + public: + + inline void WriteVarInt(int32_t value) + { + do { + uint8_t temp = uint8_t(value & 0b01111111); + value >>= 7; + if (value != 0) + temp |= 0b10000000; + + m_size++; + } while (value != 0); + } + + inline void WriteString(const char* string, int32_t length) + { + int32_t stringSize = length + 1; + WriteVarInt(stringSize); + + m_size += stringSize; + } + + inline int32_t GetSize() const { return m_size; } + + private: + int32_t m_size = 0; + }; + + class NetworkMessage + { + public: + + NetworkMessage(int32_t size) + { + NetworkMessageCounter packetSizeCounter; + packetSizeCounter.WriteVarInt(size); + + m_data.reserve(size_t(size) + size_t(packetSizeCounter.GetSize())); + WriteVarInt(size); + } + + inline void WriteVarInt(int32_t value) + { + do { + uint8_t temp = uint8_t(value & 0b01111111); + value >>= 7; + if (value != 0) + temp |= 0b10000000; + + m_data.push_back(temp); + } while (value != 0); + } + + inline void WriteString(const char* string, int32_t length) + { + int32_t stringSize = length + 1; + WriteVarInt(stringSize); + + size_t oldSize = m_data.size(); + size_t newSize = oldSize + size_t(stringSize); + m_data.resize(newSize); + std::memcpy(&m_data[oldSize], string, size_t(stringSize)); + } + + const uint8_t* GetData() const { return m_data.data(); } + size_t GetDataSize() const { return m_data.size(); } + + private: + std::vector m_data; + }; + + #define DEFINE_MESSAGE_WRAPPER(x) \ + template \ + NetworkMessage x(Args... args) \ + { \ + NetworkMessageCounter counter; \ + x(counter, args...); \ + NetworkMessage message(counter.GetSize()); \ + x(message, args...); \ + return message; \ + } +} \ No newline at end of file diff --git a/src/network/TCPListener.cpp b/src/network/TCPListener.cpp index 5d1007a..74fece3 100644 --- a/src/network/TCPListener.cpp +++ b/src/network/TCPListener.cpp @@ -1,5 +1,6 @@ #include "TCPListener.h" #include "NetworkManager.h" +#include "NetworkMessage.h" #include #include @@ -135,54 +136,20 @@ namespace Feather::Network } } - void writeVarInt(int value, std::vector& msg) { - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - msg.push_back(temp); - } while (value != 0); - } - - int fuckvarintsize(int value) + template + void WritePingMessage(T& message, std::string json) { - int i = 0; - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>= 7; - if (value != 0) { - temp |= 0b10000000; - } - i++; - } while (value != 0); - - return i; - } - - std::vector EncodeMessageTest(int packetid, const unsigned char* data, size_t size) - { - Buffer msg; - - // TODO: message size prepender. could potentially be done without copying - int msg_size = fuckvarintsize(packetid) + fuckvarintsize(int(size)) + int(size); - msg.WriteVarInt(msg_size); - - msg.WriteVarInt(packetid); - msg.WriteVarInt(size); - for (size_t i = 0; i < size; i++) - msg.WriteByte(data[i]); - - return msg.GetData(); + // Packet ID + message.WriteVarInt(0); + // JSON Contents + message.WriteString(json.c_str(), static_cast(json.length())); } + DEFINE_MESSAGE_WRAPPER(WritePingMessage); bool SendShitTest() { auto lock = std::unique_lock(m_mutex); - const char json_template[] = + const std::string json_template = R"({ "version": { "name": "1.16.1", @@ -203,9 +170,9 @@ R"({ } })"; - auto message = EncodeMessageTest(0, (const unsigned char*)json_template, sizeof(json_template)); + auto message = WritePingMessage(json_template); - bufferevent_write(m_bufferEvent, message.data(), message.size()); + bufferevent_write(m_bufferEvent, message.GetData(), message.GetDataSize()); return true; }