Fixed potentially rollback errors with missing game data (#7273);

This commit is contained in:
Oleg Agafonov 2020-12-24 23:43:53 +04:00
parent 7065d3c512
commit a87c0b1ff6
6 changed files with 34 additions and 37 deletions

View file

@ -121,8 +121,17 @@ public class CardView extends SimpleCardView {
protected Card originalCard = null; protected Card originalCard = null;
/**
* Non game usage like deck editor
*
* @param card
*/
public CardView(Card card) { public CardView(Card card) {
this(card, null, false); this(card, (Game) null);
}
public CardView(Card card, Game game) {
this(card, game, false);
} }
public CardView(Card card, SimpleCardView simpleCardView) { public CardView(Card card, SimpleCardView simpleCardView) {
@ -450,7 +459,7 @@ public class CardView extends SimpleCardView {
Card secondSideCard = card.getSecondCardFace(); Card secondSideCard = card.getSecondCardFace();
if (secondSideCard != null) { if (secondSideCard != null) {
this.secondCardFace = new CardView(secondSideCard); this.secondCardFace = new CardView(secondSideCard, game);
this.alternateName = secondCardFace.getName(); this.alternateName = secondCardFace.getName();
this.originalName = card.getName(); this.originalName = card.getName();
} }
@ -464,7 +473,7 @@ public class CardView extends SimpleCardView {
if (card instanceof ModalDoubleFacesCard) { if (card instanceof ModalDoubleFacesCard) {
this.transformable = true; // enable GUI day/night button this.transformable = true; // enable GUI day/night button
ModalDoubleFacesCard mdfCard = (ModalDoubleFacesCard) card; ModalDoubleFacesCard mdfCard = (ModalDoubleFacesCard) card;
this.secondCardFace = new CardView(mdfCard.getRightHalfCard()); this.secondCardFace = new CardView(mdfCard.getRightHalfCard(), game);
this.alternateName = mdfCard.getRightHalfCard().getName(); this.alternateName = mdfCard.getRightHalfCard().getName();
this.originalName = card.getName(); this.originalName = card.getName();
} }

View file

@ -6,7 +6,6 @@ import mage.abilities.effects.Effect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.GameState;
import mage.game.command.Emblem; import mage.game.command.Emblem;
import mage.game.command.Plane; import mage.game.command.Plane;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -29,7 +28,7 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
} }
/** /**
* Uses for card render tests * Non game usage like card render tests
* *
* @param cardViews * @param cardViews
*/ */
@ -39,6 +38,11 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
} }
} }
/**
* Non game usage like deck editor
*
* @param cards
*/
public CardsView(Collection<? extends Card> cards) { public CardsView(Collection<? extends Card> cards) {
for (Card card : cards) { for (Card card : cards) {
this.put(card.getId(), new CardView(card)); this.put(card.getId(), new CardView(card));
@ -116,9 +120,9 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
if (abilityView == null) { if (abilityView == null) {
CardView sourceCardView; CardView sourceCardView;
if (isPermanent) { if (isPermanent) {
sourceCardView = new CardView((Permanent) sourceObject); sourceCardView = new CardView((Permanent) sourceObject, game);
} else if (isCard) { } else if (isCard) {
sourceCardView = new CardView((Card) sourceObject); sourceCardView = new CardView((Card) sourceObject, game);
} else { } else {
sourceCardView = new CardView(sourceObject, game); sourceCardView = new CardView(sourceObject, game);
} }
@ -164,14 +168,4 @@ public class CardsView extends LinkedHashMap<UUID, CardView> {
+ abilities.stream().map(a -> a.getClass().getSimpleName() + " - " + a.getRule()).collect(Collectors.joining("\n"))); + abilities.stream().map(a -> a.getClass().getSimpleName() + " - " + a.getRule()).collect(Collectors.joining("\n")));
} }
} }
public CardsView(Collection<? extends Ability> abilities, GameState state) {
for (Ability ability : abilities) {
Card sourceCard = state.getPermanent(ability.getSourceId());
if (sourceCard != null) {
this.put(ability.getId(), new AbilityView(ability, sourceCard.getName(), new CardView(sourceCard)));
}
}
}
} }

View file

@ -94,7 +94,7 @@ public class GameView implements Serializable {
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, card.getName(), new CardView(card, game, false, false, false))); stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, card.getName(), new CardView(card, game, false, false, false)));
} }
} else { } else {
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, "", new CardView(card))); stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, "", new CardView(card, game)));
} }
if (card.isTransformable()) { if (card.isTransformable()) {
updateLatestCardView(game, card, stackObject.getId()); updateLatestCardView(game, card, stackObject.getId());
@ -103,7 +103,7 @@ public class GameView implements Serializable {
} else if (object != null) { } else if (object != null) {
if (object instanceof PermanentToken) { if (object instanceof PermanentToken) {
PermanentToken token = (PermanentToken) object; PermanentToken token = (PermanentToken) object;
stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, token.getName(), new CardView(token))); stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, token.getName(), new CardView(token, game)));
checkPaid(stackObject.getId(), (StackAbility) stackObject); checkPaid(stackObject.getId(), (StackAbility) stackObject);
} else if (object instanceof Emblem) { } else if (object instanceof Emblem) {
CardView cardView = new CardView(new EmblemView((Emblem) object)); CardView cardView = new CardView(new EmblemView((Emblem) object));

View file

@ -1,9 +1,5 @@
package mage.view; package mage.view;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.TurnFaceUpAbility; import mage.abilities.common.TurnFaceUpAbility;
import mage.cards.Card; import mage.cards.Card;
@ -12,8 +8,11 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken; import mage.game.permanent.PermanentToken;
import mage.players.Player; import mage.players.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class PermanentView extends CardView { public class PermanentView extends CardView {
@ -36,8 +35,8 @@ public class PermanentView extends CardView {
private final boolean attachedToPermanent; private final boolean attachedToPermanent;
public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) { public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) {
super(permanent, game, (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId)); super(permanent, game, permanent.getControllerId() != null && permanent.getControllerId().equals(createdForPlayerId));
this.controlled = (permanent.getControllerId() == null) ? false : permanent.getControllerId().equals(createdForPlayerId); this.controlled = permanent.getControllerId() != null && permanent.getControllerId().equals(createdForPlayerId);
this.rules = permanent.getRules(game); this.rules = permanent.getRules(game);
this.tapped = permanent.isTapped(); this.tapped = permanent.isTapped();
this.flipped = permanent.isFlipped(); this.flipped = permanent.isFlipped();
@ -59,7 +58,7 @@ public class PermanentView extends CardView {
} else { } else {
if (card != null) { if (card != null) {
// original may not be face down // original may not be face down
original = new CardView(card); original = new CardView(card, game);
} else { } else {
original = null; original = null;
} }

View file

@ -1,13 +1,5 @@
package mage.view; package mage.view;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.cards.Card; import mage.cards.Card;
import mage.counters.Counters; import mage.counters.Counters;
import mage.designations.Designation; import mage.designations.Designation;
@ -22,6 +14,9 @@ import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.players.net.UserData; import mage.players.net.UserData;
import java.io.Serializable;
import java.util.*;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -105,7 +100,7 @@ public class PlayerView implements Serializable {
} }
Card cardOnTop = (player.isTopCardRevealed() && player.getLibrary().hasCards()) Card cardOnTop = (player.isTopCardRevealed() && player.getLibrary().hasCards())
? player.getLibrary().getFromTop(game) : null; ? player.getLibrary().getFromTop(game) : null;
this.topCard = cardOnTop != null ? new CardView(cardOnTop) : null; this.topCard = cardOnTop != null ? new CardView(cardOnTop, game) : null;
if (player.getUserData() != null) { if (player.getUserData() != null) {
this.userData = player.getUserData(); this.userData = player.getUserData();
} else { } else {

View file

@ -784,7 +784,7 @@ public class GameController implements GameCallback {
} }
private synchronized void choosePile(UUID playerId, final String message, final List<? extends Card> pile1, final List<? extends Card> pile2) throws MageException { private synchronized void choosePile(UUID playerId, final String message, final List<? extends Card> pile1, final List<? extends Card> pile2) throws MageException {
perform(playerId, playerId1 -> getGameSession(playerId1).choosePile(message, new CardsView(pile1), new CardsView(pile2))); perform(playerId, playerId1 -> getGameSession(playerId1).choosePile(message, new CardsView(game, pile1), new CardsView(game, pile2)));
} }
private synchronized void chooseMode(UUID playerId, final Map<UUID, String> modes, final String message) throws MageException { private synchronized void chooseMode(UUID playerId, final Map<UUID, String> modes, final String message) throws MageException {