* Added check if the deck was modified during sideboarding.

This commit is contained in:
LevelX2 2017-06-05 20:23:09 +02:00
parent 3c6ede7407
commit 0fd72c3010
12 changed files with 166 additions and 112 deletions

View file

@ -421,12 +421,16 @@ public class TableController {
} }
public void updateDeck(UUID userId, DeckCardLists deckList) throws MageException { public void updateDeck(UUID userId, DeckCardLists deckList) throws MageException {
boolean validDeck;
UUID playerId = userPlayerMap.get(userId); UUID playerId = userPlayerMap.get(userId);
if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) { if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) {
return; return;
} }
Deck deck = Deck.load(deckList, false, false); Deck deck = Deck.load(deckList, false, false);
updateDeck(userId, playerId, deck); validDeck = updateDeck(userId, playerId, deck);
if (!validDeck) {
logger.warn(" userId: " + userId + " - Modified deck card list!");
}
} }
private void submitDeck(UUID userId, UUID playerId, Deck deck) { private void submitDeck(UUID userId, UUID playerId, Deck deck) {
@ -439,18 +443,20 @@ public class TableController {
} }
} }
private void updateDeck(UUID userId, UUID playerId, Deck deck) { private boolean updateDeck(UUID userId, UUID playerId, Deck deck) {
boolean validDeck = true;
if (table.isTournament()) { if (table.isTournament()) {
if (tournament != null) { if (tournament != null) {
TournamentManager.instance.updateDeck(tournament.getId(), playerId, deck); validDeck = TournamentManager.instance.updateDeck(tournament.getId(), playerId, deck);
} else { } else {
logger.fatal("Tournament == null table: " + table.getId() + " userId: " + userId); logger.fatal("Tournament == null table: " + table.getId() + " userId: " + userId);
} }
} else if (TableState.SIDEBOARDING == table.getState()) { } else if (TableState.SIDEBOARDING == table.getState()) {
match.updateDeck(playerId, deck); validDeck = match.updateDeck(playerId, deck);
} else { } else {
// deck was meanwhile submitted so the autoupdate can be ignored // deck was meanwhile submitted so the autoupdate can be ignored
} }
return validDeck;
} }
public boolean watchTable(UUID userId) { public boolean watchTable(UUID userId) {
@ -472,13 +478,6 @@ public class TableController {
} }
} }
// public boolean replayTable(UUID userId) {
// if (table.getState() != TableState.FINISHED) {
// return false;
// }
// ReplayManager.instance.replayGame(table.getId(), userId);
// return true;
// }
private Optional<Player> createPlayer(String name, PlayerType playerType, int skill) { private Optional<Player> createPlayer(String name, PlayerType playerType, int skill) {
Optional<Player> playerOpt; Optional<Player> playerOpt;
if (options == null) { if (options == null) {

View file

@ -349,10 +349,11 @@ public class TournamentController {
} }
} }
public void updateDeck(UUID playerId, Deck deck) { public boolean updateDeck(UUID playerId, Deck deck) {
if (tournamentSessions.containsKey(playerId)) { if (tournamentSessions.containsKey(playerId)) {
tournamentSessions.get(playerId).updateDeck(deck); return tournamentSessions.get(playerId).updateDeck(deck);
} }
return false;
} }
public void timeout(UUID userId) { public void timeout(UUID userId) {

View file

@ -24,14 +24,12 @@
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server.tournament; package mage.server.tournament;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.game.tournament.Tournament; import mage.game.tournament.Tournament;
import mage.view.TournamentView; import mage.view.TournamentView;
@ -74,8 +72,8 @@ public enum TournamentManager {
controllers.get(tournamentId).submitDeck(playerId, deck); controllers.get(tournamentId).submitDeck(playerId, deck);
} }
public void updateDeck(UUID tournamentId, UUID playerId, Deck deck) { public boolean updateDeck(UUID tournamentId, UUID playerId, Deck deck) {
controllers.get(tournamentId).updateDeck(playerId, deck); return controllers.get(tournamentId).updateDeck(playerId, deck);
} }
public TournamentView getTournamentView(UUID tournamentId) { public TournamentView getTournamentView(UUID tournamentId) {
@ -87,13 +85,12 @@ public enum TournamentManager {
} }
public Optional<UUID> getChatId(UUID tournamentId) { public Optional<UUID> getChatId(UUID tournamentId) {
if(controllers.containsKey(tournamentId)) { if (controllers.containsKey(tournamentId)) {
return Optional.of(controllers.get(tournamentId).getChatId()); return Optional.of(controllers.get(tournamentId).getChatId());
} }
return Optional.empty(); return Optional.empty();
} }
public void removeTournament(UUID tournamentId) { public void removeTournament(UUID tournamentId) {
TournamentController tournamentController = controllers.get(tournamentId); TournamentController tournamentController = controllers.get(tournamentId);
if (tournamentController != null) { if (tournamentController != null) {

View file

@ -24,10 +24,14 @@
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server.tournament; package mage.server.tournament;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.game.tournament.Tournament; import mage.game.tournament.Tournament;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
@ -38,16 +42,11 @@ import mage.server.util.ThreadExecutor;
import mage.view.TournamentView; import mage.view.TournamentView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TournamentSession { public class TournamentSession {
protected final static Logger logger = Logger.getLogger(TournamentSession.class); protected final static Logger logger = Logger.getLogger(TournamentSession.class);
protected final UUID userId; protected final UUID userId;
@ -79,16 +78,16 @@ public class TournamentSession {
public void update() { public void update() {
if (!killed) { if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> UserManager.instance.getUser(userId).ifPresent(user
user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_UPDATE, tournament.getId(), getTournamentView()))); -> user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_UPDATE, tournament.getId(), getTournamentView())));
} }
} }
public void gameOver(final String message) { public void gameOver(final String message) {
if (!killed) { if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> UserManager.instance.getUser(userId).ifPresent(user
user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_OVER, tournament.getId(), message))); -> user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_OVER, tournament.getId(), message)));
} }
} }
@ -108,8 +107,8 @@ public class TournamentSession {
tournament.submitDeck(playerId, deck); tournament.submitDeck(playerId, deck);
} }
public void updateDeck(Deck deck) { public boolean updateDeck(Deck deck) {
tournament.updateDeck(playerId, deck); return tournament.updateDeck(playerId, deck);
} }
public void setKilled() { public void setKilled() {
@ -171,9 +170,8 @@ public class TournamentSession {
} }
private void removeTournamentForUser() { private void removeTournamentForUser() {
UserManager.instance.getUser(userId).ifPresent(user -> UserManager.instance.getUser(userId).ifPresent(user
user.removeTournament(playerId)); -> user.removeTournament(playerId));
} }

View file

@ -27,6 +27,10 @@
*/ */
package org.mage.test.stub; package org.mage.test.stub;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.game.draft.Draft; import mage.game.draft.Draft;
@ -38,11 +42,6 @@ import mage.game.tournament.*;
import mage.players.Player; import mage.players.Player;
import mage.players.PlayerType; import mage.players.PlayerType;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/** /**
* *
* @author Quercitron * @author Quercitron
@ -112,8 +111,8 @@ public class TournamentStub implements Tournament {
} }
@Override @Override
public void updateDeck(UUID playerId, Deck deck) { public boolean updateDeck(UUID playerId, Deck deck) {
return true;
} }
@Override @Override

View file

@ -48,6 +48,7 @@ public class Deck implements Serializable {
private DeckCardLayout cardsLayout; private DeckCardLayout cardsLayout;
private DeckCardLayout sideboardLayout; private DeckCardLayout sideboardLayout;
private long deckHashCode = 0; private long deckHashCode = 0;
private long deckCompleteHashCode = 0;
public static Deck load(DeckCardLists deckCardLists) throws GameException { public static Deck load(DeckCardLists deckCardLists) throws GameException {
return Deck.load(deckCardLists, false); return Deck.load(deckCardLists, false);
@ -90,11 +91,13 @@ public class Deck implements Serializable {
for (DeckCardInfo deckCardInfo : deckCardLists.getCards()) { for (DeckCardInfo deckCardInfo : deckCardLists.getCards()) {
Card card = createCard(deckCardInfo, mockCards); Card card = createCard(deckCardInfo, mockCards);
if (card != null) { if (card != null) {
if (totalCards < 1000) { if (totalCards > 1000) {
deck.cards.add(card); break;
deckCardNames.add(card.getName());
totalCards++;
} }
deck.cards.add(card);
deckCardNames.add(card.getName());
totalCards++;
} else if (!ignoreErrors) { } else if (!ignoreErrors) {
throw createCardNotFoundGameException(deckCardInfo, deckCardLists.getName()); throw createCardNotFoundGameException(deckCardInfo, deckCardLists.getName());
} }
@ -103,11 +106,12 @@ public class Deck implements Serializable {
for (DeckCardInfo deckCardInfo : deckCardLists.getSideboard()) { for (DeckCardInfo deckCardInfo : deckCardLists.getSideboard()) {
Card card = createCard(deckCardInfo, mockCards); Card card = createCard(deckCardInfo, mockCards);
if (card != null) { if (card != null) {
if (totalCards < 1000) { if (totalCards > 1000) {
deck.sideboard.add(card); break;
sbCardNames.add(card.getName());
totalCards++;
} }
deck.sideboard.add(card);
sbCardNames.add(card.getName());
totalCards++;
} else if (!ignoreErrors) { } else if (!ignoreErrors) {
throw createCardNotFoundGameException(deckCardInfo, deckCardLists.getName()); throw createCardNotFoundGameException(deckCardInfo, deckCardLists.getName());
} }
@ -116,6 +120,15 @@ public class Deck implements Serializable {
Collections.sort(sbCardNames); Collections.sort(sbCardNames);
String deckString = deckCardNames.toString() + sbCardNames.toString(); String deckString = deckCardNames.toString() + sbCardNames.toString();
deck.setDeckHashCode(DeckUtil.fixedHash(deckString)); deck.setDeckHashCode(DeckUtil.fixedHash(deckString));
if (sbCardNames.isEmpty()) {
deck.setDeckCompleteHashCode(deck.getDeckHashCode());
} else {
List<String> deckAllCardNames = new ArrayList<>();
deckAllCardNames.addAll(deckCardNames);
deckAllCardNames.addAll(sbCardNames);
Collections.sort(deckAllCardNames);
deck.setDeckCompleteHashCode(DeckUtil.fixedHash(deckAllCardNames.toString()));
}
return deck; return deck;
} }
@ -206,6 +219,14 @@ public class Deck implements Serializable {
this.deckHashCode = deckHashCode; this.deckHashCode = deckHashCode;
} }
public long getDeckCompleteHashCode() {
return deckCompleteHashCode;
}
public void setDeckCompleteHashCode(long deckHashCode) {
this.deckCompleteHashCode = deckHashCode;
}
public void clearLayouts() { public void clearLayouts() {
this.cardsLayout = null; this.cardsLayout = null;
this.sideboardLayout = null; this.sideboardLayout = null;

View file

@ -25,21 +25,19 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.game.match; package mage.game.match;
import mage.cards.decks.Deck;
import mage.game.Game;
import mage.game.GameException;
import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.players.Player;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.cards.decks.Deck;
import mage.game.Game;
import mage.game.GameException;
import mage.game.GameInfo; import mage.game.GameInfo;
import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.game.result.ResultProtos.MatchProto; import mage.game.result.ResultProtos.MatchProto;
import mage.players.Player;
/** /**
* *
@ -50,46 +48,73 @@ public interface Match {
int SIDEBOARD_TIME = 180; int SIDEBOARD_TIME = 180;
UUID getId(); UUID getId();
String getName(); String getName();
boolean hasEnded(); boolean hasEnded();
boolean hasStarted(); boolean hasStarted();
boolean checkIfMatchEnds(); boolean checkIfMatchEnds();
List<MatchPlayer> getPlayers(); List<MatchPlayer> getPlayers();
MatchPlayer getPlayer(UUID playerId); MatchPlayer getPlayer(UUID playerId);
void addPlayer(Player player, Deck deck); void addPlayer(Player player, Deck deck);
boolean quitMatch(UUID playerId); boolean quitMatch(UUID playerId);
void submitDeck(UUID playerId, Deck deck); void submitDeck(UUID playerId, Deck deck);
void updateDeck(UUID playerId, Deck deck);
boolean updateDeck(UUID playerId, Deck deck);
void startMatch(); void startMatch();
void startGame() throws GameException; void startGame() throws GameException;
void sideboard(); void sideboard();
void endGame(); void endGame();
Game getGame(); Game getGame();
List<Game> getGames(); List<Game> getGames();
int getWinsNeeded(); int getWinsNeeded();
int getFreeMulligans(); int getFreeMulligans();
void addDraw(); void addDraw();
int getDraws(); int getDraws();
int getNumGames(); int getNumGames();
void addGame(); void addGame();
boolean isDoneSideboarding(); boolean isDoneSideboarding();
UUID getChooser(); UUID getChooser();
MatchOptions getOptions(); MatchOptions getOptions();
void addTableEventListener(Listener<TableEvent> listener); void addTableEventListener(Listener<TableEvent> listener);
void fireSideboardEvent(UUID playerId, Deck deck); void fireSideboardEvent(UUID playerId, Deck deck);
// match times // match times
Date getStartTime(); Date getStartTime();
Date getEndTime(); Date getEndTime();
/** /**
* Can the games of the match be replayed * Can the games of the match be replayed
* *
* @return * @return
*/ */
boolean isReplayAvailable(); boolean isReplayAvailable();
void setReplayAvailable(boolean replayAvailable); void setReplayAvailable(boolean replayAvailable);
/** /**
@ -111,6 +136,7 @@ public interface Match {
List<GameInfo> getGamesInfo(); List<GameInfo> getGamesInfo();
void setTableId(UUID tableId); void setTableId(UUID tableId);
void setTournamentRound(int round); void setTournamentRound(int round);
MatchProto toProto(); MatchProto toProto();

View file

@ -409,11 +409,18 @@ public abstract class MatchImpl implements Match {
} }
@Override @Override
public void updateDeck(UUID playerId, Deck deck) { public boolean updateDeck(UUID playerId, Deck deck) {
boolean validDeck = true;
MatchPlayer player = getPlayer(playerId); MatchPlayer player = getPlayer(playerId);
if (player != null) { if (player != null) {
// Check if the cards included in the deck are the same as in the original deck
validDeck = (player.getDeck().getDeckCompleteHashCode() == deck.getDeckCompleteHashCode());
if (validDeck == false) {
deck.getCards().clear(); // Clear the deck so the player cheating looses the game
}
player.updateDeck(deck); player.updateDeck(deck);
} }
return validDeck;
} }
protected String createGameStartMessage() { protected String createGameStartMessage() {
@ -502,10 +509,10 @@ public abstract class MatchImpl implements Match {
.setMatchOptions(this.getOptions().toProto()) .setMatchOptions(this.getOptions().toProto())
.setEndTimeMs((this.getEndTime() != null ? this.getEndTime() : new Date()).getTime()); .setEndTimeMs((this.getEndTime() != null ? this.getEndTime() : new Date()).getTime());
for (MatchPlayer matchPlayer : this.getPlayers()) { for (MatchPlayer matchPlayer : this.getPlayers()) {
MatchQuitStatus status = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT : MatchQuitStatus status = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT
matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT : : matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT
matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT : : matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT
MatchQuitStatus.QUIT; : MatchQuitStatus.QUIT;
builder.addPlayersBuilder() builder.addPlayersBuilder()
.setName(matchPlayer.getName()) .setName(matchPlayer.getName())
.setHuman(matchPlayer.getPlayer().isHuman()) .setHuman(matchPlayer.getPlayer().isHuman())

View file

@ -98,6 +98,7 @@ public class MatchPlayer implements Serializable {
if (this.deck != null) { if (this.deck != null) {
// preserver deck name, important for Tiny Leaders format // preserver deck name, important for Tiny Leaders format
deck.setName(this.getDeck().getName()); deck.setName(this.getDeck().getName());
// preserve the original deck hash code before sideboarding to give no information if cards were swapped
deck.setDeckHashCode(this.getDeck().getDeckHashCode()); deck.setDeckHashCode(this.getDeck().getDeckHashCode());
} }
this.deck = deck; this.deck = deck;

View file

@ -27,6 +27,10 @@
*/ */
package mage.game.tournament; package mage.game.tournament;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.game.draft.Draft; import mage.game.draft.Draft;
@ -37,11 +41,6 @@ import mage.game.result.ResultProtos.TourneyProto;
import mage.players.Player; import mage.players.Player;
import mage.players.PlayerType; import mage.players.PlayerType;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -76,7 +75,7 @@ public interface Tournament {
void submitDeck(UUID playerId, Deck deck); void submitDeck(UUID playerId, Deck deck);
void updateDeck(UUID playerId, Deck deck); boolean updateDeck(UUID playerId, Deck deck);
void autoSubmit(UUID playerId, Deck deck); void autoSubmit(UUID playerId, Deck deck);

View file

@ -27,6 +27,8 @@
*/ */
package mage.game.tournament; package mage.game.tournament;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.TournamentPlayerState; import mage.constants.TournamentPlayerState;
@ -37,14 +39,16 @@ import mage.game.events.TableEvent.EventType;
import mage.game.match.Match; import mage.game.match.Match;
import mage.game.match.MatchPlayer; import mage.game.match.MatchPlayer;
import mage.game.result.ResultProtos.*; import mage.game.result.ResultProtos.*;
import mage.game.result.ResultProtos.MatchPlayerProto;
import mage.game.result.ResultProtos.MatchProto;
import mage.game.result.ResultProtos.MatchQuitStatus;
import mage.game.result.ResultProtos.TourneyProto;
import mage.game.result.ResultProtos.TourneyRoundProto;
import mage.players.Player; import mage.players.Player;
import mage.players.PlayerType; import mage.players.PlayerType;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -168,10 +172,11 @@ public abstract class TournamentImpl implements Tournament {
} }
@Override @Override
public void updateDeck(UUID playerId, Deck deck) { public boolean updateDeck(UUID playerId, Deck deck) {
if (players.containsKey(playerId)) { if (players.containsKey(playerId)) {
players.get(playerId).updateDeck(deck); return players.get(playerId).updateDeck(deck);
} }
return false;
} }
protected Round createRoundRandom() { protected Round createRoundRandom() {
@ -588,10 +593,10 @@ public abstract class TournamentImpl implements Tournament {
private MatchPlayerProto matchToProto(Match match, TournamentPlayer player) { private MatchPlayerProto matchToProto(Match match, TournamentPlayer player) {
MatchPlayer matchPlayer = match.getPlayer(player.getPlayer().getId()); MatchPlayer matchPlayer = match.getPlayer(player.getPlayer().getId());
MatchQuitStatus quit = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT : MatchQuitStatus quit = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT
matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT : : matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT
matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT : : matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT
MatchQuitStatus.QUIT; : MatchQuitStatus.QUIT;
return MatchPlayerProto.newBuilder() return MatchPlayerProto.newBuilder()
.setName(player.getPlayer().getName()) .setName(player.getPlayer().getName())
.setHuman(player.getPlayer().isHuman()) .setHuman(player.getPlayer().isHuman())

View file

@ -25,9 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.game.tournament; package mage.game.tournament;
import java.util.Set;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.TournamentPlayerState; import mage.constants.TournamentPlayerState;
import mage.game.result.ResultProtos.TourneyPlayerProto; import mage.game.result.ResultProtos.TourneyPlayerProto;
@ -36,8 +36,6 @@ import mage.players.Player;
import mage.players.PlayerType; import mage.players.PlayerType;
import mage.util.TournamentUtil; import mage.util.TournamentUtil;
import java.util.Set;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -117,8 +115,14 @@ public class TournamentPlayer {
this.setState(TournamentPlayerState.WAITING); this.setState(TournamentPlayerState.WAITING);
} }
public void updateDeck(Deck deck) { public boolean updateDeck(Deck deck) {
// Check if the cards included in the deck are the same as in the original deck
boolean validDeck = (getDeck().getDeckCompleteHashCode() == deck.getDeckCompleteHashCode());
if (validDeck == false) {
deck.getCards().clear(); // Clear the deck so the player cheating looses the game
}
this.deck = deck; this.deck = deck;
return validDeck;
} }
public Deck generateDeck() { public Deck generateDeck() {
@ -144,8 +148,6 @@ public class TournamentPlayer {
return deck; return deck;
} }
public boolean isDoneConstructing() { public boolean isDoneConstructing() {
return this.doneConstructing; return this.doneConstructing;
} }
@ -239,4 +241,3 @@ public class TournamentPlayer {
.build(); .build();
} }
} }