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 <chrono>
#include <utils/types.hpp>
#include <utils/logs.hpp>
#include <ixwebsocket/IXNetSystem.h>
#include <ixwebsocket/IXWebSocket.h>
using json = nlohmann::json;
@ -16,7 +17,7 @@ using namespace std::chrono;
using namespace std::chrono_literals;
class WebSocket {
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"},
{AUTO_MODERATION_ACTION_EXECUTION, "AUTO_MODERATION_ACTION_EXECUTION"},
{AUTO_MODERATION_RULE_CREATE, "AUTO_MODERATION_RULE_CREATE"},
@ -129,16 +130,21 @@ private:
};
ix::initNetSystem();
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 {
if (msg->type == ix::WebSocketMessageType::Message) {
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>()) {
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) {
Logs::create(INFO, WEBSOCKET, "Heartbeat " + std::to_string(heartbeat_interval));
std::this_thread::sleep_for(milliseconds(heartbeat_interval));
webSocket.send(payload.dump());
}
@ -170,6 +176,7 @@ public:
}
*/
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);
return instance;
}
@ -193,7 +200,7 @@ public:
isCalled == false ? isCalled = true : 0, handler(message.get<json>());
};
}
void start(void) {
void start() {
while (1) std::this_thread::sleep_for(1ms);
}
};

View File

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

View File

@ -1,5 +1,5 @@
#ifndef EVENTS_HPP_
#define EVENTS_HPP_
#ifndef UTILS_EVENTS_HPP_
#define UTILS_EVENTS_HPP_
enum GatewayEvents {
APPLICATION_COMMAND_PERMISSIONS_UPDATE,
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>
using json = nlohmann::json;
#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

View File

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