diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 1bece076bd7..1f554dbdd4e 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -3169,6 +3169,7 @@ public abstract class GameImpl implements Game { if (simulation) { return; } + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.INFO, message, this); } @@ -3177,6 +3178,7 @@ public abstract class GameImpl implements Game { if (simulation) { return; } + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.STATUS, message, withTime, withTurnInfo, this); } @@ -3185,7 +3187,7 @@ public abstract class GameImpl implements Game { if (simulation) { return; } - logger.trace("fireUpdatePlayersEvent"); + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.UPDATE, null, this); getState().clearLookedAt(); getState().clearRevealed(); @@ -3196,15 +3198,27 @@ public abstract class GameImpl implements Game { if (simulation) { return; } - logger.trace("fireGameEndIfo"); + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.END_GAME_INFO, null, this); } @Override public void fireErrorEvent(String message, Exception ex) { + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.ERROR, message, ex, this); } + private void makeSureCalledOutsideLayersEffects() { + // very slow, enable/comment it for debug or load/stability tests only + // TODO: enable check and remove/rework all wrong usages + if (true) return; + Arrays.stream(Thread.currentThread().getStackTrace()).forEach(e -> { + if (e.toString().contains("GameState.applyEffects")) { + throw new IllegalStateException("Wrong code usage: client side events can't be called from layers effects (wrong informPlayers usage?"); + } + }); + } + @Override public Players getPlayers() { return state.getPlayers(); @@ -3871,6 +3885,7 @@ public abstract class GameImpl implements Game { @Override public void initTimer(UUID playerId) { if (priorityTime > 0) { + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.INIT_TIMER, playerId, null, this); } } @@ -3878,6 +3893,7 @@ public abstract class GameImpl implements Game { @Override public void resumeTimer(UUID playerId) { if (priorityTime > 0) { + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.RESUME_TIMER, playerId, null, this); } } @@ -3885,6 +3901,7 @@ public abstract class GameImpl implements Game { @Override public void pauseTimer(UUID playerId) { if (priorityTime > 0) { + makeSureCalledOutsideLayersEffects(); tableEventSource.fireTableEvent(EventType.PAUSE_TIMER, playerId, null, this); } } diff --git a/Mage/src/main/java/mage/game/events/TableEvent.java b/Mage/src/main/java/mage/game/events/TableEvent.java index ef9af06af82..ef3b80ff9da 100644 --- a/Mage/src/main/java/mage/game/events/TableEvent.java +++ b/Mage/src/main/java/mage/game/events/TableEvent.java @@ -57,7 +57,7 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab public TableEvent(EventType eventType, String message, boolean withTime, boolean withTurnInfo, Game game) { super(game); - this.game = game; + this.game = game; // TODO: potentially bugged and need game copy? See related makeSureCalledOutsideLayersEffects this.message = message; this.eventType = eventType; this.withTime = withTime;