From 9205584e7096975e05524259cd181ad446474d6e Mon Sep 17 00:00:00 2001
From: fluttershy <a@a.a>
Date: Mon, 27 Jan 2025 22:02:21 +0500
Subject: [PATCH] test

---
 CMakeLists.txt             |  2 +-
 libs/api/Author.hpp        | 42 +++++++++++++++++++++++---------------
 libs/api/User.hpp          |  9 ++++++--
 libs/gateway/websocket.hpp |  1 +
 libs/utils/functions.hpp   | 30 +++++++++++++++++++++++++++
 sources/main.cpp           | 10 ++++-----
 6 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75dac42..6dae984 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,4 +78,4 @@ 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 1e63152..b617183 100644
--- a/libs/api/Author.hpp
+++ b/libs/api/Author.hpp
@@ -4,30 +4,40 @@
 #include <net.hpp>
 class Author {
 private:
-    const nlohmann::json& data, &d;
+    const nlohmann::json& data;
     WebSocket& web;
     NetworkManager& req;
 public:
+    struct Channel {
+        std::string channel_id;
+        std::string global_name;
+        std::string id;
+        std::string content;
+        std::string avatar;
+        std::string guild_id;
+        std::string discriminator;
+        std::string message_id;
+        bool isPinned;
+        bool isBot;
+    } authorData;
     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"]),
+    Author(const nlohmann::json& data)
+        : data(data),
         web(WebSocket::getInstance()),
         req(NetworkManager::getInstance()),
-        channel_id(functions::isNull(d["channel_id"])),
-        global_name(functions::isNull(d["author"]["global_name"])),
-        id(d["author"]["id"]),
-        content(d["content"]),
-        avatar(d["author"]["avatar"]),
-        guild_id(d["guild_id"]),
-        discriminator(d["author"]["discriminator"]),
-        message_id(d["id"]),
-        isPinned(d["pinned"]),
-        isBot(d["author"].contains("bot") ? d["author"]["bot"].get<bool>() : false) {
-    };
+        channel_id(functions::testValue<std::string>(data, { "d", "channel_id" }).value_or("")),
+        global_name(functions::testValue<std::string>(data, { "d", "author", "global_name" }).value_or("")),
+        id(functions::testValue<std::string>(data, { "d", "author", "id" }).value_or("")),
+        content(functions::testValue<std::string>(data, { "d", "content" }).value_or("")),
+        avatar(functions::testValue<std::string>(data, { "d", "author", "avatar" }).value_or("")),
+        guild_id(functions::testValue<std::string>(data, { "d", "guild_id" }).value_or("")),
+        discriminator(functions::testValue<std::string>(data, { "d", "author", "discriminator" }).value_or("")),
+        message_id(functions::testValue<std::string>(data, { "d", "id" }).value_or("")),
+        isPinned(functions::testValue<bool>(data, { "d", "pinned" }).value_or(false)),
+        isBot(functions::testValue<bool>(data, { "d", "author", "bot" }).value_or(false)) {}
     std::string send(const nlohmann::json& msg) {
-        return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + d["channel_id"].get<std::string>() + "/messages", msg.dump());
+        return req.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/" + data["d"]["channel_id"].get<std::string>() + "/messages", msg.dump());
     }
 };
 #endif
\ No newline at end of file
diff --git a/libs/api/User.hpp b/libs/api/User.hpp
index 5064532..aef8bfa 100644
--- a/libs/api/User.hpp
+++ b/libs/api/User.hpp
@@ -9,8 +9,13 @@ private:
     WebSocket& web;
     NetworkManager& req;
 public:
-    User(const nlohmann::json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()),
-        isBot(data["d"]["user"].contains("bot") ? data["d"]["user"]["bot"].get<bool>() : false) {}
+    User(const nlohmann::json& data) : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()),
+        isBot(false) {
+        auto botValue = functions::testValue<bool>(data, { "d", "user", "bot" });
+        if (botValue.has_value()) {
+            isBot = botValue.value();
+        }
+    }
     bool isBot;
     /*
     nlohmann::json extract(const std::vector<std::string>& keys) {
diff --git a/libs/gateway/websocket.hpp b/libs/gateway/websocket.hpp
index 137341d..8e61897 100644
--- a/libs/gateway/websocket.hpp
+++ b/libs/gateway/websocket.hpp
@@ -103,6 +103,7 @@ private:
                             }).detach();
                             break;
                         case GatewayOpcodes::Dispatch:
+                            Log::force_create(INFO, WEBSOCKET, res.dump());
                             emit(res["t"].get<std::string>(), res);
                             break;
                         default:
diff --git a/libs/utils/functions.hpp b/libs/utils/functions.hpp
index 9f0bf2c..e6f4b66 100644
--- a/libs/utils/functions.hpp
+++ b/libs/utils/functions.hpp
@@ -1,8 +1,38 @@
 #ifndef UTILS_FUNCTIONS_HPP_
 #define UTILS_FUNCTIONS_HPP_
+#include <optional>
 struct functions {
     static inline std::string isNull(const nlohmann::json& str) {
         return str.is_null() ? str.dump() : str.get<std::string>();
     }
+    template<typename T>
+    static std::optional<T> testValue(const nlohmann::json& data, const std::vector<std::string>& keys) {
+        const nlohmann::json* current = &data;
+        for (const auto& key : keys) {
+            if (current->contains(key)) {
+                current = &(*current)[key];
+            } else {
+                return std::nullopt;
+            }
+        }
+        if constexpr (std::is_same_v<T, bool>) {
+            if (current->is_boolean()) {
+                return current->get<bool>();
+            }
+        } else if constexpr (std::is_same_v<T, int>) {
+            if (current->is_number_integer()) {
+                return current->get<int>();
+            }
+        } else if constexpr (std::is_same_v<T, double>) {
+            if (current->is_number_float()) {
+                return current->get<double>();
+            }
+        } else if constexpr (std::is_same_v<T, std::string>) {
+            if (current->is_string()) {
+                return current->get<std::string>();
+            }
+        }
+        return std::nullopt;
+    }
 };
 #endif
\ No newline at end of file
diff --git a/sources/main.cpp b/sources/main.cpp
index 85ab742..551fca7 100644
--- a/sources/main.cpp
+++ b/sources/main.cpp
@@ -34,12 +34,10 @@ int main(int argc, char* argv[]) {
         std::cout << nlohmann::json::parse(user->me())["username"].get<std::string>() << std::endl;
     });
     
-    bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord<Message, Author>& msg) {
-        auto& [message, author] = msg.ctx();
-        if (!author->isBot) {
-            message->send("939957962972229634", message->pack("content", author->content));
-            bot->getEvents();
-        }
+    bot->on(GatewayEvents::MESSAGE_CREATE, [bot](const Discord<Message, User, Author>& msg) {
+        auto& [message, user, author] = msg.ctx();
+        message->send("939957962972229634", message->pack("content", std::to_string(user->isBot)));
+        bot->getEvents();
     });
     bot->start();
     return 0;