Skip to content

Instantly share code, notes, and snippets.

@nazarovsky
Created April 1, 2024 12:09
Show Gist options
  • Save nazarovsky/7797f5095821bba28d26f2d35e484c76 to your computer and use it in GitHub Desktop.
Save nazarovsky/7797f5095821bba28d26f2d35e484c76 to your computer and use it in GitHub Desktop.
# script is used to send keyboard strokes WASD (2 sec) to run in circles in LEGO FORTINTE
# after 40 times it presses F5 to eat some food (bind this to USE and select slot with FOOD in interface)
import ctypes
from ctypes import wintypes
import time
from time import sleep
import random
user32 = ctypes.WinDLL('user32', use_last_error=True)
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP = 0x0002
KEYEVENTF_UNICODE = 0x0004
KEYEVENTF_SCANCODE = 0x0008
MAPVK_VK_TO_VSC = 0
# msdn.microsoft.com/en-us/library/dd375731
VK_TAB = 0x09
VK_MENU = 0x12
VK_W = 0x57
VK_S = 0x53
VK_D = 0x44
VK_A = 0x41
VK_F5 = 0x74
# C struct definitions
wintypes.ULONG_PTR = wintypes.WPARAM
class MOUSEINPUT(ctypes.Structure):
_fields_ = (("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
class KEYBDINPUT(ctypes.Structure):
_fields_ = (("wVk", wintypes.WORD),
("wScan", wintypes.WORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", wintypes.ULONG_PTR))
def __init__(self, *args, **kwds):
super(KEYBDINPUT, self).__init__(*args, **kwds)
# some programs use the scan code even if KEYEVENTF_SCANCODE
# isn't set in dwFflags, so attempt to map the correct code.
if not self.dwFlags & KEYEVENTF_UNICODE:
self.wScan = user32.MapVirtualKeyExW(self.wVk,
MAPVK_VK_TO_VSC, 0)
class HARDWAREINPUT(ctypes.Structure):
_fields_ = (("uMsg", wintypes.DWORD),
("wParamL", wintypes.WORD),
("wParamH", wintypes.WORD))
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = (("ki", KEYBDINPUT),
("mi", MOUSEINPUT),
("hi", HARDWAREINPUT))
_anonymous_ = ("_input",)
_fields_ = (("type", wintypes.DWORD),
("_input", _INPUT))
LPINPUT = ctypes.POINTER(INPUT)
def _check_count(result, func, args):
if result == 0:
raise ctypes.WinError(ctypes.get_last_error())
return args
user32.SendInput.errcheck = _check_count
user32.SendInput.argtypes = (wintypes.UINT, # nInputs
LPINPUT, # pInputs
ctypes.c_int) # cbSize
# Functions
def PressKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
x = INPUT(type=INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=hexKeyCode,
dwFlags=KEYEVENTF_KEYUP))
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def AltTab():
"""Press Alt+Tab and hold Alt key for 2 seconds
in order to see the overlay.
"""
PressKey(VK_MENU) # Alt
PressKey(VK_TAB) # Tab
ReleaseKey(VK_TAB) # Tab~
sleep(2)
ReleaseKey(VK_MENU) # Alt~
def W(t):
PressKey(VK_W)
sleep(t)
ReleaseKey(VK_W)
def S(t):
PressKey(VK_S)
sleep(t)
ReleaseKey(VK_S)
def A(t):
PressKey(VK_A)
sleep(t)
ReleaseKey(VK_A)
def D(t):
PressKey(VK_D)
sleep(t)
ReleaseKey(VK_D)
def F5(t):
PressKey(VK_F5)
sleep(t)
ReleaseKey(VK_F5)
if __name__ == "__main__":
for j in range(100):
for i in range(40):
W(random.randint(2,2))
A(random.randint(2,2))
S(random.randint(2,2))
D(random.randint(2,2))
F5(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment