Вопрос Авто бег в Dayz

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
31 Июл 2024
Сообщения
83
Реакции
7
/del
 
Последнее редактирование:
Пробовал написать скрипт для автобега в DayZ, персонаж вроде бежит, но есть проблемы. Если сворачиваю окно игры, персонаж перестает бежать, а в других приложениях начинается какой-то хаос (скорее всего, нажатия W и SHIFT применяются ко всем окнам). Как можно переписать код, чтобы симуляция клавиш работала исключительно в окне игры и не трогала другие программы?

Буду благодарен за помощь

C++:
Expand Collapse Copy
#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;
}
твой код не работает именно на игру если хочешь добавь просто проверку что бы работало только в окне Dayz
 
Код с гпт

Чтобы симуляция клавиш работала исключительно в окне игры и не влияла на другие программы, нужно убедиться, что ввод клавиш отправляется только в активное окно игры. В текущем коде вы проверяете, является ли окно игры активным, но не ограничиваете ввод только этим окном.

Для решения проблемы можно использовать функцию PostMessage или SendMessage, которые отправляют сообщения напрямую в окно игры, вместо использования SendInput, который отправляет ввод на уровне системы.

Вот переписанный код, который использует PostMessage для отправки клавишных сообщений только в окно игры:

C++:
Expand Collapse Copy
#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 напрямую, может потребоваться дополнительная настройка.
 
Назад
Сверху Снизу