This commit is contained in:
fluttershy 2025-01-14 05:18:08 +05:00
parent 2e0d5d5b70
commit 7c55f71596
6 changed files with 91 additions and 29 deletions

View File

@ -7,6 +7,7 @@
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
#include <utils/types.hpp> #include <utils/types.hpp>
#include <utils/logs.hpp>
#include <ixwebsocket/IXNetSystem.h> #include <ixwebsocket/IXNetSystem.h>
#include <ixwebsocket/IXWebSocket.h> #include <ixwebsocket/IXWebSocket.h>
using json = nlohmann::json; using json = nlohmann::json;
@ -16,7 +17,7 @@ using namespace std::chrono;
using namespace std::chrono_literals; using namespace std::chrono_literals;
class WebSocket { class WebSocket {
private: private:
std::array<std::pair<int, std::string_view>, 73> events = {{ const std::array<std::pair<const int, std::string_view>, 73> events = { {
{APPLICATION_COMMAND_PERMISSIONS_UPDATE, "APPLICATION_COMMAND_PERMISSIONS_UPDATE"}, {APPLICATION_COMMAND_PERMISSIONS_UPDATE, "APPLICATION_COMMAND_PERMISSIONS_UPDATE"},
{AUTO_MODERATION_ACTION_EXECUTION, "AUTO_MODERATION_ACTION_EXECUTION"}, {AUTO_MODERATION_ACTION_EXECUTION, "AUTO_MODERATION_ACTION_EXECUTION"},
{AUTO_MODERATION_RULE_CREATE, "AUTO_MODERATION_RULE_CREATE"}, {AUTO_MODERATION_RULE_CREATE, "AUTO_MODERATION_RULE_CREATE"},
@ -129,16 +130,21 @@ private:
}; };
ix::initNetSystem(); ix::initNetSystem();
webSocket.setUrl("wss://gateway.discord.gg/?v=10&encoding=json"); webSocket.setUrl("wss://gateway.discord.gg/?v=10&encoding=json");
webSocket.setHandshakeTimeout(5);
Logs::create(INFO, WEBSOCKET, "ixwebsocket init");
webSocket.setOnMessageCallback([this, res = json(), heartbeat_interval = 0, connected = false](const ix::WebSocketMessagePtr& msg) mutable { webSocket.setOnMessageCallback([this, res = json(), heartbeat_interval = 0, connected = false](const ix::WebSocketMessagePtr& msg) mutable {
if (msg->type == ix::WebSocketMessageType::Message) { if (msg->type == ix::WebSocketMessageType::Message) {
res = json::parse(msg->str); res = json::parse(msg->str);
chngcol(std::string("WEBSOCKET: " + res["op"].dump() + " " + res["t"].dump()), 0, 0, 120); //#ifdef DEBUG
Logs::create(INFO, WEBSOCKET, res["op"].dump() + " " + res["t"].dump());
//#endif
switch (res["op"].get<int>()) { switch (res["op"].get<int>()) {
case 10: case 10:
heartbeat_interval = res["d"]["heartbeat_interval"].get<int>(); heartbeat_interval = res["d"]["heartbeat_interval"].get<int>();
!connected ? connected = true, webSocket.send(id.dump()) : 0; !connected ? connected = true, webSocket.send(id.dump()) : 0;
std::thread([this, &heartbeat_interval, &connected]() { std::thread([this, &heartbeat_interval, &connected]() {
while (connected && heartbeat_interval != -1) { while (connected && heartbeat_interval != -1) {
Logs::create(INFO, WEBSOCKET, "Heartbeat " + std::to_string(heartbeat_interval));
std::this_thread::sleep_for(milliseconds(heartbeat_interval)); std::this_thread::sleep_for(milliseconds(heartbeat_interval));
webSocket.send(payload.dump()); webSocket.send(payload.dump());
} }
@ -170,6 +176,7 @@ public:
} }
*/ */
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, bool bot = true) {
Logs::create(WARNING, WEBSOCKET, "Instance event");
static WebSocket instance(token, intents, bot); static WebSocket instance(token, intents, bot);
return instance; return instance;
} }
@ -193,7 +200,7 @@ public:
isCalled == false ? isCalled = true : 0, handler(message.get<json>()); isCalled == false ? isCalled = true : 0, handler(message.get<json>());
}; };
} }
void start(void) { void start() {
while (1) std::this_thread::sleep_for(1ms); while (1) std::this_thread::sleep_for(1ms);
} }
}; };

View File

@ -9,6 +9,7 @@
#include <netdb.h> #include <netdb.h>
#include <utils/types.hpp> #include <utils/types.hpp>
#include <gateway/Websocket.hpp> #include <gateway/Websocket.hpp>
#include <utils/logs.hpp>
using std::cout; using std::cout;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@ -23,31 +24,33 @@ private:
abort(); abort();
} }
void createSSLConnection(const std::string& hostname, const std::string& port) { void createSSLConnection(const std::string& hostname, const std::string& port) {
Logs::create(INFO, NETWORK, "SSL connection");
addrinfo hints = { 0 }, *res = { 0 }; addrinfo hints = { 0 }, *res = { 0 };
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(hostname.c_str(), port.c_str(), &hints, &res) != 0) { if (getaddrinfo(hostname.c_str(), port.c_str(), &hints, &res) != 0) {
cerr << "Failed to get address info for " << hostname << ":" << port << endl; Logs::create(ERROR, NETWORK, "Failed to get address info for " + hostname + ":" + port);
handleSSLInitErrors(); handleSSLInitErrors();
} }
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1) { if (sock == -1) {
cerr << "Failed to create socket" << endl; Logs::create(ERROR, NETWORK, "Socket error");
close(sock);
handleSSLInitErrors(); handleSSLInitErrors();
} }
if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) { if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
cerr << "Failed to connect to " << hostname << ":" << port << endl; Logs::create(ERROR, NETWORK, "Failed to connect to " + hostname + ":" + port);
close(sock); close(sock);
handleSSLInitErrors(); handleSSLInitErrors();
} }
ssl.reset(SSL_new(ctx)); ssl.reset(SSL_new(ctx));
if (!ssl) { if (!ssl) {
cerr << "Failed to create SSL structure" << endl; Logs::create(ERROR, NETWORK, "Failed to create SSL structure");
close(sock); close(sock);
handleSSLInitErrors(); handleSSLInitErrors();
} }
SSL_set_fd(ssl.get(), sock); SSL_set_fd(ssl.get(), sock);
if (SSL_connect(ssl.get()) != 1) { if (SSL_connect(ssl.get()) != 1) {
cerr << "SSL connection failed" << endl; Logs::create(ERROR, NETWORK, "SSL connection failed");
close(sock); close(sock);
handleSSLInitErrors(); handleSSLInitErrors();
} }
@ -55,11 +58,12 @@ private:
} }
NetworkManager& operator=(const NetworkManager&) = delete; NetworkManager& operator=(const NetworkManager&) = delete;
NetworkManager(const NetworkManager&) = delete; NetworkManager(const NetworkManager&) = delete;
NetworkManager() : ctx(nullptr), web(WebSocket::getInstance()) { NetworkManager() : web(WebSocket::getInstance()) {
Logs::create(INFO, NETWORK, "Network init");
if (!ctx) { if (!ctx) {
ctx = SSL_CTX_new(TLS_client_method()); ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) { if (!ctx) {
cerr << "Failed to create SSL context" << endl; Logs::create(ERROR, NETWORK, "Failed to create SSL context");
handleSSLInitErrors(); handleSSLInitErrors();
} }
OPENSSL_init_ssl(0, 0); OPENSSL_init_ssl(0, 0);
@ -97,6 +101,7 @@ private:
} }
public: public:
static NetworkManager& getInstance() { static NetworkManager& getInstance() {
Logs::create(WARNING, NETWORK, "Instance event");
static NetworkManager instance; static NetworkManager instance;
return instance; return instance;
} }
@ -108,8 +113,7 @@ public:
#ifdef DEBUG #ifdef DEBUG
createSSLConnection("discord.com", "443"); createSSLConnection("discord.com", "443");
#endif #endif
std::string result; auto net = [this, method, path, data, result = std::string("")]() mutable -> std::string {
auto net = [this, method, path, data, &result]() mutable {
std::string request = method + " " + path + " HTTP/1.1\r\nHost: discord.com\r\nAccept: application/json\r\nContent-Type: application/json\r\n"; std::string request = method + " " + path + " HTTP/1.1\r\nHost: discord.com\r\nAccept: application/json\r\nContent-Type: application/json\r\n";
request += "Authorization: " + web.getToken() + "\r\nContent-Length: " + std::to_string(data.length()) + "\r\n"; request += "Authorization: " + web.getToken() + "\r\nContent-Length: " + std::to_string(data.length()) + "\r\n";
#ifdef DEBUG #ifdef DEBUG
@ -122,6 +126,7 @@ public:
std::cerr << "Failed to send request" << std::endl; std::cerr << "Failed to send request" << std::endl;
handleSSLInitErrors(); handleSSLInitErrors();
} }
Logs::create(INFO, NETWORK, "Request " + method + " " + path);
#ifdef DEBUG #ifdef DEBUG
std::vector<char> buffer(1024); std::vector<char> buffer(1024);
int bytesRead; int bytesRead;
@ -131,14 +136,12 @@ public:
buffer.resize(buffer.size() * 2); buffer.resize(buffer.size() * 2);
} }
} }
#endif
};
net();
#ifdef DEBUG
return parseJson(result); return parseJson(result);
#elif defined(RELEASE) #elif defined(RELEASE)
return result; return result;
#endif #endif
};
return net();
} }
}; };
#endif #endif

View File

@ -1,5 +1,5 @@
#ifndef EVENTS_HPP_ #ifndef UTILS_EVENTS_HPP_
#define EVENTS_HPP_ #define UTILS_EVENTS_HPP_
enum GatewayEvents { enum GatewayEvents {
APPLICATION_COMMAND_PERMISSIONS_UPDATE, APPLICATION_COMMAND_PERMISSIONS_UPDATE,
AUTO_MODERATION_ACTION_EXECUTION, AUTO_MODERATION_ACTION_EXECUTION,

57
libs/utils/logs.hpp Normal file
View File

@ -0,0 +1,57 @@
#ifndef UTILS_LOGS_HPP
#define UTILS_LOGS_HPP
#include <string>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <ctime>
using std::setfill;
using std::setw;
enum level { INFO, WARNING, ERROR };
enum type { WEBSOCKET, NETWORK };
class Logs {
public:
static void create(level lvl, type t, const std::string& message) {
std::string color;
switch (lvl) {
case INFO:
color = "\033[34m";
break;
case WARNING:
color = "\033[33m";
break;
case ERROR:
color = "\033[31m";
break;
default:
color = "\033[0m";
break;
}
std::cout << color << "[" << getCurrentTime() << "][" << str(t) << "][" << str(lvl) << "] \033[37m" << message << "\033[0m" << std::endl;
}
private:
static std::string getCurrentTime() {
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;
return oss.str();
}
static std::string str(level lvl) {
switch (lvl) {
case INFO: return "INFO";
case WARNING: return "WARNING";
case ERROR: return "ERROR";
default: return "UNKNOWN";
}
}
static std::string str(type t) {
switch (t) {
case WEBSOCKET: return "WEBSOCKET";
case NETWORK: return "NETWORK";
default: return "UNKNOWN";
}
}
};
#endif

View File

@ -8,9 +8,4 @@
#include <utils/json.hpp> #include <utils/json.hpp>
using json = nlohmann::json; using json = nlohmann::json;
#include <iostream> #include <iostream>
void chngcol(const std::string& text, int rBg, int gBg, int bBg) {
std::cout << "\033[48;2;" << rBg << ";" << gBg << ";" << bBg << "m";
std::cout << "\033[38;2;255;255;255m";
std::cout << text << "\033[0m" << std::endl;
}
#endif #endif

View File

@ -14,10 +14,10 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc != 3) return -1; if (argc != 3) return -1;
WebSocket* bot = &WebSocket::getInstance(argv[2], 131071); WebSocket* bot = &WebSocket::getInstance(argv[2], 131071);
bot->on(GatewayEvents::MESSAGE_CREATE, [](const Bot<Message, User, Author>& b) { bot->on(GatewayEvents::MESSAGE_CREATE, [](const Bot<Message, User, Author>& msg) {
if (!g(2, b.net)->isBot()) { if (!g(2, msg.net)->isBot()) {
g(0, b.net)->send("939957962972229634", j("content", g(2, b.net)->content())); g(0, msg.net)->send("939957962972229634", j("content", g(2, msg.net)->content()));
cout << g(1, b.net)->extract({ "content" }).get<string>() << endl; //cout << g(1, msg.net)->extract({ "content" }).get<string>() << endl;
} }
}); });
bot->start(); bot->start();