diff options
Diffstat (limited to 'bot')
| -rw-r--r-- | bot/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | bot/include/server.cpp | 183 | ||||
| -rw-r--r-- | bot/src/main.cpp | 90 |
3 files changed, 43 insertions, 231 deletions
diff --git a/bot/CMakeLists.txt b/bot/CMakeLists.txt index 2ac0346..18307e5 100644 --- a/bot/CMakeLists.txt +++ b/bot/CMakeLists.txt @@ -29,6 +29,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::Crypto z opus + zmq ) # Include directories diff --git a/bot/include/server.cpp b/bot/include/server.cpp deleted file mode 100644 index 9425e85..0000000 --- a/bot/include/server.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include <iostream> -#include <thread> -#include <mutex> -#include <vector> -#include <queue> -#include <algorithm> // Nécessaire pour std::remove_if -#include <functional> -#include <sys/socket.h> -#include <sys/un.h> -#include <poll.h> -#include <fcntl.h> -#include <unistd.h> -#include <cstring> - -#ifdef __APPLE__ -#define SOCKET_PATH_MAX 104 -#else -#define SOCKET_PATH_MAX 108 -#endif - -class UnixSocketServer { -public: - using MessageHandler = std::function<void(const std::string&)>; - - UnixSocketServer(const std::string& path) : - socket_path_(path.substr(0, SOCKET_PATH_MAX - 1)), - running_(false) {} - - ~UnixSocketServer() { stop(); } - - void start(MessageHandler handler) { - if (running_) return; - - server_fd_ = create_socket(); - setup_socket(); - - running_ = true; - server_thread_ = std::thread(&UnixSocketServer::event_loop, this, handler); - } - - void stop() { - running_ = false; - if (server_thread_.joinable()) { - server_thread_.join(); - } - cleanup(); - } - - void send(const std::string& message) { - std::lock_guard<std::mutex> lock(clients_mutex_); - for (auto& client : clients_) { - queue_message(client.fd, message); - } - } - -private: - struct Client { - int fd; - std::queue<std::string> write_queue; - }; - - int create_socket() { - int fd = ::socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) throw std::runtime_error("::socket() failed"); - return fd; - } - - void setup_socket() { - struct sockaddr_un addr = {}; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, socket_path_.c_str(), sizeof(addr.sun_path) - 1); - - unlink(socket_path_.c_str()); - - if (bind(server_fd_, (struct sockaddr*)&addr, sizeof(addr)) == -1) { - close(server_fd_); - throw std::runtime_error("bind() failed"); - } - - if (listen(server_fd_, 5) == -1) { - close(server_fd_); - throw std::runtime_error("listen() failed"); - } - - set_nonblocking(server_fd_); - } - - void set_nonblocking(int fd) { - int flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); - } - - void event_loop(MessageHandler handler) { - std::vector<struct pollfd> fds; - fds.push_back({server_fd_, POLLIN, 0}); - - while (running_) { - int ready = ::poll(fds.data(), fds.size(), 250); - if (ready == -1) break; - - for (size_t i = 0; i < fds.size(); ++i) { - if (fds[i].revents & POLLIN) { - if (fds[i].fd == server_fd_) { - accept_new_connection(fds); - } else { - handle_client_input(fds[i].fd, handler); - } - } - - if (fds[i].revents & POLLOUT) { - handle_client_output(fds[i].fd); - } - } - } - } - - void accept_new_connection(std::vector<struct pollfd>& fds) { - int client_fd = accept(server_fd_, nullptr, nullptr); - if (client_fd == -1) return; - - set_nonblocking(client_fd); - fds.push_back({client_fd, POLLIN | POLLOUT, 0}); - - std::lock_guard<std::mutex> lock(clients_mutex_); - clients_.push_back({client_fd, {}}); - } - - void handle_client_input(int fd, MessageHandler handler) { - char buffer[4096]; - ssize_t count = recv(fd, buffer, sizeof(buffer), 0); - - if (count > 0) { - handler(std::string(buffer, count)); - } else { - remove_client(fd); - } - } - - void handle_client_output(int fd) { - std::lock_guard<std::mutex> lock(clients_mutex_); - for (auto& client : clients_) { - if (client.fd == fd && !client.write_queue.empty()) { - const std::string& msg = client.write_queue.front(); - ssize_t sent = ::send(fd, msg.data(), msg.size(), 0); - if (sent > 0) { - client.write_queue.pop(); - } - } - } - } - - void queue_message(int fd, const std::string& message) { - std::lock_guard<std::mutex> lock(clients_mutex_); - for (auto& client : clients_) { - if (client.fd == fd) { - client.write_queue.push(message); - return; - } - } - } - - void remove_client(int fd) { - std::lock_guard<std::mutex> lock(clients_mutex_); - clients_.erase( - std::remove_if(clients_.begin(), clients_.end(), - [fd](const Client& c) { return c.fd == fd; }), - clients_.end() - ); - close(fd); - } - - void cleanup() { - close(server_fd_); - unlink(socket_path_.c_str()); - } - - std::string socket_path_; - int server_fd_ = -1; - std::atomic<bool> running_; - std::thread server_thread_; - std::mutex clients_mutex_; - std::vector<Client> clients_; -}; diff --git a/bot/src/main.cpp b/bot/src/main.cpp index 06a03b0..853e829 100644 --- a/bot/src/main.cpp +++ b/bot/src/main.cpp @@ -1,12 +1,11 @@ #include <dpp/dpp.h> #include <string> +#include <zmq.hpp> #include "../include/utils.hpp" -#include "../include/server.cpp" +#include <thread> -int main(int argc, char *argv[]) -{ - if (argc > 1) - { +int main(int argc, char *argv[]) { + if (argc > 1) { std::string token = argv[1]; setenv("BOT_TOKEN", token.c_str(), 1); } @@ -14,32 +13,21 @@ int main(int argc, char *argv[]) const std::string BOT_TOKEN = getenv("BOT_TOKEN"); dpp::cluster bot(BOT_TOKEN); - std::unique_ptr<UnixSocketServer> server; std::unique_ptr<nlohmann::json> json_data = std::make_unique<nlohmann::json>(); + bot.on_log(dpp::utility::cout_logger()); - bot.on_slashcommand([&json_data](const dpp::slashcommand_t &event) - { - // let's generate the key-value map + bot.on_slashcommand([&json_data](const dpp::slashcommand_t &event) { std::unordered_map<std::string, std::string> key_values = app::generate_key_values(event); - // let's create a string to send std::string response = "Interaction found, but no response found."; - // let's first check if it's a command or not. - if(event.command.get_command_name() != ""){ - // let's check if the command is in the json_data - // display json_data as string in the console - if (json_data->contains(event.command.get_command_name())) - { - // let's check if it does exist + if (event.command.get_command_name() != "") { + if (json_data->contains(event.command.get_command_name())) { std::cout << "Command found: " << event.command.get_command_name() << std::endl; auto command_data = json_data->at(event.command.get_command_name()); - if (command_data.contains("response")) - { + if (command_data.contains("response")) { std::cout << "Response found: " << command_data.at("response") << std::endl; response = command_data.at("response"); - }else - { - // let's display the command data + } else { std::cout << "Command data: " << command_data.dump(4) << std::endl; std::cout << "No response found for command: " << event.command.get_command_name() << std::endl; } @@ -48,36 +36,42 @@ int main(int argc, char *argv[]) event.reply(app::update_string(response, key_values)); }); - bot.on_ready([&bot, &server, &json_data](const dpp::ready_t &event) - { - if (dpp::run_once<struct register_bot_commands>()) - { - // let's start the server - std::string socket_path = "/tmp/" + bot.me.id.str() + ".sock"; - server = std::make_unique<UnixSocketServer>(socket_path); // Création explicite + bot.on_ready([&bot, &json_data](const dpp::ready_t &event) { + if (dpp::run_once<struct register_bot_commands>()) { + // Lancer la boucle ZMQ dans un thread séparé + std::thread zmq_thread([&json_data]() { + zmq::context_t ctx; + zmq::socket_t responder(ctx, zmq::socket_type::req); + responder.connect("tcp://localhost:5555"); + zmq::message_t ready_msg(5); + memcpy(ready_msg.data(), "ready", 5); + responder.send(ready_msg, zmq::send_flags::none); - server->start([&json_data, &server](const std::string& msg) - { - // Traitement du message reçu - nlohmann::json j = app::json_from_string(msg); - if (j.contains("command")) - { - std::string command = j["command"]; - // ... [traitement de la commande] - if (command == "update") - { - // ... [traitement de la commande update] - json_data = std::make_unique<nlohmann::json>(j["data"]); - } - else if (command == "stop") - { - server->stop(); - std::cout << "Server stopped." << std::endl; - exit(0); + while (true) { + zmq::message_t reply; + if (responder.recv(reply, zmq::recv_flags::none)) { + std::string json_str(static_cast<char*>(reply.data()), reply.size()); + try { + nlohmann::json j = app::json_from_string(json_str); + if (j.contains("command")) { + std::string command = j["command"]; + if (command == "update") { + json_data = std::make_unique<nlohmann::json>(j["data"]); + } + } + // Répondre de nouveau si nécessaire + zmq::message_t ping(4); + memcpy(ping.data(), "pong", 4); + responder.send(ping, zmq::send_flags::none); + } catch (const std::exception& e) { + std::cerr << "[BOT] Error parsing JSON: " << e.what() << std::endl; + } } - // ... [gestion des messages entrants] } + }); + + zmq_thread.detach(); // Le thread tourne en fond } }); |
