#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include #include #include // Required for file operations #include // Required for std::vector #include #include "stb_image.h" #include "stb_image_write.h" using namespace std; void flip_image_horizontally(unsigned char* data, int width, int height, int channels); void flip_image_vertically(unsigned char* data, int width, int height, int channels); void process_attachment(dpp::cluster& bot, const dpp::message_create_t& event, const dpp::attachment& attachment); int main() { // --- Load the bot token from a file --- string token_file_path = "token.txt"; ifstream token_file(token_file_path); string bot_token; if (!token_file.is_open()) { // if not, try parent directory if (!token_file.is_open()) { token_file_path = "../token.txt"; token_file.open(token_file_path); if (!token_file.is_open()) { cerr << "ERROR: Could not open token.txt. Please create the file and add your bot token." << std::endl; return 1; } } } getline(token_file, bot_token); token_file.close(); if (bot_token.empty()) { std::cerr << "ERROR: Token file is empty. Please add your bot token to token.txt." << std::endl; return 1; } dpp::cluster bot(bot_token, dpp::i_default_intents | dpp::i_message_content); bot.on_log(dpp::utility::cout_logger()); // Corrected: no 'true' argument std::cout<<"in main"<()) { bot.log(dpp::ll_info, "Registering global /ping command..."); bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id)); } }); bot.on_message_create([&bot](const dpp::message_create_t& event) { // Ignore messages from the bot itself to prevent infinite loops bot.log(dpp::ll_info, "author id: " + to_string(event.msg.author.id)); bot.log(dpp::ll_info, "bot id: " + to_string(bot.me.id)); if (event.msg.author.id == bot.me.id) { bot.log(dpp::ll_info, "Ignoring message, author and bot id match"); return; } // Check if the message has any attachments if (!event.msg.attachments.empty()) { // // Log that an attachment was found bot.log(dpp::ll_info, "Message from " + event.msg.author.username + " contains attachments!"); // You can iterate through the attachments if you need details about each one for (const auto& attachment : event.msg.attachments) { // bot.log(dpp::ll_info, " Attachment ID: " + std::to_string(attachment.id) + ", Filename: " + attachment.filename + ", Size: " + std::to_string(attachment.size) + " bytes"); // You can also get the URL of the attachment: attachment.url // And a proxied URL: attachment.proxy_url std::string filename = attachment.filename; if (filename.substr(strlen(filename.c_str())-3,3) == "jpg") { bot.log(dpp::ll_info, "jpg detected"); std::string local_filename = "temp_" + attachment.filename; process_attachment(bot,event,attachment); bot.log(dpp::ll_info, "image flipped horizontally"); // Download the attachment first //download_file(bot, event, attachment.url, local_filename); // // Note: The download is asynchronous. You would typically do // further processing in the http_request_completion_t handler. // For a simple example, you might call load_image from there. } } // Example: Reply to the user saying you detected an attachment // event.reply("Thanks for the attachment!"); } else { // Log if no attachments were found bot.log(dpp::ll_info, "Message from " + event.msg.author.username + " has no attachments."); } // You can also add logic for processing other types of messages or commands here }); std::cerr << "--- Direct stderr test: Bot is about to start listening ---" << std::endl; bot.start(dpp::st_wait); return 0; } void process_attachment(dpp::cluster& bot, const dpp::message_create_t& event, const dpp::attachment& attachment) { std::string local_filename = "temp_" + std::to_string(attachment.id) + "_" + attachment.filename; bot.request(attachment.url, dpp::http_method::m_get, [ &bot, event, local_filename, attachment](const dpp::http_request_completion_t& completion) { if (completion.status < 400) { std::ofstream file(local_filename, std::ios::binary); if (file.is_open()) { file.write(completion.body.c_str(), completion.body.length()); file.close(); int width, height, channels; //unsigned char* image_data = stbi_load_from_memory(local_filename.c_str(), &width, &height, &channels, 0); unsigned char* image_data = stbi_load_from_memory( reinterpret_cast(completion.body.data()), completion.body.length(), &width, &height, &channels, 0 ); if (image_data) { // Flip the image horizontally (you can choose which flip to apply) bot.log(dpp::ll_info,"channels: " + std::to_string(channels)); flip_image_horizontally(image_data, width, height, channels); // --- Save the flipped image to a new temporary file --- std::string flipped_filename = "flipped_" + local_filename; stbi_write_jpg(flipped_filename.c_str(), width, height, channels, image_data, 100); // Quality 100 // --- NEW CODE STARTS HERE --- dpp::message msg; // Add the file to the message msg.add_file(flipped_filename, dpp::utility::read_file(flipped_filename)); // Create an embed and reference the attached file dpp::embed embed; embed.set_title("Image Info"); embed.set_description("Dimensions: " + std::to_string(width) + "x" + std::to_string(height)); embed.set_image("attachment://" + flipped_filename); // Reference the file here // Add the embed to the message msg.add_embed(embed); msg.set_channel_id(1398043078559797310); bot.message_create(msg); msg.set_content("Here's your horizontally flipped image"); event.reply(msg); // --- NEW CODE ENDS HERE --- stbi_image_free(image_data); std::remove(local_filename.c_str()); std::remove(flipped_filename.c_str()); // Clean up the flipped file } else { std::cerr << "Error: Failed to load image with stb from " << local_filename << std::endl; } std::remove(local_filename.c_str()); } else { std::cerr << "Failed to open local file for writing: " << local_filename << std::endl; } } else { std::cerr << "Failed to download image from " << attachment.url << ". HTTP status code: " << completion.status << std::endl; } }); } void flip_image_horizontally(unsigned char* data, int width, int height, int channels) { for (int y = 0; y < height; ++y) { // Get pointers to the start of the current row unsigned char* row_start = data + y * width * channels; // Loop through half the row, swapping pixels from left and right for (int x = 0; x < width / 2; ++x) { // Calculate the pointers to the left and right pixels unsigned char* left_pixel = row_start + x * channels; unsigned char* right_pixel = row_start + (width - 1 - x) * channels; // Swap each channel of the pixels for (int c = 0; c < channels; ++c) { std::swap(left_pixel[c], right_pixel[c]); } } } } void flip_image_vertically(unsigned char* data, int width, int height, int channels) { // ... (your vertical flip implementation from before) int row_stride = width * channels; unsigned char* temp_row = new unsigned char [row_stride]; for (int y = 0; y < height / 2; ++y) { unsigned char* top_row = data + y * row_stride; unsigned char* bottom_row = data + (height - 1 - y) * row_stride; std::memcpy(temp_row, top_row, row_stride); std::memcpy(top_row, bottom_row, row_stride); std::memcpy(bottom_row, temp_row, row_stride); } delete[] temp_row; }