예제 #1
0
async def test_compute_rating_balanced_teamgame(game: Game, create_player):
    await game.clear_data()

    game.state = GameState.LOBBY
    players = [(
        create_player(**info), result, team
    ) for info, result, team in [
        (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0,
         1),
        (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0,
         1),
        (dict(login='******', id=3, global_rating=Rating(1200, 72.02)),
         0, 2),
        (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0,
         2),
    ]]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()
    for player, result, _ in players:
        await game.add_result(player, player.id - 1, 'score', result)
    result = game.compute_rating()
    for team in result:
        for player, new_rating in team.items():
            assert player in game.players
            assert new_rating != Rating(*player.global_rating)
예제 #2
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"] == []
예제 #3
0
def add_players_with_rating(player_factory, game, ratings, teams):
    rating_service = game.game_service._rating_service

    players = [(
        player_factory(
            f"{i}",
            player_id=i,
            global_rating=rating,
            ladder_rating=rating,
            with_lobby_connection=False,
        ),
        team,
    ) for i, (rating, team) in enumerate(zip(ratings, teams), 1)]

    game.state = GameState.LOBBY
    add_connected_players(game, [player for player, _ in players])

    for player, team in players:
        rating_service.set_mock_rating(
            player.id, RatingType.GLOBAL,
            Rating(*player.ratings[RatingType.GLOBAL]))
        rating_service.set_mock_rating(
            player.id,
            RatingType.LADDER_1V1,
            Rating(*player.ratings[RatingType.LADDER_1V1]),
        )
        player._mock_team = team
        game.set_player_option(player.id, "Team", player._mock_team)
        player._test_army = player.id - 1
        game.set_player_option(player.id, "Army", player._test_army)

    return players
예제 #4
0
async def test_compute_rating_balanced_teamgame(game: Game, player_factory):
    game.state = GameState.LOBBY
    players = [(player_factory(login=f"{i}",
                               player_id=i,
                               global_rating=rating,
                               with_lobby_connection=False), result, team)
               for i, (rating, result, team) in enumerate([
                   (Rating(1500, 250), 0, 2),
                   (Rating(1700, 120), 0, 2),
                   (Rating(1200, 72), 0, 3),
                   (Rating(1200, 72), 0, 3),
               ], 1)]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()
    for player, result, team in players:
        await game.add_result(player, player.id - 1,
                              'victory' if team == 2 else 'defeat', result)
    result = game.compute_rating()
    for team in result:
        for player, new_rating in team.items():
            assert player in game.players
            assert new_rating != Rating(*player.ratings[RatingType.GLOBAL])
예제 #5
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
예제 #6
0
async def test_compute_rating_raises_game_error(game: Game, players):
    game.state = GameState.LOBBY
    add_connected_players(game, [players.hosting, players.joining])
    # add_connected_players sets this, so we need to unset it again
    del game._player_options[players.hosting.id]["Team"]
    game.set_player_option(players.joining.id, "Team", 1)
    await game.launch()

    with pytest.raises(GameError):
        game.compute_rating(rating=RatingType.LADDER_1V1)
예제 #7
0
async def test_resolve_game_fails_if_not_launched(custom_game, players):
    rating_service = custom_game.game_service._rating_service
    custom_game.state = GameState.LOBBY
    add_connected_players(custom_game, [players.hosting, players.joining])
    custom_game.set_player_option(players.hosting.id, "Team", 2)
    custom_game.set_player_option(players.joining.id, "Team", 3)

    custom_game.enforce_rating = True
    with pytest.raises(GameError):
        await custom_game.resolve_game_results()
예제 #8
0
def game_5p(game):
    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500)),
        Player(id=3, login='******', global_rating=(1500, 500)),
        Player(id=4, login='******', global_rating=(1500, 500)),
        Player(id=5, login='******', global_rating=(1500, 500)),
    ]
    add_connected_players(game, players)
    return game
예제 #9
0
async def test_game_is_invalid_due_to_desyncs(game: Game, players):
    await game.clear_data()
    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
예제 #10
0
async def test_rating_summary_missing_team_raises_game_error(game, players):
    game.state = GameState.LOBBY
    add_connected_players(game, [players.hosting, players.joining])
    del game._player_options[players.hosting.id]["Team"]
    await game.launch()

    with pytest.raises(GameError):
        game.get_team_sets()

    with pytest.raises(GameError):
        await game.resolve_game_results()
예제 #11
0
async def test_compute_rating_computes_ladder_ratings(game: Game, players):
    game.state = GameState.LOBBY
    players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    await game.add_result(players.hosting.id, 0, 'victory', 1)
    await game.add_result(players.joining.id, 1, 'defeat', 0)
    game.set_player_option(players.hosting.id, 'Team', 1)
    game.set_player_option(players.joining.id, 'Team', 1)
    groups = game.compute_rating(rating=RatingType.LADDER_1V1)
    assert players.hosting in groups[0]
    assert players.joining in groups[1]
예제 #12
0
async def test_persist_results_not_called_with_one_player(game):
    await game.clear_data()
    game.persist_results = CoroMock()

    game.state = GameState.LOBBY
    players = [Player(id=1, login='******', global_rating=(1500, 500))]
    add_connected_players(game, players)
    await game.launch()
    assert len(game.players) == 1
    await game.add_result(0, 1, 'VICTORY', 5)
    await game.on_game_end()

    game.persist_results.assert_not_called()
예제 #13
0
async def test_persist_results_not_called_with_one_player(
        game, player_factory):
    game.persist_results = CoroutineMock()

    game.state = GameState.LOBBY
    players = [
        player_factory("Dostya", player_id=1, global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    await game.launch()
    assert len(game.players) == 1
    await game.add_result(0, 1, "victory", 5)
    await game.on_game_end()

    game.persist_results.assert_not_called()
예제 #14
0
async def test_persist_results_not_called_with_one_player(game):
    await game.clear_data()
    game.persist_results = CoroMock()

    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    await game.launch()
    assert len(game.players) == 1
    await game.add_result(0, 1, 'VICTORY', 5)
    await game.on_game_end()

    game.persist_results.assert_not_called()
예제 #15
0
async def test_game_outcomes_no_results(game: Game, players):
    await game.clear_data()

    game.state = GameState.LOBBY
    players.hosting.ladder_rating = Rating(1500, 250)
    players.joining.ladder_rating = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    game.set_player_option(players.hosting.id, 'Team', 1)
    game.set_player_option(players.joining.id, 'Team', 1)

    host_outcome = game.outcome(players.hosting)
    guest_outcome = game.outcome(players.joining)
    assert host_outcome is None
    assert guest_outcome is None
예제 #16
0
async def test_compute_rating_computes_global_ratings(game: Game, players):
    await game.clear_data()

    game.state = GameState.LOBBY
    players.hosting.global_rating = Rating(1500, 250)
    players.joining.global_rating = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    await game.add_result(players.hosting, 0, 'victory', 1)
    await game.add_result(players.joining, 1, 'defeat', 0)
    game.set_player_option(players.hosting.id, 'Team', 2)
    game.set_player_option(players.joining.id, 'Team', 3)
    groups = game.compute_rating()
    assert players.hosting in groups[0]
    assert players.joining in groups[1]
예제 #17
0
async def test_compute_rating_computes_ladder_ratings(game: Game, players):
    await game.clear_data()

    game.state = GameState.LOBBY
    players.hosting.ladder_rating = Rating(1500, 250)
    players.joining.ladder_rating = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    await game.add_result(players.hosting, 0, 'victory', 1)
    await game.add_result(players.joining, 1, 'defeat', 0)
    game.set_player_option(players.hosting.id, 'Team', 1)
    game.set_player_option(players.joining.id, 'Team', 1)
    groups = game.compute_rating(rating='ladder')
    assert players.hosting in groups[0]
    assert players.joining in groups[1]
예제 #18
0
async def test_to_dict(game, create_player):
    await game.clear_data()

    game.state = GameState.LOBBY
    players = [(
        create_player(**info), result, team
    ) for info, result, team in [
        (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0,
         1),
        (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0,
         1),
        (dict(login='******', id=3, global_rating=Rating(1200, 72.02)),
         0, 2),
        (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0,
         2),
    ]]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    game.host = players[0][0]
    await game.launch()
    data = game.to_dict()
    expected = {
        "command": "game_info",
        "visibility": VisibilityState.to_string(game.visibility),
        "password_protected": game.password is not None,
        "uid": game.id,
        "title": game.sanitize_name(game.name),
        "state": 'playing',
        "featured_mod": game.game_mode,
        "featured_mod_versions": game.getGamemodVersion(),
        "sim_mods": game.mods,
        "mapname": game.map_folder_name,
        "map_file_path": game.map_file_path,
        "host": game.host.login,
        "num_players": len(game.players),
        "max_players": game.max_players,
        "launched_at": game.launched_at,
        "teams": {
            team: [
                player.login for player in game.players
                if game.get_player_option(player.id, 'Team') == team
            ]
            for team in game.teams
        }
    }
    assert data == expected
예제 #19
0
async def test_rate_game_late_abort_no_enforce(game_service, game_stats_service, custom_game):
    custom_game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500)),
    ]
    add_connected_players(custom_game, players)
    custom_game.set_player_option(1, 'Team', 2)
    custom_game.set_player_option(2, 'Team', 3)
    await custom_game.launch()
    await custom_game.add_result(0, 1, 'VICTORY', 5)

    custom_game.launched_at = time.time() - 600 # seconds

    await custom_game.on_game_end()
    assert custom_game.validity == ValidityState.VALID
예제 #20
0
async def test_to_dict(game, player_factory):
    game.state = GameState.LOBBY
    players = [(player_factory(f"{i}", player_id=i,
                               global_rating=rating), result, team)
               for i, (rating, result, team) in enumerate([
                   (Rating(1500, 250), 0, 1),
                   (Rating(1700, 120), 0, 1),
                   (Rating(1200, 72), 0, 2),
                   (Rating(1200, 72), 0, 2),
               ], 1)]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, "Team", team)
        game.set_player_option(player.id, "Army", player.id - 1)
    game.host = players[0][0]
    await game.launch()
    data = game.to_dict()
    expected = {
        "command": "game_info",
        "visibility": game.visibility.value,
        "password_protected": game.password is not None,
        "uid": game.id,
        "title": game.sanitize_name(game.name),
        "game_type": "custom",
        "state": "playing",
        "featured_mod": game.game_mode,
        "sim_mods": game.mods,
        "mapname": game.map_folder_name,
        "map_file_path": game.map_file_path,
        "host": game.host.login,
        "num_players": len(game.players),
        "max_players": game.max_players,
        "launched_at": game.launched_at,
        "rating_type": game.rating_type,
        "rating_min": game.displayed_rating_range.lo,
        "rating_max": game.displayed_rating_range.hi,
        "enforce_rating_range": game.enforce_rating_range,
        "teams": {
            team: [
                player.login for player in game.players
                if game.get_player_option(player.id, "Team") == team
            ]
            for team in game.teams
        }
    }
    assert data == expected
예제 #21
0
async def test_game_outcomes_conflicting(game: Game, database, players):
    game.state = GameState.LOBBY
    players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    await game.add_result(players.hosting.id, 0, "victory", 1)
    await game.add_result(players.joining.id, 1, "victory", 0)
    await game.add_result(players.hosting.id, 0, "defeat", 1)
    await game.add_result(players.joining.id, 1, "defeat", 0)
    game.set_player_option(players.hosting.id, "Team", 1)
    game.set_player_option(players.joining.id, "Team", 1)

    host_outcome = game.get_player_outcome(players.hosting)
    guest_outcome = game.get_player_outcome(players.joining)
    assert host_outcome is GameOutcome.CONFLICTING
    assert guest_outcome is GameOutcome.CONFLICTING
예제 #22
0
async def test_game_outcomes_no_results(game: Game, database, players):
    game.state = GameState.LOBBY
    players.hosting.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    players.joining.ratings[RatingType.LADDER_1V1] = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    game.set_player_option(players.hosting.id, "Team", 1)
    game.set_player_option(players.joining.id, "Team", 1)

    host_outcome = game.get_player_outcome(players.hosting)
    guest_outcome = game.get_player_outcome(players.joining)
    assert host_outcome is GameOutcome.UNKNOWN
    assert guest_outcome is GameOutcome.UNKNOWN

    await game.on_game_end()
    expected_scores = {(players.hosting.id, 0), (players.joining.id, 0)}
    assert await game_player_scores(database, game) == expected_scores
예제 #23
0
async def test_game_outcomes(game: Game, players):
    await game.clear_data()

    game.state = GameState.LOBBY
    players.hosting.ladder_rating = Rating(1500, 250)
    players.joining.ladder_rating = Rating(1500, 250)
    add_connected_players(game, [players.hosting, players.joining])
    await game.launch()
    await game.add_result(players.hosting, 0, 'victory', 1)
    await game.add_result(players.joining, 1, 'defeat', 0)
    game.set_player_option(players.hosting.id, 'Team', 1)
    game.set_player_option(players.joining.id, 'Team', 1)

    host_outcome = game.outcome(players.hosting)
    guest_outcome = game.outcome(players.joining)
    assert host_outcome is GameOutcome.VICTORY
    assert guest_outcome is GameOutcome.DEFEAT
예제 #24
0
async def test_clear_slot(game: Game, mock_game_connection: GameConnection):
    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    game.set_ai_option('rush', 'StartSpot', 3)

    game.clear_slot(0)
    game.clear_slot(3)

    assert game.get_player_option(1, 'StartSpot') == -1
    assert game.get_player_option(1, 'Team') == -1
    assert game.get_player_option(1, 'Army') == -1
    assert game.get_player_option(2, 'StartSpot') == 1
    assert 'rush' not in game.AIs
예제 #25
0
async def test_single_wrong_report_still_rated_correctly(
        game: Game, player_factory):
    # based on replay with UID 11255492

    # Mocking out database calls, since not all player IDs exist.
    game.update_game_player_stats = CoroutineMock()

    game.state = GameState.LOBBY

    # Loading log data
    with open("tests/data/uid11255492.log.json", "r") as f:
        log_dict = json.load(f)

    old_rating = 1500
    players = {
        player_id: player_factory(
            login=f"{player_id}",
            player_id=player_id,
            global_rating=Rating(old_rating, 250),
            with_lobby_connection=False,
        )
        for team in log_dict["teams"].values() for player_id in team
    }

    add_connected_players(game, list(players.values()))
    for team_id, team_list in log_dict["teams"].items():
        for player_id in team_list:
            game.set_player_option(player_id, "Team", team_id)
            game.set_player_option(player_id, "Army", player_id - 1)
    await game.launch()

    for reporter, reportee, outcome, score in log_dict["results"]:
        await game.add_result(players[reporter], reportee, outcome, score)

    rating_service = game.game_service._rating_service
    await game.on_game_end()
    await rating_service._join_rating_queue()

    results = get_persisted_results(rating_service)
    winning_ids = log_dict["teams"][str(log_dict["winning_team"])]
    for player_id, new_rating in results.ratings.items():
        if player_id in winning_ids:
            assert new_rating.mu > old_rating
        else:
            assert new_rating.mu < old_rating
예제 #26
0
async def test_rate_game_late_abort_no_enforce(game_service,
                                               game_stats_service,
                                               custom_game):
    custom_game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500)),
    ]
    add_connected_players(custom_game, players)
    custom_game.set_player_option(1, 'Team', 2)
    custom_game.set_player_option(2, 'Team', 3)
    await custom_game.launch()
    await custom_game.add_result(0, 1, 'VICTORY', 5)

    custom_game.launched_at = time.time() - 600  # seconds

    await custom_game.on_game_end()
    assert custom_game.validity == ValidityState.VALID
예제 #27
0
async def test_rate_game_late_abort_no_enforce(game_service,
                                               game_stats_service, custom_game,
                                               player_factory):
    custom_game.state = GameState.LOBBY
    players = [
        player_factory("Dostya", player_id=1, global_rating=(1500, 500)),
        player_factory("Rhiza", player_id=2, global_rating=(1500, 500)),
    ]
    add_connected_players(custom_game, players)
    custom_game.set_player_option(1, "Team", 2)
    custom_game.set_player_option(2, "Team", 3)
    await custom_game.launch()
    await custom_game.add_result(0, 1, "victory", 5)

    custom_game.launched_at = time.time() - 600  # seconds

    await custom_game.on_game_end()
    assert custom_game.validity == ValidityState.VALID
예제 #28
0
async def test_clear_slot(game: Game, mock_game_connection: GameConnection,
                          player_factory):
    game.state = GameState.LOBBY
    players = [
        player_factory("Dostya", player_id=1, global_rating=(1500, 500)),
        player_factory("Rhiza", player_id=2, global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    game.set_ai_option("rush", "StartSpot", 3)

    game.clear_slot(0)
    game.clear_slot(3)

    assert game.get_player_option(1, "StartSpot") == -1
    assert game.get_player_option(1, "Team") == -1
    assert game.get_player_option(1, "Army") == -1
    assert game.get_player_option(2, "StartSpot") == 1
    assert "rush" not in game.AIs
예제 #29
0
async def test_clear_slot(game: Game, mock_game_connection: GameConnection):
    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    game.set_ai_option('rush', 'StartSpot', 3)


    game.clear_slot(0)
    game.clear_slot(3)

    assert game.get_player_option(1, 'StartSpot') == -1
    assert game.get_player_option(1, 'Team') == -1
    assert game.get_player_option(1, 'Army') == -1
    assert game.get_player_option(2, 'StartSpot') == 1
    assert 'rush' not in game.AIs
예제 #30
0
async def test_report_army_stats_sends_stats_for_defeated_player(game: Game):
    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500))
    ]
    add_connected_players(game, players)

    await game.launch()
    await game.add_result(0, 1, 'defeat', -1)

    with open("tests/data/game_stats_simple_win.json", "r") as stats_file:
        stats = stats_file.read()

    await game.report_army_stats(stats)

    game._game_stats_service.process_game_stats.assert_called_once_with(
        players[1], game, stats)
예제 #31
0
async def test_compute_rating_does_not_rate_double_win(game: Game,
                                                       player_factory):
    game.state = GameState.LOBBY
    players = [(player_factory(f"{i}", player_id=i,
                               global_rating=rating), result, team)
               for i, (rating, result, team) in enumerate([
                   (Rating(1500, 250), 10, 2),
                   (Rating(1700, 120), 0, 3),
               ], 1)]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()

    for player, result, _ in players:
        await game.add_result(player, player.id - 1, 'victory', result)
    with pytest.raises(GameRatingError):
        game.compute_rating()
예제 #32
0
async def test_persist_results_called_with_two_players(game):
    await game.clear_data()

    game.state = GameState.LOBBY
    players = [
        Player(id=1, login='******', global_rating=(1500, 500)),
        Player(id=2, login='******', global_rating=(1500, 500))
    ]
    add_connected_players(game, players)
    await game.launch()
    assert len(game.players) == 2
    await game.add_result(0, 1, 'VICTORY', 5)
    await game.on_game_end()

    assert game.get_army_result(1) == 5
    assert len(game.players) == 2

    await game.load_results()
    assert game.get_army_result(1) == 5
예제 #33
0
async def test_to_dict(game, create_player):
    await game.clear_data()

    game.state = GameState.LOBBY
    players = [
        (create_player(**info), result, team) for info, result, team in [
            (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1),
            (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1),
            (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2),
            (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2),
        ]
    ]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    game.host = players[0][0]
    await game.launch()
    data = game.to_dict()
    expected = {
        "command": "game_info",
        "visibility": VisibilityState.to_string(game.visibility),
        "password_protected": game.password is not None,
        "uid": game.id,
        "title": game.name,
        "state": 'playing',
        "featured_mod": game.game_mode,
        "featured_mod_versions": game.getGamemodVersion(),
        "sim_mods": game.mods,
        "mapname": game.map_folder_name,
        "map_file_path": game.map_file_path,
        "host": game.host.login,
        "num_players": len(game.players),
        "max_players": game.max_players,
        "launched_at": game.launched_at,
        "teams": {
            team: [player.login for player in game.players
                   if game.get_player_option(player.id, 'Team') == team]
            for team in game.teams
        }
    }
    assert data == expected
예제 #34
0
async def test_compute_rating_sum_of_scores_edge_case(game: Game,
                                                      player_factory):
    """
    For certain scores, compute_rating was determining the winner incorrectly,
    see issue <https://github.com/FAForever/server/issues/485>.
    """
    game.state = GameState.LOBBY
    win_team = 2
    lose_team = 3
    players = [(player_factory(login=f"{i}",
                               player_id=i,
                               global_rating=rating,
                               with_lobby_connection=False), result, team)
               for i, (rating, result, team) in enumerate([
                   (Rating(1500, 200), 1, lose_team),
                   (Rating(1500, 200), 1, lose_team),
                   (Rating(1500, 200), 1, lose_team),
                   (Rating(1500, 200), -10, lose_team),
                   (Rating(1500, 200), 10, win_team),
                   (Rating(1500, 200), -10, win_team),
                   (Rating(1500, 200), -10, win_team),
                   (Rating(1500, 200), 2, win_team),
               ], 1)]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()

    for player, result, team in players:
        outcome = 'victory' if team is win_team else 'defeat'
        await game.add_result(player, player.id - 1, outcome, result)

    result = game.compute_rating()
    for team in result:
        for player, new_rating in team.items():
            old_rating = Rating(*player.ratings[RatingType.GLOBAL])
            if player.id > 4:  # `team` index in result might not coincide with `team` index in players
                assert new_rating > old_rating
            else:
                assert new_rating < old_rating
예제 #35
0
async def test_compute_rating_only_one_surviver(game: Game, player_factory):
    """
    When a player dies their score is reported as "defeat", but this does not
    necessarily mean they lost the game, if their team mates went on and later
    reported a "victory".
    """
    game.state = GameState.LOBBY
    win_team = 2
    lose_team = 3
    players = [(player_factory(login=f"{i}",
                               player_id=i,
                               global_rating=Rating(1500, 200),
                               with_lobby_connection=False), outcome, result,
                team) for i, (outcome, result, team) in enumerate([
                    ("defeat", -10, lose_team),
                    ("defeat", -10, lose_team),
                    ("defeat", -10, lose_team),
                    ("defeat", -10, lose_team),
                    ("defeat", -10, win_team),
                    ("defeat", -10, win_team),
                    ("defeat", -10, win_team),
                    ("victory", 10, win_team),
                ], 1)]
    add_connected_players(game, [player for player, _, _, _ in players])
    for player, _, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()

    for player, outcome, result, team in players:
        await game.add_result(player, player.id - 1, outcome, result)

    result = game.compute_rating()
    for team in result:
        for player, new_rating in team.items():
            old_rating = Rating(*player.ratings[RatingType.GLOBAL])
            # `team` index in result might not coincide with `team` index in players
            if player.id > 4:
                assert new_rating > old_rating
            else:
                assert new_rating < old_rating
예제 #36
0
async def test_on_game_end_ladder_ratings_(ladder_game, players):
    rating_service = ladder_game.game_service._rating_service

    ladder_game.state = GameState.LOBBY
    add_connected_players(ladder_game, [players.hosting, players.joining])
    ladder_game.set_player_option(players.hosting.id, "Team", 1)
    ladder_game.set_player_option(players.joining.id, "Team", 1)

    await ladder_game.launch()
    await ladder_game.add_result(players.hosting.id, 0, "victory", 1)
    await ladder_game.add_result(players.joining.id, 1, "defeat", 0)

    await ladder_game.on_game_end()
    await rating_service._join_rating_queue()

    results = get_persisted_results(rating_service)
    assert results.rating_type is RatingType.LADDER_1V1
    assert players.hosting.id in results.ratings
    assert players.joining.id in results.ratings
    assert results.outcomes[players.hosting.id] is GameOutcome.VICTORY
    assert results.outcomes[players.joining.id] is GameOutcome.DEFEAT
예제 #37
0
async def test_compute_rating_balanced_teamgame(game: Game, create_player):
    await game.clear_data()

    game.state = GameState.LOBBY
    players = [
        (create_player(**info), result, team) for info, result, team in [
            (dict(login='******', id=1, global_rating=Rating(1500, 250.7)), 0, 1),
            (dict(login='******', id=2, global_rating=Rating(1700, 120.1)), 0, 1),
            (dict(login='******', id=3, global_rating=Rating(1200, 72.02)), 0, 2),
            (dict(login='******', id=4, global_rating=Rating(1200, 72.02)), 0, 2),
        ]
    ]
    add_connected_players(game, [player for player, _, _ in players])
    for player, _, team in players:
        game.set_player_option(player.id, 'Team', team)
        game.set_player_option(player.id, 'Army', player.id - 1)
    await game.launch()
    for player, result, _ in players:
        await game.add_result(player, player.id - 1, 'score', result)
    result = game.compute_rating()
    for team in result:
        for player, new_rating in team.items():
            assert player in game.players
            assert new_rating != Rating(*player.global_rating)
예제 #38
0
def test_game_teams_represents_active_teams(game: Game, players):
    game.state = GameState.LOBBY
    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', 2)
    assert game.teams == {1, 2}