async def on_message_received(self, message: dict) -> None: cmd, args = message.get('command'), message.get('args', []) if cmd == 'ProcessNatPacket': self.process_nat_packet(Address.from_string(args[0]), args[1]) elif cmd == 'InitiateTest': port = args[0] assert 1024 < port < 65535 asyncio.ensure_future(self.initiate_test(port)) elif cmd == 'RelayAddress': self.relay_address = Address(*args[0])
async def client_connected(self, stream_reader, stream_writer): self._logger.debug("%s: Client connected", self) protocol = QDataStreamProtocol(stream_reader, stream_writer) connection = self._connection_factory() try: await connection.on_connection_made( protocol, Address(*stream_writer.get_extra_info('peername'))) self.connections[connection] = protocol server.stats.gauge('user.agents.None', 1, delta=True) while True: message = await protocol.read_message() with server.stats.timer('connection.on_message_received'): await connection.on_message_received(message) with server.stats.timer('servercontext.drain'): await asyncio.sleep(0) await connection.drain() except ConnectionResetError: pass except ConnectionAbortedError: pass except TimeoutError: pass except asyncio.IncompleteReadError as ex: if not stream_reader.at_eof(): self._logger.exception(ex) except Exception as ex: self._logger.exception(ex) finally: del self.connections[connection] server.stats.gauge('user.agents.{}'.format(connection.user_agent), -1, delta=True) protocol.writer.close() await connection.on_connection_lost()
def command_game_join(self, message): """ We are going to join a game. """ assert isinstance(self.player, Player) if not self.able_to_launch_game: raise ClientError("You are already in a game or haven't run the connectivity test yet") if self.connectivity.result.state == ConnectivityState.STUN: self.connectivity.relay_address = Address(*message['relay_address']) uuid = message['uid'] port = message['gameport'] password = message.get('password', None) self._logger.debug("joining: %d:%d with pw: %s", uuid, port, password) try: game = self.game_service[uuid] if not game or game.state != GameState.LOBBY: self._logger.debug("Game not in lobby state: %s", game) self.sendJSON(dict(command="notice", style="info", text="The game you are trying to join is not ready.")) return if game.password != password: self.sendJSON(dict(command="notice", style="info", text="Bad password (it's case sensitive)")) return self.launch_game(game, port, False) except KeyError: self.sendJSON(dict(command="notice", style="info", text="The host has left the game"))
def lobbyconnection( event_loop, database, mock_protocol, mock_games, mock_players, mock_player, mock_geoip, mock_nts_client ): lc = LobbyConnection( database=database, geoip=mock_geoip, game_service=mock_games, players=mock_players, nts_client=mock_nts_client, ladder_service=asynctest.create_autospec(LadderService) ) lc.player = mock_player lc.protocol = mock_protocol lc.player_service.fetch_player_data = CoroutineMock() lc.peer_address = Address("127.0.0.1", 1234) lc._authenticated = True return lc
async def determine_connectivity(self): """ Determine connectivity of peer :return: Connectivity(addr, ConnectivityState) """ public = await self.test_public() if public: return ConnectivityResult(addr=Address(*self.remote_addr), state=ConnectivityState.PUBLIC) addr = await self.test_stun() if addr: return ConnectivityResult(addr=Address(*addr), state=ConnectivityState.STUN) else: return ConnectivityResult(addr=None, state=ConnectivityState.BLOCKED)
def command_game_matchmaking(self, message): mod = message.get('mod', 'ladder1v1') port = message.get('gameport', None) state = message['state'] if not self.able_to_launch_game: raise ClientError( "You are already in a game or are otherwise having connection problems. Please report this issue using HELP -> Tech support." ) if state == "stop": if self.search: self._logger.info("%s stopped searching for ladder: %s", self.player, self.search) self.search.cancel() return if self.connectivity.result.state == ConnectivityState.STUN: self.connectivity.relay_address = Address( *message['relay_address']) if port: self.player.game_port = port with (yield from db.db_pool) as conn: cursor = yield from conn.cursor() yield from cursor.execute( "SELECT id FROM matchmaker_ban WHERE `userid` = %s", (self.player.id)) if cursor.rowcount > 0: self.sendJSON( dict( command="notice", style="error", text= "You are banned from the matchmaker. Contact an admin to have the reason." )) return if mod == "ladder1v1": if state == "start": if self.search: self.search.cancel() assert self.player is not None self.search = Search(self.player) self.player.faction = message['faction'] self.game_service.ladder_service.inform_player(self.player) self._logger.info("%s is searching for ladder: %s", self.player, self.search) asyncio.ensure_future( self.player_service.ladder_queue.search( self.player, search=self.search))
def lobbyconnection(loop, mock_protocol, mock_games, mock_players, mock_player, mock_geoip): lc = LobbyConnection(geoip=mock_geoip, games=mock_games, players=mock_players, nts_client=mock_nts_client, ladder_service=mock.create_autospec(LadderService)) lc.player = mock_player lc.protocol = mock_protocol lc.player_service.get_permission_group.return_value = 0 lc.player_service.fetch_player_data = CoroMock() lc.peer_address = Address('127.0.0.1', 1234) return lc
def command_game_host(self, message): if not self.able_to_launch_game: raise ClientError( "You are already in a game or haven't run the connectivity test yet" ) if self.connectivity.result.state == ConnectivityState.STUN: self.connectivity.relay_address = Address( *message['relay_address']) assert isinstance(self.player, Player) title = cgi.escape(message.get('title', '')) port = message.get('gameport') visibility = VisibilityState.from_string(message.get('visibility')) if not isinstance(visibility, VisibilityState): # Protocol violation. self.abort("%s sent a nonsense visibility code: %s" % (self.player.login, message.get('visibility'))) return mod = message.get('mod') try: title.encode('ascii') except UnicodeEncodeError: self.sendJSON( dict(command="notice", style="error", text="Non-ascii characters in game name detected.")) return mapname = message.get('mapname') password = message.get('password') game = self.game_service.create_game( **{ 'visibility': visibility, 'game_mode': mod.lower(), 'host': self.player, 'name': title if title else self.player.login, 'mapname': mapname, 'password': password }) self.launch_game(game, port, True) server.stats.incr('game.hosted')
def relay_address(self, val): addr = Address(*val) host = ipaddress.ip_address(addr.host) assert not host.is_loopback and not host.is_private self._relay_addr = addr
def test_address_from_string_with_scheme(): address = Address.from_string("http://localhost:4000") assert address == Address("http://localhost", 4000)
def test_address_from_string(): address = Address.from_string("localhost:4000") assert address == Address("localhost", 4000)