Задать вопрос
mamonblch
@mamonblch
Python, Clang

[Python + pywin32] Как эмулировать движения курсора, клики кнопками мыши и нажатия клавиш клавиатуры в игре WoT?

Всем привет! Возможно ответ на вопрос окажется до неприличного простым, а сам вопрос глупым, однако я с этим вожусь уже 4-ю неделю, и на данный момент прямых ответов не нашел.
Есть игра: WorldOfTanks (в простонародье и СНГ "Мир танков" с завязкой на Lesta GameCenter), нужно 3-мя методами: sendMove, sendClick, sendKey - реализовать движения курсора, клики кнопок мыши и нажатия клавиш клавиатуры, соответственно, внутри окна игры, используя Python + pywin32 (т.е. не затрагивая основной курсор машины).
Я пытался реализовать такой функционал через win32gui и win32api с методами SendMessage и PostMessage, заранее активируя окно и задавая ему общий фокус, передавая фокус клавиатурой и мышью (SetForegroundWindow, SetFocus, SetCursor) - ничего не работает. Хотя с другими программами такой подход работает "как по маслу".
Сейчас методы выглядят так:
# Подключение библиотек
import win32api
import win32gui
import win32con




# Эмуляция движения курсора
def sendMove(hwnd: int, pos: tuple) -> None:

    # Преобразование к LONG
    lParam: int = win32api.MAKELONG(pos[0], pos[1])

    # Реализация движения курсора
    win32gui.PostMessage(hwnd, win32con.WM_MOUSEMOVE, 0, lParam)



# Эмуляция клика внутри указанного окна
def sendClick(hwnd: int, pos: tuple, button: int) -> None:

    # Преобразование к LONG
    lParam: int = win32api.MAKELONG(pos[0], pos[1])

    # Реализация клика
    win32gui.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, button, lParam)
    win32gui.PostMessage(hwnd, win32con.WM_LBUTTONUP, button, lParam)



# Эмуляция нажатия кнопки клавиатуры
def sendKey(hwnd: int, key: int) -> None:

    # Реализация нажатия кнопки
    win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, key, 0)
    win32gui.PostMessage(hwnd, win32con.WM_KEYUP, key, 0)




# "Начало начал"
if __name__ == "__main__":

    # Дескриптор окна
    hwnd: int = 3870292

    # Пресет "В бой"
    sendMove(hwnd, (500, 20))
    sendClick(hwnd, (500, 20), win32con.VK_LBUTTON)

    # Пресет "Закрыть игру"
    sendKey(hwnd, win32con.VK_ESCAPE)
    sendMove(hwnd, (300, 400))
    sendClick(hwnd, (300, 400), win32con.VK_LBUTTON)


Вывод Spy++ при "естественных" действиях:
679a4330916a1090360244.png

Вывод Spy++ при эмуляции действий:
679a429e36481462648310.jpeg

Тут либо я чего-то не понимаю, либо я чего-то не понимаю. В любом случае, с другими играми и программами все эти методы работают, но вот именно с этой - нет.
И такие же артефакты "невыполнения" случаются, когда используешь эти методы на программах, запущенных в "Sandboxie". Тот же AHK прекрасно выполняет данную задачу, но он использует основной курсор машины, и по определению не подходит, т.к. необходимо одновременно работать с множеством окон.
Не нужно говорить: "Это невозможно! Реализация только через виртуалки!" - нет, у нас есть рабочий софт, реализующий клик по координатам внутри окна игры, обернутого в Sandboxie. Но он собран в .exe и написан человеком давно ушедшим из проекта.
Буду рад любой помощи! Заранее спасибо!
  • Вопрос задан
  • 69 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
VoidVolker
@VoidVolker
Dark side eye. А у нас печеньки! А у вас?
Игры для работы с пользовательским вводом очень часто работают через графические API DirectX/OpenGL/Vulkan и прочее, при этом данные от системных вызовов типа оконного цикла, SendInput и прочее не используются. Сюрприз! В этом случае остаётся только три варианта:
  • Разбираться с этими API и выяснять как ему подсунуть нужные данные (не копал в эту сторону - так что без понятия возможно ли это или только ломать)
  • Установить свой драйвер пользовательского ввода в ring0 (ядро ОС)
  • Использовать внешнее устройство, которое эмулирует физически клавиатуру и мышь и управляется через USB драйвером или прошивкой

А вот эмуляция пользовательского ввода в нескольких окнах возможна только с помощью виртуализации. Ибо все современные ОС поддерживают только одну клавиатуру и мышку для одного пользователя (всякие специфические утилиты/случаи не рассматриваем). SendMessage/PostMessage работает только с приложениями, которые получают пользовательский ввод через оконный цикл.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
от 200 000 до 300 000 ₽
Greenway Global Новосибирск
от 150 000 ₽
Akronix Санкт-Петербург
от 150 000 до 200 000 ₽
30 янв. 2025, в 16:41
3000 руб./за проект
30 янв. 2025, в 16:19
19000 руб./за проект