Exemplo n.º 1
0
async def test_game_results(game: Game, players):
    game.state = GameState.LOBBY
    host_id = players.hosting.id
    join_id = players.joining.id
    add_connected_players(game, [players.hosting, players.joining])
    game.set_player_option(players.hosting.id, "Team", 1)
    game.set_player_option(players.joining.id, "Team", 1)

    await game.launch()
    await game.add_result(host_id, 0, "victory", 1)
    await game.add_result(join_id, 1, "defeat", 0)

    game_results = await game.resolve_game_results()
    result_dict = game_results.to_dict()

    assert result_dict["validity"] == "VALID"
    assert result_dict["rating_type"] == "global"
    assert len(result_dict["teams"]) == 2

    for team in result_dict["teams"]:
        assert team["outcome"] == ("VICTORY" if team["player_ids"]
                                   == [host_id] else "DEFEAT")
    assert result_dict["game_id"] == game.id
    assert result_dict["map_id"] == game.map_id
    assert result_dict["featured_mod"] == "faf"
    assert result_dict["sim_mod_ids"] == []
Exemplo n.º 2
0
async def test_disconnect_all_peers(game_connection: GameConnection,
                                    real_game: Game, players):
    real_game.state = GameState.LOBBY
    game_connection.player = players.hosting
    game_connection.game = real_game

    disconnect_done = mock.Mock()

    async def fake_send_dc(player_id):
        await asyncio.sleep(1)  # Take some time
        disconnect_done.success()
        return "OK"

    # Set up a peer that will disconnect without error
    ok_disconnect = asynctest.create_autospec(GameConnection)
    ok_disconnect.state = GameConnectionState.CONNECTED_TO_HOST
    ok_disconnect.send_DisconnectFromPeer = fake_send_dc

    # Set up a peer that will throw an exception
    fail_disconnect = asynctest.create_autospec(GameConnection)
    fail_disconnect.send_DisconnectFromPeer.return_value = Exception(
        "Test exception")
    fail_disconnect.state = GameConnectionState.CONNECTED_TO_HOST

    # Add the peers to the game
    real_game.add_game_connection(fail_disconnect)
    real_game.add_game_connection(ok_disconnect)

    await game_connection.disconnect_all_peers()

    disconnect_done.success.assert_called_once()
Exemplo n.º 3
0
async def test_handle_action_OperationComplete_invalid(
        ugame: Game, game_connection: GameConnection, database):
    """
        Sends an OperationComplete action to handle action and verifies that
    the `coop_leaderboard` table is updated accordingly.

    Requires that the map from `game.map_file_path` exists in the database.
    """

    ugame.map_file_path = "maps/prothyon16.v0005.zip"
    ugame.validity = ValidityState.OTHER_UNRANK
    game_connection.game = ugame

    secondary = 1
    time_taken = '09:08:07.654321'
    await game_connection.handle_action('OperationComplete',
                                        ['1', secondary, time_taken])

    async with database.acquire() as conn:
        result = await conn.execute(
            "SELECT secondary, gameuid from `coop_leaderboard` where gameuid=%s",
            ugame.id)

        row = await result.fetchone()

    assert row is None
Exemplo n.º 4
0
async def test_team_sets_missing_team_disallowed(game: Game, game_add_players):
    game.state = GameState.LOBBY
    player_id = 5
    game_add_players(game, player_id, team=1)
    del game._player_options[player_id]["Team"]

    with pytest.raises(GameError):
        assert game.get_team_sets()
Exemplo n.º 5
0
async def check_game_settings(game: Game,
                              settings: List[Tuple[str, Any, ValidityState]]):
    for key, value, expected in settings:
        old = game.gameOptions.get(key)
        game.gameOptions[key] = value
        await game.validate_game_settings()
        assert game.validity is expected
        game.gameOptions[key] = old
Exemplo n.º 6
0
async def test_remove_game_connection(game: Game, players,
                                      mock_game_connection):
    game.state = GameState.LOBBY
    mock_game_connection.player = players.hosting
    mock_game_connection.state = GameConnectionState.CONNECTED_TO_HOST
    game.add_game_connection(mock_game_connection)
    await game.remove_game_connection(mock_game_connection)
    assert players.hosting not in game.players
Exemplo n.º 7
0
async def test_add_game_connection_throws_if_not_lobby_state(
        game: Game, players, mock_game_connection):
    game.state = GameState.INITIALIZING
    mock_game_connection.player = players.hosting
    mock_game_connection.state = GameConnectionState.CONNECTED_TO_HOST
    with pytest.raises(GameError):
        game.add_game_connection(mock_game_connection)

    assert players.hosting not in game.players
Exemplo n.º 8
0
async def test_add_game_connection_throws_if_not_connected_to_host(
        game: Game, players, mock_game_connection):
    game.state = GameState.LOBBY
    mock_game_connection.player = players.hosting
    mock_game_connection.state = GameConnectionState.INITIALIZED
    with pytest.raises(GameError):
        game.add_game_connection(mock_game_connection)

    assert players.hosting not in game.players
Exemplo n.º 9
0
async def test_game_is_invalid_due_to_desyncs(game: Game, players):
    game.state = GameState.LOBBY
    add_connected_players(game, [players.hosting, players.joining])
    game.host = players.hosting

    await game.launch()
    game.desyncs = 30
    await game.on_game_end()

    assert game.validity is ValidityState.TOO_MANY_DESYNCS
Exemplo n.º 10
0
async def test_handle_action_GameState_lobby_sends_HostGame(
        game: Game, game_connection: GameConnection, event_loop, players):
    game_connection.player = players.hosting
    game.map_file_path = "maps/some_map.zip"
    game.map_folder_name = "some_map"

    await game_connection.handle_action("GameState", ["Lobby"])
    await exhaust_callbacks(event_loop)

    assert_message_sent(game_connection, "HostGame", [game.map_folder_name])
Exemplo n.º 11
0
async def test_handle_action_GameState_lobby_sends_HostGame(
        game: Game, game_connection: GameConnection, event_loop, players):
    game_connection.player = players.hosting
    game.map_file_path = 'maps/some_map.zip'
    game.map_folder_name = 'some_map'

    await game_connection.handle_action('GameState', ['Lobby'])
    await exhaust_callbacks(event_loop)

    assert_message_sent(game_connection, 'HostGame', [game.map_folder_name])
Exemplo n.º 12
0
async def test_game_end_when_no_more_connections(game: Game,
                                                 mock_game_connection):
    game.state = GameState.LOBBY

    game.on_game_end = CoroutineMock()
    mock_game_connection.state = GameConnectionState.CONNECTED_TO_HOST
    game.add_game_connection(mock_game_connection)
    await game.remove_game_connection(mock_game_connection)

    game.on_game_end.assert_any_call()
Exemplo n.º 13
0
async def test_game_visible_for_rating(game: Game, players):
    game.enforce_rating_range = True
    game.displayed_rating_range = InclusiveRange(2000, None)
    game.host = players.hosting

    players.joining.ratings[RatingType.GLOBAL] = (1500, 1)
    assert not game.is_visible_to_player(players.joining)

    players.joining.ratings[RatingType.GLOBAL] = (2100, 1)
    assert game.is_visible_to_player(players.joining)
Exemplo n.º 14
0
async def test_game_sim_ends_when_no_more_connections(game: Game, players):
    game.state = GameState.LOBBY
    host_conn = add_connected_player(game, players.hosting)
    join_conn = add_connected_player(game, players.joining)
    game.host = players.hosting

    await game.launch()

    await game.remove_game_connection(host_conn)
    await game.remove_game_connection(join_conn)
    assert game.ended
Exemplo n.º 15
0
async def test_handle_action_GameState_lobby_sends_HostGame(
        game: Game, game_connection: GameConnection, loop, players):
    game_connection.player = players.hosting
    game.map_file_path = 'maps/some_map.zip'
    game.map_folder_name = 'some_map'

    await game_connection.handle_action('GameState', ['Lobby'])
    # Give the connection coro time to run
    await asyncio.sleep(0.1)

    assert_message_sent(game_connection, 'HostGame', [game.map_folder_name])
Exemplo n.º 16
0
def test_send_game_list(mocker, lobbyconnection, game_stats_service):
    protocol = mocker.patch.object(lobbyconnection, 'protocol')
    games = mocker.patch.object(lobbyconnection, 'game_service')  # type: GameService
    game1, game2 = mock.create_autospec(Game(42, mock.Mock(), game_stats_service)),\
                   mock.create_autospec(Game(22, mock.Mock(), game_stats_service))

    games.open_games = [game1, game2]

    lobbyconnection.send_game_list()

    protocol.send_message.assert_any_call({'command': 'game_info',
                                           'games': [game1.to_dict(), game2.to_dict()]})
Exemplo n.º 17
0
async def test_game_ends_in_mutually_agreed_draw(game: Game, game_add_players):
    game.state = GameState.LOBBY
    players = game_add_players(game, 2)

    await game.launch()
    game.launched_at = time.time() - 60 * 60

    await game.add_result(players[0].id, 0, "mutual_draw", 0)
    await game.add_result(players[1].id, 1, "mutual_draw", 0)
    await game.on_game_end()

    assert game.validity is ValidityState.MUTUAL_DRAW
Exemplo n.º 18
0
async def test_game_sim_ends_when_connections_ended_sim(game: Game, players):
    game.state = GameState.LOBBY
    host_conn = add_connected_player(game, players.hosting)
    join_conn = add_connected_player(game, players.joining)
    game.host = players.hosting

    await game.launch()

    host_conn.finished_sim = True
    join_conn.finished_sim = True
    await game.check_sim_end()
    assert game.ended
Exemplo n.º 19
0
async def test_game_launch_freezes_players(game: Game, players):
    game.state = GameState.LOBBY
    host_conn = add_connected_player(game, players.hosting)
    game.host = players.hosting
    add_connected_player(game, players.joining)

    await game.launch()

    assert game.state is GameState.LIVE
    assert game.players == {players.hosting, players.joining}

    await game.remove_game_connection(host_conn)
    assert game.players == {players.hosting, players.joining}
Exemplo n.º 20
0
async def test_game_not_ends_in_unilatery_agreed_draw(game: Game, players,
                                                      game_add_players):
    game.state = GameState.LOBBY
    game_add_players(game, 2)

    await game.launch()
    game.launched_at = time.time() - 60 * 60

    await game.add_result(players.hosting.id, 0, "mutual_draw", 0)
    await game.add_result(players.joining.id, 1, "victory", 10)
    await game.on_game_end()

    assert game.validity is not ValidityState.MUTUAL_DRAW
Exemplo n.º 21
0
async def test_send_game_list(mocker, database, lobbyconnection, game_stats_service):
    games = mocker.patch.object(lobbyconnection, "game_service")  # type: GameService
    game1, game2 = mock.create_autospec(Game(42, database, mock.Mock(), game_stats_service)), \
                   mock.create_autospec(Game(22, database, mock.Mock(), game_stats_service))

    games.open_games = [game1, game2]
    lobbyconnection.send = CoroutineMock()

    await lobbyconnection.send_game_list()

    lobbyconnection.send.assert_any_call({
        "command": "game_info",
        "games": [game1.to_dict(), game2.to_dict()]
    })
Exemplo n.º 22
0
async def test_handle_action_GameMods_post_launch_updates_played_cache(
        game: Game, game_connection: GameConnection, database):
    game.launch = CoroutineMock()
    game.remove_game_connection = CoroutineMock()

    await game_connection.handle_action(
        'GameMods', ['uids', 'foo bar EA040F8E-857A-4566-9879-0D37420A5B9D'])
    await game_connection.handle_action('GameState', ['Launching'])

    async with database.acquire() as conn:
        result = await conn.execute(
            "select `played` from table_mod where uid=%s",
            ('EA040F8E-857A-4566-9879-0D37420A5B9D', ))
        row = await result.fetchone()
        assert 2 == row[0]
Exemplo n.º 23
0
async def test_handle_action_GameState_lobby_calls_abort(
        game: Game, game_connection: GameConnection, event_loop, players):
    game_connection.send = CoroutineMock()
    game_connection.abort = CoroutineMock()
    game_connection.player = players.joining
    players.joining.game = game
    game.host = players.hosting
    game.host.state = PlayerState.IDLE
    game.map_file_path = 'maps/some_map.zip'
    game.map_folder_name = 'some_map'

    await game_connection.handle_action('GameState', ['Lobby'])
    await exhaust_callbacks(event_loop)

    game_connection.abort.assert_called_once()
Exemplo n.º 24
0
async def test_handle_action_GameState_lobby_calls_ConnectToHost(
        game: Game, game_connection: GameConnection, event_loop, players):
    game_connection.send = CoroutineMock()
    game_connection.connect_to_host = CoroutineMock()
    game_connection.player = players.joining
    players.joining.game = game
    game.host = players.hosting
    game.map_file_path = "maps/some_map.zip"
    game.map_folder_name = "some_map"

    await game_connection.handle_action("GameState", ["Lobby"])
    await exhaust_callbacks(event_loop)

    game_connection.connect_to_host.assert_called_with(
        players.hosting.game_connection)
Exemplo n.º 25
0
def add_connected_players(game: Game, players):
    """
    Utility to add players with army and StartSpot indexed by a list
    """
    for army, player in enumerate(players):
        add_connected_player(game, player)
        game.set_player_option(player.id, 'Army', army)
        game.set_player_option(player.id, 'StartSpot', army)
        game.set_player_option(player.id, 'Team', army)
        game.set_player_option(player.id, 'Faction', 0)
        game.set_player_option(player.id, 'Color', 0)
    game.host = players[0]
Exemplo n.º 26
0
def add_connected_players(game: Game, players):
    """
    Utility to add players with army and StartSpot indexed by a list
    """
    for army, player in enumerate(players):
        add_connected_player(game, player)
        game.set_player_option(player.id, "Army", army)
        game.set_player_option(player.id, "StartSpot", army)
        game.set_player_option(player.id, "Team", army)
        game.set_player_option(player.id, "Faction", 0)
        game.set_player_option(player.id, "Color", 0)
    game.host = players[0]
Exemplo n.º 27
0
async def test_handle_action_GameMods_activated(
        game: Game, game_connection: GameConnection):
    game.mods = {"a": "b"}
    await game_connection.handle_action('GameMods', ['activated', 0])
    assert game.mods == {}
    await game_connection.handle_action('GameMods', ['activated', '0'])
    assert game.mods == {}
Exemplo n.º 28
0
async def test_handle_lobby_state_handles_GameError(
        real_game: Game, game_connection: GameConnection, event_loop, players):
    game_connection.abort = CoroutineMock()
    game_connection.connect_to_host = CoroutineMock()
    game_connection.player = players.joining
    game_connection.game = real_game

    players.joining.game = real_game

    real_game.host = players.hosting
    real_game.state = GameState.ENDED

    await game_connection.handle_action('GameState', ['Lobby'])
    await exhaust_callbacks(event_loop)

    game_connection.abort.assert_called_once()
Exemplo n.º 29
0
async def test_handle_action_GameMods_activated(
        game: Game, game_connection: GameConnection):
    game.mods = {"a": "b"}
    await game_connection.handle_action("GameMods", ["activated", 0])
    assert game.mods == {}
    await game_connection.handle_action("GameMods", ["activated", "0"])
    assert game.mods == {}
Exemplo n.º 30
0
async def test_game_connection_not_restored_if_game_state_prohibits(
        lobbyconnection: LobbyConnection, game_service: GameService,
        game_stats_service, game_state, mocker, database):
    del lobbyconnection.player.game_connection
    lobbyconnection.player.state = PlayerState.IDLE
    lobbyconnection.game_service = game_service
    game = mock.create_autospec(
        Game(42, database, game_service, game_stats_service))
    game.state = game_state
    game.password = None
    game.game_mode = 'faf'
    game.id = 42
    game_service._games[42] = game

    await lobbyconnection.on_message_received({
        'command': 'restore_game_session',
        'game_id': 42
    })

    assert not lobbyconnection.game_connection
    assert lobbyconnection.player.state == PlayerState.IDLE

    lobbyconnection.protocol.send_message.assert_any_call({
        "command":
        "notice",
        "style":
        "info",
        "text":
        "The game you were connected to is no longer available"
    })
Exemplo n.º 31
0
    async def process_game_stats(self, player: Player, game: Game, stats_json):
        stats = None
        number_of_humans = 0
        highest_score = 0
        highest_scorer = None

        for army_stats in json.loads(stats_json)['stats']:
            if army_stats['type'] == 'AI' and army_stats['name'] != 'civilian':
                self._logger.debug("Ignoring AI game reported by %s", player.login)
                return

            if army_stats['type'] == 'Human':
                number_of_humans += 1

                if highest_score < army_stats['general']['score']:
                    highest_score = army_stats['general']['score']
                    highest_scorer = army_stats['name']

            if army_stats['name'] == player.login:
                stats = army_stats

        if number_of_humans < 2:
            self._logger.debug("Ignoring single player game reported by %s", player.login)
            return

        if stats is None:
            self._logger.warn("Player %s reported stats of a game he was not part of", player.login)
            return

        army_result = game.get_army_result(player)
        if not army_result:
            self._logger.warn("No army result available for player %s", player.login)
            return

        self._logger.debug("Processing game stats for player: %s", player.login)

        faction = stats['faction']
        # Stores achievements to batch update
        a_queue = []
        # Stores events to batch update
        e_queue = []
        survived = army_result[1] == 'victory'
        blueprint_stats = stats['blueprints']
        unit_stats = stats['units']
        scored_highest = highest_scorer == player.login

        if survived and game.game_mode == 'ladder1v1':
            self._unlock(ACH_FIRST_SUCCESS, a_queue)

        self._increment(ACH_NOVICE, 1, a_queue)
        self._increment(ACH_JUNIOR, 1, a_queue)
        self._increment(ACH_SENIOR, 1, a_queue)
        self._increment(ACH_VETERAN, 1, a_queue)
        self._increment(ACH_ADDICT, 1, a_queue)

        self._faction_played(faction, survived, a_queue, e_queue)
        self._category_stats(unit_stats, survived, a_queue, e_queue)
        self._killed_acus(unit_stats, survived, a_queue)
        self._built_mercies(_count_built_units(blueprint_stats, Unit.MERCY), a_queue)
        self._built_fire_beetles(_count_built_units(blueprint_stats, Unit.FIRE_BEETLE), a_queue)
        self._built_salvations(_count_built_units(blueprint_stats, Unit.SALVATION), survived, a_queue)
        self._built_yolona_oss(_count_built_units(blueprint_stats, Unit.YOLONA_OSS), survived, a_queue)
        self._built_paragons(_count_built_units(blueprint_stats, Unit.PARAGON), survived, a_queue)
        self._built_atlantis(_count_built_units(blueprint_stats, Unit.ATLANTIS), a_queue)
        self._built_tempests(_count_built_units(blueprint_stats, Unit.TEMPEST), a_queue)
        self._built_scathis(_count_built_units(blueprint_stats, Unit.SCATHIS), survived, a_queue)
        self._built_mavors(_count_built_units(blueprint_stats, Unit.MAVOR), survived, a_queue)
        self._built_czars(_count_built_units(blueprint_stats, Unit.CZAR), a_queue)
        self._built_ahwassas(_count_built_units(blueprint_stats, Unit.AHWASSA), a_queue)
        self._built_ythothas(_count_built_units(blueprint_stats, Unit.YTHOTHA), a_queue)
        self._built_fatboys(_count_built_units(blueprint_stats, Unit.FATBOY), a_queue)
        self._built_monkeylords(_count_built_units(blueprint_stats, Unit.MONKEYLORD), a_queue)
        self._built_galactic_colossus(_count_built_units(blueprint_stats, Unit.GALACTIC_COLOSSUS), a_queue)
        self._built_soul_rippers(_count_built_units(blueprint_stats, Unit.SOUL_RIPPER), a_queue)
        self._built_megaliths(_count_built_units(blueprint_stats, Unit.MEGALITH), a_queue)
        self._built_asfs(_count_built_units(blueprint_stats, *ASFS), a_queue)
        self._built_transports(unit_stats['transportation'].get('built', 0), a_queue)
        self._built_sacus(unit_stats['sacu'].get('built', 0), a_queue)
        self._lowest_acu_health(_count(blueprint_stats, lambda x: x.get('lowest_health', 0), *ACUS), survived, a_queue)
        self._highscore(scored_highest, number_of_humans, a_queue)

        updated_achievements = await self._achievement_service.execute_batch_update(player.id, a_queue)
        await self._event_service.execute_batch_update(player.id, e_queue)

        if player.lobby_connection is not None:
            player.lobby_connection.send_updated_achievements(updated_achievements)