Untitled
unknown
c_cpp
2 years ago
4.7 kB
4
Indexable
#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 -
Editor is loading...
Leave a Comment