Untitled
#include <windows.h> #include <atomic> #include <iostream> #include <mutex> #include <thread> #include <vector> #include <chrono> // Define the target color (RGB values) const int target_red = 255; const int target_green = 102; const int target_blue = 102; // Define the maximum number of threads #define MAX_THREADS 4 // Define the screen dimensions const int screen_width = 2560; const int screen_height = 1600; // Structure to hold potential click locations and color information struct ClickCandidate { int x; int y; bool valid; // Indicates if a candidate was found std::atomic<bool> found; // Atomic flag to avoid race conditions }; // Mutex for thread-safe access to the best candidate std::mutex click_mutex; // Function to check if colors are similar bool isColorSimilar(const COLORREF& color, int threshold) { int red_diff = abs(GetRValue(color) - target_red); int green_diff = abs(GetGValue(color) - target_green); int blue_diff = abs(GetBValue(color) - target_blue); return (red_diff + green_diff + blue_diff) <= threshold; } // Function to capture a screenshot of a specific area and scan for the target color ClickCandidate captureAndScanArea(HDC hdc_screen, int x_start, int y_start, int width, int height, int threshold) { ClickCandidate best_candidate; best_candidate.x = -1; best_candidate.y = -1; best_candidate.valid = false; best_candidate.found.store(false); // Error handling: check if DC is obtained successfully if (!hdc_screen) { std::cerr << "Error: Failed to obtain screen DC." << std::endl; return best_candidate; } // Efficiently store pixel data in a vector std::vector<COLORREF> pixels(width * height); if (BitBlt(NULL, 0, 0, width, height, hdc_screen, x_start, y_start, SRCCOPY) == 0) { std::cerr << "Error: Failed to capture screenshot." << std::endl; ReleaseDC(NULL, hdc_screen); return best_candidate; } // Loop through each pixel and find the best candidate for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { COLORREF color = pixels[y * width + x]; if (isColorSimilar(color, threshold)) { click_mutex.lock(); if (!best_candidate.valid || y > best_candidate.y) { best_candidate.x = x_start + x; best_candidate.y = y_start + y; best_candidate.valid = true; best_candidate.found.store(true); } click_mutex.unlock(); } } } // Release resources ReleaseDC(NULL, hdc_screen); return best_candidate; } // Function to perform a left mouse click at a specific location void performClick(int x, int y) { // Move mouse cursor to the target position SetCursorPos(x, y); // Simulate a left mouse button click mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0); } // Function to continuously scan the screen for the target color void scanScreen() { while (true) { HDC hdc_screen = GetDC(NULL); if (!hdc_screen) { std::cerr << "Error: Failed to obtain screen DC." << std::endl; return; } ClickCandidate candidate = captureAndScanArea(hdc_screen, 0, 0, screen_width, screen_height, 25); // Change the threshold here ReleaseDC(NULL, hdc_screen); if (candidate.valid) { performClick(candidate.x, candidate.y); } std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 150)); // Adjust scan rate here } } int main() { // Start multiple threads for scanning std::vector<std::thread> threads; const int num_threads = std::min(MAX_THREADS, std::thread::hardware_concurrency()); // Divide the screen into segments for each thread const int segment_height = screen_height / num_threads; for (int i = 0; i < num_threads; ++i) { int segment_y_start = i * segment_height; int segment_y_end = (i + 1) * segment_height; // The last thread may cover the remaining area if (i == num_threads - 1) { segment_y_end = screen_height; } // Start a thread to scan its segment of the screen threads.emplace_back([segment_y_start, segment_y_end]() { while (true) { HDC hdc_screen = GetDC(NULL); if (!hdc_screen) { std::cerr << "Error: Failed to obtain screen DC." << std::endl; return; } ClickCandidate candidate = captureAndScanArea(hdc_screen, 0, segment_y_start, screen_width, segment_y_end -
Leave a Comment