private IMPL createFreshGame( final Set<FEATURES> features, final List<Player<ID>> players, final Player<ID> initiatingPlayer) { IMPL game = newGame(); game.setRound(1); game.setGamePhase(GamePhase.Challenged); game.setVersion(null); game.getFeatures().addAll(features); game.setInitiatingPlayer(initiatingPlayer.getId()); game.getPlayers().addAll(players); if (!game.getPlayers().contains(initiatingPlayer)) { game.getPlayers().add(initiatingPlayer); } return game; }
@Override public void initializeGame(final AbstractGame game) { if (game instanceof AbstractMultiPlayerGame) { //noinspection unchecked final AbstractMultiPlayerGame<ID, FEATURES> multiPlayerGame = (AbstractMultiPlayerGame<ID, FEATURES>) game; final Map<ID, PlayerState> playerStates = multiPlayerGame.getPlayerStates(); List<Player<ID>> players = multiPlayerGame.getPlayers(); players.forEach(p -> playerStates.put(p.getId(), PlayerState.Pending)); playerStates.put(multiPlayerGame.getInitiatingPlayer(), PlayerState.Accepted); } }
@Override public void gameChanged(final IMPL game, final P initiatingPlayer, final boolean initiatingServer) { if (broadcasterFactory.getBroadcasterFactory() != null) { try { //noinspection unchecked List<P> players = game.getAllPlayers().stream() .map(p -> (P) p) .filter(x -> initiatingPlayer == null || !x.equals(initiatingPlayer)) .collect(Collectors.toList()); logger.trace( "Publishing {} to {} players.", game.getIdAsString(), players.size()); players.forEach(player -> publishWithRetry(new PlayerCallable() { @Override public Boolean call() throws Exception { return publishGameToPlayer(player, game); } })); } catch (Exception e) { logger.error("Error publishing game " + game.getId(), e); } } else { logger.warn("No broadcaster in game changed"); } }
@Override protected void copyMaskedData(final IMPL game, final Player<ID> player, final M playerMaskedGame, final Map<ID, Player<ID>> idMap) { super.copyMaskedData(game, player, playerMaskedGame, idMap); playerMaskedGame.setMaskedForPlayerMD5(player.getMd5()); playerMaskedGame.setMaskedForPlayerID(player.getIdAsString()); game.getAllPlayers().forEach(p -> { playerMaskedGame.getPlayers().put(p.getMd5(), p.getDisplayName()); playerMaskedGame.getPlayerImages().put(p.getMd5(), p.getImageUrl()); playerMaskedGame.getPlayerProfiles().put(p.getMd5(), p.getProfileUrl()); playerMaskedGame.getPlayerStates().put(p.getMd5(), game.getPlayerStates().get(p.getId())); }); playerMaskedGame.setInitiatingPlayer(idMap.get(game.getInitiatingPlayer()).getMd5()); }
@Override protected void copyUnmaskedData(final IMPL game, final M playerMaskedGame) { super.copyUnmaskedData(game, playerMaskedGame); playerMaskedGame.setDeclinedTimestamp(convertTime(game.getDeclinedTimestamp())); playerMaskedGame.setRematchTimestamp(convertTime(game.getRematchTimestamp())); } }
private boolean publishGameToPlayer(final P player, final IMPL game) { logger.trace("Publishing game update on game " + game.getId() + " to player " + player.getId()); final boolean[] status = new boolean[]{false}; try { Broadcaster broadcaster = broadcasterFactory.getBroadcasterFactory() .lookup(LiveFeedService.PATH_ROOT + player.getIdAsString()); if (broadcaster != null) { WebSocketMessage message = new WebSocketMessage(); message.setMessageType(MessageType.Game); message.setGame(gameMasker.maskGameForPlayer(game, player)); broadcaster.broadcast(message); status[0] = true; } else { logger.trace( "Player {} is not connected to this server for {}.", player.getIdAsString(), game.getIdAsString()); } } catch (Exception e) { logger.error("Error publishing game " + game.getId() + " to player " + player.getId(), e); } publicationListeners.forEach(listener -> { try { listener.publishedGameUpdateToPlayer(player, game, status[0]); } catch (Exception e) { logger.error("Error publishing to publication listener", e); } }); return status[0]; }
private List<Player<ID>> rotatePlayers(final IMPL previousGame) { List<Player<ID>> players = new ArrayList<>(); players.addAll(previousGame.getPlayers()); players.add(players.remove(0)); return players; }
@SuppressWarnings("WeakerAccess") protected IMPL changeStateAndReevaluate(final GamePhase transitionTo, final IMPL game) { game.setGamePhase(transitionTo); return evaluateGame(game); } }
@Override protected IMPL evaluateChallengedPhase(final IMPL game) { Optional rejected = game.getPlayerStates().values() .stream() .filter(PlayerState.Rejected::equals) .findAny(); if (rejected.isPresent()) { return changeStateAndReevaluate(GamePhase.Declined, game); } else { Optional pending = game.getPlayerStates().values() .stream() .filter(PlayerState.Pending::equals) .findAny(); if (!pending.isPresent()) { return changeStateAndReevaluate(GamePhase.Setup, game); } } return game; }
@Override protected IMPL evaluateRoundOverPhase(final IMPL game) { if (game.getRematchTimestamp() != null) { return changeStateAndReevaluate(GamePhase.NextRoundStarted, game); } return super.evaluateRoundOverPhase(game); }
@Override public IMPL createGame(final IMPL previousGame, final Player<ID> initiatingPlayer) { List<Player<ID>> players = rotatePlayers(previousGame); IMPL game = createFreshGame(previousGame.getFeatures(), players, initiatingPlayer); copyFromPreviousGame(previousGame, game); prepareGame(game); return game; }
@Override public boolean validateGame(final IMPL game) { if (game instanceof AbstractMultiPlayerGame) { //noinspection unchecked AbstractMultiPlayerGame<ID, FEATURES> multiPlayerGame = (AbstractMultiPlayerGame<ID, FEATURES>) game; List<Player<ID>> players = multiPlayerGame.getPlayers(); List<ID> ids = players.stream().map(Player::getId).collect(Collectors.toList()); Iterable<? extends AbstractPlayer<ID>> loaded = playerRepository.findAllById(ids); long active = StreamSupport.stream(loaded.spliterator(), false) .filter(x -> !x.isDisabled()) .count(); return active == players.size(); } else if (game instanceof AbstractSinglePlayerGame) { //noinspection unchecked AbstractSinglePlayerGame<ID, FEATURES> singPlayerGame = (AbstractSinglePlayerGame<ID, FEATURES>) game; Optional<? extends AbstractPlayer<ID>> loaded = playerRepository .findById(singPlayerGame.getPlayer().getId()); return loaded.isPresent() && !loaded.get().isDisabled(); } throw new IllegalArgumentException("unsupported type"); }