parent
0a5017d023
commit
f298df5aef
|
@ -1,8 +1,12 @@
|
||||||
#include "TCPListener.h"
|
#include "TCPListener.h"
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
|
|
||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
#include <event2/listener.h>
|
#include <event2/listener.h>
|
||||||
|
#include <event2/buffer.h>
|
||||||
|
#include <event2/bufferevent.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace Feather::Network
|
namespace Feather::Network
|
||||||
{
|
{
|
||||||
|
@ -94,15 +98,130 @@ namespace Feather::Network
|
||||||
bool m_ipv6;
|
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<TCPListener*>(self);
|
bufferevent_setcb(m_bufferEvent,
|
||||||
|
[](bufferevent* be, void* self) { static_cast<TCPListenerClient*>(self)->ReadCallback(); },
|
||||||
listener->Accept();
|
[](bufferevent* be, void* self) { static_cast<TCPListenerClient*>(self)->WriteCallback(); },
|
||||||
|
[](bufferevent* be, short event, void* self) { static_cast<TCPListenerClient*>(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<unsigned char>& 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<unsigned char> EncodeMessageTest(int packetid, const unsigned char* data, size_t size)
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> 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<char> m_incomingData;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
TCPListener::TCPListener(uint16_t port)
|
TCPListener::TCPListener(uint16_t port)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +243,13 @@ namespace Feather::Network
|
||||||
if (!socket->MarkNonBlocking())
|
if (!socket->MarkNonBlocking())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!socket->Listen(TCPListenerCallback, this))
|
auto ListenerCallback = [](evconnlistener* evListener, evutil_socket_t socket, sockaddr* addr, int len, void* self)
|
||||||
|
{
|
||||||
|
TCPListener* listener = static_cast<TCPListener*>(self);
|
||||||
|
listener->m_clients.emplace_back(std::make_unique<TCPListenerClient>(listener, socket));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!socket->Listen(ListenerCallback, this))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_socket = std::move(socket);
|
m_socket = std::move(socket);
|
||||||
|
@ -134,9 +259,4 @@ namespace Feather::Network
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPListener::Accept()
|
|
||||||
{
|
|
||||||
printf("Frog");
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
namespace Feather::Network
|
namespace Feather::Network
|
||||||
{
|
{
|
||||||
class TCPSocket;
|
class TCPSocket;
|
||||||
|
class TCPListenerClient;
|
||||||
|
|
||||||
class TCPListener
|
class TCPListener
|
||||||
{
|
{
|
||||||
|
@ -14,10 +15,10 @@ namespace Feather::Network
|
||||||
TCPListener(uint16_t port);
|
TCPListener(uint16_t port);
|
||||||
~TCPListener();
|
~TCPListener();
|
||||||
|
|
||||||
void Accept();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<TCPSocket> m_socket;
|
std::unique_ptr<TCPSocket> m_socket;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<TCPListenerClient>> m_clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue