Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. import asyncio
  2. import win32api, win32con, win32gui
  3.  
  4. from urllib.parse import urljoin
  5.  
  6. from math import isnan
  7.  
  8. from beam_interactive import start, proto
  9. from requests import Session
  10.  
  11. from pymouse import PyMouse
  12.  
  13. URL = "https://beam.pro/api/v1/"
  14.  
  15. AUTHENTICATION = {
  16.     "username": "Muivinator",
  17.     "password": "Samurai12",
  18.     "code": "rt8ksm1t"  # Unnecessary if two-factor authentication is disabled.
  19. }
  20.  
  21. SESSION = Session()
  22.  
  23.  
  24. def _build(endpoint, *, url=URL):
  25.     """Build an address for an API endpoint."""
  26.     return urljoin(url, endpoint.lstrip('/'))
  27.  
  28.  
  29. def login(username, password, code='', *, session=SESSION):
  30.     """Log into Beam via the API."""
  31.     auth = dict(username=username, password=password, code=code)
  32.     return session.post(_build("/users/login"), data=auth).json()
  33.  
  34.  
  35. def join_interactive(channel, *, session=SESSION):
  36.     """Retrieve interactive connection information."""
  37.     return session.get(_build("/interactive/{channel}/robot").format(
  38.         channel=channel)).json()
  39.  
  40. MOUSE = PyMouse()
  41.  
  42. def getMousePosition():
  43.     return win32gui.GetCursorPos()
  44.  
  45. def setMousePosition(position):
  46.     win32api.SetCursorPos(position)
  47.  
  48. def on_error(error):
  49.     """Handle error packets."""
  50.     print("Oh no, there was an error!", error.message)
  51.  
  52. global down
  53. down = 0
  54.  
  55. def on_report(report):
  56.     """Handle report packets."""
  57.     global down
  58.  
  59.     # Tactile Mouse Click Control
  60.     for tactile in report.tactile:
  61.         if tactile.pressFrequency:
  62.             print("Tactile report received!", tactile, sep='\n')
  63.             mouse_x, mouse_y = getMousePosition()
  64.             setMousePosition((mouse_x, mouse_y))
  65.  
  66.             if down == 0:
  67.                 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, mouse_x, mouse_y, 0, 0)
  68.                 down = 1
  69.             else:
  70.                 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, mouse_x, mouse_y, 0, 0)
  71.                 down = 0
  72.  
  73.     # Joystick Mouse Movement Control
  74.     for joystick in report.joystick:
  75.         if not isnan(joystick.coordMean.x) and not isnan(joystick.coordMean.y):
  76.             print("Joystick report received!", joystick, sep='\n')
  77.             mouse_x, mouse_y = getMousePosition()
  78.             setMousePosition((
  79.                 round(joystick.coordMean.x*20) + mouse_x,
  80.                 round(joystick.coordMean.y*20) + mouse_y
  81.             ))
  82.  
  83.  
  84. @asyncio.coroutine
  85. def run():
  86.     """Run the interactive app."""
  87.  
  88.     # Authenticate with Beam and retrieve the channel id from the response.
  89.     channel_id = login(  # **AUTHENTICATION is a cleaner way of doing this.
  90.         AUTHENTICATION["username"],
  91.         AUTHENTICATION["password"],
  92.         AUTHENTICATION["code"]
  93.     )["channel"]["id"]
  94.  
  95.     # Get Interactive connection information.
  96.     data = join_interactive(channel_id)
  97.  
  98.     # Initialize a connection with Beam Interactive.
  99.     connection = yield from start(data["address"], channel_id, data["key"])
  100.  
  101.     # Handlers, to be called when Interacive packets are received.
  102.     handlers = {
  103.         proto.id.error: on_error,
  104.         proto.id.report: on_report
  105.     }
  106.  
  107.     # wait_message is a coroutine that will return True when it receives
  108.     # a complete packet from Beam Interactive, or False if we got disconnected.
  109.     while (yield from connection.wait_message()):
  110.  
  111.         # Decode the Interactive packet.
  112.         decoded, _ = connection.get_packet()
  113.         packet_id = proto.id.get_packet_id(decoded)
  114.  
  115.         # Handle the packet with the proper handler, if its type is known.
  116.         if packet_id in handlers:
  117.             handlers[packet_id](decoded)
  118.         elif decoded is None:
  119.             print("Unknown bytes were received. Uh oh!", packet_id)
  120.         else:
  121.             print("We got packet {} but didn't handle it!".format(packet_id))
  122.  
  123.     connection.close()
  124.  
  125.  
  126. loop = asyncio.get_event_loop()
  127.  
  128. try:
  129.     loop.run_until_complete(run())
  130. finally:
  131.     loop.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement