From 2f016c8ea68359b294a95e029d88d0d41b1053c5 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 27 Jan 2018 13:19:20 +0100 Subject: [PATCH] Fixed some more exception and/or logging problems. --- .../cubes/VintageCubeDecember2017.java | 4 ++-- .../java/mage/server/TableController.java | 24 +++++++++---------- .../src/mage/cards/c/CurseOfVengeance.java | 6 ++--- .../src/mage/cards/g/GhostlyFlicker.java | 2 +- Mage.Sets/src/mage/cards/j/JackInTheMox.java | 7 +++++- .../src/mage/cards/t/TrainingGrounds.java | 13 ++++++---- Mage/src/main/java/mage/game/GameImpl.java | 21 +++++++++------- .../java/mage/game/combat/CombatGroup.java | 2 +- .../mage/game/permanent/PermanentImpl.java | 2 +- .../main/java/mage/players/PlayerList.java | 22 +++++++++-------- .../src/main/java/mage/util/CircularList.java | 7 +++--- 11 files changed, 63 insertions(+), 47 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java index 26a495c0261..3236f9fb8b1 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java @@ -550,6 +550,6 @@ public class VintageCubeDecember2017 extends DraftCube { cubeCards.add(new DraftCube.CardIdentity("Sphinx of the Steel Wind", "")); cubeCards.add(new DraftCube.CardIdentity("Basalt Monolith", "")); cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", "")); - cubeCards.add(new DraftCube.CardIdentity("Thran Dynam", "")); + cubeCards.add(new DraftCube.CardIdentity("Thran Dynamo", "")); } -} \ No newline at end of file +} diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index b22b2f49c14..35df50ba08f 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -959,13 +959,13 @@ public class TableController { if (!table.isTournament()) { if (!(table.getState() == TableState.WAITING || table.getState() == TableState.STARTING || table.getState() == TableState.READY_TO_START)) { if (match == null) { - logger.debug("- Match table with no match:"); - logger.debug("-- matchId:" + match.getId() + " [" + match.getName() + ']'); + logger.warn("- Match table with no match:"); + logger.warn("-- matchId:" + match.getId() + " [" + match.getName() + ']'); // return false; } else if (match.isDoneSideboarding() && match.getGame() == null) { // no sideboarding and not active game -> match seems to hang (maybe the Draw bug) - logger.debug("- Match with no active game and not in sideboard state:"); - logger.debug("-- matchId:" + match.getId() + " [" + match.getName() + ']'); + logger.warn("- Match with no active game and not in sideboard state:"); + logger.warn("-- matchId:" + match.getId() + " [" + match.getName() + ']'); // return false; } } @@ -976,10 +976,10 @@ public class TableController { for (Map.Entry userPlayerEntry : userPlayerMap.entrySet()) { MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue()); if (matchPlayer == null) { - logger.debug("- Match player not found:"); - logger.debug("-- matchId:" + match.getId()); - logger.debug("-- userId:" + userPlayerEntry.getKey()); - logger.debug("-- playerId:" + userPlayerEntry.getValue()); + logger.warn("- Match player not found:"); + logger.warn("-- matchId:" + match.getId()); + logger.warn("-- userId:" + userPlayerEntry.getKey()); + logger.warn("-- playerId:" + userPlayerEntry.getValue()); continue; } if (matchPlayer.getPlayer().isHuman()) { @@ -991,10 +991,10 @@ public class TableController { || (!matchPlayer.hasQuit() && match.getGame() != null && matchPlayer.getPlayer().isInGame())) { Optional user = UserManager.instance.getUser(userPlayerEntry.getKey()); if (!user.isPresent()) { - logger.debug("- Active user of match is missing: " + matchPlayer.getName()); - logger.debug("-- matchId:" + match.getId()); - logger.debug("-- userId:" + userPlayerEntry.getKey()); - logger.debug("-- playerId:" + userPlayerEntry.getValue()); + logger.warn("- Active user of match is missing: " + matchPlayer.getName()); + logger.warn("-- matchId:" + match.getId()); + logger.warn("-- userId:" + userPlayerEntry.getKey()); + logger.warn("-- playerId:" + userPlayerEntry.getValue()); return false; } // user exits on the server and match player has not quit -> player is valid diff --git a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java index 0182b81d45b..5ec579aca4c 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java @@ -27,6 +27,7 @@ */ package mage.cards.c; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -50,8 +51,6 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTarget; -import java.util.UUID; - /** * @author spjspj */ @@ -152,7 +151,8 @@ class CurseOfVengeancePlayerLosesTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getPermanent(this.getSourceId()).getAttachedTo().equals(event.getPlayerId()); + Permanent sourceObject = game.getPermanentOrLKIBattlefield(this.getSourceId()); + return sourceObject != null && sourceObject.getAttachedTo().equals(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java b/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java index 1716626b868..84d9c3dacc0 100644 --- a/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java +++ b/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java @@ -113,7 +113,7 @@ class GhostlyFlickerEffect extends OneShotEffect { for (Card card : toExile) { Zone currentZone = game.getState().getZone(card.getId()); if (Zone.BATTLEFIELD != currentZone && currentZone.isPublicZone()) { - toBattlefield.add(game.getCard(card.getId())); + toBattlefield.add(card); } } controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); diff --git a/Mage.Sets/src/mage/cards/j/JackInTheMox.java b/Mage.Sets/src/mage/cards/j/JackInTheMox.java index 919c625e958..1f3d8d022b4 100644 --- a/Mage.Sets/src/mage/cards/j/JackInTheMox.java +++ b/Mage.Sets/src/mage/cards/j/JackInTheMox.java @@ -76,7 +76,12 @@ class JackInTheMoxManaEffect extends ManaEffect { JackInTheMoxManaEffect() { super(); - staticText = "Roll a six-sided die. If result is 1 - Sacrifice {this} and you lose 5 life. 2 - Add {W} 3 - Add {U} 4 - Add {B} 5 - Add {R} 6 - Add {G} to your mana pool"; + staticText = "Roll a six-sided die for {this}. On a 1, sacrifice {this} and lose 5 life. Otherwise, {this} has one of the following effects. Treat this ability as a mana source." + + "
2 Add {W} to your mana pool.\n" + + "
3 Add {U} to your mana pool.\n" + + "
4 Add {B} to your mana pool.\n" + + "
5 Add {R} to your mana pool.\n" + + "
6 Add {G} to your mana pool."; } JackInTheMoxManaEffect(final JackInTheMoxManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java index 5545a374dce..391f27ddbc9 100644 --- a/Mage.Sets/src/mage/cards/t/TrainingGrounds.java +++ b/Mage.Sets/src/mage/cards/t/TrainingGrounds.java @@ -57,8 +57,9 @@ import mage.util.CardUtil; public class TrainingGrounds extends CardImpl { public TrainingGrounds(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + // Activated abilities of creatures you control cost up to {2} less to activate. This effect can't reduce the amount of mana an ability costs to activate to less than one mana. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TrainingGroundsEffect())); } @@ -107,10 +108,14 @@ class TrainingGroundsEffect extends CostModificationEffectImpl { } choice.setChoices(set); choice.setMessage("Reduce ability cost"); - if (controller.choose(Outcome.Benefit, choice, game)) { - int reduce = Integer.parseInt(choice.getChoice()); - CardUtil.reduceCost(abilityToModify, reduce); + while (!choice.isChosen()) { + controller.choose(Outcome.Benefit, choice, game); + if (!controller.isInGame()) { + return false; + } } + int reduce = Integer.parseInt(choice.getChoice()); + CardUtil.reduceCost(abilityToModify, reduce); } return true; } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 52c0856a99a..4b46792cbb1 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -668,17 +668,20 @@ public abstract class GameImpl implements Game, Serializable { if (!simulation && !this.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner if (bookmark != 0) { if (!savedStates.contains(bookmark - 1)) { - throw new UnsupportedOperationException("It was not possible to do the requested undo operation (bookmark " + (bookmark - 1) + " does not exist) context: " + context); - } - int stateNum = savedStates.get(bookmark - 1); - removeBookmark(bookmark); - GameState restore = gameStates.rollback(stateNum); - if (restore != null) { - state.restore(restore); - playerList.setCurrent(state.getPlayerByOrderId()); + logger.error("It was not possible to do the requested undo operation (bookmark " + (bookmark - 1) + " does not exist) context: " + context); + logger.info("Saved states: " + savedStates.toString()); + } else { + int stateNum = savedStates.get(bookmark - 1); + removeBookmark(bookmark); + GameState restore = gameStates.rollback(stateNum); + if (restore != null) { + state.restore(restore); + playerList.setCurrent(state.getPlayerByOrderId()); + } } } } + } @Override @@ -1355,7 +1358,7 @@ public abstract class GameImpl implements Game, Serializable { logger.fatal(ex.getStackTrace()); } this.fireErrorEvent("Game exception occurred: ", ex); - restoreState(bookmark, ""); + restoreState(bookmark, "Game exception: " + ex.getMessage()); bookmark = 0; Player activePlayer = this.getPlayer(getActivePlayerId()); if (errorContinueCounter > 15) { diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 1717901b6e6..7cd416da0b5 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -304,7 +304,7 @@ public class CombatGroup implements Serializable, Copyable { Map assigned = new HashMap<>(); if (blocked) { boolean excessDamageToDefender = true; - for (UUID blockerId : blockerOrder) { + for (UUID blockerId : new ArrayList<>(blockerOrder)) { // prevent ConcurrentModificationException Permanent blocker = game.getPermanent(blockerId); if (blocker != null) { int lethalDamage; diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 6df53053982..c68a8be15db 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -703,7 +703,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } } if (getSpellAbility() == null) { - logger.info("FATAL : no spell ability for attach to permanent: " + getName()); + // Can happen e.g. for Token Equipments like Stoneforged Blade return; } if (!getSpellAbility().getTargets().isEmpty() && (getSpellAbility().getTargets().get(0) instanceof TargetCard)) { diff --git a/Mage/src/main/java/mage/players/PlayerList.java b/Mage/src/main/java/mage/players/PlayerList.java index bd0c6fe6cc7..b82a661b91f 100644 --- a/Mage/src/main/java/mage/players/PlayerList.java +++ b/Mage/src/main/java/mage/players/PlayerList.java @@ -24,8 +24,7 @@ * 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.players; import java.util.UUID; @@ -38,7 +37,8 @@ import mage.util.CircularList; */ public class PlayerList extends CircularList { - public PlayerList() {} + public PlayerList() { + } public PlayerList(final PlayerList list) { super(list); @@ -47,23 +47,25 @@ public class PlayerList extends CircularList { public Player getCurrent(Game game) { return game.getPlayer(this.get()); } - + public Player getNextInRange(Player basePlayer, Game game) { - UUID currentPlayerBefore = get(); + UUID currentPlayerBefore = get(); UUID nextPlayerId = super.getNext(); do { if (basePlayer.getInRange().contains(nextPlayerId)) { - return game.getPlayer(nextPlayerId); + return game.getPlayer(nextPlayerId); } nextPlayerId = super.getNext(); - } - while (!nextPlayerId.equals(currentPlayerBefore)); + } while (!nextPlayerId.equals(currentPlayerBefore)); return null; } - + public Player getNext(Game game) { - Player player; UUID start = this.get(); + if (start == null) { + return null; + } + Player player; while (true) { player = game.getPlayer(super.getNext()); if (!player.hasLeft() && !player.hasLost()) { diff --git a/Mage/src/main/java/mage/util/CircularList.java b/Mage/src/main/java/mage/util/CircularList.java index cc7cad2e4a2..eced4b874d1 100644 --- a/Mage/src/main/java/mage/util/CircularList.java +++ b/Mage/src/main/java/mage/util/CircularList.java @@ -27,8 +27,6 @@ */ package mage.util; - - import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -111,7 +109,10 @@ public class CircularList implements List, Iterable, Serializable { * @return */ public E get() { - return list.get(this.index); + if (list.size() > this.index) { + return list.get(this.index); + } + return null; } @Override