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);
}
}
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();
}
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);
}
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);
}
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();
}
};
}
Aggregations