summaryrefslogtreecommitdiff
path: root/bot
diff options
context:
space:
mode:
Diffstat (limited to 'bot')
-rw-r--r--bot/CMakeLists.txt1
-rw-r--r--bot/include/server.cpp183
-rw-r--r--bot/src/main.cpp90
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
}
});