diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 6bae8df419..ab9e201465 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -304,7 +304,9 @@ countdown.start(); } - SessionHandler.setBoosterLoaded(draftId); // confirm to the server that the booster has been loaded + if (!draftBooster.isEmptyGrid()) { + SessionHandler.setBoosterLoaded(draftId); // confirm to the server that the booster has been successfully loaded, otherwise the server will re-send the booster + } } private void loadCardsToPickedCardsArea(SimpleCardsView pickedCards) { diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java index 98f8ab3d86..150ac7a428 100644 --- a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java @@ -31,6 +31,7 @@ public class DraftSession { protected final Draft draft; protected boolean killed = false; protected UUID markedCard; + protected int timeoutCardNum; // the pick number for which the current timeout has been set up private ScheduledFuture futureTimeout; protected final ScheduledExecutorService timeoutExecutor; @@ -79,6 +80,7 @@ public class DraftSession { public void pickCard(int timeout) { if (!killed) { setupTimeout(timeout); + timeoutCardNum = draft.getCardNum(); managerFactory.userManager() .getUser(userId) .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_PICK, draft.getId(), @@ -91,7 +93,16 @@ public class DraftSession { cancelTimeout(); if (seconds > 0) { futureTimeout = timeoutExecutor.schedule( - () -> managerFactory.draftManager().timeout(draft.getId(), userId), + () -> { + try { + if (timeoutCardNum == draft.getCardNum()) { + managerFactory.draftManager().timeout(draft.getId(), userId); + setupTimeout(1); // The timeout keeps happening at a 1 second interval to make sure that the draft moves onto the next pick + } + } catch (Exception e) { + logger.fatal("DraftSession error - userId " + userId + " draftId " + draft.getId(), e); + } + }, seconds, TimeUnit.SECONDS ); } @@ -113,7 +124,6 @@ public class DraftSession { } public DraftPickView sendCardPick(UUID cardId, Set hiddenCards) { - cancelTimeout(); if (draft.addPick(playerId, cardId, hiddenCards)) { return getDraftPickView(0); } diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index c1ee45112b..16bbdc34ed 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -8,6 +8,7 @@ import mage.game.events.*; import mage.game.events.TableEvent.EventType; import mage.players.Player; import mage.players.PlayerList; +import org.apache.log4j.Logger; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -20,6 +21,8 @@ import java.util.concurrent.TimeUnit; */ public abstract class DraftImpl implements Draft { + protected static final Logger logger = Logger.getLogger(DraftImpl.class); + protected final UUID id; protected final Map players = new LinkedHashMap<>(); protected final PlayerList table = new PlayerList(); @@ -225,7 +228,7 @@ public abstract class DraftImpl implements Draft { synchronized (this) { while (!donePicking()) { try { - this.wait(); + this.wait(10000); // checked every 10s to make sure the draft moves on } catch (InterruptedException ex) { } } @@ -245,6 +248,7 @@ public abstract class DraftImpl implements Draft { boosterLoadingCounter++; } } catch (Exception ex) { + logger.fatal("Fatal boosterLoadingHandle error in draft " + id + " pack " + boosterNum + " pick " + cardNum, ex); } }, 0, BOOSTER_LOADING_INTERVAL, TimeUnit.SECONDS); }