Search in sources :

Example 1 with RequestException

use of com.faforever.server.error.RequestException in project faf-java-server by FAForever.

the class LegacyRequestTransformer method transform.

@Override
public ClientMessage transform(Map<String, Object> source) {
    String command = (String) source.get("command");
    LegacyClientMessageType messageType = LegacyClientMessageType.fromString(command);
    Requests.verify(messageType != null, ErrorCode.INVALID_COMMAND, command);
    switch(messageType) {
        case HOST_GAME:
            return handleHostGame(source);
        case JOIN_GAME:
            return new JoinGameRequest(((Number) source.get("uid")).intValue(), (String) source.get("password"));
        case ASK_SESSION:
            String userAgent = (String) source.get("user_agent");
            return LegacySessionRequest.forUserAgent(userAgent);
        case SOCIAL_ADD:
            return handleSocialAdd(source);
        case SOCIAL_REMOVE:
            return handleSocialRemove(source);
        case LOGIN:
            return handleLogin(source);
        case GAME_MATCH_MAKING:
            return handleMatchMaking(source);
        case AVATAR:
            return handleAvatar(source);
        case GAME_STATE:
            return handleGameState(source);
        case GAME_OPTION:
            List<Object> args = getArgs(source);
            return new GameOptionReport((String) args.get(0), args.get(1));
        case PLAYER_OPTION:
            args = getArgs(source);
            return new PlayerOptionReport(Integer.parseInt((String) args.get(0)), (String) args.get(1), args.get(2));
        case CLEAR_SLOT:
            args = getArgs(source);
            return ClearSlotRequest.valueOf((int) args.get(0));
        case DESYNC:
            return DesyncReport.INSTANCE;
        case GAME_MODS:
            return handleGameMods(source);
        case GAME_RESULT:
            return handleGameResult(source);
        case OPERATION_COMPLETE:
            return handleOperationComplete(source);
        case JSON_STATS:
            return handleJsonStats(source);
        case ENFORCE_RATING:
            return PlayerDefeatedReport.INSTANCE;
        case TEAMKILL_REPORT:
            return handleTeamKillReport(source);
        case MUTUAL_DRAW:
            return MutuallyAgreedDrawRequest.INSTANCE;
        case AI_OPTION:
            return handleAiOption(source);
        case INITIATE_TEST:
            throw new RequestException(ErrorCode.UNSUPPORTED_REQUEST, source);
        case ICE_SERVERS:
            return IceServersRequest.INSTANCE;
        case ICE_MESSAGE:
            args = getArgs(source);
            return new IceMessage((int) args.get(0), args.get(1));
        case RESTORE_GAME_SESSION:
            return new RestoreGameSessionRequest((int) source.get("game_id"));
        case CREATE_ACCOUNT:
            throw new RequestException(ErrorCode.CREATE_ACCOUNT_IS_DEPRECATED);
        case ADMIN:
            return handleAdminAction(source);
        case DISCONNECTED:
            return DisconnectedReport.INSTANCE;
        case BOTTLENECK:
            return BottleneckReport.INSTANCE;
        case CHAT:
            return handleGameChatMessage((String) getArgs(source).get(0));
        case BOTTLENECK_CLEARED:
            return BottleneckClearedReport.INSTANCE;
        default:
            throw new ProgrammingError("Uncovered message type: " + messageType);
    }
}
Also used : LegacyClientMessageType(com.faforever.server.integration.legacy.LegacyClientMessageType) PlayerOptionReport(com.faforever.server.game.PlayerOptionReport) GameOptionReport(com.faforever.server.game.GameOptionReport) ProgrammingError(com.faforever.server.error.ProgrammingError) RequestException(com.faforever.server.error.RequestException) IceMessage(com.faforever.server.ice.IceMessage) JoinGameRequest(com.faforever.server.game.JoinGameRequest)

Example 2 with RequestException

use of com.faforever.server.error.RequestException in project faf-java-server by FAForever.

the class GameService method createGame.

/**
 * Creates a new, transient game with the specified options and tells the client to start the game process. The
 * player's current game is set to the new game.
 *
 * @return a future that will be completed as soon as the player's game has been started and is ready to be joined. Be
 * aware that there are various reasons for the game to never start (crash, disconnect, abort) so never wait without a
 * timeout.
 */
@Transactional(readOnly = true)
public CompletableFuture<Game> createGame(String title, String featuredModName, String mapFileName, String password, GameVisibility visibility, Integer minRating, Integer maxRating, Player player) {
    Game currentGame = player.getCurrentGame();
    if (currentGame != null && currentGame.getState() == GameState.INITIALIZING) {
        /* Apparently, the user's game crashed before it reached the lobby, leaving it in state INITIALIZING. One solution
      is to let the game time out, but as usual, that's not a good solution since no matter what timeout one chooses,
      there is always some drawback. Therefore, we don't timeout games but reset a player's game state when he tries
      to create a new game. Or when he logs out. */
        removePlayer(currentGame, player);
    }
    Requests.verify(currentGame == null, ErrorCode.ALREADY_IN_GAME);
    int gameId = this.lastGameId.incrementAndGet();
    Game game = new Game(gameId);
    game.setHost(player);
    modService.getFeaturedMod(featuredModName).map(game::setFeaturedMod).orElseThrow(() -> new RequestException(ErrorCode.INVALID_FEATURED_MOD, featuredModName));
    game.setTitle(title);
    mapService.findMap(mapFileName).ifPresent(game::setMapVersion);
    game.setMapName(mapFileName);
    game.setPassword(password);
    game.setGameVisibility(visibility);
    game.setMinRating(minRating);
    game.setMaxRating(maxRating);
    activeGamesById.put(game.getId(), game);
    counterService.increment(String.format(Metrics.GAMES_STATE_FORMAT, game.getState()));
    log.debug("Player '{}' created game '{}'", player, game);
    clientService.startGameProcess(game, player);
    player.setCurrentGame(game);
    changePlayerGameState(player, PlayerGameState.INITIALIZING);
    CompletableFuture<Game> gameJoinedFuture = new CompletableFuture<>();
    player.setGameFuture(gameJoinedFuture);
    return game.getJoinableFuture();
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) Game(com.faforever.server.entity.Game) RequestException(com.faforever.server.error.RequestException) Transactional(org.springframework.transaction.annotation.Transactional)

Example 3 with RequestException

use of com.faforever.server.error.RequestException in project faf-java-server by FAForever.

the class GameService method updatePlayerOption.

/**
 * Updates an option value of a specific player. Only the host of a game is allowed to report such options and for
 * unstarted games, otherwise an exception will be thrown.
 *
 * @throws RequestException if the reporting player is not the host, or if the game is not in state {@link
 * GameState#OPEN}
 */
public void updatePlayerOption(Player reporter, int playerId, String key, Object value) {
    Game game = reporter.getCurrentGame();
    if (game == null) {
        // Since this is called repeatedly, throwing exceptions here would not be a good idea. Happens after restarts.
        log.warn("Received player option for player w/o game: {}", reporter);
        return;
    }
    Requests.verify(game.getState() == GameState.OPEN, ErrorCode.INVALID_GAME_STATE, game.getState(), GameState.OPEN);
    Requests.verify(Objects.equals(reporter.getCurrentGame().getHost(), reporter), ErrorCode.HOST_ONLY_OPTION, key);
    if (!game.getConnectedPlayers().containsKey(playerId)) {
        log.warn("Player '{}' reported option '{}' with value '{}' for unknown player '{}' in game '{}'", reporter, key, value, playerId, game);
        return;
    }
    log.trace("Updating option for player '{}' in game '{}': '{}' = '{}'", playerId, game.getId(), key, value);
    game.getPlayerOptions().computeIfAbsent(playerId, id -> new HashMap<>()).put(key, value);
    markDirty(game, DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY);
}
Also used : Arrays(java.util.Arrays) ProgrammingError(com.faforever.server.error.ProgrammingError) ModVersion(com.faforever.server.entity.ModVersion) BiFunction(java.util.function.BiFunction) ArmyResult(com.faforever.server.entity.ArmyResult) PlayerOfflineEvent(com.faforever.server.player.PlayerOfflineEvent) PlayerService(com.faforever.server.player.PlayerService) Metrics(com.faforever.server.stats.Metrics) Player(com.faforever.server.entity.Player) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) Pair(org.springframework.data.util.Pair) ArmyStatistics(com.faforever.server.stats.ArmyStatistics) ClientService(com.faforever.server.client.ClientService) CounterService(org.springframework.boot.actuate.metrics.CounterService) ConnectionAware(com.faforever.server.client.ConnectionAware) RatingService(com.faforever.server.rating.RatingService) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) EventListener(org.springframework.context.event.EventListener) ErrorCode(com.faforever.server.error.ErrorCode) Streams(com.google.common.collect.Streams) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) GameState(com.faforever.server.entity.GameState) MapService(com.faforever.server.map.MapService) Ladder1v1Rating(com.faforever.server.entity.Ladder1v1Rating) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Requests(com.faforever.server.error.Requests) Stream(java.util.stream.Stream) DivisionService(com.faforever.server.ladder1v1.DivisionService) RatingType(com.faforever.server.rating.RatingType) Game(com.faforever.server.entity.Game) GlobalRating(com.faforever.server.entity.GlobalRating) Entry(java.util.Map.Entry) Optional(java.util.Optional) RequestException(com.faforever.server.error.RequestException) Joiner(com.google.common.base.Joiner) ModService(com.faforever.server.mod.ModService) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) FeaturedMod(com.faforever.server.entity.FeaturedMod) Validity(com.faforever.server.entity.Validity) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) VictoryCondition(com.faforever.server.entity.VictoryCondition) GameResponses(com.faforever.server.client.GameResponses) Service(org.springframework.stereotype.Service) ServerProperties(com.faforever.server.config.ServerProperties) Iterator(java.util.Iterator) FeaturedModFileVersion(com.faforever.server.game.GameResponse.FeaturedModFileVersion) EntityManager(javax.persistence.EntityManager) Consumer(java.util.function.Consumer) SimMod(com.faforever.server.game.GameResponse.SimMod) ContextRefreshedEvent(org.springframework.context.event.ContextRefreshedEvent) ArmyStatisticsService(com.faforever.server.stats.ArmyStatisticsService) PlayerOnlineEvent(com.faforever.server.player.PlayerOnlineEvent) GamePlayerStats(com.faforever.server.entity.GamePlayerStats) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Transactional(org.springframework.transaction.annotation.Transactional) Assert(org.springframework.util.Assert) Game(com.faforever.server.entity.Game) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 4 with RequestException

use of com.faforever.server.error.RequestException in project faf-java-server by FAForever.

the class GameService method updateAiOption.

/**
 * Updates an option value of a specific AI player. Only the host of a game is allowed to report such options,
 * otherwise an exception will be thrown.
 *
 * @throws RequestException if the reporting player is not the host
 */
public void updateAiOption(Player reporter, String aiName, String key, Object value) {
    Game game = reporter.getCurrentGame();
    if (game == null) {
        // Since this is called repeatedly, throwing exceptions here would not be a good idea. Happens after restarts.
        log.warn("Received AI option for player w/o game: {}", reporter);
        return;
    }
    Requests.verify(Objects.equals(reporter.getCurrentGame().getHost(), reporter), ErrorCode.HOST_ONLY_OPTION, key);
    if (!OPTION_ARMY.equals(key)) {
        log.trace("Ignoring option '{}' = '{}' for AI '{}' in game '{}' because only the option 'Army' is currently sent with the correct, final AI name", key, value, aiName, game.getId());
        return;
    }
    log.trace("Updating option for AI '{}' in game '{}': '{}' = '{}'", aiName, game.getId(), key, value);
    game.getAiOptions().computeIfAbsent(aiName, s -> new HashMap<>()).put(key, value);
    markDirty(game, DEFAULT_MIN_DELAY, DEFAULT_MAX_DELAY);
}
Also used : Arrays(java.util.Arrays) ProgrammingError(com.faforever.server.error.ProgrammingError) ModVersion(com.faforever.server.entity.ModVersion) BiFunction(java.util.function.BiFunction) ArmyResult(com.faforever.server.entity.ArmyResult) PlayerOfflineEvent(com.faforever.server.player.PlayerOfflineEvent) PlayerService(com.faforever.server.player.PlayerService) Metrics(com.faforever.server.stats.Metrics) Player(com.faforever.server.entity.Player) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Map(java.util.Map) Pair(org.springframework.data.util.Pair) ArmyStatistics(com.faforever.server.stats.ArmyStatistics) ClientService(com.faforever.server.client.ClientService) CounterService(org.springframework.boot.actuate.metrics.CounterService) ConnectionAware(com.faforever.server.client.ConnectionAware) RatingService(com.faforever.server.rating.RatingService) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) EventListener(org.springframework.context.event.EventListener) ErrorCode(com.faforever.server.error.ErrorCode) Streams(com.google.common.collect.Streams) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) GameState(com.faforever.server.entity.GameState) MapService(com.faforever.server.map.MapService) Ladder1v1Rating(com.faforever.server.entity.Ladder1v1Rating) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Requests(com.faforever.server.error.Requests) Stream(java.util.stream.Stream) DivisionService(com.faforever.server.ladder1v1.DivisionService) RatingType(com.faforever.server.rating.RatingType) Game(com.faforever.server.entity.Game) GlobalRating(com.faforever.server.entity.GlobalRating) Entry(java.util.Map.Entry) Optional(java.util.Optional) RequestException(com.faforever.server.error.RequestException) Joiner(com.google.common.base.Joiner) ModService(com.faforever.server.mod.ModService) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) FeaturedMod(com.faforever.server.entity.FeaturedMod) Validity(com.faforever.server.entity.Validity) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) VictoryCondition(com.faforever.server.entity.VictoryCondition) GameResponses(com.faforever.server.client.GameResponses) Service(org.springframework.stereotype.Service) ServerProperties(com.faforever.server.config.ServerProperties) Iterator(java.util.Iterator) FeaturedModFileVersion(com.faforever.server.game.GameResponse.FeaturedModFileVersion) EntityManager(javax.persistence.EntityManager) Consumer(java.util.function.Consumer) SimMod(com.faforever.server.game.GameResponse.SimMod) ContextRefreshedEvent(org.springframework.context.event.ContextRefreshedEvent) ArmyStatisticsService(com.faforever.server.stats.ArmyStatisticsService) PlayerOnlineEvent(com.faforever.server.player.PlayerOnlineEvent) GamePlayerStats(com.faforever.server.entity.GamePlayerStats) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Comparator(java.util.Comparator) Transactional(org.springframework.transaction.annotation.Transactional) Assert(org.springframework.util.Assert) Game(com.faforever.server.entity.Game) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 5 with RequestException

use of com.faforever.server.error.RequestException in project faf-java-server by FAForever.

the class IntegrationConfig method requestExceptionTransformer.

/**
 * Transformer that transforms a {@link MessageHandlingException} into and {@link ErrorResponse}.
 */
private AbstractTransformer requestExceptionTransformer() {
    return new AbstractTransformer() {

        @Override
        protected Object doTransform(Message<?> message) throws Exception {
            MessagingException messageException = (MessagingException) message.getPayload();
            Message<?> failedMessage = messageException.getFailedMessage();
            // TODO try to make more intuitive? Meanwhile, look at requestExceptionFilter() to understand.
            RequestException requestException;
            if (messageException instanceof MessageTransformationException) {
                requestException = (RequestException) messageException.getCause().getCause();
            } else {
                requestException = (RequestException) messageException.getCause();
            }
            MessageBuilder<ErrorResponse> builder = MessageBuilder.withPayload(new ErrorResponse(requestException.getErrorCode(), requestException.getRequestId(), requestException.getArgs())).copyHeaders(message.getHeaders());
            builder.setHeader(CLIENT_CONNECTION, failedMessage.getHeaders().get(CLIENT_CONNECTION, ClientConnection.class));
            return builder.build();
        }
    };
}
Also used : AbstractTransformer(org.springframework.integration.transformer.AbstractTransformer) MessageTransformationException(org.springframework.integration.transformer.MessageTransformationException) IceMessage(com.faforever.server.ice.IceMessage) Message(org.springframework.messaging.Message) MessagingException(org.springframework.messaging.MessagingException) ClientConnection(com.faforever.server.client.ClientConnection) RequestException(com.faforever.server.error.RequestException) ErrorResponse(com.faforever.server.error.ErrorResponse)

Aggregations

RequestException (com.faforever.server.error.RequestException)8 Game (com.faforever.server.entity.Game)4 Player (com.faforever.server.entity.Player)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 Transactional (org.springframework.transaction.annotation.Transactional)4 ClientService (com.faforever.server.client.ClientService)3 ConnectionAware (com.faforever.server.client.ConnectionAware)3 ServerProperties (com.faforever.server.config.ServerProperties)3 FeaturedMod (com.faforever.server.entity.FeaturedMod)3 Ladder1v1Rating (com.faforever.server.entity.Ladder1v1Rating)3 ErrorCode (com.faforever.server.error.ErrorCode)3 ProgrammingError (com.faforever.server.error.ProgrammingError)3 Requests (com.faforever.server.error.Requests)3 MapService (com.faforever.server.map.MapService)3 ModService (com.faforever.server.mod.ModService)3 PlayerService (com.faforever.server.player.PlayerService)3 RatingService (com.faforever.server.rating.RatingService)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 Duration (java.time.Duration)3 Instant (java.time.Instant)3