diff --git a/dance.py b/dance.py index 1b88422..b7c243a 100644 --- a/dance.py +++ b/dance.py @@ -29,6 +29,7 @@ class WsCommand(Enum): class PairingMethod(Enum): DEFAULT = 'default' FAST = 'fast' + STADIA = 'stadia' OLD = 'old' @@ -139,31 +140,29 @@ async def connect_joycon(app, ws, data): config_parser['joydance'] = config save_config(config_parser) - if pairing_method == PairingMethod.DEFAULT.value: + if pairing_method == PairingMethod.DEFAULT.value or pairing_method == PairingMethod.STADIA.value: app['joycons_info'][serial]['pairing_code'] = pairing_code + console_ip_addr = None else: app['joycons_info'][serial]['pairing_code'] = '' joycon = ButtonEventJoyCon(vendor_id, product_id, serial) - if pairing_method == PairingMethod.DEFAULT.value: - console_ip_addr = None - if pairing_method == PairingMethod.OLD.value: protocol_version = WsSubprotocolVersion.V1 else: protocol_version = WsSubprotocolVersion.V2 joydance = JoyDance( - joycon, - protocol_version=protocol_version, - pairing_code=pairing_code, - host_ip_addr=host_ip_addr, - console_ip_addr=console_ip_addr, - on_state_changed=on_joydance_state_changed, - accel_acquisition_freq_hz=config['accel_acquisition_freq_hz'], - accel_acquisition_latency=config['accel_acquisition_latency'], - accel_max_range=config['accel_max_range'], + joycon, + protocol_version=protocol_version, + pairing_code=pairing_code, + host_ip_addr=host_ip_addr, + console_ip_addr=console_ip_addr, + on_state_changed=on_joydance_state_changed, + accel_acquisition_freq_hz=config['accel_acquisition_freq_hz'], + accel_acquisition_latency=config['accel_acquisition_latency'], + accel_max_range=config['accel_max_range'], ) app['joydance_connections'][serial] = joydance @@ -234,7 +233,12 @@ def is_valid_ip_address(val): def is_valid_pairing_method(val): - return val in [PairingMethod.DEFAULT.value, PairingMethod.FAST.value, PairingMethod.OLD.value] + return val in [ + PairingMethod.DEFAULT.value, + PairingMethod.FAST.value, + PairingMethod.STADIA.value, + PairingMethod.OLD.value, + ] def get_host_ip(): diff --git a/joydance/__init__.py b/joydance/__init__.py index 0164fe5..3c45a41 100644 --- a/joydance/__init__.py +++ b/joydance/__init__.py @@ -5,6 +5,7 @@ import socket import ssl import time from enum import Enum +from urllib.parse import urlparse import aiohttp import websockets @@ -56,6 +57,7 @@ class JoyDance: self.host_ip_addr = host_ip_addr self.console_ip_addr = console_ip_addr self.host_port = self.get_random_port() + self.tls_certificate = None self.accel_acquisition_freq_hz = accel_acquisition_freq_hz self.accel_acquisition_latency = accel_acquisition_latency @@ -114,7 +116,17 @@ class JoyDance: raise Exception('ERROR: Invalid pairing code!') json_body = await resp.json() - self.pairing_url = json_body['pairingUrl'].replace('https://', 'wss://') + 'smartphone' + import pprint + pprint.pprint(json_body) + + self.pairing_url = json_body['pairingUrl'].replace('https://', 'wss://') + if not self.pairing_url.endswith('/'): + self.pairing_url += '/' + self.pairing_url += 'smartphone' + + self.tls_certificate = json_body['tlsCertificate'] + + print(self.pairing_url) self.requires_punch_pairing = json_body.get('requiresPunchPairing', False) async def send_initiate_punch_pairing(self): @@ -205,7 +217,7 @@ class JoyDance: await self.send_message('JD_CancelKeyboard_PhoneCommandData') elif __class == 'JD_PhoneUiSetupData': self.is_input_allowed = True - shortcuts = set() + self.available_shortcuts = set() if message.get('setupData', {}).get('gameplaySetup', {}).get('pauseSlider', {}): self.available_shortcuts.add(Command.PAUSE) @@ -274,7 +286,7 @@ class JoyDance: delta_time += (end - start) * 1000 async def send_command(self): - ''' Capture Joycon's input and send to console. Only works on procol v2 ''' + ''' Capture Joycon's input and send to console. Only works on protocol v2 ''' if self.protocol_version == WsSubprotocolVersion.V1: return @@ -351,12 +363,15 @@ class JoyDance: await asyncio.sleep(0.01) except Exception as e: print(e) + import traceback + traceback.print_exc() await self.disconnect() async def connect_ws(self): + server_hostname = None + if self.protocol_version == WsSubprotocolVersion.V1: ssl_context = None - server_hostname = None else: ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.set_ciphers('ALL') @@ -364,7 +379,16 @@ class JoyDance: ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE - server_hostname = self.console_conn.getpeername()[0] if self.console_conn else None + if self.tls_certificate: + ssl_context.load_verify_locations(cadata=self.tls_certificate) + + if '192.168' in self.pairing_url: + if self.console_conn: + server_hostname = self.console_conn.getpeername()[0] + else: + # Stadia + tmp = urlparse(self.pairing_url) + server_hostname = tmp.hostname subprotocol = WS_SUBPROTOCOLS[self.protocol_version.value] try: @@ -387,7 +411,8 @@ class JoyDance: except websockets.ConnectionClosed: await self.on_state_changed(self.joycon.serial, PairingState.ERROR_CONSOLE_CONNECTION) await self.disconnect(close_ws=False) - except Exception: + except Exception as e: + print(e) await self.on_state_changed(self.joycon.serial, PairingState.ERROR_CONSOLE_CONNECTION) await self.disconnect(close_ws=False) diff --git a/joydance/constants.py b/joydance/constants.py index fdcb3e0..26e12bd 100644 --- a/joydance/constants.py +++ b/joydance/constants.py @@ -129,8 +129,8 @@ SHORTCUT_MAPPING = { } # Same with Joy-Con (L) -SHORTCUT_MAPPING[JoyConButton.UP] = JoyConButton.X -SHORTCUT_MAPPING[JoyConButton.LEFT] = JoyConButton.Y -SHORTCUT_MAPPING[JoyConButton.MINUS] = JoyConButton.PLUS -SHORTCUT_MAPPING[JoyConButton.L] = JoyConButton.R -SHORTCUT_MAPPING[JoyConButton.ZL] = JoyConButton.ZR +SHORTCUT_MAPPING[JoyConButton.UP] = SHORTCUT_MAPPING[JoyConButton.X] +SHORTCUT_MAPPING[JoyConButton.LEFT] = SHORTCUT_MAPPING[JoyConButton.Y] +SHORTCUT_MAPPING[JoyConButton.MINUS] = SHORTCUT_MAPPING[JoyConButton.PLUS] +SHORTCUT_MAPPING[JoyConButton.L] = SHORTCUT_MAPPING[JoyConButton.R] +SHORTCUT_MAPPING[JoyConButton.ZL] = SHORTCUT_MAPPING[JoyConButton.ZR] diff --git a/static/js/app.js b/static/js/app.js index d4db99d..f0b4d14 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -18,6 +18,7 @@ const BATTERY_LEVEL = { const PairingMethod = { DEFAULT: 'default', FAST: 'fast', + STADIA: 'stadia', OLD: 'old', } @@ -85,8 +86,9 @@ class PairingMethodPicker extends Component { + ${(pairing_method == PairingMethod.STADIA) && html` + `} - ${(pairing_method != PairingMethod.DEFAULT || !state.lock_host) && html` + ${(pairing_method == PairingMethod.DEFAULT && state.lock_host) && html` + + `} + + ${([PairingMethod.FAST, PairingMethod.OLD].indexOf(pairing_method) > -1 || (pairing_method == PairingMethod.DEFAULT && !state.lock_host)) && html` `} @@ -183,12 +189,13 @@ class PairingCode extends Component { } render(props, state) { + const pairing_method = props.pairing_method return html` - ${props.pairing_method == PairingMethod.DEFAULT && html` + ${[PairingMethod.DEFAULT, PairingMethod.STADIA].indexOf(pairing_method) > -1 && html` !/[0-9]/.test(e.key) && e.preventDefault()} onChange=${this.onChange} /> `} - ${props.pairing_method != PairingMethod.DEFAULT && html` + ${[PairingMethod.DEFAULT, PairingMethod.STADIA].indexOf(pairing_method) == -1 && html` `} `