import time from random import randint from Xlib import display, X, XK, ext from PIL import Image WINDOW_WIDTH = 1600 WINDOW_HEIGHT = 900 BOARD_X = 367 BOARD_Y = 129 BOARD_WIDTH = 420 BOARD_HEIGHT = 638 KEY_DELAY = 14 # milliseconds disp = display.Display() def find_window(name): def traverse(window): if window.get_wm_name() == name: return window for child in window.query_tree().children: win = traverse(child) if win: return win return traverse(disp.screen().root) def get_exapunks_window(): win = find_window('EXAPUNKS') assert win, 'EXAPUNKS window not found' geo = win.get_geometry() assert geo.width == WINDOW_WIDTH assert geo.height == WINDOW_HEIGHT return win def focus_window(window): window.set_input_focus(X.RevertToNone, X.CurrentTime) window.raise_window() disp.sync() def screenshot_board(window): raw = window.get_image(BOARD_X, BOARD_Y, BOARD_WIDTH, BOARD_HEIGHT, X.ZPixmap, 0xffffffff) dim = BOARD_WIDTH, BOARD_HEIGHT im = Image.frombytes('RGB', dim, raw.data, 'raw', 'BGRX') return im.convert('HSV') def press_keys(window, keys): assert disp.has_extension('XTEST') for key in keys: keysym = XK.string_to_keysym(key) keycode = disp.keysym_to_keycode(keysym) ext.xtest.fake_input(disp, X.KeyPress, keycode) disp.sync() time.sleep(KEY_DELAY / 1000) ext.xtest.fake_input(disp, X.KeyRelease, keycode) disp.sync() time.sleep(KEY_DELAY / 1000) def listen_keys(handlers): from pynput import keyboard def handler(keycode): key = str(keycode).replace('\'', '') if key in handlers: handlers[key]() keyboard.Listener(on_release=handler).start() if __name__ == '__main__': win = get_exapunks_window() win.raise_window() old_focus = disp.get_input_focus() disp.set_input_focus(win, X.RevertToParent, X.CurrentTime) #press_keys(win, 'aaaj') #while True: # press_keys(win, 'djkj' * 7) # press_keys(win, 'ajkj' * 7) while True: press_keys(win, 'adjk'[randint(0, 3)]) disp.set_input_focus(old_focus.focus, X.RevertToParent, X.CurrentTime) disp.sync()