Merge pull request 'main' (#1) from main into tests

Reviewed-on: http://applejack.ygg/fluttershy/sparkle/pulls/1
This commit is contained in:
fluttershy 2025-01-25 09:36:15 +01:00
commit 00d3df8784
15 changed files with 63 additions and 67 deletions

View File

@ -10,9 +10,8 @@ Library for creating Discord bots.
### Build Instructions
```sh
git clone http://applejack.ygg/fluttershy/sparkle.git
mkdir sparkle/build && cd sparkle/build
cmake .. && make -j$(nproc)
./sparkle -t <BOT_TOKEN>
cmake -B build && cmake --build build -j$(nproc)
build/sparkle -t <BOT_TOKEN>
```
# ToDo
- [x] Websocket support

View File

@ -1,5 +1,5 @@
#ifndef INCLUDE_API_H_
#define INCLUDE_API_H_
#ifndef INCLUDE_API_HPP_
#define INCLUDE_API_HPP_
#include <api/Author.hpp>
#include <api/Message.hpp>
#include <api/Channel.hpp>

View File

@ -1,5 +1,5 @@
#ifndef INCLUDE_INCLUDES_H_
#define INCLUDE_INCLUDES_H_
#ifndef INCLUDE_INCLUDES_HPP_
#define INCLUDE_INCLUDES_HPP_
#include <utils/types.hpp>
#include <utils/json.hpp>
#include <utils/log.hpp>

View File

@ -1,5 +1,5 @@
#ifndef INCLUDE_NET_H_
#define INCLUDE_NET_H_
#ifndef INCLUDE_NET_HPP_
#define INCLUDE_NET_HPP_
#include <gateway/Websocket.hpp>
#include <network/Network.hpp>
#endif

View File

@ -1,11 +1,11 @@
#ifndef API_AUTHOR_HPP_
#define API_AUTHOR_HPP_
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
class Author {
private:
nlohmann::json data;
const nlohmann::json &d;
const nlohmann::json& d;
WebSocket& web;
NetworkManager& req;
public:
@ -25,7 +25,8 @@ public:
discriminator(d["author"]["discriminator"]),
message_id(d["id"]),
isPinned(d["pinned"]),
isBot(d["author"].contains("bot") ? d["author"]["bot"].get<bool>() : false) {};
isBot(d["author"].contains("bot") ? d["author"]["bot"].get<bool>() : 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());
}

View File

@ -1,6 +1,6 @@
#ifndef API_BOT_HPP_
#define API_BOT_HPP_
#include <includes.h>
#include <includes.hpp>
template<typename...Args>
class Discord {
private:
@ -33,8 +33,7 @@ public:
bool isBot() const {
try {
return data["d"]["bot"];
}
catch (...) {
} catch (...) {
return false;
}
}

View File

@ -1,7 +1,7 @@
#ifndef API_CHANNEL_HPP_
#define API_CHANNEL_HPP_
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
class Channel {
private:
nlohmann::json data;

View File

@ -1,6 +1,6 @@
#ifndef API_EMBED_HPP_
#define API_EMBED_HPP_
#include <includes.h>
#include <includes.hpp>
class EmbedBuilder {
private:
nlohmann::json embed = {

View File

@ -1,7 +1,7 @@
#ifndef API_GUILD_HPP_
#define API_GUILD_HPP_
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
class Guild {
private:
nlohmann::json data;

View File

@ -1,7 +1,7 @@
#ifndef API_MESSAGE_HPP_
#define API_MESSAGE_HPP_
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
class Message {
private:
nlohmann::json data;
@ -15,8 +15,7 @@ public:
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);
}
else {
} else {
return req.request(HttpMethods::GET, DiscordEndpoints::details::latest + "/channels/" + id + "/messages?before=" + before + "&limit=" + count);
}
return "";
@ -25,7 +24,7 @@ public:
return req.request(HttpMethods::DELETE, DiscordEndpoints::details::latest + "/channels/" + channel_id + "/messages/" + message_id);
}
nlohmann::json pack(const nlohmann::json& key, const std::string& value) const {
return {{ key, value }};
return { { key, value } };
}
struct Api {
nlohmann::json data;

View File

@ -1,7 +1,7 @@
#ifndef API_USER_HPP_
#define API_USER_HPP_
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
#include <vector>
class User {
private:
@ -10,7 +10,7 @@ private:
NetworkManager& req;
public:
User(const nlohmann::json& data = "") : data(data), web(WebSocket::getInstance()), req(NetworkManager::getInstance()) {}
#ifdef DEBUG
#ifdef DEBUG
nlohmann::json extract(const std::vector<std::string>& keys) {
std::vector<std::string> d = { "d" };
d.insert(d.end(), keys.begin(), keys.end());
@ -18,22 +18,20 @@ public:
for (const auto& key : d) {
if (current.contains(key)) {
current = current[key];
}
else {
} else {
return "Key not found.";
}
}
return current;
}
#endif
#endif
std::string me() {
return req.request(HttpMethods::GET, DiscordEndpoints::details::latest + "/users/@me");
}
bool isBot() const {
try {
return data["d"]["author"]["bot"];
}
catch (...) {
} catch (...) {
return false;
}
}

View File

@ -1,6 +1,6 @@
#ifndef GATEWAY_WEBSOCKET_HPP_
#define GATEWAY_WEBSOCKET_HPP_
#include <includes.h>
#include <includes.hpp>
#include <thread>
#include <ixwebsocket/IXNetSystem.h>
#include <ixwebsocket/IXWebSocket.h>
@ -30,19 +30,19 @@ private:
{"browser", "firefox"},
{"device", "firefox"}
}},
//{"compress", 1},
{"presence", {
{"activities", nlohmann::json::array({
{
//{"name", "asdsadsadsadsa"},
//{"type", 2}
}
})},
{"status", "idle"},
{"since", 91879201},
{"afk", false}
}}
//{"compress", 1},
{"presence", {
{"activities", nlohmann::json::array({
{
//{"name", "asdsadsadsadsa"},
//{"type", 2}
}
})},
{"status", "idle"},
{"since", 91879201},
{"afk", false}
}}
}}
};
ix::initNetSystem();
webSocket.setUrl("wss://gateway.discord.gg/?v=10&encoding=json");
@ -53,22 +53,22 @@ private:
res = nlohmann::json::parse(msg->str);
Log::create(INFO, WEBSOCKET, res["op"].dump() + " " + res["t"].dump());
switch (res["op"].get<int>()) {
case 10:
heartbeat_interval = res["d"]["heartbeat_interval"].get<int>();
!connected ? connected = true, webSocket.send(id.dump()) : 0;
std::thread([this, &heartbeat_interval, &connected]() {
while (connected && heartbeat_interval != -1) {
Log::create(INFO, WEBSOCKET, "Heartbeat " + std::to_string(heartbeat_interval));
std::this_thread::sleep_for(milliseconds(heartbeat_interval));
webSocket.send(payload.dump());
case 10:
heartbeat_interval = res["d"]["heartbeat_interval"].get<int>();
!connected ? connected = true, webSocket.send(id.dump()) : 0;
std::thread([this, &heartbeat_interval, &connected]() {
while (connected && heartbeat_interval != -1) {
Log::create(INFO, WEBSOCKET, "Heartbeat " + std::to_string(heartbeat_interval));
std::this_thread::sleep_for(milliseconds(heartbeat_interval));
webSocket.send(payload.dump());
}
}).detach();
break;
case 0:
if (eventHandlers.find(res["t"].get<std::string>()) != eventHandlers.end()) {
eventHandlers[res["t"].get<std::string>()](res);
}
}).detach();
break;
case 0:
if (eventHandlers.find(res["t"].get<std::string>()) != eventHandlers.end()) {
eventHandlers[res["t"].get<std::string>()](res);
}
break;
break;
}
}
});

View File

@ -1,6 +1,6 @@
#ifndef TLS_NETWORK_HPP_
#define TLS_NETWORK_HPP_
#include <includes.h>
#include <includes.hpp>
#include <gateway/Websocket.hpp>
#include <curl/curl.h>
class NetworkManager {

View File

@ -1,5 +1,5 @@
#include <api.h>
#include <includes.h>
#include <api.hpp>
#include <includes.hpp>
int main(int argc, char* argv[]) {
if (argc != 3) return -1;
WebSocket* bot = &WebSocket::getInstance(argv[2], GatewayIntents::AllIntents);

View File

@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include <includes.h>
#include <net.h>
#include <includes.hpp>
#include <net.hpp>
TEST(NetworkManagerTest, RequestReturnsExpectedValue) {
NetworkManager& networkManager = NetworkManager::getInstance();
EXPECT_FALSE(networkManager.request(HttpMethods::POST, DiscordEndpoints::details::latest + "/channels/939957962972229634/messages", { "content", "test" }).empty());