interaction.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import sys
  2. from os.path import dirname, join
  3. sys.path.insert(0, join(dirname(__file__), 'python-xlib'))
  4. import time
  5. from random import randint
  6. from Xlib import display, X, XK, ext
  7. WINDOW_WIDTH = 1600
  8. WINDOW_HEIGHT = 900
  9. BOARD_X = 367
  10. BOARD_Y = 129
  11. BOARD_WIDTH = 420
  12. BOARD_HEIGHT = 638
  13. KEY_DELAY = 14 # milliseconds
  14. disp = display.Display()
  15. def find_window(name):
  16. def traverse(window):
  17. if window.get_wm_name() == name:
  18. return window
  19. for child in window.query_tree().children:
  20. win = traverse(child)
  21. if win:
  22. return win
  23. return traverse(disp.screen().root)
  24. def get_exapunks_window():
  25. win = find_window('EXAPUNKS')
  26. assert win, 'EXAPUNKS window not found'
  27. geo = win.get_geometry()
  28. assert geo.width == WINDOW_WIDTH
  29. assert geo.height == WINDOW_HEIGHT
  30. return win
  31. def focus_window(window):
  32. window.set_input_focus(X.RevertToNone, X.CurrentTime)
  33. window.raise_window()
  34. disp.sync()
  35. def screenshot_board(window):
  36. im = window.get_image(BOARD_X, BOARD_Y, BOARD_WIDTH, BOARD_HEIGHT,
  37. X.ZPixmap, 0xffffffff)
  38. return BoardImage(im.data)
  39. def press_keys(window, keys):
  40. assert disp.has_extension('XTEST')
  41. for key in keys:
  42. keysym = XK.string_to_keysym(key)
  43. keycode = disp.keysym_to_keycode(keysym)
  44. ext.xtest.fake_input(disp, X.KeyPress, keycode)
  45. disp.sync()
  46. time.sleep(KEY_DELAY / 1000)
  47. ext.xtest.fake_input(disp, X.KeyRelease, keycode)
  48. disp.sync()
  49. time.sleep(KEY_DELAY / 1000)
  50. def rgb2hsv(r, g, b):
  51. r /= 255
  52. g /= 255
  53. b /= 255
  54. cmax = max(r, g, b)
  55. cmin = min(r, g, b)
  56. diff = cmax - cmin
  57. if cmax == cmin:
  58. h = 0
  59. elif cmax == r:
  60. h = (60 * ((g - b) / diff) + 360) % 360
  61. elif cmax == g:
  62. h = (60 * ((b - r) / diff) + 120) % 360
  63. elif cmax == b:
  64. h = (60 * ((r - g) / diff) + 240) % 360
  65. h = int(h * 256 / 360)
  66. s = 0 if cmax == 0 else int(diff * 256 / cmax)
  67. v = int(cmax * 256)
  68. return h, s, v
  69. class BoardImage:
  70. def __init__(self, data):
  71. self.data = data
  72. def getpixel(self, xy):
  73. x, y = xy
  74. i = (y * BOARD_WIDTH + x) * 4
  75. b, g, r = self.data[i:i + 3]
  76. return rgb2hsv(r, g, b)
  77. if __name__ == '__main__':
  78. win = get_exapunks_window()
  79. win.raise_window()
  80. old_focus = disp.get_input_focus()
  81. disp.set_input_focus(win, X.RevertToParent, X.CurrentTime)
  82. #press_keys(win, 'aaaj')
  83. #while True:
  84. # press_keys(win, 'djkj' * 7)
  85. # press_keys(win, 'ajkj' * 7)
  86. while True:
  87. press_keys(win, 'adjk'[randint(0, 3)])
  88. disp.set_input_focus(old_focus.focus, X.RevertToParent, X.CurrentTime)
  89. disp.sync()