diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 07d58fcea6e..0fa3a940233 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -239,25 +239,28 @@ public class MageServerImpl implements MageServer { public TableView execute() throws MageException { UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); User user = UserManager.getInstance().getUser(userId); - - // check if the user satisfies the quitRatio requirement. - if (user != null) { - int quitRatio = options.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("Create table", message); - throw new MageException("No message"); - } + if (user == null) { + logger.error("User for session not found. session = " + sessionId); + return null; + } + // check if user can create another table + int notStartedTables = user.getNumberOfNotStartedTables(); + if (notStartedTables > 1) { + user.showUserMessage("Create table", "You have already " + notStartedTables + " not started table" + (notStartedTables == 1 ? "" : "s") + ". You can't create another."); + throw new MageException("No message"); + } + // check if the user itself satisfies the quitRatio requirement. + int quitRatio = options.getQuitRatio(); + if (quitRatio < user.getMatchQuitRatio()) { + user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + "%"); + throw new MageException("No message"); } TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(userId, options); if (logger.isDebugEnabled()) { - if (user != null) { - logger.debug("TABLE created - tableId: " + table.getTableId() + " " + table.getTableName()); - logger.debug("- " + user.getName() + " userId: " + user.getId()); - logger.debug("- chatId: " + TableManager.getInstance().getChatId(table.getTableId())); - } + logger.debug("TABLE created - tableId: " + table.getTableId() + " " + table.getTableName()); + logger.debug("- " + user.getName() + " userId: " + user.getId()); + logger.debug("- chatId: " + TableManager.getInstance().getChatId(table.getTableId())); } LogServiceImpl.instance.log(LogKeys.KEY_TABLE_CREATED, sessionId, userId.toString(), table.getTableId().toString()); return table; @@ -273,6 +276,16 @@ public class MageServerImpl implements MageServer { try { UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); User user = UserManager.getInstance().getUser(userId); + if (user == null) { + logger.error("User for session not found. session = " + sessionId); + return null; + } + // check if user can create another table + int notStartedTables = user.getNumberOfNotStartedTables(); + if (notStartedTables > 1) { + user.showUserMessage("Create table", "You have already " + notStartedTables + " not started table" + (notStartedTables == 1 ? "" : "s") + ". You can't create another."); + throw new MageException("No message"); + } // check AI players max String maxAiOpponents = ConfigSettings.getInstance().getMaxAiOpponents(); if (maxAiOpponents != null) { @@ -284,21 +297,17 @@ public class MageServerImpl implements MageServer { } } if (aiPlayers > max) { - if (user != null) { - user.showUserMessage("Create tournament", "It's only allowed to use a maximum of " + max + " AI players."); - } + user.showUserMessage("Create tournament", "It's only allowed to use a maximum of " + max + " AI players."); throw new MageException("No message"); } } // check if the user satisfies the quitRatio requirement. - if (user != null) { - int quitRatio = options.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("Create tournament", message); - throw new MageException("No message"); - } + int quitRatio = options.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("Create tournament", message); + throw new MageException("No message"); } TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTournamentTable(userId, options); logger.debug("Tournament table " + table.getTableId() + " created"); diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index 2348e4b3d43..c75784bb40a 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -900,6 +900,22 @@ public class TableController { return null; } + public boolean isUserStillActive(UUID userId) { + UUID playerId = userPlayerMap.get(userId); + if (playerId != null) { + if (tournament != null) { + TournamentPlayer tournamentPlayer = tournament.getPlayer(playerId); + if (tournamentPlayer != null) { + return tournamentPlayer.isInTournament(); + } + } else if (match != null) { + MatchPlayer matchPlayer = match.getPlayer(playerId); + return matchPlayer != null && !matchPlayer.hasQuit(); + } + } + return false; + } + public boolean isMatchTableStillValid() { // check only normal match table with state != Finished if (!table.isTournament()) { diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 866d1da00f6..f223cdfcec8 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import mage.cards.decks.Deck; import mage.constants.ManaType; +import mage.constants.TableState; import mage.game.Table; import mage.game.result.ResultProtos; import mage.game.tournament.TournamentPlayer; @@ -563,8 +564,8 @@ public class User { } public static String userStatsToHistory(ResultProtos.UserStatsProto proto) { - return "Matches:" + userStatsToMatchHistory(proto) + - " Tourneys: " + userStatsToTourneyHistory(proto); + return "Matches:" + userStatsToMatchHistory(proto) + + " Tourneys: " + userStatsToTourneyHistory(proto); } public int getTourneyQuitRatio() { @@ -600,9 +601,9 @@ public class User { if (matches == 0) { return 0; } - int quits = proto.getMatchesIdleTimeout() + - proto.getMatchesTimerTimeout() + - proto.getMatchesQuit(); + int quits = proto.getMatchesIdleTimeout() + + proto.getMatchesTimerTimeout() + + proto.getMatchesQuit(); return 100 * quits / matches; } @@ -632,9 +633,9 @@ public class User { if (tourneys == 0) { return 0; } - int quits = proto.getTourneysQuitDuringDrafting() + - proto.getTourneysQuitDuringConstruction() + - proto.getTourneysQuitDuringRound(); + int quits = proto.getTourneysQuitDuringDrafting() + + proto.getTourneysQuitDuringConstruction() + + proto.getTourneysQuitDuringRound(); return 100 * quits / tourneys; } @@ -647,4 +648,28 @@ public class User { } } + public int getNumberOfNotStartedTables() { + int number = 0; + for (Table table : tables.values()) { + if (table.getState().equals(TableState.WAITING) || table.getState().equals(TableState.STARTING)) { + number++; + } + } + return number; + } + + public int getNumberOfNotFinishedTables() { + int number = 0; + for (Table table : tables.values()) { + if (table.getState().equals(TableState.FINISHED)) { + number++; + } else { + TableController tableController = TableManager.getInstance().getController(table.getId()); + if (tableController != null && tableController.isUserStillActive(userId)) { + number++; + } + } + } + return number; + } } diff --git a/Mage/src/main/java/mage/game/tournament/Tournament.java b/Mage/src/main/java/mage/game/tournament/Tournament.java index 97c3d7f1d43..266edc736ce 100644 --- a/Mage/src/main/java/mage/game/tournament/Tournament.java +++ b/Mage/src/main/java/mage/game/tournament/Tournament.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.game.tournament; import java.util.Collection; @@ -48,56 +47,86 @@ import mage.players.Player; public interface Tournament { UUID getId(); + void addPlayer(Player player, String playerType); + void removePlayer(UUID playerId); + TournamentPlayer getPlayer(UUID playerId); + Collection getPlayers(); + Collection getRounds(); + List getSets(); void updateResults(); + void setBoosterInfo(String setInfo); + /** - * Gives back a String that shows the included sets (e.g. "3xRTR" or "1xDGM 1xGTC 1xRTR") or cube name + * Gives back a String that shows the included sets (e.g. "3xRTR" or "1xDGM + * 1xGTC 1xRTR") or cube name + * * @return String */ String getBoosterInfo(); + void submitDeck(UUID playerId, Deck deck); + void updateDeck(UUID playerId, Deck deck); + void autoSubmit(UUID playerId, Deck deck); + boolean allJoined(); + boolean isDoneConstructing(); + void quit(UUID playerId); + void leave(UUID playerId); + void nextStep(); void addTableEventListener(Listener listener); + void addPlayerQueryEventListener(Listener listener); + void fireConstructEvent(UUID playerId); TournamentOptions getOptions(); - + // tournament times void setStartTime(); + Date getStartTime(); + Date getEndTime(); Date getStepStartTime(); + void setStepStartTime(Date date); // tournament type - TournamentType getTournamentType(); + TournamentType getTournamentType(); + void setTournamentType(TournamentType tournamentType); + // tournamentState - String getTournamentState(); + String getTournamentState(); + void setTournamentState(String tournamentState); - + int getNumberRounds(); + void cleanUpOnTournamentEnd(); + boolean isAbort(); + void setAbort(boolean abort); void clearDraft(); + Draft getDraft(); TourneyProto toProto();