Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
Пробовал написать скрипт для автобега в DayZ, персонаж вроде бежит, но есть проблемы. Если сворачиваю окно игры, персонаж перестает бежать, а в других приложениях начинается какой-то хаос (скорее всего, нажатия W и SHIFT применяются ко всем окнам). Как можно переписать код, чтобы симуляция клавиш работала исключительно в окне игры и не трогала другие программы?
Буду благодарен за помощь
C++:
#include <windows.h>
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<bool> is_running{ true };
void PressKey(HWND game_hwnd, DWORD vkey) {
if (GetForegroundWindow() == game_hwnd) {
const auto key_scancode = MapVirtualKeyA(vkey, MAPVK_VK_TO_VSC);
INPUT input{};
input.type = INPUT_KEYBOARD;
input.ki.wScan = static_cast<WORD>(key_scancode);
input.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &input, sizeof(INPUT));
}
}
void AutoRun(HWND game_hwnd) {
while (is_running) {
PressKey(game_hwnd, 0x57);
PressKey(game_hwnd, VK_SHIFT);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
int main() {
HWND game_hwnd = FindWindow(nullptr, L"DayZ");
if (!game_hwnd) {
std::cout << "Окно игры DayZ не найдено!" << std::endl;
return 1;
}
std::cout << "Окно игры найдено!" << std::endl;
std::cout << "Зажимаем W и Shift для автобега. Нажмите F10, чтобы остановить!" << std::endl;
std::thread run_thread(AutoRun, game_hwnd);
while (true) {
if (GetAsyncKeyState(VK_F10) & 0x8000) { // F10 stop
std::cout << "Автобег остановлен!" << std::endl;
is_running = false;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if (run_thread.joinable()) {
run_thread.join();
}
return 0;
}
Чтобы симуляция клавиш работала исключительно в окне игры и не влияла на другие программы, нужно убедиться, что ввод клавиш отправляется только в активное окно игры. В текущем коде вы проверяете, является ли окно игры активным, но не ограничиваете ввод только этим окном.
Для решения проблемы можно использовать функцию PostMessage или SendMessage, которые отправляют сообщения напрямую в окно игры, вместо использования SendInput, который отправляет ввод на уровне системы.
Вот переписанный код, который использует PostMessage для отправки клавишных сообщений только в окно игры:
C++:
#include <windows.h>
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<bool> is_running{ true };
void PressKey(HWND hwnd, WPARAM key) {
if (hwnd) {
PostMessage(hwnd, WM_KEYDOWN, key, 0);
PostMessage(hwnd, WM_KEYUP, key, 0);
}
}
void AutoRun(HWND Dayz_hwnd) {
while (is_running) {
PressKey(Dayz_hwnd, 'W');
PressKey(Dayz_hwnd, VK_SHIFT);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
int main() {
HWND Dayz_hwnd = FindWindow(nullptr, L"DayZ");
if (!Dayz_hwnd) {
std::cout << "Окно игры DayZ не найдено!" << std::endl;
return 1;
}
std::cout << "Окно игры найдено!" << std::endl;
std::cout << "Зажимаем W и Shift для автобега. Нажмите F10, чтобы остановить!" << std::endl;
std::thread run_thread(AutoRun, Dayz_hwnd);
while (true) {
if (GetAsyncKeyState(VK_F10) & 0x8000) { // F10 stop
std::cout << "Автобег остановлен!" << std::endl;
is_running = false;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if (run_thread.joinable()) {
run_thread.join();
}
return 0;
}
Объяснение изменений:
1. Использование PostMessage: Вместо SendInput, который отправляет ввод на уровне системы, используется PostMessage, который отправляет сообщения напрямую в окно игры. Это гарантирует, что ввод не будет влиять на другие программы.
2. Проверка окна игры: В функции PressKey проверяется, существует ли окно игры (hwnd). Если окно существует, отправляются сообщения WM_KEYDOWN и WM_KEYUP для симуляции нажатия и отпускания клавиши.
3. Упрощение логики: Логика нажатия клавиш упрощена, так как теперь не нужно проверять, активно ли окно игры, потому что PostMessage отправляет сообщения только в указанное окно.
Этот код должен работать корректно, даже если окно игры свернуто, и не будет влиять на другие программы. Однако, если игра не обрабатывает сообщения WM_KEYDOWN и WM_KEYUP напрямую, может потребоваться дополнительная настройка.