added timeout on sideboard + show construct and/or sideboard on reconnect

This commit is contained in:
BetaSteward 2011-09-03 21:44:05 -04:00
parent a4ed12b47b
commit ea44fc973f
18 changed files with 161 additions and 53 deletions

View file

@ -56,7 +56,12 @@ import org.apache.log4j.Logger;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.decks.InvalidDeckException;
import mage.game.match.MatchPlayer;
import mage.server.util.ThreadExecutor;
/**
*
@ -74,6 +79,9 @@ public class TableController {
private MatchOptions options;
private Tournament tournament;
private ConcurrentHashMap<UUID, UUID> userPlayerMap = new ConcurrentHashMap<UUID, UUID>();
private ScheduledFuture<?> futureTimeout;
protected static ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor();
public TableController(UUID roomId, UUID userId, MatchOptions options) {
this.userId = userId;
@ -111,10 +119,7 @@ public class TableController {
try {
switch (event.getEventType()) {
case SIDEBOARD:
sideboard(event.getPlayerId(), event.getDeck(), event.getTimeout());
break;
case SUBMIT_DECK:
submitDeck(event.getPlayerId(), event.getDeck());
sideboard(event.getPlayerId(), event.getDeck());
break;
}
} catch (MageException ex) {
@ -200,16 +205,18 @@ public class TableController {
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
throw new InvalidDeckException("Invalid deck for this format", table.getValidator().getInvalid());
}
submitDeck(playerId, deck);
submitDeck(userId, playerId, deck);
return true;
}
private void submitDeck(UUID playerId, Deck deck) {
private void submitDeck(UUID userId, UUID playerId, Deck deck) {
if (table.getState() == TableState.SIDEBOARDING) {
match.submitDeck(playerId, deck);
UserManager.getInstance().getUser(userId).removeSideboarding(table.getId());
}
else {
TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck);
UserManager.getInstance().getUser(userId).removeConstructing(table.getId());
}
}
@ -350,17 +357,22 @@ public class TableController {
}
}
private void sideboard(UUID playerId, Deck deck, int timeout) throws MageException {
private void sideboard(UUID playerId, Deck deck) throws MageException {
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) {
User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null)
user.sideboard(deck, table.getId(), timeout);
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
if (user != null)
user.sideboard(deck, table.getId(), remaining);
break;
}
}
}
public int getRemainingTime() {
return (int) futureTimeout.getDelay(TimeUnit.SECONDS);
}
public void construct() {
table.construct();
}
@ -374,7 +386,9 @@ public class TableController {
try {
if (!match.isMatchOver()) {
table.sideboard();
setupTimeout(Match.SIDEBOARD_TIME);
match.sideboard();
cancelTimeout();
startGame(choosingPlayerId);
}
// else {
@ -385,7 +399,35 @@ public class TableController {
}
}
public void endDraft(Draft draft) {
private synchronized void setupTimeout(int seconds) {
cancelTimeout();
if (seconds > 0) {
futureTimeout = timeoutExecutor.schedule(
new Runnable() {
@Override
public void run() {
autoSideboard();
}
},
seconds, TimeUnit.SECONDS
);
}
}
private synchronized void cancelTimeout() {
if (futureTimeout != null) {
futureTimeout.cancel(false);
}
}
private void autoSideboard() {
for (MatchPlayer player: match.getPlayers()) {
if (!player.isDoneSideboarding())
match.submitDeck(player.getPlayer().getId(), player.generateDeck());
}
}
public void endDraft(Draft draft) {
for (DraftPlayer player: draft.getPlayers()) {
tournament.getPlayer(player.getPlayer().getId()).setDeck(player.getDeck());
}

View file

@ -96,6 +96,10 @@ public class TableManager {
return tables.values();
}
public TableController getController(UUID tableId) {
return controllers.get(tableId);
}
public boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException {
if (controllers.containsKey(tableId))
return controllers.get(tableId).joinTable(userId, name, playerType, skill, deckList);

View file

@ -27,8 +27,10 @@
*/
package mage.server;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
@ -62,6 +64,8 @@ public class User {
private Map<UUID, GameSession> gameSessions = new HashMap<UUID, GameSession>();
private Map<UUID, DraftSession> draftSessions = new HashMap<UUID, DraftSession>();
private Map<UUID, TournamentSession> tournamentSessions = new HashMap<UUID, TournamentSession>();
private Map<UUID, TournamentSession> constructing = new HashMap<UUID, TournamentSession>();
private Map<UUID, Deck> sideboarding = new HashMap<UUID, Deck>();
public User(String userName, String host) {
this.userName = userName;
@ -130,6 +134,7 @@ public class User {
public void sideboard(final Deck deck, final UUID tableId, final int time) {
fireCallback(new ClientCallback("sideboard", tableId, new TableClientMessage(deck, tableId, time)));
sideboarding.put(tableId, deck);
}
public void construct(final Deck deck, final UUID tableId, final int time) {
@ -187,6 +192,13 @@ public class User {
entry.getValue().init();
entry.getValue().update();
}
for (Entry<UUID, TournamentSession> entry: constructing.entrySet()) {
entry.getValue().construct(0);
}
for (Entry<UUID, Deck> entry: sideboarding.entrySet()) {
int remaining = TableManager.getInstance().getController(entry.getKey()).getRemainingTime();
sideboard(entry.getValue(), entry.getKey(), remaining);
}
}
public void addGame(UUID playerId, GameSession gameSession) {
@ -220,8 +232,20 @@ public class User {
public void removeTable(UUID playerId) {
tables.remove(playerId);
}
public void addConstructing(UUID playerId, TournamentSession tournamentSession) {
constructing.put(playerId, tournamentSession);
}
public void kill() {
public void removeConstructing(UUID playerId) {
constructing.remove(playerId);
}
public void removeSideboarding(UUID tableId) {
sideboarding.remove(tableId);
}
public void kill() {
for (GameSession session: gameSessions.values()) {
session.kill();
}

View file

@ -91,9 +91,9 @@ public class TournamentController {
case START_MATCH:
startMatch(event.getPair(), event.getMatchOptions());
break;
case SUBMIT_DECK:
submitDeck(event.getPlayerId(), event.getDeck());
break;
// case SUBMIT_DECK:
// submitDeck(event.getPlayerId(), event.getDeck());
// break;
case CONSTRUCT:
construct();
break;
@ -111,7 +111,7 @@ public class TournamentController {
try {
switch (event.getQueryType()) {
case CONSTRUCT:
construct(event.getPlayerId(), event.getDeck(), event.getMax());
construct(event.getPlayerId(), event.getMax());
break;
}
} catch (MageException ex) {
@ -208,9 +208,12 @@ public class TournamentController {
TableManager.getInstance().construct(tableId);
}
private void construct(UUID playerId, Deck deck, int timeout) throws MageException {
if (tournamentSessions.containsKey(playerId))
tournamentSessions.get(playerId).construct(deck, timeout);
private void construct(UUID playerId, int timeout) throws MageException {
if (tournamentSessions.containsKey(playerId)) {
TournamentSession tournamentSession = tournamentSessions.get(playerId);
tournamentSession.construct(timeout);
UserManager.getInstance().getUser(getPlayerSessionId(playerId)).addConstructing(playerId, tournamentSession);
}
}
public void submitDeck(UUID playerId, Deck deck) {
@ -220,7 +223,7 @@ public class TournamentController {
public void timeout(UUID userId) {
if (userPlayerMap.containsKey(userId)) {
TournamentPlayer player = tournament.getPlayer(userPlayerMap.get(userId));
tournament.autoSubmit(userPlayerMap.get(userId), player.getDeck());
tournament.autoSubmit(userPlayerMap.get(userId), player.generateDeck());
}
}

View file

@ -96,12 +96,13 @@ public class TournamentSession {
}
}
public void construct(Deck deck, int timeout) throws MageException {
public void construct(int timeout) {
if (!killed) {
setupTimeout(timeout);
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.construct(deck, tableId, timeout);
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
user.construct(tournament.getPlayer(playerId).getDeck(), tableId, remaining);
}
}
}
@ -121,6 +122,8 @@ public class TournamentSession {
}
private synchronized void setupTimeout(int seconds) {
if (futureTimeout != null && !futureTimeout.isDone())
return;
cancelTimeout();
if (seconds > 0) {
futureTimeout = timeoutExecutor.schedule(