public synchronized void startTournament(UUID userId) { try { if (userId.equals(this.userId) && table.getState().equals(TableState.STARTING)) { tournament.setStartTime(); TournamentManager.getInstance() .createTournamentSession(tournament, userPlayerMap, table.getId()); for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { User user = UserManager.getInstance().getUser(entry.getKey()); if (user != null) { logger.info( new StringBuilder("User ") .append(user.getName()) .append(" tournament started: ") .append(tournament.getId()) .append(" userId: ") .append(user.getId())); user.ccTournamentStarted(tournament.getId(), entry.getValue()); } } ServerMessagesUtil.getInstance().incTournamentsStarted(); } } catch (Exception ex) { logger.fatal("Error starting tournament", ex); TableManager.getInstance().removeTable(table.getId()); TournamentManager.getInstance().quit(tournament.getId(), userId); } }
public TableController(UUID roomId, UUID userId, TournamentOptions options) { this.userId = userId; tournament = TournamentFactory.getInstance().createTournament(options.getTournamentType(), options); if (userId != null) { User user = UserManager.getInstance().getUser(userId); if (user == null) { logger.fatal( new StringBuilder("User for userId ") .append(userId) .append(" could not be retrieved from UserManager") .toString()); controllerName = "[unknown]"; } else { controllerName = user.getName(); } } else { controllerName = "System"; } table = new Table( roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.getInstance() .createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), tournament); chatId = ChatManager.getInstance().createChatSession("Tourn. table " + table.getId()); }
@Override public TableView createTournamentTable(UUID userId, TournamentOptions options) { Table table = TableManager.getInstance().createTournamentTable(this.getRoomId(), userId, options); tables.put(table.getId(), table); return new TableView(table); }
private void submitDeck(UUID userId, UUID playerId, Deck deck) { if (table.getState() == TableState.SIDEBOARDING) { match.submitDeck(playerId, deck); UserManager.getInstance().getUser(userId).removeSideboarding(table.getId()); } else { TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck); UserManager.getInstance().getUser(userId).removeConstructing(playerId); } }
private void sideboard(UUID playerId, Deck deck) throws MageException { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { if (entry.getValue().equals(playerId)) { User user = UserManager.getInstance().getUser(entry.getKey()); int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS); if (user != null) { user.ccSideboard(deck, table.getId(), remaining, options.isLimited()); } break; } } }
public synchronized boolean changeTableStateToStarting() { if (!getTable().getState().equals(TableState.READY_TO_START)) { // tournament is not ready, can't start return false; } if (!table.allSeatsAreOccupied()) { logger.debug("Not alle Seats are occupied: stop start tableId:" + table.getId()); return false; } getTable().setState(TableState.STARTING); return true; }
private void checkExpired() { debugServerState(); Date now = new Date(); List<UUID> toRemove = new ArrayList<>(); for (Table table : tables.values()) { if (!table.getState().equals(TableState.FINISHED)) { // remove all not finished tables created more than expire_time ago long diff = (now.getTime() - table.getCreateTime().getTime()) / EXPIRE_TIME_UNIT_VALUE; if (diff >= EXPIRE_TIME) { logger.warn( "Table expired: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing..."); toRemove.add(table.getId()); } // remove tables not valid anymore else if (!table.isTournament()) { TableController tableController = getController(table.getId()); if (!tableController.isMatchTableStillValid()) { logger.warn( "Table with no active human player: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing..."); toRemove.add(table.getId()); } } } } for (UUID tableId : toRemove) { try { removeTable(tableId); } catch (Exception e) { logger.error(e); } } }
private void updateDeck(UUID userId, UUID playerId, Deck deck) { if (table.isTournament()) { if (tournament != null) { TournamentManager.getInstance().updateDeck(tournament.getId(), playerId, deck); } else { logger.fatal("Tournament == null table: " + table.getId() + " userId: " + userId); } } else if (TableState.SIDEBOARDING.equals(table.getState())) { match.updateDeck(playerId, deck); } else { // deck was meanwhile submitted so the autoupdate can be ignored } }
public synchronized boolean replaceDraftPlayer( Player oldPlayer, String name, String playerType, int skill) { Player newPlayer = createPlayer(name, playerType, skill); if (newPlayer == null || table.getState() != TableState.DRAFTING) { return false; } TournamentPlayer oldTournamentPlayer = tournament.getPlayer(oldPlayer.getId()); tournament.removePlayer(oldPlayer.getId()); tournament.addPlayer(newPlayer, playerType); TournamentPlayer newTournamentPlayer = tournament.getPlayer(newPlayer.getId()); newTournamentPlayer.setState(oldTournamentPlayer.getState()); newTournamentPlayer.setReplacedTournamentPlayer(oldTournamentPlayer); DraftManager.getInstance().getController(table.getId()).replacePlayer(oldPlayer, newPlayer); return true; }
public void debugServerState() { logger.debug("--- Server state ----------------------------------------------"); Collection<User> users = UserManager.getInstance().getUsers(); logger.debug( "--------User: "******" [userId | since | name -----------------------"); for (User user : users) { logger.debug( user.getId() + " | " + formatter.format(user.getConnectionTime()) + " | " + user.getName() + " (" + user.getUserState().toString() + ")"); } ArrayList<ChatSession> chatSessions = ChatManager.getInstance().getChatSessions(); logger.debug( "------- ChatSessions: " + chatSessions.size() + " ----------------------------------"); for (ChatSession chatSession : chatSessions) { logger.debug( chatSession.getChatId() + " " + formatter.format(chatSession.getCreateTime()) + " " + chatSession.getInfo() + " " + chatSession.getClients().values().toString()); } logger.debug( "------- Tables: " + tables.size() + " --------------------------------------------"); for (Table table : tables.values()) { logger.debug( table.getId() + " [" + table.getName() + "] " + formatter.format(table.getStartTime()) + " (" + table.getState().toString() + ")"); } logger.debug("--- Server state END ------------------------------------------"); }
public void startDraft(Draft draft) { table.initDraft(); DraftManager.getInstance().createDraftSession(draft, userPlayerMap, table.getId()); for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { User user = UserManager.getInstance().getUser(entry.getKey()); if (user != null) { logger.info( new StringBuilder("User ") .append(user.getName()) .append(" draft started: ") .append(draft.getId()) .append(" userId: ") .append(user.getId())); user.ccDraftStarted(draft.getId(), entry.getValue()); } else { logger.fatal( new StringBuilder("Start draft user not found userId: ").append(entry.getKey())); } } }
public TableController(UUID roomId, UUID userId, MatchOptions options) { this.userId = userId; this.options = options; match = GameFactory.getInstance().createMatch(options.getGameType(), options); if (userId != null) { User user = UserManager.getInstance().getUser(userId); // TODO: Handle if user == null controllerName = user.getName(); } else { controllerName = "System"; } table = new Table( roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), match); chatId = ChatManager.getInstance().createChatSession("Match Table " + table.getId()); init(); }
public synchronized boolean joinTournament( UUID userId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws GameException { if (table.getState() != TableState.WAITING) { return false; } Seat seat = table.getNextAvailableSeat(playerType); if (seat == null) { throw new GameException("No available seats."); } User user = UserManager.getInstance().getUser(userId); if (user == null) { logger.fatal( new StringBuilder("couldn't get user ") .append(name) .append(" for join tournament userId = ") .append(userId) .toString()); return false; } // check password if (!table.getTournament().getOptions().getPassword().isEmpty() && playerType.equals("Human")) { if (!table.getTournament().getOptions().getPassword().equals(password)) { user.showUserMessage("Join Table", "Wrong password."); return false; } } if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) { user.showUserMessage("Join Table", "You can join a table only one time."); return false; } Deck deck = null; if (!table.getTournament().getTournamentType().isLimited()) { if (deckList != null) { deck = Deck.load(deckList, false, false); } else { user.showUserMessage("Join Table", "No valid deck selected!"); return false; } if (!Main.isTestMode() && !table.getValidator().validate(deck)) { StringBuilder sb = new StringBuilder("You (") .append(name) .append(") have an invalid deck for the selected ") .append(table.getValidator().getName()) .append(" Format. \n\n"); for (Map.Entry<String, String> entry : table.getValidator().getInvalid().entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!"); user.showUserMessage("Join Table", sb.toString()); if (isOwner(userId)) { logger.debug( "New table removed because owner submitted invalid deck tableId " + table.getId()); TableManager.getInstance().removeTable(table.getId()); } return false; } } // Check quit ratio. int quitRatio = table.getTournament().getOptions().getQuitRatio(); if (quitRatio < user.getTourneyQuitRatio()) { String message = new StringBuilder("Your quit ratio ") .append(user.getTourneyQuitRatio()) .append("% is higher than the table requirement ") .append(quitRatio) .append("%") .toString(); user.showUserMessage("Join Table", message); return false; } Player player = createPlayer(name, seat.getPlayerType(), skill); if (player != null) { if (!player.canJoinTable(table)) { user.showUserMessage( "Join Table", new StringBuilder("A ") .append(seat.getPlayerType()) .append(" player can't join this table.") .toString()); return false; } tournament.addPlayer(player, seat.getPlayerType()); TournamentPlayer tournamentPlayer = tournament.getPlayer(player.getId()); if (deck != null && tournamentPlayer != null) { tournamentPlayer.submitDeck(deck); } table.joinTable(player, seat); logger.debug( "Player " + player.getName() + " id: " + player.getId() + " joined tableId: " + table.getId()); // only inform human players and add them to sessionPlayerMap if (seat.getPlayer().isHuman()) { seat.getPlayer().setUserData(user.getUserData()); user.addTable(player.getId(), table); user.ccJoinedTable(table.getRoomId(), table.getId(), true); userPlayerMap.put(userId, player.getId()); } return true; } else { throw new GameException("Playertype " + seat.getPlayerType() + " could not be created."); } }
private void startGame(UUID choosingPlayerId) throws GameException { try { match.startGame(); table.initGame(); GameOptions gameOptions = new GameOptions(); gameOptions.rollbackTurnsAllowed = match.getOptions().isRollbackTurnsAllowed(); match.getGame().setGameOptions(gameOptions); GameManager.getInstance() .createGameSession( match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions); String creator = null; StringBuilder opponent = new StringBuilder(); for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { // no AI players if (match.getPlayer(entry.getValue()) != null && !match.getPlayer(entry.getValue()).hasQuit()) { User user = UserManager.getInstance().getUser(entry.getKey()); if (user != null) { user.ccGameStarted(match.getGame().getId(), entry.getValue()); if (creator == null) { creator = user.getName(); } else { if (opponent.length() > 0) { opponent.append(" - "); } opponent.append(user.getName()); } } else { logger.error( "Unable to find user: "******" playerId: " + entry.getValue()); MatchPlayer matchPlayer = match.getPlayer(entry.getValue()); if (matchPlayer != null && !matchPlayer.hasQuit()) { matchPlayer.setQuit(true); } } } } // Append AI opponents to the log file for (MatchPlayer mPlayer : match.getPlayers()) { if (!mPlayer.getPlayer().isHuman()) { if (opponent.length() > 0) { opponent.append(" - "); } opponent.append(mPlayer.getName()); } } ServerMessagesUtil.getInstance().incGamesStarted(); // log about game started logger.info( "GAME started " + (match.getGame() != null ? match.getGame().getId() : "no Game") + " [" + match.getName() + "] " + creator + " - " + opponent.toString()); logger.debug("- matchId: " + match.getId() + " [" + match.getName() + "]"); if (match.getGame() != null) { logger.debug("- chatId: " + GameManager.getInstance().getChatId(match.getGame().getId())); } } catch (Exception ex) { logger.fatal("Error starting game table: " + table.getId(), ex); if (table != null) { TableManager.getInstance().removeTable(table.getId()); } if (match != null) { Game game = match.getGame(); if (game != null) { GameManager.getInstance().removeGame(game.getId()); } } } }
public synchronized void leaveTable(UUID userId) { if (table == null) { logger.error("No table object - userId: " + userId); return; } if (table.isTournament() && tournament == null) { logger.error("No tournament object - userId: " + userId + " table: " + table.getId()); return; } if (table != null && this.userId != null && this.userId.equals(userId) // tourn. sub tables have no creator user && (table.getState().equals(TableState.WAITING) || table.getState().equals(TableState.READY_TO_START))) { // table not started yet and user is the owner, remove the table TableManager.getInstance().removeTable(table.getId()); } else { UUID playerId = userPlayerMap.get(userId); if (playerId != null) { if (table.getState() == TableState.WAITING || table.getState() == TableState.READY_TO_START) { table.leaveNotStartedTable(playerId); if (table.isTournament()) { tournament.removePlayer(playerId); } else { match.quitMatch(playerId); } User user = UserManager.getInstance().getUser(userId); if (user != null) { ChatManager.getInstance() .broadcast( chatId, user.getName(), "has left the table", ChatMessage.MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, ChatMessage.SoundToPlay.PlayerLeft); if (!table.isTournamentSubTable()) { user.removeTable(playerId); } } else { logger.debug("User not found - userId: " + userId + " tableId:" + table.getId()); } userPlayerMap.remove(userId); } else if (!table.getState().equals(TableState.FINISHED)) { if (table.isTournament()) { logger.debug("Quit tournament sub tables for userId: " + userId); TableManager.getInstance().userQuitTournamentSubTables(tournament.getId(), userId); logger.debug( "Quit tournament Id: " + table.getTournament().getId() + "(" + table.getTournament().getTournamentState() + ")"); TournamentManager.getInstance().quit(tournament.getId(), userId); } else { MatchPlayer matchPlayer = match.getPlayer(playerId); if (matchPlayer != null && !match.hasEnded() && !matchPlayer.hasQuit()) { Game game = match.getGame(); if (game != null && !game.hasEnded()) { Player player = match.getPlayer(playerId).getPlayer(); if (player != null && player.isInGame()) { GameManager.getInstance().quitMatch(game.getId(), userId); } match.quitMatch(playerId); } else { if (table.getState().equals(TableState.SIDEBOARDING)) { if (!matchPlayer.isDoneSideboarding()) { // submit deck to finish sideboarding and trigger match start / end matchPlayer.submitDeck(matchPlayer.getDeck()); } } match.quitMatch(playerId); } } } } } else { logger.error("No playerId found for userId: " + userId); } } }
private void update() { ArrayList<TableView> tableList = new ArrayList<>(); ArrayList<MatchView> matchList = new ArrayList<>(); List<Table> allTables = new ArrayList<>(tables.values()); Collections.sort(allTables, new TableListSorter()); for (Table table : allTables) { if (table.getState() != TableState.FINISHED) { tableList.add(new TableView(table)); } else if (matchList.size() < 50) { matchList.add(new MatchView(table)); } else { // more since 50 matches finished since this match so remove it if (table.isTournament()) { TournamentManager.getInstance().removeTournament(table.getTournament().getId()); } this.removeTable(table.getId()); } } tableView = tableList; matchView = matchList; List<UsersView> users = new ArrayList<>(); for (User user : UserManager.getInstance().getUsers()) { try { users.add( new UsersView( user.getUserData().getFlagName(), user.getName(), user.getMatchHistory(), user.getMatchQuitRatio(), user.getTourneyHistory(), user.getTourneyQuitRatio(), user.getGameInfo(), user.getPingInfo())); } catch (Exception ex) { logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex); users.add( new UsersView( (user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world", user.getName() != null ? user.getName() : "<no name>", user.getMatchHistory() != null ? user.getMatchHistory() : "<no match history>", user.getMatchQuitRatio(), user.getTourneyHistory() != null ? user.getTourneyHistory() : "<no tourney history>", user.getTourneyQuitRatio(), "[exception]", user.getPingInfo() != null ? user.getPingInfo() : "<no ping>")); } } Collections.sort(users, new UserNameSorter()); List<RoomUsersView> roomUserInfo = new ArrayList<>(); roomUserInfo.add( new RoomUsersView( users, GameManager.getInstance().getNumberActiveGames(), ThreadExecutor.getInstance() .getActiveThreads(ThreadExecutor.getInstance().getGameExecutor()), ConfigSettings.getInstance().getMaxGameThreads())); roomUsersView = roomUserInfo; }
public synchronized boolean joinTable( UUID userId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException { User user = UserManager.getInstance().getUser(userId); if (user == null) { return false; } if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) { user.showUserMessage( "Join Table", new StringBuilder("You can join a table only one time.").toString()); return false; } if (table.getState() != TableState.WAITING) { user.showUserMessage("Join Table", "No available seats."); return false; } // check password if (!table.getMatch().getOptions().getPassword().isEmpty() && playerType.equals("Human")) { if (!table.getMatch().getOptions().getPassword().equals(password)) { user.showUserMessage("Join Table", "Wrong password."); return false; } } Seat seat = table.getNextAvailableSeat(playerType); if (seat == null) { user.showUserMessage("Join Table", "No available seats."); return false; } Deck deck = Deck.load(deckList, false, false); if (!Main.isTestMode() && !table.getValidator().validate(deck)) { StringBuilder sb = new StringBuilder("You (") .append(name) .append(") have an invalid deck for the selected ") .append(table.getValidator().getName()) .append(" Format. \n\n"); for (Map.Entry<String, String> entry : table.getValidator().getInvalid().entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!"); user.showUserMessage("Join Table", sb.toString()); if (isOwner(userId)) { logger.debug( "New table removed because owner submitted invalid deck tableId " + table.getId()); TableManager.getInstance().removeTable(table.getId()); } return false; } // Check quit ratio. int quitRatio = table.getMatch().getOptions().getQuitRatio(); if (quitRatio < user.getMatchQuitRatio()) { String message = new StringBuilder("Your quit ratio ") .append(user.getMatchQuitRatio()) .append("% is higher than the table requirement ") .append(quitRatio) .append("%") .toString(); user.showUserMessage("Join Table", message); return false; } // Check power level for table (currently only used for EDH/Commander table) int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel(); if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase().equals("commander")) { int deckEdhPowerLevel = table.getValidator().getEdhPowerLevel(deck); if (deckEdhPowerLevel > edhPowerLevel) { String message = new StringBuilder( "Your deck appears to be too powerful for this table.\n\nReduce the number of extra turn cards, infect, counters, fogs, reconsider your commander. ") .append("\nThe table requirement has a maximum power level of ") .append(edhPowerLevel) .append(" whilst your deck has a calculated power level of ") .append(deckEdhPowerLevel) .toString(); user.showUserMessage("Join Table", message); return false; } } Player player = createPlayer(name, seat.getPlayerType(), skill); if (player == null) { String message = new StringBuilder("Could not create player ") .append(name) .append(" of type ") .append(seat.getPlayerType()) .toString(); logger.warn( new StringBuilder("User: "******" => ") .append(message) .toString()); user.showUserMessage("Join Table", message); return false; } logger.debug( "DECK validated: " + table.getValidator().getName() + " " + player.getName() + " " + deck.getName()); if (!player.canJoinTable(table)) { user.showUserMessage( "Join Table", new StringBuilder("A ") .append(seat.getPlayerType()) .append(" player can't join this table.") .toString()); return false; } match.addPlayer(player, deck); table.joinTable(player, seat); logger.trace(player.getName() + " joined tableId: " + table.getId()); // only inform human players and add them to sessionPlayerMap if (seat.getPlayer().isHuman()) { seat.getPlayer().setUserData(user.getUserData()); if (!table.isTournamentSubTable()) { user.addTable(player.getId(), table); } user.ccJoinedTable(table.getRoomId(), table.getId(), false); userPlayerMap.put(userId, player.getId()); } return true; }