diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form index 0b1bdc66198..fdd4db97cf0 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form @@ -106,6 +106,9 @@ + + + @@ -128,7 +131,7 @@ - + @@ -228,6 +231,7 @@ + @@ -257,6 +261,11 @@ + + + + + @@ -270,13 +279,8 @@ - - - - - - -
+ +
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 11938f4a615..06ca513e1cd 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -48,7 +48,6 @@ import mage.remote.Session; import mage.client.util.ButtonColumn; import mage.game.match.MatchOptions; import mage.sets.Sets; -import mage.utils.CompressUtil; import mage.view.TableView; import org.apache.log4j.Logger; @@ -63,6 +62,8 @@ import java.util.*; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import mage.client.util.gui.GuiDisplayUtil; +import mage.view.MatchView; /** @@ -74,12 +75,15 @@ public class TablesPanel extends javax.swing.JPanel { private final static Logger logger = Logger.getLogger(TablesPanel.class); private TableTableModel tableModel; + private MatchesTableModel matchesModel; private UUID roomId; - private UpdateTablesTask updateTask; + private UpdateTablesTask updateTablesTask; private UpdatePlayersTask updatePlayersTask; + private UpdateMatchesTask updateMatchesTask; private JoinTableDialog joinTableDialog; private NewTableDialog newTableDialog; private NewTournamentDialog newTournamentDialog; + private GameChooser gameChooser; private Session session; private List messages; private int currentMessage; @@ -88,6 +92,8 @@ public class TablesPanel extends javax.swing.JPanel { public TablesPanel() { tableModel = new TableTableModel(); + matchesModel = new MatchesTableModel(); + gameChooser = new GameChooser(); initComponents(); @@ -96,7 +102,7 @@ public class TablesPanel extends javax.swing.JPanel { chatPanel.setOpaque(false); chatPanel.setBorder(null); - Action join = new AbstractAction() + Action joinTable = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) @@ -149,7 +155,24 @@ public class TablesPanel extends javax.swing.JPanel { } }; - ButtonColumn buttonColumn = new ButtonColumn(tableTables, join, 6); + Action replayMatch = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + int modelRow = Integer.valueOf( e.getActionCommand() ); + List games = (List)matchesModel.getValueAt(modelRow, 6); + if (games.size() == 1) { + session.replayGame(games.get(0)); + } + else { + gameChooser.show(games, MageFrame.getDesktop().getMousePosition()); + } + } + }; + + ButtonColumn buttonColumn1 = new ButtonColumn(tableTables, joinTable, 6); + ButtonColumn buttonColumn2 = new ButtonColumn(tableCompleted, replayMatch, 5); jSplitPane1.setOpaque(false); jScrollPane1.setOpaque(false); @@ -168,7 +191,7 @@ public class TablesPanel extends javax.swing.JPanel { return components; } - public void update(Collection tables) { + public void updateTables(Collection tables) { try { tableModel.loadData(tables); this.tableTables.repaint(); @@ -177,24 +200,45 @@ public class TablesPanel extends javax.swing.JPanel { } } - public void startTasks() { + public void updateMatches(Collection matches) { + try { + matchesModel.loadData(matches); + this.tableCompleted.repaint(); + } catch (Exception ex) { + hideTables(); + } + } + + public void startTasks() { if (session != null) { - if (updateTask == null || updateTask.isDone()) { - updateTask = new UpdateTablesTask(session, roomId, this); - updateTask.execute(); + if (updateTablesTask == null || updateTablesTask.isDone()) { + updateTablesTask = new UpdateTablesTask(session, roomId, this); + updateTablesTask.execute(); } if (updatePlayersTask == null || updatePlayersTask.isDone()) { updatePlayersTask = new UpdatePlayersTask(session, roomId, this.chatPanel); updatePlayersTask.execute(); } + if (this.chkShowCompleted.isSelected()) { + if (updateMatchesTask == null || updateMatchesTask.isDone()) { + updateMatchesTask = new UpdateMatchesTask(session, roomId, this); + updateMatchesTask.execute(); + } + } + else { + if (updateMatchesTask != null) + updateMatchesTask.cancel(true); + } } } public void stopTasks() { - if (updateTask != null) - updateTask.cancel(true); + if (updateTablesTask != null) + updateTablesTask.cancel(true); if (updatePlayersTask != null) updatePlayersTask.cancel(true); + if (updateMatchesTask != null) + updateMatchesTask.cancel(true); } public void showTables(UUID roomId) { @@ -203,6 +247,7 @@ public class TablesPanel extends javax.swing.JPanel { session = MageFrame.getSession(); if (session != null) { btnQuickStart.setVisible(session.isTestMode()); + gameChooser.init(session); } if (newTableDialog == null) { newTableDialog = new NewTableDialog(); @@ -311,6 +356,11 @@ public class TablesPanel extends javax.swing.JPanel { chkShowCompleted.setSelected(true); chkShowCompleted.setText("Show Completed"); + chkShowCompleted.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + chkShowCompletedActionPerformed(evt); + } + }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -342,7 +392,7 @@ public class TablesPanel extends javax.swing.JPanel { jPanel2.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); jPanel2.setPreferredSize(new java.awt.Dimension(664, 39)); - jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); jLabel1.setText("Message of the Day:"); jLabel1.setAlignmentY(0.3F); @@ -366,7 +416,7 @@ public class TablesPanel extends javax.swing.JPanel { .addContainerGap() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 449, Short.MAX_VALUE) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(440, 440, 440)) @@ -388,23 +438,16 @@ public class TablesPanel extends javax.swing.JPanel { jSplitPane1.setRightComponent(chatPanel); jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + jSplitPane2.setResizeWeight(0.5); tableTables.setModel(this.tableModel); jScrollPane1.setViewportView(tableTables); jSplitPane2.setLeftComponent(jScrollPane1); - tableCompleted.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null} - }, - new String [] { - "Title 1", "Title 2", "Title 3", "Title 4" - } - )); + jScrollPane2.setMinimumSize(new java.awt.Dimension(23, 0)); + + tableCompleted.setModel(this.matchesModel); jScrollPane2.setViewportView(tableCompleted); jSplitPane2.setRightComponent(jScrollPane2); @@ -486,6 +529,16 @@ public class TablesPanel extends javax.swing.JPanel { } }//GEN-LAST:event_jButton1ActionPerformed +private void chkShowCompletedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowCompletedActionPerformed + if (this.chkShowCompleted.isSelected()) { + this.jSplitPane2.setDividerLocation(-1); + } + else { + this.jSplitPane2.setDividerLocation(this.jPanel3.getHeight()); + } + this.startTasks(); +}//GEN-LAST:event_chkShowCompletedActionPerformed + private void handleError(Exception ex) { logger.fatal("Error loading deck: ", ex); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error loading deck.", "Error", JOptionPane.ERROR_MESSAGE); @@ -622,7 +675,7 @@ class UpdateTablesTask extends SwingWorker> { @Override protected void process(List> view) { - panel.update(view.get(0)); + panel.updateTables(view.get(0)); } @Override @@ -677,4 +730,148 @@ class UpdatePlayersTask extends SwingWorker> { } catch (CancellationException ex) {} } -} \ No newline at end of file +} + +class MatchesTableModel extends AbstractTableModel { + private String[] columnNames = new String[]{"Match Name", "Game Type", "Deck Type", "Players", "Result", "Action"}; + private MatchView[] matches = new MatchView[0]; + private static final DateFormat timeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT); + + public void loadData(Collection matches) throws MageRemoteException { + this.matches = matches.toArray(new MatchView[0]); + this.fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return matches.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return matches[arg0].getName(); + case 1: + return matches[arg0].getGameType(); + case 2: + return matches[arg0].getDeckType(); + case 3: + return matches[arg0].getPlayers(); + case 4: + return matches[arg0].getResult(); + case 5: + return "Replay"; + case 6: + return matches[arg0].getGames(); + } + return ""; + } + + @Override + public String getColumnName(int columnIndex) { + String colName = ""; + + if (columnIndex <= getColumnCount()) + colName = columnNames[columnIndex]; + + return colName; + } + + @Override + public Class getColumnClass(int columnIndex){ + return String.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + if (columnIndex != 5) + return false; + return true; + } + +} + +class UpdateMatchesTask extends SwingWorker> { + + private Session session; + private UUID roomId; + private TablesPanel panel; + + private final static Logger logger = Logger.getLogger(UpdateTablesTask.class); + + UpdateMatchesTask(Session session, UUID roomId, TablesPanel panel) { + this.session = session; + this.roomId = roomId; + this.panel = panel; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + Collection matches = session.getFinishedMatches(roomId); + if (matches != null) this.publish(matches); + Thread.sleep(5000); + } + return null; + } + + @Override + protected void process(List> view) { + panel.updateMatches(view.get(0)); + } + + @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) {} + } + +} + +class GameChooser extends JPopupMenu { + + private Session session; + + public void init(Session session) { + this.session = session; + } + + public void show(List games, Point p) { + if (p == null) return; + this.removeAll(); + for (UUID gameId: games) { + this.add(new GameChooserAction(gameId, gameId.toString())); + } + this.show(MageFrame.getDesktop(), p.x, p.y); + GuiDisplayUtil.keepComponentInsideScreen(p.x, p.y, this); + } + + private class GameChooserAction extends AbstractAction { + + private UUID id; + + public GameChooserAction(UUID id, String choice) { + this.id = id; + putValue(Action.NAME, choice); + } + + @Override + public void actionPerformed(ActionEvent e) { + session.replayGame(id); + setVisible(false); + } + + } + +} diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index aba894aae90..97f4edfb1a3 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -39,6 +39,7 @@ import mage.utils.MageVersion; import mage.view.DraftPickView; import mage.view.TableView; import mage.view.GameView; +import mage.view.MatchView; import mage.view.TournamentView; import mage.view.UserView; @@ -68,6 +69,7 @@ public interface MageServer { public TableView getTable(UUID roomId, UUID tableId) throws MageException; public List getTables(UUID roomId) throws MageException; public List getConnectedPlayers(UUID roomId) throws MageException; + public List getFinishedMatches(UUID roomId) throws MageException; //chat methods public void sendChatMessage(UUID chatId, String userName, String message) throws MageException; @@ -91,7 +93,6 @@ public interface MageServer { public void sendPlayerBoolean(UUID gameId, String sessionId, Boolean data) throws MageException; public void sendPlayerInteger(UUID gameId, String sessionId, Integer data) throws MageException; public void concedeGame(UUID gameId, String sessionId) throws MageException; - //tournament methods public void startTournament(String sessionId, UUID roomId, UUID tableId) throws MageException; diff --git a/Mage.Common/src/mage/remote/Session.java b/Mage.Common/src/mage/remote/Session.java index f7c342f9ac1..7e8cdc6525e 100644 --- a/Mage.Common/src/mage/remote/Session.java +++ b/Mage.Common/src/mage/remote/Session.java @@ -49,6 +49,7 @@ import mage.interfaces.callback.ClientCallback; import mage.utils.CompressUtil; import mage.view.DraftPickView; import mage.view.GameTypeView; +import mage.view.MatchView; import mage.view.TableView; import mage.view.TournamentTypeView; import mage.view.TournamentView; @@ -342,7 +343,6 @@ public class Session { } public Collection getTables(UUID roomId) throws MageRemoteException { -// lock.readLock().lock(); try { if (isConnected()) return server.getTables(roomId); @@ -351,14 +351,24 @@ public class Session { throw new MageRemoteException(); } catch (Throwable t) { handleThrowable(t); -// } finally { -// lock.readLock().unlock(); } return null; } - public Collection getConnectedPlayers(UUID roomId) throws MageRemoteException { -// lock.readLock().lock(); + public Collection getFinishedMatches(UUID roomId) throws MageRemoteException { + try { + if (isConnected()) + return server.getFinishedMatches(roomId); + } catch (MageException ex) { + handleMageException(ex); + throw new MageRemoteException(); + } catch (Throwable t) { + handleThrowable(t); + } + return null; + } + + public Collection getConnectedPlayers(UUID roomId) throws MageRemoteException { try { if (isConnected()) return server.getConnectedPlayers(roomId); @@ -367,8 +377,6 @@ public class Session { throw new MageRemoteException(); } catch (Throwable t) { handleThrowable(t); -// } finally { -// lock.readLock().unlock(); } return null; } diff --git a/Mage.Common/src/mage/view/MatchView.java b/Mage.Common/src/mage/view/MatchView.java new file mode 100644 index 00000000000..0dce84153fc --- /dev/null +++ b/Mage.Common/src/mage/view/MatchView.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.view; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.game.Game; +import mage.game.match.Match; +import mage.game.match.MatchPlayer; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class MatchView implements Serializable { + + private UUID matchId; + private String matchName; + private String gameType; + private String deckType; + + private List games = new ArrayList(); + private String result; + private String players; + + public MatchView(Match match) { + this.matchId = match.getId(); + this.matchName = match.getName(); + this.gameType = match.getOptions().getGameType(); + this.deckType = match.getOptions().getDeckType(); + for (Game game: match.getGames()) { + games.add(game.getId()); + } + StringBuilder sb1 = new StringBuilder(); + StringBuilder sb2 = new StringBuilder(); + for (MatchPlayer player: match.getPlayers()) { + sb1.append(player.getPlayer().getName()).append(", "); + sb2.append(player.getPlayer().getName()).append(" ").append(player.getWins()).append("-").append(player.getLoses()).append(", "); + players = sb1.substring(0, sb1.length() - 2); + result = sb2.substring(0, sb2.length() - 2); + } + + } + + public UUID getMatchId() { + return matchId; + } + + public String getName() { + return matchName; + } + + public String getGameType() { + return gameType; + } + + public String getDeckType() { + return deckType; + } + + public List getGames() { + return games; + } + + public String getResult() { + return result; + } + + public String getPlayers() { + return players; + } + +} diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 48c29278ba4..c9dc2284001 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -56,6 +56,7 @@ import mage.utils.MageVersion; import mage.view.ChatMessage.MessageColor; import mage.view.DraftPickView; import mage.view.GameView; +import mage.view.MatchView; import mage.view.TableView; import mage.view.TournamentView; import mage.view.UserView; @@ -224,6 +225,17 @@ public class MageServerImpl implements MageServer { } @Override + public List getFinishedMatches(UUID roomId) throws MageException { + try { + return GamesRoomManager.getInstance().getRoom(roomId).getFinished(); + } + catch (Exception ex) { + handleException(ex); + } + return null; + } + + @Override public List getConnectedPlayers(UUID roomId) throws MageException { try { List players = new ArrayList(); diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index 10ba2bacd88..4aa95357ad8 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -377,9 +377,9 @@ public class TableController { match.sideboard(); startGame(choosingPlayerId); } - else { - GamesRoomManager.getInstance().removeTable(table.getId()); - } +// else { +// GamesRoomManager.getInstance().removeTable(table.getId()); +// } } catch (GameException ex) { logger.fatal(null, ex); } diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java index 8c5a527e130..0fd5255f702 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java @@ -36,6 +36,7 @@ import mage.game.GameException; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; import mage.MageException; +import mage.view.MatchView; import mage.view.TableView; /** @@ -45,6 +46,7 @@ import mage.view.TableView; public interface GamesRoom extends Room { public List getTables(); + public List getFinished(); public boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException; public boolean joinTournamentTable(UUID userId, UUID tableId, String name, String playerType, int skill) throws GameException; public TableView createTable(UUID userId, MatchOptions options); diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java index b2346b67ccf..3395e6a0662 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java @@ -36,11 +36,13 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import mage.Constants.TableState; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; import mage.MageException; +import mage.view.MatchView; import mage.view.TableView; import org.apache.log4j.Logger; @@ -58,11 +60,22 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { public List getTables() { ArrayList tableList = new ArrayList(); for (Table table: tables.values()) { - tableList.add(new TableView(table)); + if (table.getState() != TableState.FINISHED) + tableList.add(new TableView(table)); } return tableList; } + @Override + public List getFinished() { + ArrayList matchList = new ArrayList(); + for (Table table: tables.values()) { + if (table.getState() == TableState.FINISHED) + matchList.add(new MatchView(table.getMatch())); + } + return matchList; + } + @Override public boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException { if (tables.containsKey(tableId)) { diff --git a/Mage/src/mage/game/match/Match.java b/Mage/src/mage/game/match/Match.java index 64ae80b3439..f8777118176 100644 --- a/Mage/src/mage/game/match/Match.java +++ b/Mage/src/mage/game/match/Match.java @@ -44,6 +44,7 @@ import mage.players.Player; public interface Match { public UUID getId(); + public String getName(); public boolean isMatchOver(); public List getPlayers(); public MatchPlayer getPlayer(UUID playerId); @@ -59,6 +60,7 @@ public interface Match { public int getNumGames(); public boolean isDoneSideboarding(); public UUID getChooser(); + public MatchOptions getOptions(); public void addTableEventListener(Listener listener); public void fireSideboardEvent(UUID playerId, Deck deck); diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java index f0f63e5c77a..e591aaeeda3 100644 --- a/Mage/src/mage/game/match/MatchImpl.java +++ b/Mage/src/mage/game/match/MatchImpl.java @@ -51,6 +51,7 @@ public abstract class MatchImpl implements Match { private static final int SIDEBOARD_TIME = 180; protected UUID id = UUID.randomUUID(); + protected String name; protected List players = new ArrayList(); protected List games = new ArrayList(); protected MatchOptions options; @@ -91,6 +92,16 @@ public abstract class MatchImpl implements Match { return id; } + @Override + public String getName() { + return options.getName(); + } + + @Override + public MatchOptions getOptions() { + return options; + } + @Override public boolean isMatchOver() { for (MatchPlayer player: players) {