From d8cf6e742f584a6b47806124259097f84b782671 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Sun, 19 Jan 2025 04:43:55 +0500 Subject: [PATCH 01/13] test --- sources/main.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/sources/main.cpp b/sources/main.cpp index 5ef0e39..7f465a3 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -3,40 +3,45 @@ int main(int argc, char* argv[]) { if (argc != 3) return -1; WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents, false); - bot->on(GatewayEvents::READY, [](const Bot& msg) { - std::string lastID = "1292591828888977589"; + bot->on(GatewayEvents::READY, [](const Discord& msg) { + std::string lastID = "1221155685518278708"; while (true) { std::vector ids; std::cout << "Last ID: " << lastID << std::endl; json js = json::parse(g(0, msg.net)->getMessages("956854968260890654", "100", lastID)); if (js.is_array() && !js.empty()) { + int counter = 0; for (const auto& message : js) { if (message["author"]["id"] == "956790566463614986") { - std::cout << "My message ID: " << message["id"].get() << std::endl; - ids.push_back(message["id"].get()); + printf("\rMessage ID: %s %d", message["id"].get().c_str(), ++counter); + ids.emplace_back(message["id"].get()); + } + else { + lastID = message["id"].get(); } - lastID = message["id"].get(); } + cout << endl; if (ids.size() > 1) { - for (size_t x = 0; x < ids.size(); x++) { + for (unsigned long x = 0; x < ids.size(); x++) { try { json jss = json::parse(g(0, msg.net)->deleteMessage("956854968260890654", ids[x])); if (jss["code"].get() == "20028") { - std::this_thread::sleep_for(10s); + std::this_thread::sleep_for(15s); } std::cout << "Delete response: " << jss["message"] << ":" << jss["code"] << std::endl; } catch (...) { - std::cout << "DELETED" << std::endl; + std::cout << "\rDeleted ID: " << ids[x] << " " << x + 1; + std::cout.flush(); } - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::this_thread::sleep_for(200ms); } + cout << endl; } } else { std::cout << "No messages found or error in response." << std::endl; } - //std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); bot->start(); From 8ae437bc77a6b17879f1aa3d0b30467414aa33e2 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 00:03:53 +0500 Subject: [PATCH 02/13] default code --- sources/main.cpp | 44 +++++++------------------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/sources/main.cpp b/sources/main.cpp index 5ef0e39..08def8d 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -2,43 +2,13 @@ #include int main(int argc, char* argv[]) { if (argc != 3) return -1; - WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents, false); - bot->on(GatewayEvents::READY, [](const Bot& msg) { - std::string lastID = "1292591828888977589"; - while (true) { - std::vector ids; - std::cout << "Last ID: " << lastID << std::endl; - json js = json::parse(g(0, msg.net)->getMessages("956854968260890654", "100", lastID)); - if (js.is_array() && !js.empty()) { - for (const auto& message : js) { - if (message["author"]["id"] == "956790566463614986") { - std::cout << "My message ID: " << message["id"].get() << std::endl; - ids.push_back(message["id"].get()); - } - lastID = message["id"].get(); - } - if (ids.size() > 1) { - for (size_t x = 0; x < ids.size(); x++) { - try { - json jss = json::parse(g(0, msg.net)->deleteMessage("956854968260890654", ids[x])); - if (jss["code"].get() == "20028") { - std::this_thread::sleep_for(10s); - } - std::cout << "Delete response: " << jss["message"] << ":" << jss["code"] << std::endl; - } - catch (...) { - std::cout << "DELETED" << std::endl; - } - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - } - } - else { - std::cout << "No messages found or error in response." << std::endl; - } - //std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } + WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents); + bot->on(GatewayEvents::READY, [](const Discorda) { + cout << DiscordEndpoints::details::latest << endl; + }); + bot->on(GatewayEvents::MESSAGE_CREATE, [](const Discord msg) { + g(0, msg.net)->send("939957962972229634", j("content", g(2, msg.net)->content())); }); bot->start(); return 0; -} +} \ No newline at end of file From be0be09a24aa20ffd520cd0a37f8f474f9c2399e Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 03:09:27 +0500 Subject: [PATCH 03/13] code cleanup --- libs/api/Author.hpp | 2 +- libs/api/Bot.hpp | 7 +++++-- libs/api/Message.hpp | 3 +++ libs/tls/Network.hpp | 2 +- libs/utils/enums.hpp | 28 ++++++++++++++-------------- libs/utils/log.hpp | 20 +++++--------------- libs/utils/types.hpp | 3 +-- sources/main.cpp | 6 +++--- 8 files changed, 33 insertions(+), 38 deletions(-) diff --git a/libs/api/Author.hpp b/libs/api/Author.hpp index 074e40e..fd6bb70 100644 --- a/libs/api/Author.hpp +++ b/libs/api/Author.hpp @@ -9,7 +9,7 @@ private: WebSocket& web; NetworkManager& req; public: - Author(const json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {} + Author(const json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; string content() { try { return data["d"]["content"]; diff --git a/libs/api/Bot.hpp b/libs/api/Bot.hpp index b79a2d6..c0948fa 100644 --- a/libs/api/Bot.hpp +++ b/libs/api/Bot.hpp @@ -8,8 +8,7 @@ private: void initializeNets(const json& data) { initializeNetsImpl(data, std::index_sequence_for{}); } - template - void initializeNetsImpl(const json& data, std::index_sequence) { + templatevoid initializeNetsImpl(const json& data, std::index_sequence) { net = std::make_tuple(std::make_unique(data)...); } json data; @@ -18,6 +17,10 @@ public: Discord(const json& data) : data(data) { initializeNets(data); } + template + auto& get() const { + return *std::get(net); + } }; class Bot { private: diff --git a/libs/api/Message.hpp b/libs/api/Message.hpp index 98a1ed9..bf9c6f5 100644 --- a/libs/api/Message.hpp +++ b/libs/api/Message.hpp @@ -25,5 +25,8 @@ public: string deleteMessage(const string& channel_id, const string& message_id) { return req.request(HttpMethods::DELETE, DiscordEndpoints::details::latest + "/channels/" + channel_id + "/messages/" + message_id); } + json pack(const json& pack) const { + return { pack }; + } }; #endif \ No newline at end of file diff --git a/libs/tls/Network.hpp b/libs/tls/Network.hpp index f278ce3..71443e6 100644 --- a/libs/tls/Network.hpp +++ b/libs/tls/Network.hpp @@ -16,7 +16,7 @@ private: curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (!curl) { - Log::create(ERROR, NETWORK, "Failed to initialize CURL"); + Log::create(CRITICAL, NETWORK, "Failed to initialize CURL"); abort(); } } diff --git a/libs/utils/enums.hpp b/libs/utils/enums.hpp index 13ecf92..95e95d4 100644 --- a/libs/utils/enums.hpp +++ b/libs/utils/enums.hpp @@ -84,23 +84,23 @@ struct HttpMethods { static constexpr const char* OPTIONS = "OPTIONS"; }; struct ApiVersion { - static inline std::string api = "/api/"; - static inline std::string v10 = "v10"; - static inline std::string v9 = "v9"; - static inline std::string v8 = "v8"; - static inline std::string v7 = "v7"; - static inline std::string v6 = "v6"; - static inline std::string current = api + v6; - static inline std::string latest = api + v10; + static const inline std::string api = "/api/"; + static const inline std::string v10 = "v10"; + static const inline std::string v9 = "v9"; + static const inline std::string v8 = "v8"; + static const inline std::string v7 = "v7"; + static const inline std::string v6 = "v6"; + static const inline std::string current = api + v6; + static const inline std::string latest = api + v10; }; struct DiscordEndpoints { - static inline std::string main_scheme = "https://"; - static inline std::string discord = main_scheme + "discord.com"; - static inline std::string images = main_scheme + "cdn.discord.com"; - static inline std::string media = main_scheme + "media.discord.com"; + static const inline std::string main_scheme = "https://"; + static const inline std::string discord = main_scheme + "discord.com"; + static const inline std::string images = main_scheme + "cdn.discord.com"; + static const inline std::string media = main_scheme + "media.discord.com"; struct details { - static inline std::string current = DiscordEndpoints::discord + ApiVersion::current; - static inline std::string latest = DiscordEndpoints::discord + ApiVersion::latest; + static const inline std::string current = DiscordEndpoints::discord + ApiVersion::current; + static const inline std::string latest = DiscordEndpoints::discord + ApiVersion::latest; }; }; enum GatewayIntents { diff --git a/libs/utils/log.hpp b/libs/utils/log.hpp index 5d7fb5b..b99799d 100644 --- a/libs/utils/log.hpp +++ b/libs/utils/log.hpp @@ -14,21 +14,11 @@ public: #ifdef DEBUG std::string color; switch (lvl) { - case INFO: - color = "\033[34;1m"; - break; - case WARNING: - color = "\033[33;1m"; - break; - case ERROR: - color = "\033[31;1m"; - break; - case CRITICAL: - color = "\033[31;1;2m"; - break; - default: - color = "\033[0m"; - break; + case INFO: color = "\033[34;1m"; break; + case WARNING: color = "\033[33;1m"; break; + case ERROR: color = "\033[31;1m"; break; + case CRITICAL: color = "\033[31;1;2m"; break; + default: color = "\033[0m"; break; } std::cout << color << "[" << getCurrentTime() << "][" << str(t) << "][" << str(lvl) << "] \033[0m" << message << "\033[0m" << std::endl; #endif diff --git a/libs/utils/types.hpp b/libs/utils/types.hpp index b285e18..5e84e84 100644 --- a/libs/utils/types.hpp +++ b/libs/utils/types.hpp @@ -3,6 +3,5 @@ #define j(...) {{__VA_ARGS__}} #define je(...) {__VA_ARGS__} #define g(x, y) (std::get(y)) -#define ALL_INTENTS 131071 -#define DEBUG +#define RELEASE #endif \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index 08def8d..60a025d 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -3,11 +3,11 @@ int main(int argc, char* argv[]) { if (argc != 3) return -1; WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents); - bot->on(GatewayEvents::READY, [](const Discorda) { + bot->on(GatewayEvents::READY, [](const Discord&a) { cout << DiscordEndpoints::details::latest << endl; }); - bot->on(GatewayEvents::MESSAGE_CREATE, [](const Discord msg) { - g(0, msg.net)->send("939957962972229634", j("content", g(2, msg.net)->content())); + bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord& msg) { + msg.get<0>().send("939957962972229634", msg.get<0>().pack({ "content", msg.get<2>().content() })); }); bot->start(); return 0; From 1cbfe59bf65b81d456e5176a161cd8ca81f4ac39 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 04:03:27 +0500 Subject: [PATCH 04/13] fixes --- include/includes.h | 1 + libs/api/Author.hpp | 26 +++++++++++++------------- libs/api/Bot.hpp | 8 ++++---- libs/api/Guild.hpp | 2 +- libs/api/User.hpp | 2 +- libs/utils/functions.hpp | 13 +++++++++++++ libs/utils/types.hpp | 3 --- sources/main.cpp | 2 +- 8 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 libs/utils/functions.hpp diff --git a/include/includes.h b/include/includes.h index 2823bd0..35a0ef4 100644 --- a/include/includes.h +++ b/include/includes.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #endif \ No newline at end of file diff --git a/libs/api/Author.hpp b/libs/api/Author.hpp index fd6bb70..a7f22d8 100644 --- a/libs/api/Author.hpp +++ b/libs/api/Author.hpp @@ -9,8 +9,16 @@ private: WebSocket& web; NetworkManager& req; public: - Author(const json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; - string content() { + Author(const json& data) : + data(data), + web(WebSocket::getInstance()), + req(NetworkManager::getInstance()), + channel_id(functions::isNull(data["d"]["channel_id"])), + global_name(functions::isNull(data["d"]["author"]["global_name"])), + id(data["d"]["author"]["id"]) + { + }; + string content() const { try { return data["d"]["content"]; } @@ -18,19 +26,11 @@ public: return ""; } } - string channel_id() { - return data["d"]["channel_id"]; - } - string id() { - return data["d"]["author"]["id"]; - } - string global_name() { - return data["d"]["author"]["global_name"].dump(); - } - string discriminator() { + const string channel_id, global_name, id; + string discriminator() const { return data["d"]["author"]["discriminator"]; } - bool isBot() { + bool isBot() const { try { return data["d"]["author"]["bot"]; } diff --git a/libs/api/Bot.hpp b/libs/api/Bot.hpp index c0948fa..bc31ed0 100644 --- a/libs/api/Bot.hpp +++ b/libs/api/Bot.hpp @@ -5,15 +5,15 @@ using std::string, std::cout, std::endl, nlohmann::json; template class Discord { private: + std::tuple...> net; + json data; void initializeNets(const json& data) { initializeNetsImpl(data, std::index_sequence_for{}); } templatevoid initializeNetsImpl(const json& data, std::index_sequence) { net = std::make_tuple(std::make_unique(data)...); } - json data; public: - std::tuple...> net; Discord(const json& data) : data(data) { initializeNets(data); } @@ -27,10 +27,10 @@ private: json data; public: Bot(const json& data) : data(data) {}; - string id() { + string id() const { return data["d"]["id"]; } - bool isBot() { + bool isBot() const { try { return data["d"]["bot"]; } diff --git a/libs/api/Guild.hpp b/libs/api/Guild.hpp index 510cd7f..d88eaae 100644 --- a/libs/api/Guild.hpp +++ b/libs/api/Guild.hpp @@ -8,7 +8,7 @@ private: json data; public: Guild(const json& data) : data(data) {} - string id() { + string id() const { return data["d"]["user"]["id"]; } }; diff --git a/libs/api/User.hpp b/libs/api/User.hpp index 02bfe38..f065679 100644 --- a/libs/api/User.hpp +++ b/libs/api/User.hpp @@ -28,7 +28,7 @@ public: virtual string me() { return req.request(HttpMethods::GET, DiscordEndpoints::details::latest + "/users/@me"); } - bool isBot() { + bool isBot() const { try { return data["d"]["author"]["bot"]; } diff --git a/libs/utils/functions.hpp b/libs/utils/functions.hpp new file mode 100644 index 0000000..ad19ed9 --- /dev/null +++ b/libs/utils/functions.hpp @@ -0,0 +1,13 @@ +#ifndef UTILS_FUNCTIONS_HPP_ +#define UTILS_FUNCTIONS_HPP_ +struct functions { + static inline std::string isNull(const nlohmann::json& str) { + try { + return str.is_null() ? str.dump() : str.get(); + } + catch (...) { + return "null"; + } + } +}; +#endif \ No newline at end of file diff --git a/libs/utils/types.hpp b/libs/utils/types.hpp index 5e84e84..13526ef 100644 --- a/libs/utils/types.hpp +++ b/libs/utils/types.hpp @@ -1,7 +1,4 @@ #ifndef UTILS_TYPES_HPP_ #define UTILS_TYPES_HPP_ -#define j(...) {{__VA_ARGS__}} -#define je(...) {__VA_ARGS__} -#define g(x, y) (std::get(y)) #define RELEASE #endif \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index 60a025d..25f547e 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -7,7 +7,7 @@ int main(int argc, char* argv[]) { cout << DiscordEndpoints::details::latest << endl; }); bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord& msg) { - msg.get<0>().send("939957962972229634", msg.get<0>().pack({ "content", msg.get<2>().content() })); + msg.get<0>().send("939957962972229634", msg.get<0>().pack({ "content", msg.get<2>().id })); }); bot->start(); return 0; From b85478d64b2f9db63e8c9af94ad9b9ee0e40f3f7 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 15:12:57 +0500 Subject: [PATCH 05/13] compiler --- CMakeLists.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e774c1..1c554fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,27 @@ set(SOURCE sources/main.cpp) set(LIBS ${CMAKE_SOURCE_DIR}/libs/) set(INCLUDE ${CMAKE_SOURCE_DIR}/include/) set(TESTS ${CMAKE_SOURCE_DIR}/tests) +set(CMAKE_C_COMPILER "clang") +set(CMAKE_CXX_COMPILER "clang++") +find_program(CMAKE_C_COMPILER clang) +find_program(CLANG_CXX_COMPILER clang++) find_package(CURL REQUIRED) find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket) find_library(IXWEBSOCKET_LIBRARIES ixwebsocket) +if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) + message(STATUS "clang not found") + set(CMAKE_C_COMPILER "gcc") + set(CMAKE_CXX_COMPILER "g++") + find_program(CMAKE_C_COMPILER clang) + find_program(CLANG_CXX_COMPILER clang++) + if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) + message(FATAL_ERROR "gcc not found") + endif() +endif() +message(STATUS "current compiler: ${CMAKE_C_COMPILER}") + if(NOT IXWEBSOCKET_INCLUDE_DIR OR NOT IXWEBSOCKET_LIBRARIES) message(FATAL_ERROR "ixwebsocket not found") endif() @@ -60,5 +76,4 @@ target_link_libraries(${PROJECT_NAME} PRIVATE set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED True) -set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe") -#set(CMAKE_CXX_FLAGS "-O0 -pipe") \ No newline at end of file +set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe") \ No newline at end of file From 7079675d94e799b7009ed1ebe488d3b4d853d452 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 15:14:27 +0500 Subject: [PATCH 06/13] deleted try catch --- libs/utils/functions.hpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libs/utils/functions.hpp b/libs/utils/functions.hpp index ad19ed9..9f0bf2c 100644 --- a/libs/utils/functions.hpp +++ b/libs/utils/functions.hpp @@ -2,12 +2,7 @@ #define UTILS_FUNCTIONS_HPP_ struct functions { static inline std::string isNull(const nlohmann::json& str) { - try { - return str.is_null() ? str.dump() : str.get(); - } - catch (...) { - return "null"; - } + return str.is_null() ? str.dump() : str.get(); } }; #endif \ No newline at end of file From fd16e499b3be500f180c8c29bd60ea498cc71f1c Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 16:07:42 +0500 Subject: [PATCH 07/13] fixes --- libs/api/Author.hpp | 46 ++++++++++++++------------------------ libs/api/Bot.hpp | 16 ++++++------- libs/api/Channel.hpp | 9 ++++---- libs/api/Embed.hpp | 31 +++++++++++++------------ libs/api/Guild.hpp | 9 ++++---- libs/api/Message.hpp | 16 ++++++------- libs/api/User.hpp | 15 +++++++------ libs/gateway/Websocket.hpp | 25 ++++++++++----------- libs/tls/Network.hpp | 4 +++- libs/utils/log.hpp | 6 +++-- libs/utils/types.hpp | 2 +- sources/main.cpp | 8 ++++--- 12 files changed, 89 insertions(+), 98 deletions(-) diff --git a/libs/api/Author.hpp b/libs/api/Author.hpp index a7f22d8..d48fd8f 100644 --- a/libs/api/Author.hpp +++ b/libs/api/Author.hpp @@ -2,56 +2,44 @@ #define API_AUTHOR_HPP_ #include #include -using std::string, std::cout, std::endl, nlohmann::json; class Author { private: - json data; + nlohmann::json data; + const nlohmann::json &d; WebSocket& web; NetworkManager& req; public: - Author(const json& data) : + Author(const nlohmann::json& data) : data(data), + d(data["d"]), web(WebSocket::getInstance()), req(NetworkManager::getInstance()), - channel_id(functions::isNull(data["d"]["channel_id"])), - global_name(functions::isNull(data["d"]["author"]["global_name"])), - id(data["d"]["author"]["id"]) + channel_id(functions::isNull(d["channel_id"])), + global_name(functions::isNull(d["author"]["global_name"])), + id(d["author"]["id"]), + content(d["content"]), + isBot(d["author"].contains("bot") ? d["author"]["bot"].get() : false) { }; - string content() const { - try { - return data["d"]["content"]; - } - catch (...) { - return ""; - } - } - const string channel_id, global_name, id; - string discriminator() const { + const std::string channel_id, global_name, id, content; + bool isBot; + std::string discriminator() const { return data["d"]["author"]["discriminator"]; } - bool isBot() const { - try { - return data["d"]["author"]["bot"]; - } - catch (...) { - return 0; - } - } - string guild_id() { + std::string guild_id() { return data["d"]["guild_id"]; } - string msg_id() { + std::string msg_id() { return data["d"]["id"]; } bool isPinned() { return data["d"]["pinned"]; } - string avatar() { + std::string avatar() { return data["d"]["author"]["avatar"]; } - string send(const json& msg) { - return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get() + "/messages", msg.dump()); + std::string send(const nlohmann::json& msg) { + return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get() + "/messages", msg.dump()); } }; #endif \ No newline at end of file diff --git a/libs/api/Bot.hpp b/libs/api/Bot.hpp index bc31ed0..5e7b56f 100644 --- a/libs/api/Bot.hpp +++ b/libs/api/Bot.hpp @@ -1,20 +1,20 @@ #ifndef API_BOT_HPP_ #define API_BOT_HPP_ #include -using std::string, std::cout, std::endl, nlohmann::json; template class Discord { private: std::tuple...> net; - json data; - void initializeNets(const json& data) { + nlohmann::json data; + void initializeNets(const nlohmann::json& data) { initializeNetsImpl(data, std::index_sequence_for{}); } - templatevoid initializeNetsImpl(const json& data, std::index_sequence) { + template + void initializeNetsImpl(const nlohmann::json& data, std::index_sequence) { net = std::make_tuple(std::make_unique(data)...); } public: - Discord(const json& data) : data(data) { + Discord(const nlohmann::json& data) : data(data) { initializeNets(data); } template @@ -24,10 +24,10 @@ public: }; class Bot { private: - json data; + nlohmann::json data; public: - Bot(const json& data) : data(data) {}; - string id() const { + Bot(const nlohmann::json& data) : data(data) {}; + std::string id() const { return data["d"]["id"]; } bool isBot() const { diff --git a/libs/api/Channel.hpp b/libs/api/Channel.hpp index f4f81e0..548f2b3 100644 --- a/libs/api/Channel.hpp +++ b/libs/api/Channel.hpp @@ -2,16 +2,15 @@ #define API_CHANNEL_HPP_ #include #include -using std::string, std::cout, std::endl, nlohmann::json; class Channel { private: - json data; + nlohmann::json data; WebSocket& web; NetworkManager& req; public: - Channel(const json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {} - string send(const json& msg) { - return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get() + "/messages", msg.dump()); + Channel(const nlohmann::json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {} + std::string send(const nlohmann::json& msg) { + return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get() + "/messages", msg.dump()); } }; #endif \ No newline at end of file diff --git a/libs/api/Embed.hpp b/libs/api/Embed.hpp index 9f3efd8..24a2c1f 100644 --- a/libs/api/Embed.hpp +++ b/libs/api/Embed.hpp @@ -1,58 +1,57 @@ #ifndef API_EMBED_HPP_ #define API_EMBED_HPP_ #include -using std::string, std::cout, std::endl, nlohmann::json; class EmbedBuilder { private: - json embed = { + nlohmann::json embed = { {"content", ""}, {"tts", false}, - {"embeds", json::array()} + {"embeds", nlohmann::json::array()} }, data; public: - EmbedBuilder(const json& data) : data(data) { + EmbedBuilder(const nlohmann::json& data) : data(data) { embed = { {"content", ""}, {"tts", false}, - {"embeds", json::array()} + {"embeds", nlohmann::json::array()} }; } - EmbedBuilder& addTitle(const string& title) { + EmbedBuilder& addTitle(const std::string& title) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(json::object()); + embed["embeds"].push_back(nlohmann::json::object()); } embed["embeds"].back()["title"] = title; return *this; } - EmbedBuilder& addDescription(const string& desc) { + EmbedBuilder& addDescription(const std::string& desc) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(json::object()); + embed["embeds"].push_back(nlohmann::json::object()); } embed["embeds"].back()["description"] = desc; return *this; } - EmbedBuilder& addColor(const string& color) { + EmbedBuilder& addColor(const std::string& color) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(json::object()); + embed["embeds"].push_back(nlohmann::json::object()); } embed["embeds"].back()["color"] = color; return *this; } - EmbedBuilder& addUrl(const string& url) { + EmbedBuilder& addUrl(const std::string& url) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(json::object()); + embed["embeds"].push_back(nlohmann::json::object()); } embed["embeds"].back()["url"] = url; return *this; } - EmbedBuilder& addImage(const string& imageurl) { + EmbedBuilder& addImage(const std::string& imageurl) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(json::object()); + embed["embeds"].push_back(nlohmann::json::object()); } embed["embeds"].back()["image"] = { {"url", imageurl} }; return *this; } - json getEmbed() const { + nlohmann::json getEmbed() const { return embed; } }; diff --git a/libs/api/Guild.hpp b/libs/api/Guild.hpp index d88eaae..0b684dd 100644 --- a/libs/api/Guild.hpp +++ b/libs/api/Guild.hpp @@ -1,14 +1,13 @@ #ifndef API_GUILD_HPP_ #define API_GUILD_HPP_ #include -//#include -using std::string, std::cout, std::endl, nlohmann::json; +#include class Guild { private: - json data; + nlohmann::json data; public: - Guild(const json& data) : data(data) {} - string id() const { + Guild(const nlohmann::json& data) : data(data) {} + std::string id() const { return data["d"]["user"]["id"]; } }; diff --git a/libs/api/Message.hpp b/libs/api/Message.hpp index bf9c6f5..456b566 100644 --- a/libs/api/Message.hpp +++ b/libs/api/Message.hpp @@ -2,18 +2,18 @@ #define API_MESSAGE_HPP_ #include #include -using std::string, std::cout, std::endl, nlohmann::json; class Message { private: - json data; + nlohmann::json data; WebSocket& web; NetworkManager& req; public: - Message(const json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; - string send(const string& id, const json& msg) { + Message(const nlohmann::json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; + std::string send(const std::string& id, const nlohmann::json& msg) { + std::cout << id << msg << std::endl; return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + id + "/messages", msg.dump()); } - string getMessages(const string& id, const string& count, const string& before = "") { + std::string getMessages(const std::string& id, const std::string& count, const std::string& before = "") { if (before.empty()) { return req.request(HttpMethods::GET, DiscordEndpoints::details::latest + "/channels/" + id + "/messages?limit=" + count); } @@ -22,11 +22,11 @@ public: } return ""; } - string deleteMessage(const string& channel_id, const string& message_id) { + std::string deleteMessage(const std::string& channel_id, const std::string& message_id) { return req.request(HttpMethods::DELETE, DiscordEndpoints::details::latest + "/channels/" + channel_id + "/messages/" + message_id); } - json pack(const json& pack) const { - return { pack }; + nlohmann::json pack(const nlohmann::json& key, const std::string& value) const { + return {{ key, value }}; } }; #endif \ No newline at end of file diff --git a/libs/api/User.hpp b/libs/api/User.hpp index f065679..c5feff3 100644 --- a/libs/api/User.hpp +++ b/libs/api/User.hpp @@ -3,18 +3,18 @@ #include #include #include -using std::string, std::cout, std::endl, nlohmann::json; class User { private: - json data; + nlohmann::json data; WebSocket& web; NetworkManager& req; public: - User(const json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {} - json extract(const std::vector& keys) { - std::vector d = { "d" }; + User(const nlohmann::json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {} + #ifdef DEBUG + nlohmann::json extract(const std::vector& keys) { + std::vector d = { "d" }; d.insert(d.end(), keys.begin(), keys.end()); - json current = data; + nlohmann::json current = data; for (const auto& key : d) { if (current.contains(key)) { current = current[key]; @@ -25,7 +25,8 @@ public: } return current; } - virtual string me() { + #endif + std::string me() { return req.request(HttpMethods::GET, DiscordEndpoints::details::latest + "/users/@me"); } bool isBot() const { diff --git a/libs/gateway/Websocket.hpp b/libs/gateway/Websocket.hpp index e9baa28..4f0d037 100644 --- a/libs/gateway/Websocket.hpp +++ b/libs/gateway/Websocket.hpp @@ -5,7 +5,6 @@ #include #include #include -using std::string, std::cout, std::endl, nlohmann::json; using namespace std::chrono; using namespace std::chrono_literals; class WebSocket { @@ -14,11 +13,11 @@ private: int intents; std::string token; ix::WebSocket webSocket; - json payload = { {"op", 1},{"d", nullptr} }, id; - std::unordered_map> eventHandlers; + nlohmann::json payload = { {"op", 1},{"d", nullptr} }, id; + std::unordered_map> eventHandlers; WebSocket& operator=(const WebSocket&) = delete; WebSocket(const WebSocket&) = delete; - WebSocket(const std::string& token, const int& intents, bool& isBot) { + WebSocket(const std::string& token, const int& intents, const bool& isBot) { WebSocket::token = token; WebSocket::intents = intents; WebSocket::isBot = isBot; @@ -34,7 +33,7 @@ private: }}, //{"compress", 1}, {"presence", { - {"activities", json::array({ + {"activities", nlohmann::json::array({ { //{"name", "asdsadsadsadsa"}, //{"type", 2} @@ -50,9 +49,9 @@ private: webSocket.setUrl("wss://gateway.discord.gg/?v=10&encoding=json"); webSocket.setHandshakeTimeout(5); Log::create(INFO, WEBSOCKET, "ixwebsocket init"); - webSocket.setOnMessageCallback([this, res = json(), heartbeat_interval = 0, connected = false](const ix::WebSocketMessagePtr& msg) mutable { + webSocket.setOnMessageCallback([this, res = nlohmann::json(), heartbeat_interval = 0, connected = false](const ix::WebSocketMessagePtr& msg) mutable { if (msg->type == ix::WebSocketMessageType::Message) { - res = json::parse(msg->str); + res = nlohmann::json::parse(msg->str); Log::create(INFO, WEBSOCKET, res["op"].dump() + " " + res["t"].dump()); switch (res["op"].get()) { case 10: @@ -106,14 +105,14 @@ public: int getIntents() const { return WebSocket::intents; } - void on(const string& event, std::function handler) { - eventHandlers[event] = [handler](const json& message) { - handler(message.get()); + void on(const std::string& event, std::function handler) { + eventHandlers[event] = [handler](const nlohmann::json& message) { + handler(message.get()); }; } - void once(const string& event, std::function handler) { - eventHandlers[event] = [event, handler, isCalled = false](const json& message) mutable { - isCalled == false ? isCalled = true : 0, handler(message.get()); + void once(const std::string& event, std::function handler) { + eventHandlers[event] = [event, handler, isCalled = false](const nlohmann::json& message) mutable { + isCalled == false ? isCalled = true : 0, handler(message.get()); }; } void start() { diff --git a/libs/tls/Network.hpp b/libs/tls/Network.hpp index 71443e6..c2ef6a3 100644 --- a/libs/tls/Network.hpp +++ b/libs/tls/Network.hpp @@ -3,7 +3,6 @@ #include #include #include -using std::string, std::cout, std::endl, nlohmann::json; class NetworkManager { private: CURL* curl; @@ -53,6 +52,9 @@ public: if ((res = curl_easy_perform(curl)) != 0) Log::create(ERROR, NETWORK, "curl_easy_perform() failed: " + std::string(curl_easy_strerror(res))); curl_slist_free_all(headers); } + #ifdef DEBUG + Log::create(INFO, NETWORK, response); + #endif return response; } }; diff --git a/libs/utils/log.hpp b/libs/utils/log.hpp index b99799d..373ab0a 100644 --- a/libs/utils/log.hpp +++ b/libs/utils/log.hpp @@ -5,7 +5,6 @@ #include #include #include -using std::setfill, std::setw; enum level { INFO, WARNING, ERROR, CRITICAL }; enum type { WEBSOCKET, NETWORK, API }; class Log { @@ -28,7 +27,10 @@ private: std::time_t now_c = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::tm* timer = std::localtime(&now_c); std::ostringstream oss; - oss << setfill('0') << setw(2) << timer->tm_hour << ":" << setfill('0') << setw(2) << timer->tm_min << ":" << setfill('0') << setw(2) << timer->tm_sec; + oss << std::setfill('0') << std::setw(2) + << timer->tm_hour << ":" << std::setfill('0') << std::setw(2) + << timer->tm_min << ":" << std::setfill('0') << std::setw(2) + << timer->tm_sec; return oss.str(); } static std::string str(const level& lvl) { diff --git a/libs/utils/types.hpp b/libs/utils/types.hpp index 13526ef..4ab7438 100644 --- a/libs/utils/types.hpp +++ b/libs/utils/types.hpp @@ -1,4 +1,4 @@ #ifndef UTILS_TYPES_HPP_ #define UTILS_TYPES_HPP_ -#define RELEASE +#define DEBUG #endif \ No newline at end of file diff --git a/sources/main.cpp b/sources/main.cpp index 25f547e..ffdd3ea 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -3,11 +3,13 @@ int main(int argc, char* argv[]) { if (argc != 3) return -1; WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents); - bot->on(GatewayEvents::READY, [](const Discord&a) { - cout << DiscordEndpoints::details::latest << endl; + bot->on(GatewayEvents::READY, [](const Discord& a) { + std::cout << DiscordEndpoints::details::latest << std::endl; }); bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord& msg) { - msg.get<0>().send("939957962972229634", msg.get<0>().pack({ "content", msg.get<2>().id })); + if (msg.get<2>().isBot == false) { + msg.get<0>().send("939957962972229634", msg.get<0>().pack("content", msg.get<2>().global_name)); + } }); bot->start(); return 0; From f70201131c1905d417a0e0f9ba3f5ea27c571645 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 16:11:58 +0500 Subject: [PATCH 08/13] structure update --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c665cdf..a7582a1 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,28 @@ # Sparkle -Library for creating discord bots -# ToDo - - [x] Websocket support - - [x] Minimal discord api support - - [x] Selfbot support - - [x] Easy to use - - [ ] Support json extraction from server response - - [ ] Optimised for high loads - - [ ] Full api support - - [ ] Fixes for known bugs - - [ ] Windows support - - [ ] Sharding -# How to build +Library for creating Discord bots. + +## How to Build + +### Required Libraries +- `curl` +- `ixwebsocket` + +### Build Instructions ```sh git clone http://applejack.ygg/fluttershy/sparkle.git mkdir sparkle/build && cd sparkle/build cmake .. && make -j$(nproc) ./sparkle -t ``` +# ToDo +- [x] Websocket support +- [x] Minimal discord api support +- [x] Selfbot support +- [x] Easy to use +- [x] Support json extraction from server response +- [ ] Optimised for high loads (not tested) +- [ ] Full api support +- [ ] Fixes for known bugs +- [ ] Windows support +- [ ] Sharding +- [ ] Tests \ No newline at end of file From 8747d65e7dff14b1427f564b897c5ab282c92591 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 16:19:31 +0500 Subject: [PATCH 09/13] cmake fix --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c554fb..ee79351 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,10 +19,10 @@ find_library(IXWEBSOCKET_LIBRARIES ixwebsocket) if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) message(STATUS "clang not found") - set(CMAKE_C_COMPILER "gcc") - set(CMAKE_CXX_COMPILER "g++") - find_program(CMAKE_C_COMPILER clang) - find_program(CLANG_CXX_COMPILER clang++) + set(CMAKE_C_COMPILER gcc) + set(CMAKE_CXX_COMPILER g++) + find_program(CMAKE_C_COMPILER gcc) + find_program(CLANG_CXX_COMPILER g++) if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) message(FATAL_ERROR "gcc not found") endif() From 34fa837413934fb5fcec25ceaf205bbd9918d207 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 16:44:33 +0500 Subject: [PATCH 10/13] cmake clang only --- CMakeLists.txt | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee79351..8cf2921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,23 +11,11 @@ set(TESTS ${CMAKE_SOURCE_DIR}/tests) set(CMAKE_C_COMPILER "clang") set(CMAKE_CXX_COMPILER "clang++") -find_program(CMAKE_C_COMPILER clang) -find_program(CLANG_CXX_COMPILER clang++) find_package(CURL REQUIRED) find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket) find_library(IXWEBSOCKET_LIBRARIES ixwebsocket) - -if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) - message(STATUS "clang not found") - set(CMAKE_C_COMPILER gcc) - set(CMAKE_CXX_COMPILER g++) - find_program(CMAKE_C_COMPILER gcc) - find_program(CLANG_CXX_COMPILER g++) - if(NOT CMAKE_C_COMPILER OR NOT CLANG_CXX_COMPILER) - message(FATAL_ERROR "gcc not found") - endif() -endif() -message(STATUS "current compiler: ${CMAKE_C_COMPILER}") +find_program(CMAKE_C_COMPILER clang) +find_program(CMAKE_CXX_COMPILER clang++) if(NOT IXWEBSOCKET_INCLUDE_DIR OR NOT IXWEBSOCKET_LIBRARIES) message(FATAL_ERROR "ixwebsocket not found") From c75cdae0c29b50efbf32c3993f154ca2185ec0d7 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 16:50:13 +0500 Subject: [PATCH 11/13] cmake fix --- CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cf2921..54e40c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,14 +8,12 @@ set(SOURCE sources/main.cpp) set(LIBS ${CMAKE_SOURCE_DIR}/libs/) set(INCLUDE ${CMAKE_SOURCE_DIR}/include/) set(TESTS ${CMAKE_SOURCE_DIR}/tests) -set(CMAKE_C_COMPILER "clang") -set(CMAKE_CXX_COMPILER "clang++") find_package(CURL REQUIRED) find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket) find_library(IXWEBSOCKET_LIBRARIES ixwebsocket) -find_program(CMAKE_C_COMPILER clang) -find_program(CMAKE_CXX_COMPILER clang++) + +message(STATUS "Current compiler: ${CMAKE_CXX_COMPILER}") if(NOT IXWEBSOCKET_INCLUDE_DIR OR NOT IXWEBSOCKET_LIBRARIES) message(FATAL_ERROR "ixwebsocket not found") From d7511fda9259df80b464fce7e456b9bcb4abec81 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Mon, 20 Jan 2025 17:10:52 +0500 Subject: [PATCH 12/13] cmake release/debug --- CMakeLists.txt | 24 +++++++++++++++++++----- libs/utils/types.hpp | 1 - 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54e40c1..1981e30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ project(sparkle) include(GoogleTest) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED True) set(SOURCE sources/main.cpp) set(LIBS ${CMAKE_SOURCE_DIR}/libs/) set(INCLUDE ${CMAKE_SOURCE_DIR}/include/) @@ -23,6 +25,22 @@ if(NOT CURL_INCLUDE_DIRS OR NOT CURL_LIBRARIES) message(FATAL_ERROR "curl not found") endif() +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) +endif() + +if(CMAKE_BUILD_TYPE) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_CXX_FLAGS "-march=native -O0 -pipe") + add_definitions(-DDEBUG) + elseif(CMAKE_BUILD_TYPE STREQUAL "Release") + add_definitions(-DRELEASE) + set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe") + endif() +endif() + +message(STATUS "${CMAKE_BUILD_TYPE}") + add_executable(${PROJECT_NAME} ${SOURCE}) #add_library(sparkles STATIC ${SOURCE}) #add_executable(tests ${TESTS}/tests.cpp) @@ -58,8 +76,4 @@ target_link_libraries(${PROJECT_NAME} PRIVATE # ${IXWEBSOCKET_LIBRARIES} # ${CURL_LIBRARIES} # gtest_main -#) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED True) -set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe") \ No newline at end of file +#) \ No newline at end of file diff --git a/libs/utils/types.hpp b/libs/utils/types.hpp index 4ab7438..38dff59 100644 --- a/libs/utils/types.hpp +++ b/libs/utils/types.hpp @@ -1,4 +1,3 @@ #ifndef UTILS_TYPES_HPP_ #define UTILS_TYPES_HPP_ -#define DEBUG #endif \ No newline at end of file From 0f05501ea340ed874ce1e1c16c7ab48ba8c14b33 Mon Sep 17 00:00:00 2001 From: fluttershy Date: Sat, 25 Jan 2025 11:22:04 +0500 Subject: [PATCH 13/13] cmake flags, some fixes in api --- CMakeLists.txt | 36 ++++++++++++++++-------------------- libs/api/Author.hpp | 28 ++++++++-------------------- libs/api/Embed.hpp | 10 +++++----- libs/api/Message.hpp | 13 ++++++++++++- libs/gateway/Websocket.hpp | 5 ++--- libs/tls/Network.hpp | 9 ++++++++- sources/main.cpp | 5 +++-- tests/tests.cpp | 15 +++++---------- 8 files changed, 59 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1981e30..25cdd12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,11 +31,11 @@ endif() if(CMAKE_BUILD_TYPE) if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_CXX_FLAGS "-march=native -O0 -pipe") + set(CMAKE_CXX_FLAGS "-march=native -O0 -pipe -Wall -Werror") add_definitions(-DDEBUG) elseif(CMAKE_BUILD_TYPE STREQUAL "Release") add_definitions(-DRELEASE) - set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe") + set(CMAKE_CXX_FLAGS "-march=native -O2 -pipe -Wall -Werror") endif() endif() @@ -43,15 +43,11 @@ message(STATUS "${CMAKE_BUILD_TYPE}") add_executable(${PROJECT_NAME} ${SOURCE}) #add_library(sparkles STATIC ${SOURCE}) -#add_executable(tests ${TESTS}/tests.cpp) +add_executable(tests ${TESTS}/tests.cpp) -#enable_testing() +enable_testing() -add_test(NAME network COMMAND tests) - -#target_include_directories(sparkles PRIVATE ${LIBS} ${INCLUDE} ${IXWEBSOCKET_INCLUDE_DIR} ${CURL_INCLUDE_DIRS}) - -#target_link_libraries(sparkles PRIVATE ${IXWEBSOCKET_LIBRARIES} ${CURL_LIBRARIES}) +add_test(NAME NetworkManagerTest COMMAND tests) target_include_directories(${PROJECT_NAME} PRIVATE ${LIBS} @@ -65,15 +61,15 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${CURL_LIBRARIES} ) -#target_include_directories(tests PRIVATE -# ${LIBS} -# ${INCLUDE} -# ${IXWEBSOCKET_INCLUDE_DIR} -# ${CURL_INCLUDE_DIRS} -#) +target_include_directories(tests PRIVATE + ${LIBS} + ${INCLUDE} + ${IXWEBSOCKET_INCLUDE_DIR} + ${CURL_INCLUDE_DIRS} +) -#target_link_libraries(tests gtest -# ${IXWEBSOCKET_LIBRARIES} -# ${CURL_LIBRARIES} -# gtest_main -#) \ No newline at end of file +target_link_libraries(tests gtest + ${IXWEBSOCKET_LIBRARIES} + ${CURL_LIBRARIES} + gtest_main +) \ No newline at end of file diff --git a/libs/api/Author.hpp b/libs/api/Author.hpp index d48fd8f..80100d1 100644 --- a/libs/api/Author.hpp +++ b/libs/api/Author.hpp @@ -9,6 +9,8 @@ private: WebSocket& web; NetworkManager& req; public: + const std::string channel_id, global_name, id, content, avatar, guild_id, discriminator, message_id; + bool isPinned, isBot; Author(const nlohmann::json& data) : data(data), d(data["d"]), @@ -18,26 +20,12 @@ public: global_name(functions::isNull(d["author"]["global_name"])), id(d["author"]["id"]), content(d["content"]), - isBot(d["author"].contains("bot") ? d["author"]["bot"].get() : false) - { - }; - const std::string channel_id, global_name, id, content; - bool isBot; - std::string discriminator() const { - return data["d"]["author"]["discriminator"]; - } - std::string guild_id() { - return data["d"]["guild_id"]; - } - std::string msg_id() { - return data["d"]["id"]; - } - bool isPinned() { - return data["d"]["pinned"]; - } - std::string avatar() { - return data["d"]["author"]["avatar"]; - } + avatar(data["d"]["author"]["avatar"]), + guild_id(data["d"]["guild_id"]), + discriminator(data["d"]["author"]["discriminator"]), + message_id(data["d"]["id"]), + isPinned(data["d"]["pinned"]), + isBot(d["author"].contains("bot") ? d["author"]["bot"].get() : false) {}; std::string send(const nlohmann::json& msg) { return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get() + "/messages", msg.dump()); } diff --git a/libs/api/Embed.hpp b/libs/api/Embed.hpp index 24a2c1f..d689e17 100644 --- a/libs/api/Embed.hpp +++ b/libs/api/Embed.hpp @@ -18,35 +18,35 @@ public: } EmbedBuilder& addTitle(const std::string& title) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(nlohmann::json::object()); + embed["embeds"].emplace_back(nlohmann::json::object()); } embed["embeds"].back()["title"] = title; return *this; } EmbedBuilder& addDescription(const std::string& desc) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(nlohmann::json::object()); + embed["embeds"].emplace_back(nlohmann::json::object()); } embed["embeds"].back()["description"] = desc; return *this; } EmbedBuilder& addColor(const std::string& color) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(nlohmann::json::object()); + embed["embeds"].emplace_back(nlohmann::json::object()); } embed["embeds"].back()["color"] = color; return *this; } EmbedBuilder& addUrl(const std::string& url) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(nlohmann::json::object()); + embed["embeds"].emplace_back(nlohmann::json::object()); } embed["embeds"].back()["url"] = url; return *this; } EmbedBuilder& addImage(const std::string& imageurl) { if (embed["embeds"].size() == 0) { - embed["embeds"].push_back(nlohmann::json::object()); + embed["embeds"].emplace_back(nlohmann::json::object()); } embed["embeds"].back()["image"] = { {"url", imageurl} }; return *this; diff --git a/libs/api/Message.hpp b/libs/api/Message.hpp index 456b566..8c3611c 100644 --- a/libs/api/Message.hpp +++ b/libs/api/Message.hpp @@ -8,7 +8,7 @@ private: WebSocket& web; NetworkManager& req; public: - Message(const nlohmann::json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; + Message(const nlohmann::json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}; std::string send(const std::string& id, const nlohmann::json& msg) { std::cout << id << msg << std::endl; return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + id + "/messages", msg.dump()); @@ -28,5 +28,16 @@ public: nlohmann::json pack(const nlohmann::json& key, const std::string& value) const { return {{ key, value }}; } + struct Api { + nlohmann::json data; + NetworkManager& req; + Api(const nlohmann::json& json = "") : data(json), req(NetworkManager::getInstance()) {}; + unsigned latency() const { + return req.getLatency(); + } + }; + std::string str() const { + return std::string(data); + } }; #endif \ No newline at end of file diff --git a/libs/gateway/Websocket.hpp b/libs/gateway/Websocket.hpp index 4f0d037..ffb574c 100644 --- a/libs/gateway/Websocket.hpp +++ b/libs/gateway/Websocket.hpp @@ -2,7 +2,6 @@ #define GATEWAY_WEBSOCKET_HPP_ #include #include -#include #include #include using namespace std::chrono; @@ -105,12 +104,12 @@ public: int getIntents() const { return WebSocket::intents; } - void on(const std::string& event, std::function handler) { + 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) { + void once(const std::string&& event, std::function handler) { eventHandlers[event] = [event, handler, isCalled = false](const nlohmann::json& message) mutable { isCalled == false ? isCalled = true : 0, handler(message.get()); }; diff --git a/libs/tls/Network.hpp b/libs/tls/Network.hpp index c2ef6a3..ae909f5 100644 --- a/libs/tls/Network.hpp +++ b/libs/tls/Network.hpp @@ -8,6 +8,7 @@ private: CURL* curl; CURLcode res; WebSocket& web; + std::chrono::duration duration; NetworkManager& operator=(const NetworkManager&) = delete; NetworkManager(const NetworkManager&) = delete; NetworkManager() : web(WebSocket::getInstance()) { @@ -35,13 +36,17 @@ public: static NetworkManager instance; return instance; } + unsigned long getLatency() const { + return duration.count(); + } std::string request(const std::string& method, const std::string& path, const std::string& data = "") { std::string response; if (curl) { curl_easy_setopt(curl, CURLOPT_URL, path.c_str()); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); - curl_slist* headers = curl_slist_append(headers, "Accept: application/json"); + curl_slist* headers = nullptr; + headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, ("Authorization: " + web.getToken()).c_str()); headers = curl_slist_append(headers, "User-Agent: DiscordBot"); @@ -49,8 +54,10 @@ public: curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3ONLY); + auto start = std::chrono::steady_clock::now(); if ((res = curl_easy_perform(curl)) != 0) Log::create(ERROR, NETWORK, "curl_easy_perform() failed: " + std::string(curl_easy_strerror(res))); curl_slist_free_all(headers); + duration = std::chrono::steady_clock::now() - start; } #ifdef DEBUG Log::create(INFO, NETWORK, response); diff --git a/sources/main.cpp b/sources/main.cpp index ffdd3ea..91870d3 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -6,9 +6,10 @@ int main(int argc, char* argv[]) { bot->on(GatewayEvents::READY, [](const Discord& a) { std::cout << DiscordEndpoints::details::latest << std::endl; }); - bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord& msg) { + bot->on(GatewayEvents::MESSAGE_CREATE, [](const Discord& msg) { if (msg.get<2>().isBot == false) { - msg.get<0>().send("939957962972229634", msg.get<0>().pack("content", msg.get<2>().global_name)); + msg.get<0>().send("939957962972229634", msg.get<0>().pack("content", std::to_string(msg.get<3>().latency()) + "ms")); + msg.get<0>().send("939957962972229634", msg.get<0>().pack("content", msg.get<2>().avatar)); } }); bot->start(); diff --git a/tests/tests.cpp b/tests/tests.cpp index b863039..5a07259 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -1,12 +1,7 @@ #include -int add(int a, int b) { - return a + b; -} -TEST(AddTest, PositiveNumbers) { - EXPECT_EQ(add(1, 2), 3); - EXPECT_EQ(add(2, 3), 5); -} -TEST(AddTest, NegativeNumbers) { - EXPECT_EQ(add(-1, -1), -2); - EXPECT_EQ(add(-1, 1), 0); +#include +#include +TEST(NetworkManagerTest, RequestReturnsExpectedValue) { + NetworkManager& networkManager = NetworkManager::getInstance(); + EXPECT_FALSE(networkManager.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/939957962972229634/messages", { "content", "test" }).empty()); } \ No newline at end of file