diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 7c50341c347..7cfe79b084f 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -41,12 +41,11 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import javax.swing.*; import javax.swing.filechooser.FileFilter; -import javax.swing.table.TableModel; import mage.cards.Card; import mage.cards.decks.Deck; @@ -60,8 +59,10 @@ import mage.client.util.Event; import mage.client.util.Listener; import mage.components.CardInfoPane; import mage.game.GameException; +import mage.remote.Session; import mage.sets.Sets; import mage.view.CardView; +import org.apache.log4j.Logger; /** * @@ -69,7 +70,9 @@ import mage.view.CardView; */ public class DeckEditorPanel extends javax.swing.JPanel { - private JFileChooser fcSelectDeck; + private final static Logger logger = Logger.getLogger(DeckEditorPanel.class); + + private JFileChooser fcSelectDeck; private JFileChooser fcImportDeck; private Deck deck = new Deck(); private boolean isShowCardInfo = false; @@ -77,6 +80,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { private DeckEditorMode mode; private int timeout; private Timer countdown; + private UpdateDeckTask updateDeckTask; /** Creates new form DeckEditorPanel */ @@ -100,6 +104,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { setTimeout(Integer.toString(timeout)); } else { + if (updateDeckTask != null) + updateDeckTask.cancel(true); setTimeout("0"); countdown.stop(); hideDeckEditor(); @@ -134,6 +140,10 @@ public class DeckEditorPanel extends javax.swing.JPanel { setTimeout(Integer.toString(timeout)); if (timeout != 0) { countdown.start(); + if (updateDeckTask == null || updateDeckTask.isDone()) { + updateDeckTask = new UpdateDeckTask(MageFrame.getSession(), tableId, deck); + updateDeckTask.execute(); + } } break; case Constructed: @@ -256,6 +266,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { } public void hideDeckEditor() { + if (updateDeckTask != null) + updateDeckTask.cancel(true); Component c = this.getParent(); while (c != null && !(c instanceof DeckEditorPane)) { c = c.getParent(); @@ -526,7 +538,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } catch (GameException ex) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { - Logger.getLogger(DeckEditorPanel.class.getName()).log(Level.SEVERE, null, ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -554,7 +566,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { setCursor(new Cursor(Cursor.WAIT_CURSOR)); Sets.saveDeck(fileName, deck.getDeckCardLists()); } catch (Exception ex) { - Logger.getLogger(DeckEditorPanel.class.getName()).log(Level.SEVERE, null, ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -601,7 +613,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Unknown deck format", "Error importing deck", JOptionPane.ERROR_MESSAGE); } } catch (Exception ex) { - Logger.getLogger(DeckEditorPanel.class.getName()).log(Level.SEVERE, null, ex); + logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -616,6 +628,9 @@ public class DeckEditorPanel extends javax.swing.JPanel { }//GEN-LAST:event_btnImportActionPerformed private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) { + if (updateDeckTask != null) + updateDeckTask.cancel(true); + if (MageFrame.getSession().submitDeck(tableId, deck.getDeckCardLists())) hideDeckEditor(); } @@ -712,4 +727,40 @@ class ImportFilter extends FileFilter { } -} \ No newline at end of file +} + +class UpdateDeckTask extends SwingWorker { + + private final static Logger logger = Logger.getLogger(UpdateDeckTask.class); + + private Session session; + private UUID tableId; + private Deck deck; + + UpdateDeckTask(Session session, UUID tableId, Deck deck) { + this.session = session; + this.tableId = tableId; + this.deck = deck; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + session.updateDeck(tableId, deck.getDeckCardLists()); + Thread.sleep(5000); + } + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException ex) { + logger.fatal("Update Matches Task error", ex); + } catch (ExecutionException ex) { + logger.fatal("Update Matches Task error", ex); + } catch (CancellationException ex) {} + } + +} diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index 97f4edfb1a3..9d61d2077df 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -61,6 +61,7 @@ public interface MageServer { public boolean joinTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException, GameException; public boolean joinTournamentTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill) throws MageException, GameException; public boolean submitDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException; + public void updateDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException; public boolean watchTable(String sessionId, UUID roomId, UUID tableId) throws MageException; public void leaveTable(String sessionId, UUID roomId, UUID tableId) throws MageException; public void swapSeats(String sessionId, UUID roomId, UUID tableId, int seatNum1, int seatNum2) throws MageException; diff --git a/Mage.Common/src/mage/remote/Session.java b/Mage.Common/src/mage/remote/Session.java index bd266cab681..5c3169dea64 100644 --- a/Mage.Common/src/mage/remote/Session.java +++ b/Mage.Common/src/mage/remote/Session.java @@ -743,7 +743,23 @@ public class Session { return false; } - public boolean concedeGame(UUID gameId) { + public boolean updateDeck(UUID tableId, DeckCardLists deck) { + try { + if (isConnected()) { + server.updateDeck(sessionId, tableId, deck); + return true; + } + } catch (GameException ex) { + handleGameException(ex); + } catch (MageException ex) { + handleMageException(ex); + } catch (Throwable t) { + handleThrowable(t); + } + return false; + } + + public boolean concedeGame(UUID gameId) { try { if (isConnected()) { server.concedeGame(gameId, sessionId); diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 95689d7da69..121794f44a9 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -217,6 +217,22 @@ public class MageServerImpl implements MageServer { } @Override + public void updateDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException { + try { + if (SessionManager.getInstance().isValidSession(sessionId)) { + UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); + TableManager.getInstance().updateDeck(userId, tableId, deckList); + logger.debug("Session " + sessionId + " updated deck"); + } + } + catch (Exception ex) { + if (ex instanceof GameException) + throw (GameException)ex; + handleException(ex); + } + } + + @Override public List getTables(UUID roomId) throws MageException { try { return GamesRoomManager.getInstance().getRoom(roomId).getTables(); diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index d11cf594941..fb549c212cb 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -209,7 +209,16 @@ public class TableController { return true; } - private void submitDeck(UUID userId, UUID playerId, Deck deck) { + public void updateDeck(UUID userId, DeckCardLists deckList) throws MageException { + UUID playerId = userPlayerMap.get(userId); + if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) { + return; + } + Deck deck = Deck.load(deckList); + updateDeck(userId, playerId, 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()); @@ -220,7 +229,16 @@ public class TableController { } } - public boolean watchTable(UUID userId) { + private void updateDeck(UUID userId, UUID playerId, Deck deck) { + if (table.getState() == TableState.SIDEBOARDING) { + match.updateDeck(playerId, deck); + } + else { + TournamentManager.getInstance().updateDeck(tournament.getId(), playerId, deck); + } + } + + public boolean watchTable(UUID userId) { if (table.getState() != TableState.DUELING) { return false; } diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java index 63984059d3d..48a752cbd0f 100644 --- a/Mage.Server/src/main/java/mage/server/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -118,7 +118,12 @@ public class TableManager { return false; } - public void removeSession(UUID userId) { + public void updateDeck(UUID userId, UUID tableId, DeckCardLists deckList) throws MageException { + if (controllers.containsKey(tableId)) + controllers.get(tableId).updateDeck(userId, deckList); + } + + public void removeSession(UUID userId) { for (TableController controller: controllers.values()) { controller.kill(userId); } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index cd8dc605631..c4c21e1fad8 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -220,7 +220,11 @@ public class TournamentController { tournamentSessions.get(playerId).submitDeck(deck); } - public void timeout(UUID userId) { + public void updateDeck(UUID playerId, Deck deck) { + tournamentSessions.get(playerId).updateDeck(deck); + } + + public void timeout(UUID userId) { if (userPlayerMap.containsKey(userId)) { TournamentPlayer player = tournament.getPlayer(userPlayerMap.get(userId)); tournament.autoSubmit(userPlayerMap.get(userId), player.generateDeck()); diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java index 0238d686960..a7adce93cf9 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java @@ -69,7 +69,11 @@ public class TournamentManager { controllers.get(tournamentId).submitDeck(playerId, deck); } - public TournamentView getTournamentView(UUID tournamentId) { + public void updateDeck(UUID tournamentId, UUID playerId, Deck deck) { + controllers.get(tournamentId).updateDeck(playerId, deck); + } + + public TournamentView getTournamentView(UUID tournamentId) { return controllers.get(tournamentId).getTournamentView(); } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index 7b4fa5e9639..8de913be7cd 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -112,7 +112,11 @@ public class TournamentSession { tournament.submitDeck(playerId, deck); } - protected void handleRemoteException(RemoteException ex) { + public void updateDeck(Deck deck) { + tournament.updateDeck(playerId, deck); + } + + protected void handleRemoteException(RemoteException ex) { logger.fatal("TournamentSession error ", ex); TournamentManager.getInstance().kill(tournament.getId(), userId); } diff --git a/Mage/src/mage/game/match/Match.java b/Mage/src/mage/game/match/Match.java index f16a8c46172..9cfef6ae4ab 100644 --- a/Mage/src/mage/game/match/Match.java +++ b/Mage/src/mage/game/match/Match.java @@ -52,6 +52,7 @@ public interface Match { public MatchPlayer getPlayer(UUID playerId); public void addPlayer(Player player, Deck deck); public void submitDeck(UUID playerId, Deck deck); + public void updateDeck(UUID playerId, Deck deck); public void startMatch() throws GameException; public void startGame() throws GameException; public void sideboard(); diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java index 74326818ca1..cd0c02b8289 100644 --- a/Mage/src/mage/game/match/MatchImpl.java +++ b/Mage/src/mage/game/match/MatchImpl.java @@ -216,4 +216,13 @@ public abstract class MatchImpl implements Match { } } + @Override + public void updateDeck(UUID playerId, Deck deck) { + MatchPlayer player = getPlayer(playerId); + if (player != null) { + player.updateDeck(deck); + } + } + + } diff --git a/Mage/src/mage/game/match/MatchPlayer.java b/Mage/src/mage/game/match/MatchPlayer.java index 6677783da40..5714724a91d 100644 --- a/Mage/src/mage/game/match/MatchPlayer.java +++ b/Mage/src/mage/game/match/MatchPlayer.java @@ -76,6 +76,10 @@ public class MatchPlayer { this.doneSideboarding = true; } + public void updateDeck(Deck deck) { + this.deck = deck; + } + public Deck generateDeck() { //TODO: improve this while (deck.getCards().size() < 40 && deck.getSideboard().size() > 0) { diff --git a/Mage/src/mage/game/tournament/Tournament.java b/Mage/src/mage/game/tournament/Tournament.java index fa9e08afbbb..5a397e64e3c 100644 --- a/Mage/src/mage/game/tournament/Tournament.java +++ b/Mage/src/mage/game/tournament/Tournament.java @@ -51,6 +51,7 @@ public interface Tournament { public Collection getRounds(); public List getSets(); public void submitDeck(UUID playerId, Deck deck); + public void updateDeck(UUID playerId, Deck deck); public void autoSubmit(UUID playerId, Deck deck); public boolean allJoined(); public boolean isDoneConstructing(); diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java index 0cc1fac03cc..09f4de85dcf 100644 --- a/Mage/src/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/mage/game/tournament/TournamentImpl.java @@ -124,7 +124,14 @@ public abstract class TournamentImpl implements Tournament { } } - protected Round createRoundRandom() { + @Override + public void updateDeck(UUID playerId, Deck deck) { + if (players.containsKey(playerId)) { + players.get(playerId).updateDeck(deck); + } + } + + protected Round createRoundRandom() { Round round = new Round(rounds.size() + 1); rounds.add(round); List roundPlayers = getActivePlayers(); diff --git a/Mage/src/mage/game/tournament/TournamentPlayer.java b/Mage/src/mage/game/tournament/TournamentPlayer.java index 6dfd2e7dc6d..0c361eb7400 100644 --- a/Mage/src/mage/game/tournament/TournamentPlayer.java +++ b/Mage/src/mage/game/tournament/TournamentPlayer.java @@ -98,6 +98,10 @@ public class TournamentPlayer { this.doneConstructing = true; } + public void updateDeck(Deck deck) { + this.deck = deck; + } + public Deck generateDeck() { //TODO: improve this while (deck.getCards().size() < 40 && deck.getSideboard().size() > 0) {