Draft stability improvements (#9435)

This commit is contained in:
sprangg 2022-09-26 00:33:16 +03:00 committed by GitHub
parent c8c663b976
commit b9530e307d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 116 additions and 4 deletions

View file

@ -273,6 +273,10 @@ public final class SessionHandler {
public static void sendCardMark(UUID draftId, UUID id) {
session.sendCardMark(draftId, id);
}
public static void setBoosterLoaded(UUID draftId) {
session.setBoosterLoaded(draftId);
}
public static Optional<UUID> getRoomChatId(UUID roomId) {
return session.getRoomChatId(roomId);

View file

@ -303,6 +303,8 @@
if (timeout != 0) {
countdown.start();
}
SessionHandler.setBoosterLoaded(draftId); // confirm to the server that the booster has been loaded
}
private void loadCardsToPickedCardsArea(SimpleCardsView pickedCards) {

View file

@ -149,6 +149,8 @@ public interface MageServer {
void sendCardMark(UUID draftId, String sessionId, UUID cardId) throws MageException;
void setBoosterLoaded(UUID draftId, String sessionId) throws MageException;
//challenge methods
// void startChallenge(String sessionId, UUID roomId, UUID tableId, UUID challengeId) throws MageException;
//replay methods

View file

@ -987,6 +987,20 @@ public class SessionImpl implements Session {
}
return null;
}
@Override
public boolean setBoosterLoaded(UUID draftId) {
try {
if (isConnected()) {
server.setBoosterLoaded(draftId, sessionId);
}
} catch (MageException ex) {
handleMageException(ex);
} catch (Throwable t) {
handleThrowable(t);
}
return false;
}
@Override
public boolean joinChat(UUID chatId) {

View file

@ -39,6 +39,8 @@ public interface GamePlay {
boolean updateDeck(UUID tableId, DeckCardLists deck);
boolean setBoosterLoaded(UUID draftId);
DraftPickView sendCardPick(UUID draftId, UUID cardId, Set<UUID> hiddenCards);
DraftPickView sendCardMark(UUID draftId, UUID cardId);

View file

@ -736,6 +736,16 @@ public class MageServerImpl implements MageServer {
});
});
}
@Override
public void setBoosterLoaded(final UUID draftId, final String sessionId) throws MageException {
execute("setBoosterLoaded", sessionId, () -> {
managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
managerFactory.draftManager().setBoosterLoaded(draftId, userId);
});
});
}
@Override
public void quitMatch(final UUID gameId, final String sessionId) throws MageException {

View file

@ -199,6 +199,10 @@ public class DraftController {
public void sendCardMark(UUID userId, UUID cardId) {
draftSessions.get(userPlayerMap.get(userId)).setMarkedCard(cardId);
}
public void setBoosterLoaded(UUID userId) {
draftSessions.get(userPlayerMap.get(userId)).setBoosterLoaded();
}
private synchronized void updateDraft() throws MageException {
for (final Entry<UUID, DraftSession> entry : draftSessions.entrySet()) {

View file

@ -49,6 +49,11 @@ public class DraftManagerImpl implements DraftManager {
public void sendCardMark(UUID draftId, UUID userId, UUID cardId) {
draftControllers.get(draftId).sendCardMark(userId, cardId);
}
@Override
public void setBoosterLoaded(UUID draftId, UUID userId) {
draftControllers.get(draftId).setBoosterLoaded(userId);
}
@Override
public void removeSession(UUID userId) {

View file

@ -144,5 +144,9 @@ public class DraftSession {
public void setMarkedCard(UUID markedCard) {
this.markedCard = markedCard;
}
public void setBoosterLoaded() {
draft.setBoosterLoaded(playerId);
}
}

View file

@ -19,6 +19,8 @@ public interface DraftManager {
DraftPickView sendCardPick(UUID draftId, UUID userId, UUID cardId, Set<UUID> hiddenCards);
void sendCardMark(UUID draftId, UUID userId, UUID cardId);
void setBoosterLoaded(UUID draftId, UUID userId);
void removeSession(UUID userId);

View file

@ -30,6 +30,7 @@ public interface Draft extends MageItem, Serializable {
int getBoosterNum();
int getCardNum();
boolean addPick(UUID playerId, UUID cardId, Set<UUID> hiddenCards);
void setBoosterLoaded(UUID playerID);
void start();
boolean isStarted();
void setStarted();

View file

@ -9,6 +9,11 @@ import mage.game.events.TableEvent.EventType;
import mage.players.Player;
import mage.players.PlayerList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
*
* @author BetaSteward_at_googlemail.com
@ -25,12 +30,17 @@ public abstract class DraftImpl implements Draft {
protected int boosterNum = 1; // starts with booster 1
protected int cardNum = 1; // starts with card number 1, increases by +1 after each picking
protected TimingOption timing;
protected int boosterLoadingCounter; // number of times the boosters have been sent to players until all are confirmed to have received them
protected final int BOOSTER_LOADING_INTERVAL = 3; // interval in seconds
protected boolean abort = false;
protected boolean started = false;
protected transient TableEventSource tableEventSource = new TableEventSource();
protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource();
protected ScheduledFuture<?> boosterLoadingHandle;
protected final ScheduledExecutorService boosterLoadingExecutor = Executors.newSingleThreadScheduledExecutor();
public DraftImpl(DraftOptions options, List<ExpansionSet> sets) {
id = UUID.randomUUID();
@ -209,9 +219,9 @@ public abstract class DraftImpl implements Draft {
return false;
}
player.setPicking();
player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this);
player.setBoosterNotLoaded();
}
cardNum++;
setupBoosterLoadingHandle();
synchronized (this) {
while (!donePicking()) {
try {
@ -220,9 +230,42 @@ public abstract class DraftImpl implements Draft {
}
}
}
cardNum++;
return true;
}
protected void setupBoosterLoadingHandle() {
cancelBoosterLoadingHandle();
boosterLoadingCounter = 0;
boosterLoadingHandle = boosterLoadingExecutor.scheduleAtFixedRate(() -> {
try {
if (loadBoosters() == true) {
cancelBoosterLoadingHandle();
} else {
boosterLoadingCounter++;
}
} catch (Exception ex) {
}
}, 0, BOOSTER_LOADING_INTERVAL, TimeUnit.SECONDS);
}
protected void cancelBoosterLoadingHandle() {
if (boosterLoadingHandle != null) {
boosterLoadingHandle.cancel(true);
}
}
protected boolean loadBoosters () {
boolean allBoostersLoaded = true;
for (DraftPlayer player : players.values()) {
if (player.isPicking() && !player.isBoosterLoaded()) {
allBoostersLoaded = false;
player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this);
}
}
return allBoostersLoaded;
}
protected boolean donePicking() {
if (isAbort()) {
return true;
@ -263,7 +306,7 @@ public abstract class DraftImpl implements Draft {
public void firePickCardEvent(UUID playerId) {
DraftPlayer player = players.get(playerId);
int cardNum = Math.min(15, this.cardNum);
int time = timing.getPickTimeout(cardNum);
int time = timing.getPickTimeout(cardNum) - boosterLoadingCounter * BOOSTER_LOADING_INTERVAL;
playerQueryEventSource.pickCard(playerId, "Pick card", player.getBooster(), time);
}
@ -284,6 +327,12 @@ public abstract class DraftImpl implements Draft {
}
return !player.isPicking();
}
@Override
public void setBoosterLoaded(UUID playerId) {
DraftPlayer player = players.get(playerId);
player.setBoosterLoaded();
}
@Override
public boolean isAbort() {

View file

@ -21,6 +21,7 @@ public class DraftPlayer {
protected Deck deck;
protected List<Card> booster;
protected boolean picking;
protected boolean boosterLoaded;
protected boolean joined = false;
protected Set<UUID> hiddenCards;
@ -97,5 +98,17 @@ public class DraftPlayer {
public void setJoined() {
this.joined = true;
}
public void setBoosterLoaded() {
boosterLoaded = true;
}
public void setBoosterNotLoaded() {
boosterLoaded = false;
}
public boolean isBoosterLoaded() {
return boosterLoaded;
}
}