From e1541ece20cae44dccd709aa270ceca6e538b562 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 7 Sep 2015 00:33:33 +0200 Subject: [PATCH] Some fixes to prevent concurrent modification errors on public server. --- Mage/src/mage/abilities/keyword/AwakenAbility.java | 11 +++++++---- Mage/src/mage/abilities/keyword/RetraceAbility.java | 11 +++++++---- Mage/src/mage/game/GameState.java | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Mage/src/mage/abilities/keyword/AwakenAbility.java b/Mage/src/mage/abilities/keyword/AwakenAbility.java index 58becb8661..27508fe957 100644 --- a/Mage/src/mage/abilities/keyword/AwakenAbility.java +++ b/Mage/src/mage/abilities/keyword/AwakenAbility.java @@ -51,6 +51,7 @@ import mage.target.Target; import mage.target.common.TargetControlledPermanent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import mage.watchers.Watcher; /** * @@ -66,10 +67,12 @@ public class AwakenAbility extends SpellAbility { public AwakenAbility(Card card, int awakenValue, String awakenCosts) { super(new ManaCostsImpl<>(awakenCosts), card.getName() + " with awaken", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); this.getCosts().addAll(card.getSpellAbility().getCosts().copy()); - this.getEffects().addAll(card.getSpellAbility().getEffects()); - this.getTargets().addAll(card.getSpellAbility().getTargets()); - this.getChoices().addAll(card.getSpellAbility().getChoices()); - this.getWatchers().addAll(card.getSpellAbility().getWatchers()); + this.getEffects().addAll(card.getSpellAbility().getEffects().copy()); + this.getTargets().addAll(card.getSpellAbility().getTargets().copy()); + this.getChoices().addAll(card.getSpellAbility().getChoices().copy()); + for (Watcher watcher : card.getSpellAbility().getWatchers()) { + this.getWatchers().add(watcher.copy()); + } this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; this.timing = card.getSpellAbility().getTiming(); this.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent(filterMessage))); diff --git a/Mage/src/mage/abilities/keyword/RetraceAbility.java b/Mage/src/mage/abilities/keyword/RetraceAbility.java index e834652840..d210607856 100644 --- a/Mage/src/mage/abilities/keyword/RetraceAbility.java +++ b/Mage/src/mage/abilities/keyword/RetraceAbility.java @@ -34,6 +34,7 @@ import mage.constants.SpellAbilityType; import mage.constants.Zone; import mage.filter.common.FilterLandCard; import mage.target.common.TargetCardInHand; +import mage.watchers.Watcher; /** * @@ -45,10 +46,12 @@ public class RetraceAbility extends SpellAbility { super(card.getManaCost(), card.getName() + " with retrace", Zone.GRAVEYARD, SpellAbilityType.BASE_ALTERNATE); this.getCosts().addAll(card.getSpellAbility().getCosts().copy()); this.addCost(new DiscardTargetCost(new TargetCardInHand(new FilterLandCard()))); - this.getEffects().addAll(card.getSpellAbility().getEffects()); - this.getTargets().addAll(card.getSpellAbility().getTargets()); - this.getChoices().addAll(card.getSpellAbility().getChoices()); - this.getWatchers().addAll(card.getSpellAbility().getWatchers()); + this.getEffects().addAll(card.getSpellAbility().getEffects().copy()); + this.getTargets().addAll(card.getSpellAbility().getTargets().copy()); + this.getChoices().addAll(card.getSpellAbility().getChoices().copy()); + for (Watcher watcher : card.getSpellAbility().getWatchers()) { + this.getWatchers().add(watcher.copy()); + } this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE; this.timing = card.getSpellAbility().getTiming(); diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index 463b91446c..3b1bdd805a 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -742,7 +742,8 @@ public class GameState implements Serializable, Copyable { // TODO: add sources for triggers - the same way as in addEffect: sources this.triggers.add((TriggeredAbility) ability, sourceId, attachedTo); } - for (Watcher watcher : ability.getWatchers()) { + List watcherList = new ArrayList<>(ability.getWatchers()); // Workaround to prevent ConcurrentModificationException, not clear to me why this is happening now + for (Watcher watcher : watcherList) { // TODO: Check that watcher for commanderAbility (where attachedTo = null) also work correctly watcher.setControllerId(attachedTo == null ? ability.getControllerId() : attachedTo.getOwnerId()); watcher.setSourceId(attachedTo == null ? ability.getSourceId() : attachedTo.getId());