diff --git a/Mage.Common/src/mage/view/MatchView.java b/Mage.Common/src/mage/view/MatchView.java index d7d31ad2b14..61c447b2207 100644 --- a/Mage.Common/src/mage/view/MatchView.java +++ b/Mage.Common/src/mage/view/MatchView.java @@ -67,8 +67,13 @@ public class MatchView implements Serializable { StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); for (MatchPlayer player: match.getPlayers()) { - sb1.append(player.getPlayer().getName()).append(", "); - sb2.append(player.getPlayer().getName()).append(" ").append(player.getWins()).append("-").append(player.getLoses()).append(", "); + sb1.append(player.getPlayer().getName()); + if(player.hasQuit()) { + sb1.append(" [quit] "); + } + sb1.append(", "); + sb2.append(player.getPlayer().getName()).append(" "); + sb2.append(player.getWins()).append("-").append(player.getLoses()).append(", "); } players = sb1.substring(0, sb1.length() - 2); result = sb2.substring(0, sb2.length() - 2); diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index a2cb5a1adfb..3ffc5311c4f 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -44,6 +44,7 @@ import mage.cards.decks.DeckCardLists; import mage.cards.decks.InvalidDeckException; import mage.game.GameException; import mage.game.GameOptions; +import mage.game.GameState; import mage.game.Seat; import mage.game.Table; import mage.game.draft.Draft; @@ -56,6 +57,7 @@ import mage.game.match.MatchPlayer; import mage.game.tournament.Tournament; import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentPlayer; +import mage.interfaces.callback.ClientCallback; import mage.players.Player; import mage.server.challenge.ChallengeManager; import mage.server.draft.DraftManager; @@ -66,6 +68,7 @@ import mage.server.tournament.TournamentFactory; import mage.server.tournament.TournamentManager; import mage.server.util.ServerMessagesUtil; import mage.server.util.ThreadExecutor; +import mage.view.GameEndView; import org.apache.log4j.Logger; @@ -175,6 +178,22 @@ public class TableController { } } + 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()); + + DraftManager.getInstance().getController(table.getId()).replacePlayer(oldPlayer, newPlayer); + return true; + } + public synchronized boolean joinTable(UUID userId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException { User user = UserManager.getInstance().getUser(userId); if (user == null) { @@ -334,26 +353,29 @@ public class TableController { return player; } - public void kill(UUID userId) { - leaveTable(userId); - userPlayerMap.remove(userId); - } - public synchronized void leaveTable(UUID userId) { - if (table.getState() == TableState.WAITING || table.getState() == TableState.STARTING) { - UUID playerId = userPlayerMap.get(userId); - if (playerId != null) { - table.leaveTable(playerId); + UUID playerId = userPlayerMap.get(userId); + if (playerId != null) { + if (table.getState() == TableState.WAITING || table.getState() == TableState.STARTING) { + table.leaveNotStartedTable(playerId); if (table.isTournament()) { - tournament.leave(playerId); + TournamentManager.getInstance().quit(tournament.getId(), userId); } else { match.leave(playerId); } User user = UserManager.getInstance().getUser(userId); user.removeTable(playerId); userPlayerMap.remove(userId); - } + } else if (!table.getState().equals(TableState.FINISHED)) { + if (table.isTournament()) { + TableManager.getInstance().userQuitTournamentSubTables(userId); + TournamentManager.getInstance().quit(tournament.getId(), userId); + } else { + match.leave(playerId); + } + } } + } public synchronized void startMatch(UUID userId) { @@ -497,6 +519,30 @@ public class TableController { } } + private void sendMatchEndInfo(UUID playerId) { + for (Entry entry: userPlayerMap.entrySet()) { + if (entry.getValue().equals(playerId)) { + User user = UserManager.getInstance().getUser(entry.getKey()); + if (user != null) { + StringBuilder sb = new StringBuilder(); + if (table.isTournamentSubTable()) { + sb.append("Your tournament match of round "); + sb.append(table.getTournament().getRounds().size()); + sb.append(" is over. "); + } else { + sb.append("Match [").append(match.getName()).append("] is over. "); + } + if(match.getPlayers().size() > 2) { + sb.append("All your opponents have lost or quit the match."); + } else { + sb.append("Your opponent has quit the match."); + } + user.showUserMessage("Match info", sb.toString()); + } + break; + } + } + } public int getRemainingTime() { return (int) futureTimeout.getDelay(TimeUnit.SECONDS); } @@ -533,7 +579,17 @@ public class TableController { setupTimeout(Match.SIDEBOARD_TIME); match.sideboard(); cancelTimeout(); - startGame(choosingPlayerId); + if (!match.isMatchOver()) { + startGame(choosingPlayerId); + } else { + table.endGame(); + // opponent(s) left during sideboarding + for (MatchPlayer mPlayer :match.getPlayers()) { + if(!mPlayer.hasQuit()) { + this.sendMatchEndInfo(mPlayer.getPlayer().getId()); + } + } + } } else { match.getGames().clear(); diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java index 8af3c75c51e..639f00182d4 100644 --- a/Mage.Server/src/main/java/mage/server/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -166,9 +166,12 @@ public class TableManager { } } - public void removeSession(UUID userId) { + // remove user from all tournament sub tables + public void userQuitTournamentSubTables(UUID userId) { for (TableController controller: controllers.values()) { - controller.kill(userId); + if (controller.getTable().isTournamentSubTable()) { + controller.leaveTable(userId); + } } } @@ -190,6 +193,13 @@ public class TableManager { public void leaveTable(UUID userId, UUID tableId) { if (controllers.containsKey(tableId)) { controllers.get(tableId).leaveTable(userId); + // table not started yet and user is he owner, remove the table + if (isTableOwner(tableId, userId)) { + if (getTable(tableId).getState().equals(TableState.WAITING) + || getTable(tableId).getState().equals(TableState.STARTING)) { + removeTable(tableId); + } + } } } diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 8441ee306be..789b5de49dd 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -293,14 +293,7 @@ public class User { session.setKilled(); } for (Entry entry: tables.entrySet()) { - entry.getValue().leaveTable(entry.getKey()); - // remove tables here only, if the match or tournament did not start yet (states waiting/starting). - // all other situations have to lead to a fnished match / tournament where players left / conceded for which reasons ever - if (TableManager.getInstance().isTableOwner(entry.getValue().getId(), userId) - && (entry.getValue().getState().equals(TableState.WAITING) - || entry.getValue().getState().equals(TableState.STARTING))) { - TableManager.getInstance().removeTable(userId, entry.getValue().getId()); - } + TableManager.getInstance().leaveTable(userId, entry.getValue().getId()); } ChatManager.getInstance().removeUser(userId, reason); } diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 80371180da3..05b55b38c11 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -120,10 +120,10 @@ public class UserManager { public void removeUser(UUID userId, User.DisconnectReason reason) { if (users.containsKey(userId)) { - logger.info("user removed " + userId); + logger.info("Remove user " + users.get(userId).getName() + ": " + userId + " Reason: " + reason.toString()); ChatManager.getInstance().removeUser(userId, reason); ChatManager.getInstance().broadcast(userId, "has disconnected", MessageColor.BLACK); - users.get(userId).kill(User.DisconnectReason.Disconnected); + users.get(userId).kill(reason); users.remove(userId); } } diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftController.java b/Mage.Server/src/main/java/mage/server/draft/DraftController.java index 20c804c304a..7867cc50f9e 100644 --- a/Mage.Server/src/main/java/mage/server/draft/DraftController.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftController.java @@ -38,6 +38,7 @@ import mage.game.draft.DraftPlayer; import mage.game.events.Listener; import mage.game.events.PlayerQueryEvent; import mage.game.events.TableEvent; +import mage.players.Player; import mage.server.TableManager; import mage.server.UserManager; import mage.server.game.GameController; @@ -129,6 +130,15 @@ public class DraftController { checkStart(); } + public boolean replacePlayer(Player oldPlayer, Player newPlayer) { + if (draft.replacePlayer(oldPlayer, newPlayer)) { + draftSessions.get(oldPlayer.getId()).setKilled(); + draftSessions.remove(oldPlayer.getId()); + return true; + } + return false; + } + private synchronized void startDraft() { for (final Entry entry: draftSessions.entrySet()) { if (!entry.getValue().init()) { @@ -212,4 +222,11 @@ public class DraftController { } } + public UUID getTableId() { + return tableId; + } + + public void abortDraft() { + draft.setAbort(true); + } } diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftManager.java b/Mage.Server/src/main/java/mage/server/draft/DraftManager.java index 953d0ab3524..c0a600b4791 100644 --- a/Mage.Server/src/main/java/mage/server/draft/DraftManager.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftManager.java @@ -84,4 +84,12 @@ public class DraftManager { draftControllers.remove(draftId); } + public DraftController getController(UUID tableId) { + for (DraftController controller: draftControllers.values()) { + if (controller.getTableId().equals(tableId)) { + return controller; + } + } + return null; + } } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index d33b85e6e6f..5453f6917b6 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -46,8 +46,11 @@ import mage.game.tournament.Tournament; import mage.game.tournament.TournamentPairing; import mage.game.tournament.TournamentPlayer; import mage.server.ChatManager; +import mage.server.TableController; import mage.server.TableManager; +import mage.server.User; import mage.server.UserManager; +import mage.server.draft.DraftManager; import mage.server.game.GamesRoomManager; import mage.server.util.ThreadExecutor; import mage.view.ChatMessage.MessageColor; @@ -71,6 +74,8 @@ public class TournamentController { private ConcurrentHashMap userPlayerMap = new ConcurrentHashMap(); private ConcurrentHashMap tournamentSessions = new ConcurrentHashMap(); + private boolean abort = false; + public TournamentController(Tournament tournament, ConcurrentHashMap userPlayerMap, UUID tableId) { this.userPlayerMap = userPlayerMap; chatId = ChatManager.getInstance().createChatSession(); @@ -93,16 +98,18 @@ public class TournamentController { startDraft(event.getDraft()); break; case CONSTRUCT: - construct(); + if (!abort) { + construct(); + } else { + endTournament(); + } break; case START_MATCH: - initTournament(); // set state - startMatch(event.getPair(), event.getMatchOptions()); + if (!abort) { + initTournament(); // set state + startMatch(event.getPair(), event.getMatchOptions()); + } break; -// case SUBMIT_DECK: -// submitDeck(event.getPlayerId(), event.getDeck()); -// break; - case END: endTournament(); break; @@ -265,37 +272,57 @@ public class TournamentController { public void quit(UUID userId) { UUID playerId = userPlayerMap.get(userId); if (playerId != null) { - TournamentPlayer player = tournament.getPlayer(playerId); - if (player != null) { - ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has quit the tournament", MessageColor.BLACK, true, SoundToPlay.PlayerLeft); - String info; - if (tournament.isDoneConstructing()) { - info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString(); + TournamentPlayer tPlayer = tournament.getPlayer(playerId); + if (tPlayer != null) { + if (started) { + ChatManager.getInstance().broadcast(chatId, "", tPlayer.getPlayer().getName() + " has quit the tournament", MessageColor.BLACK, true, SoundToPlay.PlayerLeft); + String info; + if (tournament.isDoneConstructing()) { + info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString(); + } else { + if (tPlayer.getState().equals(TournamentPlayerState.DRAFTING)) { + info = "during Draft phase"; + if (!checkToReplaceDraftPlayerByAi(userId, tPlayer)) { + this.abortTournament(); + } + } else if (tPlayer.getState().equals(TournamentPlayerState.CONSTRUCTING)) { + info = "during Construction phase"; + } else { + info = ""; + } + } + tPlayer.setQuit(info); + tournament.quit(playerId); } else { - info = "during Construction phase"; + tournament.leave(playerId); } - player.setQuit(info); - tournament.quit(playerId); } } } - public void kill(UUID userId) { - quit(userId); -// if (userPlayerMap.containsKey(userId)) { -// tournamentSessions.get(userPlayerMap.get(userId)).setKilled(); -// tournamentSessions.remove(userPlayerMap.get(userId)); -// leave(userId); -// userPlayerMap.remove(userId); -// } - } + private boolean checkToReplaceDraftPlayerByAi(UUID userId, TournamentPlayer leavingPlayer) { - private void leave(UUID userId) { - tournament.leave(getPlayerId(userId)); - } - - private UUID getPlayerId(UUID userId) { - return userPlayerMap.get(userId); + int humans = 0; + for (TournamentPlayer tPlayer :tournament.getPlayers()) { + if (tPlayer.getPlayer().isHuman()) { + humans++; + } + } + // replace player that quits with draft bot + if (humans > 1) { + String replacePlayerName = "Draftbot"; + User user = UserManager.getInstance().getUser(userId); + if (user != null) { + replacePlayerName = "Draftbot (" + user.getName() + ")"; + } + TableController tableController = TableManager.getInstance().getController(tableId); + if (tableController != null) { + tableController.replaceDraftPlayer(leavingPlayer.getPlayer(), replacePlayerName, "Computer - draftbot", 5); + ChatManager.getInstance().broadcast(chatId, "", leavingPlayer.getPlayer().getName() + " was replaced by draftbot", MessageColor.BLACK, true, null); + } + return true; + } + return false; } private UUID getPlayerSessionId(UUID playerId) { @@ -311,4 +338,8 @@ public class TournamentController { return new TournamentView(tournament); } + private void abortTournament() { + this.abort = true; + DraftManager.getInstance().getController(tableId).abortDraft(); + } } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java index dea7a0d9049..21d1d780ecf 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java @@ -48,6 +48,10 @@ public class TournamentManager { return INSTANCE; } + public TournamentController getTournamentController(UUID tournamentId) { + return controllers.get(tournamentId); + } + public void createTournamentSession(Tournament tournament, ConcurrentHashMap userPlayerMap, UUID tableId) { TournamentController tournamentController = new TournamentController(tournament, userPlayerMap, tableId); controllers.put(tournament.getId(), tournamentController); @@ -63,7 +67,7 @@ public class TournamentManager { public void kill(UUID tournamentId, UUID userId) { - controllers.get(tournamentId).kill(userId); + controllers.get(tournamentId).quit(userId); } public void timeout(UUID tournamentId, UUID userId) { diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index c5510165ad2..8d2cf601d30 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -121,7 +121,6 @@ public class TournamentSession { public void setKilled() { killed = true; - TournamentManager.getInstance().kill(tournament.getId(), userId); } private synchronized void setupTimeout(int seconds) { diff --git a/Mage/src/mage/game/Table.java b/Mage/src/mage/game/Table.java index b148c5094ab..716102bf830 100644 --- a/Mage/src/mage/game/Table.java +++ b/Mage/src/mage/game/Table.java @@ -182,7 +182,7 @@ public class Table implements Serializable { return null; } - public void leaveTable(UUID playerId) { + public void leaveNotStartedTable(UUID playerId) { for (int i = 0; i < numSeats; i++ ) { Player player = seats[i].getPlayer(); if (player != null && player.getId().equals(playerId)) { diff --git a/Mage/src/mage/game/draft/BoosterDraft.java b/Mage/src/mage/game/draft/BoosterDraft.java index 4c337c8e1f5..a0703cec1fe 100644 --- a/Mage/src/mage/game/draft/BoosterDraft.java +++ b/Mage/src/mage/game/draft/BoosterDraft.java @@ -45,11 +45,13 @@ public class BoosterDraft extends DraftImpl { public void start() { while (boosterNum < sets.size()) { openBooster(); - while (pickCards()) { - if (boosterNum % 2 == 1) + while (!isAbort() && pickCards()) { + if (boosterNum % 2 == 1) { passLeft(); - else + } + else { passRight(); + } fireUpdatePlayersEvent(); } } diff --git a/Mage/src/mage/game/draft/Draft.java b/Mage/src/mage/game/draft/Draft.java index 7937d7eccf8..5ab22747c4a 100644 --- a/Mage/src/mage/game/draft/Draft.java +++ b/Mage/src/mage/game/draft/Draft.java @@ -47,6 +47,7 @@ public interface Draft extends MageItem, Serializable { void addPlayer(Player player); Collection getPlayers(); + boolean replacePlayer(Player oldPlayer, Player newPlayer); DraftPlayer getPlayer(UUID playerId); List getSets(); int getBoosterNum(); @@ -63,4 +64,6 @@ public interface Draft extends MageItem, Serializable { void addPlayerQueryEventListener(Listener listener); void firePickCardEvent(UUID playerId); + boolean isAbort(); + void setAbort(boolean abort); } diff --git a/Mage/src/mage/game/draft/DraftImpl.java b/Mage/src/mage/game/draft/DraftImpl.java index 272b49d072c..248a8763573 100644 --- a/Mage/src/mage/game/draft/DraftImpl.java +++ b/Mage/src/mage/game/draft/DraftImpl.java @@ -61,6 +61,8 @@ public abstract class DraftImpl> implements Draft { protected TimingOption timing; protected int[] times = {75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5}; + protected boolean abort = false; + protected transient TableEventSource tableEventSource = new TableEventSource(); protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource(); @@ -83,9 +85,48 @@ public abstract class DraftImpl> implements Draft { table.add(player.getId()); } + @Override + public boolean replacePlayer(Player oldPlayer, Player newPlayer) { + if (newPlayer != null) { + DraftPlayer newDraftPlayer = new DraftPlayer(newPlayer); + DraftPlayer oldDraftPlayer = players.get(oldPlayer.getId()); + newDraftPlayer.setBooster(oldDraftPlayer.getBooster()); + Map newPlayers = new HashMap(); + PlayerList newTable = new PlayerList(); + synchronized (players) { + for(Map.Entry entry :players.entrySet()) { + if (entry.getKey().equals(oldPlayer.getId())) { + newPlayers.put(newPlayer.getId(), newDraftPlayer); + } else { + newPlayers.put(entry.getKey(), entry.getValue()); + } + } + players = newPlayers; + } + synchronized (table) { + for(UUID playerId :table) { + if (playerId.equals(oldPlayer.getId())) { + newTable.add(newPlayer.getId()); + } else { + newTable.add(playerId); + } + } + table = newTable; + } + if (oldDraftPlayer.isPicking()) { + newDraftPlayer.setPicking(); + newDraftPlayer.getPlayer().pickCard(newDraftPlayer.getBooster(), newDraftPlayer.getDeck(), this); + } + return true; + } + return false; + } + @Override public Collection getPlayers() { - return players.values(); + synchronized (players) { + return players.values(); + } } @Override @@ -118,46 +159,53 @@ public abstract class DraftImpl> implements Draft { this.addPick(playerId, players.get(playerId).getBooster().get(0).getId()); } - protected void passLeft() { - UUID startId = table.get(0); - UUID currentId = startId; - UUID nextId = table.getNext(); - DraftPlayer current = players.get(currentId); - DraftPlayer next = players.get(nextId); - List currentBooster = current.booster; - while (true) { - List nextBooster = next.booster; - next.setBooster(currentBooster); - if (nextId == startId) - break; - currentBooster = nextBooster; - current = next; - currentId = nextId; - nextId = table.getNext(); - next = players.get(nextId); + protected void passLeft() { + synchronized (players) { + UUID startId = table.get(0); + UUID currentId = startId; + UUID nextId = table.getNext(); + DraftPlayer current = players.get(currentId); + DraftPlayer next = players.get(nextId); + List currentBooster = current.booster; + while (true) { + List nextBooster = next.booster; + next.setBooster(currentBooster); + if (nextId == startId) { + break; + } + currentBooster = nextBooster; + current = next; + currentId = nextId; + nextId = table.getNext(); + next = players.get(nextId); + } } } protected void passRight() { - UUID startId = table.get(0); - UUID currentId = startId; - UUID prevId = table.getPrevious(); - DraftPlayer current = players.get(currentId); - DraftPlayer prev = players.get(prevId); - List currentBooster = current.booster; - while (true) { - List prevBooster = prev.booster; - prev.setBooster(currentBooster); - if (prevId == startId) - break; - currentBooster = prevBooster; - current = prev; - currentId = prevId; - prevId = table.getPrevious(); - prev = players.get(prevId); + synchronized (players) { + UUID startId = table.get(0); + UUID currentId = startId; + UUID prevId = table.getPrevious(); + DraftPlayer current = players.get(currentId); + DraftPlayer prev = players.get(prevId); + List currentBooster = current.booster; + while (true) { + List prevBooster = prev.booster; + prev.setBooster(currentBooster); + if (prevId == startId) { + break; + } + currentBooster = prevBooster; + current = prev; + currentId = prevId; + prevId = table.getPrevious(); + prev = players.get(prevId); + } } } + protected void openBooster() { if (boosterNum < sets.size()) { for (DraftPlayer player: players.values()) { @@ -172,8 +220,9 @@ public abstract class DraftImpl> implements Draft { protected boolean pickCards() { cardNum++; for (DraftPlayer player: players.values()) { - if (player.getBooster().size() == 0) + if (player.getBooster().isEmpty()) { return false; + } player.setPicking(); player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this); } @@ -189,8 +238,9 @@ public abstract class DraftImpl> implements Draft { protected boolean donePicking() { for (DraftPlayer player: players.values()) { - if (player.isPicking()) + if (player.isPicking()) { return false; + } } return true; } @@ -198,8 +248,9 @@ public abstract class DraftImpl> implements Draft { @Override public boolean allJoined() { for (DraftPlayer player: this.players.values()) { - if (!player.isJoined()) + if (!player.isJoined()) { return false; + } } return true; } @@ -227,8 +278,9 @@ public abstract class DraftImpl> implements Draft { @Override public void firePickCardEvent(UUID playerId) { DraftPlayer player = players.get(playerId); - if (cardNum > 15) + if (cardNum > 15) { cardNum = 15; + } int time = times[cardNum - 1] * timing.getFactor(); playerQueryEventSource.pickCard(playerId, "Pick card", player.getBooster(), time); } @@ -251,4 +303,14 @@ public abstract class DraftImpl> implements Draft { return !player.isPicking(); } + @Override + public boolean isAbort() { + return abort; + } + + @Override + public void setAbort(boolean abort) { + this.abort = abort; + } + } diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java index 2d813ce6e32..3e7b2f2ceab 100644 --- a/Mage/src/mage/game/match/MatchImpl.java +++ b/Mage/src/mage/game/match/MatchImpl.java @@ -285,7 +285,7 @@ public abstract class MatchImpl implements Match { player.updateDeck(deck); } } - + protected String createGameStartMessage() { StringBuilder sb = new StringBuilder(); sb.append("\nMatch score:\n"); diff --git a/Mage/src/mage/game/match/MatchPlayer.java b/Mage/src/mage/game/match/MatchPlayer.java index 6830b2c6e88..d3c74f38877 100644 --- a/Mage/src/mage/game/match/MatchPlayer.java +++ b/Mage/src/mage/game/match/MatchPlayer.java @@ -119,6 +119,7 @@ public class MatchPlayer { } public void setQuit(boolean quit) { + this.doneSideboarding = true; this.quit = quit; } } diff --git a/Mage/src/mage/game/tournament/Tournament.java b/Mage/src/mage/game/tournament/Tournament.java index aad1343ff5b..eac15b1d2aa 100644 --- a/Mage/src/mage/game/tournament/Tournament.java +++ b/Mage/src/mage/game/tournament/Tournament.java @@ -47,6 +47,7 @@ public interface Tournament { UUID getId(); void addPlayer(Player player, String playerType); + void removePlayer(UUID playerId); TournamentPlayer getPlayer(UUID playerId); Collection getPlayers(); Collection getRounds(); diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java index bf96a3930d1..deeb1ee48af 100644 --- a/Mage/src/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/mage/game/tournament/TournamentImpl.java @@ -76,6 +76,11 @@ public abstract class TournamentImpl implements Tournament { players.put(player.getId(), new TournamentPlayer(player, playerType)); } + @Override + public void removePlayer(UUID playerId) { + players.remove(playerId); + } + @Override public TournamentPlayer getPlayer(UUID playerId) { return players.get(playerId); @@ -125,6 +130,7 @@ public abstract class TournamentImpl implements Tournament { } } + // can only be used, if tournament did not start yet? @Override public void leave(UUID playerId) { if (players.containsKey(playerId)) {