- 41
- 2
В общем накостылял код на плюсах но не пойму почему в самой игре.
main:
//
// CMakeProject2.cpp: определяет точку входа для приложения.
//
#include "CMakeProject2.h"
#include <opencv2/opencv.hpp>
#include <windows.h>
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <random> // Для случайных задержек
using namespace std;
using namespace cv;
// Отключение параллельных бэкендов OpenCV
static void disableOpenCVParallel() {
cv::setNumThreads(1); // Ограничение до 1 потока
cv::setUseOptimized(false); // Отключение оптимизаций, зависящих от параллелизма
}
string getExecutableDirectory() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string path(buffer);
return path.substr(0, path.find_last_of("\\/")) + "\\photo\\";
}
const string template_dir = getExecutableDirectory();
// Коды клавиш с виртуальными кодами и скан-кодами
const map<string, pair<WORD, BYTE>> key_map = {
{"F", {0x46, 0x21}},
{"H", {0x48, 0x23}},
{"Q", {0x51, 0x10}},
{"R", {0x52, 0x13}},
{"V", {0x56, 0x2F}},
{"W", {0x57, 0x11}},
{"B", {0x42, 0x30}},
{"D", {0x44, 0x20}},
{"Space", {0x20, 0x39}},
{"Left Arrow", {0x25, 0x4B}},
{"Right Arrow", {0x26, 0x4D}},
{"Up Arrow", {0x27, 0x48}},
{"Down Arrow", {0x28, 0x50}},
{"Left Shift", {0xA0, 0x2A}}
};
// Функция для определения, является ли скан-код расширенным
bool isExtendedKey(BYTE scan) noexcept {
return (scan == 0x4B || scan == 0x4D || scan == 0x48 || scan == 0x50 || scan == 0x2A);
}
// Функция эмуляции зажатия клавиши на 3 секунды
void simulateKeyHold(WORD vk, BYTE scan, HWND hwnd = NULL) {
cout << " -> Эмуляция зажатия клавиши на 3 секунды..." << endl;
DWORD extendedFlag = isExtendedKey(scan) ? KEYEVENTF_EXTENDEDKEY : 0;
INPUT input[2] = { 0 };
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = vk;
input[0].ki.wScan = scan;
input[0].ki.dwFlags = KEYEVENTF_SCANCODE | extendedFlag;
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = vk;
input[1].ki.wScan = scan;
input[1].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP | extendedFlag;
SendInput(1, &input[0], sizeof(INPUT)); // Нажатие
Sleep(3000); // Удержание на 3 секунды
SendInput(1, &input[1], sizeof(INPUT)); // Отпускание
cout << " -> Зажатие завершено" << endl;
}
// Функция поиска окна игры
HWND findGameWindow() {
const char* game_names[] = {
"AMAZING3 online",
"AMAZING3",
"Amazing3",
"Amazing 3",
"AMAZING ONLINE",
NULL
};
for (int i = 0; game_names[i] != NULL; i++) {
HWND hwnd = FindWindowA(NULL, game_names[i]);
if (hwnd) {
cout << " -> Найдено окно игры: " << game_names[i] << endl;
return hwnd;
}
}
HWND hwnd = FindWindowA("UnityWndClass", NULL);
if (hwnd) {
cout << " -> Найдено окно Unity игры" << endl;
return hwnd;
}
cout << " -> Окно игры не найдено" << endl;
return NULL;
}
// Улучшенная функция активации окна игры
void activateGameWindow(HWND hwnd) {
if (hwnd) {
cout << " -> Активирую окно игры..." << endl;
for (int attempt = 0; attempt < 3; attempt++) {
ShowWindow(hwnd, SW_RESTORE);
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetFocus(hwnd);
Sleep(200);
if (GetForegroundWindow() == hwnd) {
cout << " -> Фокус успешно установлен." << endl;
return;
}
cout << " [!] Попытка " << attempt + 1 << "/3: Не удалось установить фокус." << endl;
}
cout << " [!] Предупреждение: Не удалось установить фокус на окно игры после 3 попыток." << endl;
}
}
// Функция сравнения с порогом сходства
bool matchTemplateLowLevel(const Mat& screen, const Mat& template_img, double threshold = 0.3) noexcept {
if (template_img.empty() || screen.empty()) {
return false;
}
int result_cols = screen.cols - template_img.cols + 1;
int result_rows = screen.rows - template_img.rows + 1;
if (result_cols <= 0 || result_rows <= 0) {
return false;
}
Mat result;
try {
result.create(result_rows, result_cols, CV_32FC1);
matchTemplate(screen, template_img, result, TM_CCOEFF_NORMED);
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
cout << "Совпадение для " << template_img.cols << "x" << template_img.rows << ": maxVal = " << maxVal << " at (" << maxLoc.x << ", " << maxLoc.y << ")" << endl;
return maxVal > threshold;
}
catch (...) {
cout << "[-] Ошибка в matchTemplateLowLevel" << endl;
return false;
}
}
// Захват всего экрана
Mat captureFullScreen() {
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
HDC hScreenDC = GetDC(NULL);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, screenWidth, screenHeight);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, screenWidth, screenHeight, hScreenDC, 0, 0, SRCCOPY | CAPTUREBLT);
BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = screenWidth;
bmi.bmiHeader.biHeight = -screenHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
Mat screenMat(screenHeight, screenWidth, CV_8UC4);
GetDIBits(hScreenDC, hBitmap, 0, screenHeight, screenMat.data, &bmi, DIB_RGB_COLORS);
SelectObject(hMemoryDC, hOldBitmap);
DeleteObject(hBitmap);
DeleteDC(hMemoryDC);
ReleaseDC(NULL, hScreenDC);
Mat bgrScreen;
cvtColor(screenMat, bgrScreen, COLOR_BGRA2BGR);
return bgrScreen;
}
int main()
{
cout << "=== Автоматизация добычи руды ===" << endl;
cout << "Агрессивный режим нажатий клавиш" << endl;
cout << "=================================" << endl;
disableOpenCVParallel(); // Отключение параллельных бэкендов
// Загрузка шаблонов
vector<pair<Mat, string>> templates;
vector<string> filenames = {
"F.png", "H.png", "Q.png", "R.png", "V.png", "W.png",
"B.png", "D.png", "Space.png",
"Left Arrow.png", "Right Arrow.png", "Up Arrow.png", "Down Arrow.png",
"Left Shift.png"
};
int loaded_templates = 0;
cout << "Проверка загрузки шаблонов из: " << template_dir << endl;
for (const auto& fname : filenames) {
string path = template_dir + fname;
Mat img = imread(path, IMREAD_COLOR);
if (!img.empty()) {
templates.push_back({ img, fname });
cout << "[+] Загружен шаблон: " << fname << " (" << img.cols << "x" << img.rows << ")" << endl;
loaded_templates++;
}
else {
cout << "[-] Не удалось загрузить шаблон: " << fname << " (Проверьте путь: " << path << ")" << endl;
}
}
cout << "Всего загружено шаблонов: " << loaded_templates << endl;
cout << "=================================" << endl;
if (loaded_templates == 0) {
cout << "ОШИБКА: Не загружено ни одного шаблона! Убедитесь, что папка 'photo' с изображениями находится в директории исполняемого файла." << endl;
return -1;
}
// Найти окно игры один раз
HWND game_hwnd = findGameWindow();
if (game_hwnd) {
cout << "[i] Окно игры найдено, используем агрессивные методы" << endl;
}
else {
cout << "[!] Окно игры не найдено, используем только глобальные методы" << endl;
}
int matches_found = 0;
string last_key_pressed = "";
// Основной цикл
while (true) {
static int frame_counter = 0;
frame_counter++;
// Захват экрана
Mat screen = captureFullScreen();
if (screen.empty()) {
cout << "[-] Ошибка: Пустой захват экрана, пауза 1s" << endl;
Sleep(1000);
continue;
}
// Отладка каждые 100 кадров
if (frame_counter % 100 == 0) {
cout << "[i] Кадр " << frame_counter << ": " << screen.cols << "x" << screen.rows << endl;
}
// Поиск шаблонов
bool new_key_detected = false;
for (const auto& [template_img, filename] : templates) {
if (matchTemplateLowLevel(screen, template_img, 0.3)) {
size_t dot_pos = filename.find(".png");
if (dot_pos != string::npos) {
string key_name = filename.substr(0, dot_pos);
if (key_map.find(key_name) != key_map.end()) {
if (key_name != last_key_pressed) {
matches_found++;
cout << "[***] НАЙДЕНА КНОПКА " << matches_found << ": " << key_name
<< " (кадр " << frame_counter << ")" << endl;
activateGameWindow(game_hwnd);
auto key_pair = key_map.at(key_name);
for (int attempt = 1; attempt <= 3; attempt++) {
cout << " -> Попытка зажатия " << attempt << "/3..." << endl;
simulateKeyHold(key_pair.first, key_pair.second, game_hwnd);
Sleep(1000); // Задержка между попытками
// Проверка, не появилась ли новая кнопка
Mat new_screen = captureFullScreen();
bool other_key = false;
for (const auto& [new_template, new_filename] : templates) {
if (new_filename != filename && matchTemplateLowLevel(new_screen, new_template, 0.3)) {
other_key = true;
break;
}
}
if (other_key) {
cout << " -> Обнаружена новая кнопка, прерывание повторений." << endl;
break;
}
}
last_key_pressed = key_name;
new_key_detected = true;
Sleep(5000); // Задержка для обновления экрана
}
}
}
}
}
if (!new_key_detected) {
Sleep(300); // Задержка, если нет новых совпадений
}
}
return 0;
}