mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
added timeout on sideboard + show construct and/or sideboard on reconnect
This commit is contained in:
parent
a4ed12b47b
commit
ea44fc973f
18 changed files with 161 additions and 53 deletions
|
|
@ -848,12 +848,30 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
public void showDeckEditor(DeckEditorMode mode, Deck deck, UUID tableId, int time) {
|
||||
String name;
|
||||
if (mode == DeckEditorMode.Sideboard || mode == DeckEditorMode.Limited)
|
||||
name = "Deck Editor - " + tableId.toString();
|
||||
else {
|
||||
if (deck != null)
|
||||
name = "Deck Editor - " + deck.getName();
|
||||
else
|
||||
name = "Deck Editor";
|
||||
}
|
||||
JInternalFrame[] windows = desktopPane.getAllFramesInLayer(JLayeredPane.DEFAULT_LAYER);
|
||||
for (JInternalFrame window : windows) {
|
||||
if (window instanceof DeckEditorPane) {
|
||||
if (window.getTitle().equals(name)) {
|
||||
setActive((MagePane)window);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
DeckEditorPane deckEditorPane = new DeckEditorPane();
|
||||
desktopPane.add(deckEditorPane, JLayeredPane.DEFAULT_LAYER);
|
||||
deckEditorPane.setMaximum(true);
|
||||
deckEditorPane.setVisible(true);
|
||||
deckEditorPane.show(mode, deck, tableId, time);
|
||||
deckEditorPane.show(mode, deck, name, tableId, time);
|
||||
setActive(deckEditorPane);
|
||||
} catch (PropertyVetoException ex) {
|
||||
logger.fatal(null, ex);
|
||||
|
|
|
|||
|
|
@ -73,11 +73,15 @@ public class DeckEditorPane extends MagePane {
|
|||
}
|
||||
}
|
||||
|
||||
public void show(DeckEditorMode mode, Deck deck, UUID tableId, int time) {
|
||||
if (deck != null)
|
||||
this.setTitle("Deck Editor - " + deck.getName());
|
||||
else
|
||||
this.setTitle("Deck Editor");
|
||||
public void show(DeckEditorMode mode, Deck deck, String name, UUID tableId, int time) {
|
||||
if (mode == DeckEditorMode.Sideboard || mode == DeckEditorMode.Limited)
|
||||
this.setTitle("Deck Editor - " + tableId.toString());
|
||||
else {
|
||||
if (deck != null)
|
||||
this.setTitle("Deck Editor - " + deck.getName());
|
||||
else
|
||||
this.setTitle("Deck Editor");
|
||||
}
|
||||
this.deckEditorPanel1.showDeckEditor(mode, deck, tableId, time);
|
||||
this.repaint();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
else {
|
||||
setTimeout("0");
|
||||
countdown.stop();
|
||||
hideDeckEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
|
|||
|
||||
@Override
|
||||
public void construct(Tournament tournament, Deck deck) {
|
||||
tournament.fireConstructEvent(playerId, deck);
|
||||
tournament.fireConstructEvent(playerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import mage.abilities.ActivatedAbility;
|
|||
import mage.abilities.TriggeredAbilities;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
|
|
@ -61,7 +60,6 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
|
|||
private boolean required;
|
||||
private int min;
|
||||
private int max;
|
||||
private Deck deck;
|
||||
private Map<String, Serializable> options;
|
||||
private Map<UUID, String> modes;
|
||||
|
||||
|
|
@ -93,12 +91,11 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
|
|||
this.max = time;
|
||||
}
|
||||
|
||||
private PlayerQueryEvent(UUID playerId, String message, QueryType queryType, Deck deck, int time) {
|
||||
private PlayerQueryEvent(UUID playerId, String message, QueryType queryType, int time) {
|
||||
super(playerId);
|
||||
this.queryType = queryType;
|
||||
this.message = message;
|
||||
this.playerId = playerId;
|
||||
this.deck = deck;
|
||||
this.max = time;
|
||||
}
|
||||
|
||||
|
|
@ -179,8 +176,8 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
|
|||
return new PlayerQueryEvent(playerId, message, booster, QueryType.PICK_CARD, time);
|
||||
}
|
||||
|
||||
public static PlayerQueryEvent construct(UUID playerId, String message, Deck deck, int time) {
|
||||
return new PlayerQueryEvent(playerId, message, QueryType.CONSTRUCT, deck, time);
|
||||
public static PlayerQueryEvent construct(UUID playerId, String message, int time) {
|
||||
return new PlayerQueryEvent(playerId, message, QueryType.CONSTRUCT, time);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -232,10 +229,6 @@ public class PlayerQueryEvent extends EventObject implements ExternalEvent, Seri
|
|||
return max;
|
||||
}
|
||||
|
||||
public Deck getDeck() {
|
||||
return deck;
|
||||
}
|
||||
|
||||
public Map<String, Serializable> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ public class PlayerQueryEventSource implements EventSource<PlayerQueryEvent>, Se
|
|||
dispatcher.fireEvent(PlayerQueryEvent.pickCard(playerId, message, booster, time));
|
||||
}
|
||||
|
||||
public void construct(UUID playerId, String message, Deck deck, int time) {
|
||||
dispatcher.fireEvent(PlayerQueryEvent.construct(playerId, message, deck, time));
|
||||
public void construct(UUID playerId, String message, int time) {
|
||||
dispatcher.fireEvent(PlayerQueryEvent.construct(playerId, message, time));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ import mage.players.Player;
|
|||
*/
|
||||
public interface Match {
|
||||
|
||||
public UUID getId();
|
||||
public static final int SIDEBOARD_TIME = 180;
|
||||
|
||||
public UUID getId();
|
||||
public String getName();
|
||||
public boolean isMatchOver();
|
||||
public List<MatchPlayer> getPlayers();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ package mage.game.match;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
|
|
@ -48,7 +47,6 @@ import mage.players.Player;
|
|||
public abstract class MatchImpl implements Match {
|
||||
|
||||
// private final static Logger logger = Logging.getLogger(MatchImpl.class.getName());
|
||||
private static final int SIDEBOARD_TIME = 180;
|
||||
|
||||
protected UUID id = UUID.randomUUID();
|
||||
protected String name;
|
||||
|
|
@ -199,7 +197,7 @@ public abstract class MatchImpl implements Match {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void fireSideboardEvent(UUID playerId, Deck deck) {
|
||||
MatchPlayer player = getPlayer(playerId);
|
||||
if (player != null) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.game.match;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -75,6 +76,16 @@ public class MatchPlayer {
|
|||
this.doneSideboarding = true;
|
||||
}
|
||||
|
||||
public Deck generateDeck() {
|
||||
//TODO: improve this
|
||||
while (deck.getCards().size() < 40 && deck.getSideboard().size() > 0) {
|
||||
Card card = deck.getSideboard().iterator().next();
|
||||
deck.getCards().add(card);
|
||||
deck.getSideboard().remove(card);
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public interface Tournament {
|
|||
|
||||
public void addTableEventListener(Listener<TableEvent> listener);
|
||||
public void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener);
|
||||
public void fireConstructEvent(UUID playerId, Deck deck);
|
||||
public void fireSubmitDeckEvent(UUID playerId, Deck deck);
|
||||
public void fireConstructEvent(UUID playerId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,20 +214,15 @@ public abstract class TournamentImpl implements Tournament {
|
|||
tableEventSource.addListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireSubmitDeckEvent(UUID playerId, Deck deck) {
|
||||
tableEventSource.fireTableEvent(EventType.SUBMIT_DECK, playerId, deck, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayerQueryEventListener(Listener<PlayerQueryEvent> listener) {
|
||||
playerQueryEventSource.addListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireConstructEvent(UUID playerId, Deck deck) {
|
||||
public void fireConstructEvent(UUID playerId) {
|
||||
TournamentPlayer player = players.get(playerId);
|
||||
playerQueryEventSource.construct(playerId, "Construct", deck, CONSTRUCT_TIME);
|
||||
playerQueryEventSource.construct(playerId, "Construct", CONSTRUCT_TIME);
|
||||
}
|
||||
|
||||
public void construct() {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.game.tournament;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -97,6 +98,16 @@ public class TournamentPlayer {
|
|||
this.doneConstructing = true;
|
||||
}
|
||||
|
||||
public Deck generateDeck() {
|
||||
//TODO: improve this
|
||||
while (deck.getCards().size() < 40 && deck.getSideboard().size() > 0) {
|
||||
Card card = deck.getSideboard().iterator().next();
|
||||
deck.getCards().add(card);
|
||||
deck.getSideboard().remove(card);
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
public boolean isDoneConstructing() {
|
||||
return this.doneConstructing;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue