diff --git a/src/network/TCPListener.cpp b/src/network/TCPListener.cpp index 1540aee..6ceff1a 100644 --- a/src/network/TCPListener.cpp +++ b/src/network/TCPListener.cpp @@ -1,8 +1,12 @@ -#include "TCPListener.h" +#include "TCPListener.h" #include "NetworkManager.h" #include #include +#include +#include + +#include namespace Feather::Network { @@ -94,15 +98,130 @@ namespace Feather::Network bool m_ipv6; }; - namespace + class TCPListenerClient { - void TCPListenerCallback(evconnlistener* evListener, evutil_socket_t socket, sockaddr* addr, int len, void* self) + public: + TCPListenerClient(TCPListener* parent, evutil_socket_t socket) + : m_parent(parent) + , m_bufferEvent(bufferevent_socket_new(NetworkManager::Instance().GetEventBase(), socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)) { - TCPListener* listener = static_cast(self); - - listener->Accept(); + bufferevent_setcb(m_bufferEvent, + [](bufferevent* be, void* self) { static_cast(self)->ReadCallback(); }, + [](bufferevent* be, void* self) { static_cast(self)->WriteCallback(); }, + [](bufferevent* be, short event, void* self) { static_cast(self)->EventCallback(event); }, + this); + bufferevent_enable(m_bufferEvent, EV_READ | EV_WRITE); } + + ~TCPListenerClient() + { + bufferevent_free(m_bufferEvent); + } + + void ReadCallback() + { + auto lock = std::unique_lock(m_mutex); + + char data[1024]; + size_t length; + while ((length = bufferevent_read(m_bufferEvent, data, sizeof(data))) > 0) + { + size_t oldSize = m_incomingData.size(); + m_incomingData.resize(oldSize + length); + std::memcpy(&m_incomingData[oldSize], data, length); + } + } + + 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) + { + 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) + { + std::vector message; + int msg_size = fuckvarintsize(packetid) + fuckvarintsize(int(size)) + int(size); + // fuck fuck fuck this is terrible + // TODO proper clas for this varint bullshit + writeVarInt(msg_size, message); + writeVarInt(packetid, message); + writeVarInt(size, message); + for (size_t i = 0; i < size; i++) + message.push_back(data[i]); + + return message; + } + + bool SendShitTest() + { + auto lock = std::unique_lock(m_mutex); + const char json_template[] = +R"({ + "version": { + "name": "1.16.1", + "protocol": 736 + }, + "players": { + "max": 10, + "online": 10, + "sample": [ + { + "name": "thinkofdeath", + "id": "4566e69f-c907-48ee-8d71-d7ba5aa00d20" + } + ] + }, + "description": { + "text": "Hello Nukem!" } +})"; + + auto message = EncodeMessageTest(0, (const unsigned char*)json_template, sizeof(json_template)); + + bufferevent_write(m_bufferEvent, message.data(), message.size()); + return true; + } + + void WriteCallback() + { + printf("Write callback!\n"); + SendShitTest(); + } + + void EventCallback(short event) + { + printf("Event!\n"); + } + private: + TCPListener* m_parent; + bufferevent* m_bufferEvent; + + std::vector m_incomingData; + std::mutex m_mutex; + }; TCPListener::TCPListener(uint16_t port) { @@ -124,7 +243,13 @@ namespace Feather::Network if (!socket->MarkNonBlocking()) return; - if (!socket->Listen(TCPListenerCallback, this)) + auto ListenerCallback = [](evconnlistener* evListener, evutil_socket_t socket, sockaddr* addr, int len, void* self) + { + TCPListener* listener = static_cast(self); + listener->m_clients.emplace_back(std::make_unique(listener, socket)); + }; + + if (!socket->Listen(ListenerCallback, this)) return; m_socket = std::move(socket); @@ -134,9 +259,4 @@ namespace Feather::Network { } - - void TCPListener::Accept() - { - printf("Frog"); - } } \ No newline at end of file diff --git a/src/network/TCPListener.h b/src/network/TCPListener.h index 2461266..66b7bd1 100644 --- a/src/network/TCPListener.h +++ b/src/network/TCPListener.h @@ -7,6 +7,7 @@ namespace Feather::Network { class TCPSocket; + class TCPListenerClient; class TCPListener { @@ -14,10 +15,10 @@ namespace Feather::Network TCPListener(uint16_t port); ~TCPListener(); - void Accept(); - private: std::unique_ptr m_socket; + + std::vector> m_clients; };