Skip to content

Commit

Permalink
Unlocked teams make game invalid
Browse files Browse the repository at this point in the history
Fixes #48
  • Loading branch information
1-alex98 committed Apr 8, 2018
1 parent fcf573e commit 22e64f1
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 50 deletions.
4 changes: 3 additions & 1 deletion src/main/java/com/faforever/server/entity/Validity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/**
* Defines whether a game is ranked or - if not - why it isn't ranked.
* Identifiers must be kept in sync with the contents of the invalid_game_reasons table.
*/
public enum Validity {
// Order sensitive
Expand All @@ -21,5 +22,6 @@ public enum Validity {
SINGLE_PLAYER,
FREE_FOR_ALL,
UNEVEN_TEAMS,
UNKNOWN_RESULT
UNKNOWN_RESULT,
TEAMS_UNLOCKED
}
4 changes: 3 additions & 1 deletion src/main/java/com/faforever/server/game/GameService.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class GameService {
public static final String OPTION_SCENARIO_FILE = "ScenarioFile";
public static final String OPTION_TITLE = "Title";
public static final String OPTION_TEAM = "Team";
public static final String OPTION_TEAM_LOCK = "TeamLock";
public static final String OPTION_VICTORY_CONDITION = VictoryCondition.GAME_OPTION_NAME;
public static final Duration DEFAULT_MIN_DELAY = Duration.ofSeconds(1);
public static final Duration DEFAULT_MAX_DELAY = Duration.ofSeconds(5);
Expand Down Expand Up @@ -155,7 +156,8 @@ public GameService(GameRepository gameRepository, CounterService counterService,
ValidityVoter.mutualDrawVoter(),
ValidityVoter.singlePlayerVoter(),
ValidityVoter.gameResultVoter(),
ValidityVoter.gameLengthVoter(properties)
ValidityVoter.gameLengthVoter(properties),
ValidityVoter.teamsUnlockedVoter()
);
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/faforever/server/game/ValidityVoter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static com.faforever.server.game.GameService.OPTION_PREBUILT_UNITS;
import static com.faforever.server.game.GameService.OPTION_RESTRICTED_CATEGORIES;
import static com.faforever.server.game.GameService.OPTION_TEAM;
import static com.faforever.server.game.GameService.OPTION_TEAM_LOCK;

@UtilityClass
class ValidityVoter {
Expand Down Expand Up @@ -84,6 +85,10 @@ Function<Game, Validity> desyncVoter() {
return game -> game.getDesyncCounter().intValue() > game.getPlayerStats().size() ? Validity.TOO_MANY_DESYNCS : Validity.VALID;
}

Function<Game, Validity> teamsUnlockedVoter() {
return game -> "unlocked".equals(game.getOptions().get(OPTION_TEAM_LOCK)) ? Validity.TEAMS_UNLOCKED : Validity.VALID;
}

Function<Game, Validity> rankedMapVoter() {
return game -> game.getMapVersion() == null || !game.getMapVersion().isRanked() ? Validity.BAD_MAP : Validity.VALID;
}
Expand Down
107 changes: 59 additions & 48 deletions src/test/java/com/faforever/server/game/GameServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public void joinGameWrongPassword() throws Exception {
}

@Test
public void updateGameStateIdle() throws Exception {
public void updateGameStateIdle() {
instance.createGame("Game title", FAF_TECHNICAL_NAME, MAP_NAME, "secret",
GameVisibility.PUBLIC, GAME_MIN_RATING, GAME_MAX_RATING, player1);
instance.updatePlayerGameState(PlayerGameState.IDLE, player1);
Expand All @@ -223,7 +223,7 @@ public void updateGameOption() throws Exception {
}

@Test
public void updateGameOptionNotInGameIgnored() throws Exception {
public void updateGameOptionNotInGameIgnored() {
instance.updateGameOption(player2, "GameSpeed", "normal");
verifyZeroInteractions(clientService);
}
Expand Down Expand Up @@ -636,18 +636,23 @@ public void onLadder1v1GameEndedProcessedStats() throws Exception {
addPlayer(game, player2);
launchGame(game);

Stream.of(player1, player2)
.forEach(player -> {
instance.reportArmyOutcome(player, 1, Outcome.VICTORY);
instance.reportArmyScore(player, 1, 10);
instance.reportArmyOutcome(player, 2, Outcome.DEFEAT);
instance.reportArmyScore(player, 2, -1);
});
reportPlayerScores();

assertThat(game.getValidity(), is(Validity.VALID));
verify(divisionService).postResult(player1, player2, player1);
}

@Test
public void simpleValidGameWithEnded() throws Exception {
Game game = hostGame(player1);
addPlayer(game, player2);
launchGame(game);

reportPlayerScores();

assertThat(game.getValidity(), is(Validity.VALID));
}

@Test
public void onGameLaunching() throws Exception {
Game game = hostGame(player1);
Expand Down Expand Up @@ -901,19 +906,15 @@ public void scoresCalculatedCorrectly() throws Exception {
}

@Test
public void simpleValidGameWithEnded() throws Exception {
public void updateGameValidityTeamsUnlocked() throws Exception {
Game game = hostGame(player1);
addPlayer(game, player2);
game.getOptions().put(GameService.OPTION_TEAM_LOCK, "unlocked");
launchGame(game);

Stream.of(player1, player2).forEach(player -> {
instance.reportArmyOutcome(player, 1, Outcome.VICTORY);
instance.reportArmyScore(player, 1, 10);
instance.reportArmyOutcome(player, 2, Outcome.DEFEAT);
instance.reportArmyScore(player, 2, -1);
});
reportPlayerScores();

assertThat(game.getValidity(), is(Validity.VALID));
assertThat(game.getValidity(), is(Validity.TEAMS_UNLOCKED));
}

@Test
Expand Down Expand Up @@ -1012,6 +1013,25 @@ public void updateGameValiditySinglePlayer() throws Exception {
assertThat(game.getValidity(), is(Validity.SINGLE_PLAYER));
}

@Test
@SuppressWarnings("unchecked")
public void onAuthenticationSuccess() {
player1.setCurrentGame(null);
instance.createGame("Test game", FAF_TECHNICAL_NAME, MAP_NAME, null, GameVisibility.PUBLIC, GAME_MIN_RATING, GAME_MAX_RATING, player1);

TestingAuthenticationToken authentication = new TestingAuthenticationToken("JUnit", "foo");
authentication.setDetails(new TestingAuthenticationToken(new FafUserDetails((User) new User().setPlayer(player2).setPassword("pw").setLogin("JUnit")), null));

instance.onPlayerOnlineEvent(new PlayerOnlineEvent(this, player2));

ArgumentCaptor<GameResponses> captor = ArgumentCaptor.forClass((Class) Collection.class);
verify(clientService).sendGameList(captor.capture(), eq(player2));
GameResponses games = captor.getValue();

assertThat(games.getResponses(), hasSize(1));
assertThat(games.getResponses().iterator().next().getTitle(), is("Test game"));
}

@Test
public void updateGameValidityUnknownResult() throws Exception {
Game game = hostGame(player1);
Expand Down Expand Up @@ -1061,22 +1081,9 @@ public void onClientDisconnectRemovesPlayerAndUnsetsGameAndRemovesGameIfLastPlay
}

@Test
@SuppressWarnings("unchecked")
public void onAuthenticationSuccess() throws Exception {
player1.setCurrentGame(null);
instance.createGame("Test game", FAF_TECHNICAL_NAME, MAP_NAME, null, GameVisibility.PUBLIC, GAME_MIN_RATING, GAME_MAX_RATING, player1);

TestingAuthenticationToken authentication = new TestingAuthenticationToken("JUnit", "foo");
authentication.setDetails(new TestingAuthenticationToken(new FafUserDetails((User) new User().setPlayer(player2).setPassword("pw").setLogin("JUnit")), null));

instance.onPlayerOnlineEvent(new PlayerOnlineEvent(this, player2));

ArgumentCaptor<GameResponses> captor = ArgumentCaptor.forClass((Class) Collection.class);
verify(clientService).sendGameList(captor.capture(), eq(player2));
GameResponses games = captor.getValue();

assertThat(games.getResponses(), hasSize(1));
assertThat(games.getResponses().iterator().next().getTitle(), is("Test game"));
public void disconnectFromGameIgnoredWhenPlayerUnknown() {
instance.disconnectPlayerFromGame(player1, 412312);
verifyZeroInteractions(clientService);
}

/**
Expand Down Expand Up @@ -1109,16 +1116,21 @@ public void disconnectFromGame() throws Exception {
}

@Test
public void disconnectFromGameIgnoredWhenPlayerUnknown() throws Exception {
instance.disconnectPlayerFromGame(player1, 412312);
public void disconnectFromGameIgnoredWhenPlayerNotInGame() {
when(playerService.getOnlinePlayer(3)).thenReturn(Optional.of(new Player()));
instance.disconnectPlayerFromGame(player1, 3);
verifyZeroInteractions(clientService);
}

@Test
public void disconnectFromGameIgnoredWhenPlayerNotInGame() throws Exception {
when(playerService.getOnlinePlayer(3)).thenReturn(Optional.of(new Player()));
instance.disconnectPlayerFromGame(player1, 3);
verifyZeroInteractions(clientService);
public void mutualDrawRequestedByPlayerInNonPlayingGameState() {
player1.setCurrentGame(null);
instance.createGame("Game title", FAF_TECHNICAL_NAME, MAP_NAME, "secret", GameVisibility.PUBLIC, GAME_MIN_RATING, GAME_MAX_RATING, player1);
instance.updatePlayerGameState(PlayerGameState.LOBBY, player1);

expectedException.expect(requestExceptionWithCode(ErrorCode.INVALID_GAME_STATE));

instance.mutuallyAgreeDraw(player1);
}

@Test
Expand Down Expand Up @@ -1192,15 +1204,14 @@ public void mutualDrawRequestedByPlayerWithoutGame() throws Exception {
instance.mutuallyAgreeDraw(player2);
}

@Test
public void mutualDrawRequestedByPlayerInNonPlayingGameState() throws Exception {
player1.setCurrentGame(null);
instance.createGame("Game title", FAF_TECHNICAL_NAME, MAP_NAME, "secret", GameVisibility.PUBLIC, GAME_MIN_RATING, GAME_MAX_RATING, player1);
instance.updatePlayerGameState(PlayerGameState.LOBBY, player1);

expectedException.expect(requestExceptionWithCode(ErrorCode.INVALID_GAME_STATE));

instance.mutuallyAgreeDraw(player1);
private void reportPlayerScores() {
Stream.of(player1, player2)
.forEach(player -> {
instance.reportArmyOutcome(player, 1, Outcome.VICTORY);
instance.reportArmyScore(player, 1, 10);
instance.reportArmyOutcome(player, 2, Outcome.DEFEAT);
instance.reportArmyScore(player, 2, -1);
});
}

@Test
Expand Down

0 comments on commit 22e64f1

Please sign in to comment.