예제 #1
0
 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])
예제 #2
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()
예제 #3
0
    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"))
예제 #4
0
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
예제 #5
0
    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)
예제 #6
0
 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])
예제 #7
0
    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))
예제 #8
0
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
예제 #9
0
    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')
예제 #10
0
 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
예제 #11
0
def test_address_from_string_with_scheme():
    address = Address.from_string("http://localhost:4000")

    assert address == Address("http://localhost", 4000)
예제 #12
0
def test_address_from_string():
    address = Address.from_string("localhost:4000")

    assert address == Address("localhost", 4000)