diff --git a/libs/gateway/Websocket.hpp b/libs/gateway/Websocket.hpp index 8f5c845..678c511 100644 --- a/libs/gateway/Websocket.hpp +++ b/libs/gateway/Websocket.hpp @@ -1,26 +1,52 @@ #ifndef GATEWAY_WEBSOCKET_HPP_ #define GATEWAY_WEBSOCKET_HPP_ #include -#include #include #include -class WebSocket { +class EventEmitter { +private: + using eventHandlers = std::function; + std::unordered_map> handlers; +public: + void on(const std::string& event, eventHandlers handler) { + handlers[event].emplace_back(handler); + } + void once(const std::string& event, eventHandlers handler) { + auto wrappedHandler = [this, event, handler](const nlohmann::json& data) { + handler(data); + off(event, handler); + }; + handlers[event].emplace_back(wrappedHandler); + } + void emit(const std::string& event, const nlohmann::json& data) { + if (handlers.find(event) != handlers.end()) { + for (const auto& handler : handlers[event]) { + handler(data); + } + } + } + void off(const std::string& event, eventHandlers handler) { + if (handlers.find(event) != handlers.end()) { + auto& vec = handlers[event]; + vec.erase(std::remove_if(vec.begin(), vec.end(), [&handler](const eventHandlers& h) { + return h.target() == handler.target(); + }), vec.end()); + } + } +}; +class WebSocket : public EventEmitter { private: - bool isBot; - int intents; std::string token; + int intents; + bool isBot; ix::WebSocket webSocket; - nlohmann::json payload = { {"op", 1},{"d", nullptr} }, id; - std::unordered_map> eventHandlers; + const nlohmann::json payload = { {"op", 1}, {"d", nullptr} }; WebSocket& operator=(const WebSocket&) = delete; WebSocket& operator=(WebSocket&&) = delete; WebSocket(WebSocket&&) = delete; WebSocket(const WebSocket&) = delete; - explicit WebSocket(const std::string& token, const int& intents, const bool& isBot) { - WebSocket::token = token; - WebSocket::intents = intents; - WebSocket::isBot = isBot; - id = { + WebSocket(const std::string& token = "", const int& intents = 0, const bool& isBot = true) : token(token), intents(intents), isBot(isBot) { + nlohmann::json id = { {"op", 2}, {"d", { {"token", token}, @@ -30,12 +56,12 @@ private: {"browser", "firefox"}, {"device", "firefox"} }}, - //{"compress", 1}, + {"compress", 1}, {"presence", { {"activities", nlohmann::json::array({ { - //{"name", "asdsadsadsadsa"}, - //{"type", 2} + {"name", "asdsadsadsadsa"}, + {"type", 2} } })}, {"status", "idle"}, @@ -48,7 +74,7 @@ private: webSocket.setUrl("wss://gateway.discord.gg/?v=10&encoding=json"); webSocket.disableAutomaticReconnection(); Log::create(INFO, WEBSOCKET, "ixwebsocket init"); - webSocket.setOnMessageCallback([this, res = nlohmann::json(), heartbeat_interval = 1000, connected = false](const ix::WebSocketMessagePtr& msg) mutable { + webSocket.setOnMessageCallback([this, res = nlohmann::json(), heartbeat_interval = 0, connected = false, id](const ix::WebSocketMessagePtr& msg) mutable { if (msg->type == ix::WebSocketMessageType::Message) { res = nlohmann::json::parse(msg->str); Log::create(INFO, WEBSOCKET, res["op"].dump() + " " + res["t"].dump()); @@ -64,11 +90,7 @@ private: } }).detach(); break; - case 0: - if (eventHandlers.find(res["t"].get()) != eventHandlers.end()) { - eventHandlers[res["t"].get()](res); - } - break; + case 0: emit(res["t"].get(), res); break; } } else if (msg->type == ix::WebSocketMessageType::Error) { std::cout << msg->errorInfo.reason << std::endl; @@ -92,7 +114,7 @@ public: webSocket.send(prsUpdate.dump()); } */ - static WebSocket& getInstance(const std::string& token = "", const int intents = 0, bool bot = true) { + static WebSocket& getInstance(const std::string& token = "", const int& intents = 0, const bool& bot = true) { Log::create(INFO, WEBSOCKET, "Instance event"); static WebSocket instance(token, intents, bot); return instance; @@ -107,18 +129,8 @@ public: int getIntents() const { return WebSocket::intents; } - void on(const std::string& event, std::function handler) { - eventHandlers[event] = [handler](const nlohmann::json& message) { - handler(message.get()); - }; - } - void once(const std::string& event, std::function handler) { - eventHandlers[event] = [event, handler, isCalled = false](const nlohmann::json& message) mutable { - isCalled ? handler(message.get()), true : isCalled = true; - }; - } void start() { - while (1) std::this_thread::sleep_for(std::chrono::milliseconds(100)); + while (1) std::this_thread::sleep_for(std::chrono::milliseconds(1)); } }; #endif \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index e31a3ea..cc39ae9 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -3,7 +3,6 @@ #include int main(int argc, char* argv[]) { cxxopts::Options options("sparkle", "WIP discord bot library in C++"); - options.add_options() ("h,help", "Print help") ("V,version", "Show version information") @@ -12,10 +11,11 @@ int main(int argc, char* argv[]) { auto result = options.parse(argc, argv); if (result.count("version")) { - std::cout << "sparkle version 0.1" << std::endl; + std::cout << "sparkle version 0.3" << std::endl; return 0; } - if (result.count("help")){ + + if (result.count("help")) { std::cout << options.help() << std::endl; return 0; } @@ -36,10 +36,13 @@ int main(int argc, char* argv[]) { bot->on(GatewayEvents::MESSAGE_CREATE, [](const Discord& msg) { const auto& [message, user, author] = msg.ctx(); if (!author->isBot) { - message->send("939957962972229634", message->pack("content", author->avatar)); + message->send("939957962972229634", message->pack("content", author->channel_id)); } }); - + bot->on(GatewayEvents::MESSAGE_REACTION_ADD, [](const Discord& msg) { + const auto& [message] = msg.ctx(); + message->send("939957962972229634", message->pack("content", "test")); + }); bot->start(); return 0; } \ No newline at end of file