Всем привет! Возможно ответ на вопрос окажется до неприличного простым, а сам вопрос глупым, однако я с этим вожусь уже 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++ при "естественных" действиях:
Вывод Spy++ при эмуляции действий:
Тут либо я чего-то не понимаю, либо я чего-то не понимаю. В любом случае, с другими играми и программами все эти методы работают, но вот именно с этой - нет.
И такие же артефакты "невыполнения" случаются, когда используешь эти методы на программах, запущенных в "Sandboxie". Тот же AHK прекрасно выполняет данную задачу, но он использует основной курсор машины, и по определению не подходит, т.к. необходимо одновременно работать с множеством окон.
Не нужно говорить: "Это невозможно! Реализация только через виртуалки!" - нет, у нас есть рабочий софт, реализующий клик по координатам внутри окна игры, обернутого в Sandboxie. Но он собран в .exe и написан человеком давно ушедшим из проекта.
Буду рад любой помощи! Заранее спасибо!