Simulate Python keypresses for controlling a game Simulate Python keypresses for controlling a game python python

Simulate Python keypresses for controlling a game


I just had the same problem trying to simulate keypresses in Half-Life 2. As Robin said, the solution is to use ScanCodes instead of VKs.

I edited your last code example such that it uses ScanCodes. I tried it with Half-Life 2 and it works just fine:

import ctypesimport timeSendInput = ctypes.windll.user32.SendInput# C struct redefinitions PUL = ctypes.POINTER(ctypes.c_ulong)class KeyBdInput(ctypes.Structure):    _fields_ = [("wVk", ctypes.c_ushort),                ("wScan", ctypes.c_ushort),                ("dwFlags", ctypes.c_ulong),                ("time", ctypes.c_ulong),                ("dwExtraInfo", PUL)]class HardwareInput(ctypes.Structure):    _fields_ = [("uMsg", ctypes.c_ulong),                ("wParamL", ctypes.c_short),                ("wParamH", ctypes.c_ushort)]class MouseInput(ctypes.Structure):    _fields_ = [("dx", ctypes.c_long),                ("dy", ctypes.c_long),                ("mouseData", ctypes.c_ulong),                ("dwFlags", ctypes.c_ulong),                ("time",ctypes.c_ulong),                ("dwExtraInfo", PUL)]class Input_I(ctypes.Union):    _fields_ = [("ki", KeyBdInput),                 ("mi", MouseInput),                 ("hi", HardwareInput)]class Input(ctypes.Structure):    _fields_ = [("type", ctypes.c_ulong),                ("ii", Input_I)]# Actuals Functionsdef PressKey(hexKeyCode):    extra = ctypes.c_ulong(0)    ii_ = Input_I()    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )    x = Input( ctypes.c_ulong(1), ii_ )    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))def ReleaseKey(hexKeyCode):    extra = ctypes.c_ulong(0)    ii_ = Input_I()    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )    x = Input( ctypes.c_ulong(1), ii_ )    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))# directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.htmlwhile (True):    PressKey(0x11)    time.sleep(1)    ReleaseKey(0x11)    time.sleep(1)


It's likely that the game is using DirectInput devices.

So, the game is expecting DirectInput key presses. According to the last post of this forum thread, DirectInput responds to ScanCodes, not VKs. You can try sending DirectInput key presses using this tool. The dev also supplies the source and a detailed explanation.

If this works, you could just try sending appropriate ScanCodes instead of VKs (list of scancodes).

There's also an older project called DirectPython that allows you to interface with DirectX/DirectInput.