From ffc7b5bfd8140cc509ddc0c41dede736e03ac882 Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Sun, 6 Feb 2011 11:09:25 -0500 Subject: [PATCH] added tournaments - drafts are now a variant of tournament --- .../src/main/java/mage/client/MageFrame.java | 16 + .../java/mage/client/cards/DraftGrid.java | 36 +- .../main/java/mage/client/chat/ChatPanel.form | 2 +- .../mage/client/dialog/ConnectDialog.java | 7 - .../client/dialog/NewTournamentDialog.form | 210 ++++++++++ .../client/dialog/NewTournamentDialog.java | 359 ++++++++++++++++++ .../client/dialog/TableWaitingDialog.form | 4 +- .../client/dialog/TableWaitingDialog.java | 9 +- .../main/java/mage/client/remote/Client.java | 24 +- .../main/java/mage/client/remote/Session.java | 63 ++- .../mage/client/table/NewPlayerPanel.java | 19 +- .../java/mage/client/table/TablesPanel.form | 12 +- .../java/mage/client/table/TablesPanel.java | 39 +- .../client/table/TournamentPlayerPanel.form | 105 +++++ .../client/table/TournamentPlayerPanel.java | 168 ++++++++ .../client/tournament/TournamentPane.form | 35 ++ .../client/tournament/TournamentPane.java | 87 +++++ .../client/tournament/TournamentPanel.form | 76 ++++ .../client/tournament/TournamentPanel.java | 300 +++++++++++++++ Mage.Common/src/mage/interfaces/Server.java | 14 +- .../src/mage/interfaces/ServerState.java | 9 +- .../interfaces/callback/ClientCallback.java | 4 + Mage.Common/src/mage/view/RoundView.java | 18 +- .../src/mage/view/TournamentGameView.java | 89 +++++ .../src/mage/view/TournamentPlayerView.java | 25 ++ .../src/mage/view/TournamentTypeView.java | 79 ++++ Mage.Common/src/mage/view/TournamentView.java | 16 + .../src/mage/game/FreeForAllMatch.java | 2 +- .../src/mage/game/TwoPlayerMatch.java | 2 +- .../Mage.Tournament.BoosterDraft/pom.xml | 51 +++ .../BoosterDraftEliminationTournament.java | 90 +++++ ...BoosterDraftEliminationTournamentType.java | 47 +++ .../target/maven-archiver/pom.properties | 5 + Mage.Server.Plugins/pom.xml | 2 +- Mage.Server/config/config.xml | 6 +- Mage.Server/plugins/mage-game-freeforall.jar | Bin 5305 -> 5286 bytes .../plugins/mage-game-twoplayerduel.jar | Bin 4879 -> 4835 bytes Mage.Server/plugins/mage-player-ai.jar | Bin 39797 -> 39772 bytes Mage.Server/plugins/mage-player-aiminimax.jar | Bin 36437 -> 36412 bytes Mage.Server/plugins/mage-player-human.jar | Bin 11602 -> 11577 bytes .../plugins/mage-tournament-booster-draft.jar | Bin 0 -> 5679 bytes .../main/java/mage/server/ChatSession.java | 1 - .../src/main/java/mage/server/Main.java | 20 +- .../java/mage/server/{game => }/Room.java | 2 +- .../java/mage/server/{game => }/RoomImpl.java | 2 +- .../src/main/java/mage/server/ServerImpl.java | 64 +++- .../src/main/java/mage/server/Session.java | 5 +- .../main/java/mage/server/SessionManager.java | 19 +- .../server/{game => }/TableController.java | 85 +++-- .../mage/server/{game => }/TableManager.java | 41 +- .../{game => draft}/DraftController.java | 60 +-- .../server/{game => draft}/DraftManager.java | 6 +- .../server/{game => draft}/DraftSession.java | 9 +- .../java/mage/server/game/GameController.java | 30 +- .../java/mage/server/game/GameManager.java | 4 +- .../main/java/mage/server/game/GamesRoom.java | 7 +- .../java/mage/server/game/GamesRoomImpl.java | 11 +- .../java/mage/server/game/ReplaySession.java | 1 + .../tournament/TournamentController.java | 214 +++++++++++ .../server/tournament/TournamentFactory.java | 91 +++++ .../TournamentManager.java} | 63 ++- .../server/tournament/TournamentSession.java | 106 ++++++ .../java/mage/server/util/ConfigSettings.java | 4 +- .../main/xml-resources/jaxb/Config/Config.xsd | 6 +- Mage.Tests/config/config.xml | 6 +- .../src/mage/game}/draft/BoosterDraft.java | 5 +- Mage/src/mage/game/draft/Draft.java | 2 +- Mage/src/mage/game/draft/DraftImpl.java | 38 +- Mage/src/mage/game/draft/DraftOptions.java | 14 - Mage/src/mage/game/draft/DraftPlayer.java | 15 +- Mage/src/mage/game/events/TableEvent.java | 27 +- .../mage/game/events/TableEventSource.java | 10 + Mage/src/mage/game/match/Match.java | 2 + Mage/src/mage/game/match/MatchImpl.java | 20 +- Mage/src/mage/game/match/MatchType.java | 2 - Mage/src/mage/game/tournament/Round.java | 37 +- Mage/src/mage/game/tournament/Tournament.java | 20 +- .../mage/game/tournament/TournamentImpl.java | 179 ++++++++- .../game/tournament/TournamentOptions.java | 77 ++++ .../game/tournament/TournamentPairing.java | 78 ++++ .../game/tournament/TournamentPlayer.java | 58 ++- .../tournament/TournamentSealedOptions.java | 41 ++ .../TournamentSingleElimination.java | 58 +++ .../mage/game/tournament/TournamentSwiss.java | 45 +++ .../mage/game/tournament/TournamentType.java | 72 ++++ src/mage/game/tournament/TournamentImpl.java | 219 +++++++++++ .../game/tournament/TournamentPlayer.java | 115 ++++++ .../TournamentSingleElimination.java | 58 +++ 88 files changed, 3768 insertions(+), 311 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form create mode 100644 Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java create mode 100644 Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form create mode 100644 Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java create mode 100644 Mage.Client/src/main/java/mage/client/tournament/TournamentPane.form create mode 100644 Mage.Client/src/main/java/mage/client/tournament/TournamentPane.java create mode 100644 Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form create mode 100644 Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java create mode 100644 Mage.Common/src/mage/view/TournamentGameView.java create mode 100644 Mage.Common/src/mage/view/TournamentTypeView.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournamentType.java create mode 100644 Mage.Server.Plugins/Mage.Tournament.BoosterDraft/target/maven-archiver/pom.properties create mode 100644 Mage.Server/plugins/mage-tournament-booster-draft.jar rename Mage.Server/src/main/java/mage/server/{game => }/Room.java (98%) rename Mage.Server/src/main/java/mage/server/{game => }/RoomImpl.java (98%) rename Mage.Server/src/main/java/mage/server/{game => }/TableController.java (82%) rename Mage.Server/src/main/java/mage/server/{game => }/TableManager.java (81%) rename Mage.Server/src/main/java/mage/server/{game => draft}/DraftController.java (88%) rename Mage.Server/src/main/java/mage/server/{game => draft}/DraftManager.java (96%) rename Mage.Server/src/main/java/mage/server/{game => draft}/DraftSession.java (94%) create mode 100644 Mage.Server/src/main/java/mage/server/tournament/TournamentController.java create mode 100644 Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java rename Mage.Server/src/main/java/mage/server/{game/DraftFactory.java => tournament/TournamentManager.java} (55%) create mode 100644 Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java rename {Mage.Server.Plugins/Mage.Draft.8PlayerBooster/src/mage => Mage/src/mage/game}/draft/BoosterDraft.java (95%) create mode 100644 Mage/src/mage/game/tournament/TournamentOptions.java create mode 100644 Mage/src/mage/game/tournament/TournamentPairing.java create mode 100644 Mage/src/mage/game/tournament/TournamentSealedOptions.java create mode 100644 Mage/src/mage/game/tournament/TournamentSingleElimination.java create mode 100644 Mage/src/mage/game/tournament/TournamentSwiss.java create mode 100644 Mage/src/mage/game/tournament/TournamentType.java create mode 100644 src/mage/game/tournament/TournamentImpl.java create mode 100644 src/mage/game/tournament/TournamentPlayer.java create mode 100644 src/mage/game/tournament/TournamentSingleElimination.java diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 65eb2130f8..5f763a2463 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -75,6 +75,7 @@ import java.util.prefs.Preferences; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import mage.client.draft.DraftPane; +import mage.client.tournament.TournamentPane; /** * @author BetaSteward_at_googlemail.com @@ -155,6 +156,14 @@ public class MageFrame extends javax.swing.JFrame { e1.printStackTrace(); } + tournamentPane = new TournamentPane(); + desktopPane.add(tournamentPane, javax.swing.JLayeredPane.DEFAULT_LAYER); + try { + tournamentPane.setMaximum(true); + } catch (java.beans.PropertyVetoException e1) { + e1.printStackTrace(); + } + addTooltipContainer(); setBackground(); addMageLabel(); @@ -407,6 +416,12 @@ public class MageFrame extends javax.swing.JFrame { this.draftPane.showDraft(draftId); } + public void showTournament(UUID tournamentId) { + this.tournamentPane.setVisible(true); + this.tournamentPane.toFront(); + this.tournamentPane.showTournament(tournamentId); + } + public static boolean connect(String userName, String serverName, int port) { return session.connect(userName, serverName, port); } @@ -746,6 +761,7 @@ public class MageFrame extends javax.swing.JFrame { private static final long serialVersionUID = -9104885239063142218L; private ImagePanel backgroundPane; private DraftPane draftPane; + private TournamentPane tournamentPane; public void setStatusText(String status) { this.lblStatus.setText(status); diff --git a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java index 89d889cd21..c6273795dc 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java @@ -1,6 +1,29 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * 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. */ /* @@ -14,11 +37,9 @@ package mage.client.cards; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import java.util.UUID; import mage.cards.CardDimensions; import mage.cards.MageCard; -import mage.client.MageFrame; import mage.client.plugins.impl.Plugins; import mage.client.util.Config; import mage.view.CardView; @@ -97,13 +118,6 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener { @Override public void mouseClicked(MouseEvent e) { - /*if (e.getClickCount() == 2 && !e.isConsumed()) { - e.consume(); - Object obj = e.getSource(); - if (obj instanceof MageCard) { - this.cardEventSource.doubleClick(((MageCard)obj).getOriginal().getId(), "double-click"); - } - }*/ } @Override diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanel.form b/Mage.Client/src/main/java/mage/client/chat/ChatPanel.form index 83bebbdb94..210d34b1e4 100644 --- a/Mage.Client/src/main/java/mage/client/chat/ChatPanel.form +++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanel.form @@ -1,4 +1,4 @@ - +
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index f6fb105820..33b438bd3a 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -35,13 +35,9 @@ package mage.client.dialog; import java.awt.Cursor; -import java.rmi.NotBoundException; -import java.rmi.RemoteException; -import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import mage.client.MageFrame; -import mage.client.remote.Session; import mage.client.util.Config; import mage.util.Logging; @@ -212,9 +208,6 @@ public class ConnectDialog extends MageDialog { MageFrame.getPreferences().put("autoConnect", Boolean.toString(chkAutoConnect.isSelected())); this.setVisible(false); } - else { - JOptionPane.showMessageDialog(rootPane, "Unable to connect to server"); - } } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form new file mode 100644 index 0000000000..3c78b2e9f4 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java new file mode 100644 index 0000000000..b6b2547960 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -0,0 +1,359 @@ +/* + * 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. + */ + +/* + * NewTournamentDialog.java + * + * Created on Jan 28, 2011, 12:15:56 PM + */ + +package mage.client.dialog; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JOptionPane; +import javax.swing.SpinnerNumberModel; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; +import mage.cards.ExpansionSet; +import mage.client.MageFrame; +import mage.client.remote.Session; +import mage.client.table.TournamentPlayerPanel; +import mage.game.draft.DraftOptions; +import mage.game.tournament.TournamentOptions; +import mage.sets.Sets; +import mage.util.Logging; +import mage.view.TableView; +import mage.view.TournamentTypeView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class NewTournamentDialog extends MageDialog { + + private final static Logger logger = Logging.getLogger(NewTournamentDialog.class.getName()); + + private TableView table; + private UUID playerId; + private UUID roomId; + private Session session; + private List players = new ArrayList(); + private List packs = new ArrayList(); + + /** Creates new form NewTournamentDialog */ + public NewTournamentDialog() { + initComponents(); + } + + public void showDialog(UUID roomId) { + this.roomId = roomId; + session = MageFrame.getSession(); + this.txtPlayer1Name.setText(session.getUserName()); + cbTournamentType.setModel(new DefaultComboBoxModel(session.getTournamentTypes().toArray())); + this.setModal(true); + setTournamentOptions(); + this.setLocation(150, 100); + this.setVisible(true); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + cbTournamentType = new javax.swing.JComboBox(); + spnNumPlayers = new javax.swing.JSpinner(); + jLabel2 = new javax.swing.JLabel(); + btnOk = new javax.swing.JButton(); + btnCancel = new javax.swing.JButton(); + pnlPacks = new javax.swing.JPanel(); + jPanel1 = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + txtPlayer1Name = new javax.swing.JTextField(); + pnlOtherPlayers = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + + setTitle("New Tournament"); + + jLabel1.setText("Tournament Type:"); + + cbTournamentType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + cbTournamentType.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbTournamentTypeActionPerformed(evt); + } + }); + + spnNumPlayers.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spnNumPlayersStateChanged(evt); + } + }); + + jLabel2.setText("Players:"); + + btnOk.setText("OK"); + btnOk.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnOkActionPerformed(evt); + } + }); + + btnCancel.setText("Cancel"); + btnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCancelActionPerformed(evt); + } + }); + + pnlPacks.setLayout(new java.awt.GridLayout(0, 1, 2, 0)); + + jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel3.setText("Player 1 (You)"); + + jLabel4.setText("Name:"); + + txtPlayer1Name.setEditable(false); + + pnlOtherPlayers.setLayout(new java.awt.GridLayout(0, 1, 2, 0)); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 445, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() + .addComponent(jLabel4) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPlayer1Name, javax.swing.GroupLayout.DEFAULT_SIZE, 490, Short.MAX_VALUE))) + .addContainerGap()) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4) + .addComponent(txtPlayer1Name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 58, Short.MAX_VALUE)) + ); + + jLabel5.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel5.setText("Packs"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(btnOk) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCancel)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbTournamentType, 0, 408, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel5)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(3, 3, 3) + .addComponent(jLabel5) + .addGap(1, 1, 1) + .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addGap(19, 19, 19) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnCancel) + .addComponent(btnOk)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void cbTournamentTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTournamentTypeActionPerformed + setTournamentOptions(); + }//GEN-LAST:event_cbTournamentTypeActionPerformed + + private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed + TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); + TournamentOptions tOptions = new TournamentOptions(tournamentType.getName()); + tOptions.setTournamentType(tournamentType.getName()); + tOptions.getPlayerTypes().add("Human"); + for (TournamentPlayerPanel player: players) { + tOptions.getPlayerTypes().add(player.getPlayerType()); + } + if (tournamentType.isDraft()) { + tOptions.getDraftOptions().setDraftType(""); + tOptions.getDraftOptions().setTiming(DraftOptions.TimingOption.REGULAR); + for (JComboBox pack: packs) { + tOptions.getDraftOptions().getSets().add((ExpansionSet) pack.getSelectedItem()); + } + } + tOptions.getMatchOptions().setDeckType("Limited"); + tOptions.getMatchOptions().setWinsNeeded(2); + tOptions.getMatchOptions().setAttackOption(MultiplayerAttackOption.LEFT); + tOptions.getMatchOptions().setRange(RangeOfInfluence.ALL); + table = session.createTournamentTable(roomId, tOptions); + if (session.joinTournamentTable(roomId, table.getTableId(), this.txtPlayer1Name.getText())) { + for (TournamentPlayerPanel player: players) { + if (!player.getPlayerType().equals("Human")) { + if (!player.joinTournamentTable(roomId, table.getTableId())) { + JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error joining tournament.", "Error", JOptionPane.ERROR_MESSAGE); + session.removeTable(roomId, table.getTableId()); + table = null; + return; + } + } + } + this.setVisible(false); + return; + } + JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error joining tournament.", "Error", JOptionPane.ERROR_MESSAGE); + session.removeTable(roomId, table.getTableId()); + table = null; + }//GEN-LAST:event_btnOkActionPerformed + + private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed + this.table = null; + this.playerId = null; + this.setVisible(false); + }//GEN-LAST:event_btnCancelActionPerformed + + private void spnNumPlayersStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumPlayersStateChanged + int numPlayers = (Integer)this.spnNumPlayers.getValue() - 1; + createPlayers(numPlayers); + }//GEN-LAST:event_spnNumPlayersStateChanged + + private void setTournamentOptions() { + TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); + this.spnNumPlayers.setModel(new SpinnerNumberModel(tournamentType.getMinPlayers(), tournamentType.getMinPlayers(), tournamentType.getMaxPlayers(), 1)); + this.spnNumPlayers.setEnabled(tournamentType.getMinPlayers() != tournamentType.getMaxPlayers()); + createPlayers(tournamentType.getMinPlayers() - 1); + createPacks(tournamentType.getNumBoosters()); + } + + private void createPacks(int numPacks) { + while (packs.size() < numPacks) { + JComboBox pack = new JComboBox(); + pack.setModel(new DefaultComboBoxModel(Sets.getInstance().values().toArray())); + pnlPacks.add(pack); + packs.add(pack); + } + this.pack(); + this.revalidate(); + this.repaint(); + } + + private void createPlayers(int numPlayers) { + if (numPlayers > players.size()) { + while (players.size() != numPlayers) { + TournamentPlayerPanel playerPanel = new TournamentPlayerPanel(); + playerPanel.init(players.size() + 2); + players.add(playerPanel); + } + } + else if (numPlayers < players.size()) { + while (players.size() != numPlayers) { + players.remove(players.size() - 1); + } + } + drawPlayers(); + } + + private void drawPlayers() { + this.pnlOtherPlayers.removeAll(); + for (TournamentPlayerPanel panel: players) { + this.pnlOtherPlayers.add(panel); + } + this.pack(); + this.revalidate(); + this.repaint(); + } + + public TableView getTable() { + return table; + } + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCancel; + private javax.swing.JButton btnOk; + private javax.swing.JComboBox cbTournamentType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel pnlOtherPlayers; + private javax.swing.JPanel pnlPacks; + private javax.swing.JSpinner spnNumPlayers; + private javax.swing.JTextField txtPlayer1Name; + // End of variables declaration//GEN-END:variables + +} diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form index b2b9e434c8..93a0e2c261 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form @@ -1,4 +1,4 @@ - +
@@ -39,7 +39,7 @@ - + diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index 81d98777cd..b6702db277 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -60,6 +60,7 @@ public class TableWaitingDialog extends MageDialog implements Observer { private UUID tableId; private UUID roomId; + private boolean isTournament; private Session session; private TableWaitModel tableWaitModel; private SeatsWatchdog seatsWatchdog = new SeatsWatchdog(); @@ -105,9 +106,10 @@ public class TableWaitingDialog extends MageDialog implements Observer { } } - public void showDialog(UUID roomId, UUID tableId) { + public void showDialog(UUID roomId, UUID tableId, boolean isTournament) { this.roomId = roomId; this.tableId = tableId; + this.isTournament = isTournament; session = MageFrame.getSession(); if (session.isTableOwner(roomId, tableId)) { this.btnStart.setVisible(true); @@ -235,7 +237,10 @@ public class TableWaitingDialog extends MageDialog implements Observer { private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartActionPerformed closeDialog(); - session.startGame(roomId, tableId); + if (!isTournament) + session.startGame(roomId, tableId); + else + session.startTournament(roomId, tableId); }//GEN-LAST:event_btnStartActionPerformed private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed diff --git a/Mage.Client/src/main/java/mage/client/remote/Client.java b/Mage.Client/src/main/java/mage/client/remote/Client.java index 53270116c1..e6f01c3b05 100644 --- a/Mage.Client/src/main/java/mage/client/remote/Client.java +++ b/Mage.Client/src/main/java/mage/client/remote/Client.java @@ -86,6 +86,10 @@ public class Client implements CallbackClient { GameManager.getInstance().setCurrentPlayerUUID(message.getPlayerId()); gameStarted(message.getGameId(), message.getPlayerId()); } + else if(callback.getMethod().equals("startTournament")) { + TableClientMessage message = (TableClientMessage) callback.getData(); + tournamentStarted(message.getGameId(), message.getPlayerId()); + } else if(callback.getMethod().equals("startDraft")) { TableClientMessage message = (TableClientMessage) callback.getData(); draftStarted(message.getGameId(), message.getPlayerId()); @@ -171,6 +175,9 @@ public class Client implements CallbackClient { TableClientMessage message = (TableClientMessage) callback.getData(); construct(message.getDeck(), message.getTableId()); } + else if (callback.getMethod().equals("draftOver")) { + session.getDraft().hideDraft(); + } else if (callback.getMethod().equals("draftPick")) { DraftClientMessage message = (DraftClientMessage) callback.getData(); session.getDraft().loadBooster(message.getDraftPickView()); @@ -189,6 +196,9 @@ public class Client implements CallbackClient { else if (callback.getMethod().equals("draftInit")) { session.ack("draftInit"); } + else if (callback.getMethod().equals("tournamentInit")) { + session.ack("tournamentInit"); + } messageId = callback.getMessageId(); } catch (Exception ex) { @@ -202,7 +212,7 @@ public class Client implements CallbackClient { return clientId; } - protected void gameStarted(UUID gameId, UUID playerId) { + protected void gameStarted(final UUID gameId, final UUID playerId) { try { frame.showGame(gameId, playerId); logger.info("Game " + gameId + " started for player " + playerId); @@ -210,7 +220,7 @@ public class Client implements CallbackClient { catch (Exception ex) { handleException(ex); } - + if (Plugins.getInstance().isCounterPluginLoaded()) { Plugins.getInstance().addGamesPlayed(); } @@ -226,6 +236,16 @@ public class Client implements CallbackClient { } } + protected void tournamentStarted(UUID tournamentId, UUID playerId) { + try { + frame.showTournament(tournamentId); + logger.info("Tournament " + tournamentId + " started for player " + playerId); + } + catch (Exception ex) { + handleException(ex); + } + } + protected void watchGame(UUID gameId) { try { frame.watchGame(gameId); diff --git a/Mage.Client/src/main/java/mage/client/remote/Session.java b/Mage.Client/src/main/java/mage/client/remote/Session.java index 641a16dbfb..d8cecf86be 100644 --- a/Mage.Client/src/main/java/mage/client/remote/Session.java +++ b/Mage.Client/src/main/java/mage/client/remote/Session.java @@ -46,17 +46,20 @@ import mage.client.chat.ChatPanel; import mage.client.components.MageUI; import mage.client.draft.DraftPanel; import mage.client.game.GamePanel; +import mage.client.tournament.TournamentPanel; import mage.client.util.Config; import mage.game.GameException; -import mage.game.draft.DraftOptions; import mage.interfaces.MageException; import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; import mage.interfaces.Server; import mage.interfaces.ServerState; import mage.interfaces.callback.CallbackClientDaemon; import mage.util.Logging; import mage.view.GameTypeView; import mage.view.TableView; +import mage.view.TournamentTypeView; +import mage.view.TournamentView; /** * @@ -75,6 +78,7 @@ public class Session { private Map chats = new HashMap(); private GamePanel game; private DraftPanel draft; + private TournamentPanel tournament; private CallbackClientDaemon callbackDaemon; private MageUI ui = new MageUI(); @@ -101,6 +105,7 @@ public class Session { return true; } catch (MageException ex) { logger.log(Level.SEVERE, null, ex); + JOptionPane.showMessageDialog(frame, "Unable to connect to server. " + ex.getMessage()); } catch (RemoteException ex) { logger.log(Level.SEVERE, "Unable to connect to server - ", ex); } catch (NotBoundException ex) { @@ -156,6 +161,10 @@ public class Session { return serverState.getDeckTypes(); } + public List getTournamentTypes() { + return serverState.getTournamentTypes(); + } + public boolean isTestMode() { return serverState.isTestMode(); } @@ -180,6 +189,10 @@ public class Session { draft = draftPanel; } + public void setTournament(TournamentPanel tournament) { + this.tournament = tournament; + } + public UUID getMainRoomId() { try { return server.getMainRoomId(); @@ -272,9 +285,9 @@ public class Session { return false; } - public boolean joinDraftTable(UUID roomId, UUID tableId, String playerName) { + public boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName) { try { - return server.joinDraftTable(sessionId, roomId, tableId, playerName); + return server.joinTournamentTable(sessionId, roomId, tableId, playerName); } catch (RemoteException ex) { handleRemoteException(ex); } catch (MageException ex) { @@ -297,6 +310,29 @@ public class Session { } } + public TournamentView getTournament(UUID tournamentId) throws MageRemoteException { + try { + return server.getTournament(tournamentId); + } catch (RemoteException ex) { + handleRemoteException(ex); + throw new MageRemoteException(); + } catch (MageException ex) { + handleMageException(ex); + throw new MageRemoteException(); + } + } + + public UUID getTournamentChatId(UUID tournamentId) { + try { + return server.getTournamentChatId(tournamentId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + public boolean sendPlayerUUID(UUID gameId, UUID data) { try { server.sendPlayerUUID(gameId, sessionId, data); @@ -419,6 +455,18 @@ public class Session { return false; } + public boolean joinTournament(UUID tournamentId) { + try { + server.joinTournament(tournamentId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + public boolean watchGame(UUID gameId) { try { server.watchGame(gameId, sessionId); @@ -454,9 +502,9 @@ public class Session { return null; } - public TableView createDraftTable(UUID roomId, DraftOptions draftOptions) { + public TableView createTournamentTable(UUID roomId, TournamentOptions tournamentOptions) { try { - return server.createDraftTable(sessionId, roomId, draftOptions); + return server.createTournamentTable(sessionId, roomId, tournamentOptions); } catch (RemoteException ex) { handleRemoteException(ex); } catch (MageException ex) { @@ -524,9 +572,9 @@ public class Session { return false; } - public boolean startDraft(UUID roomId, UUID tableId) { + public boolean startTournament(UUID roomId, UUID tableId) { try { - server.startDraft(sessionId, roomId, tableId); + server.startTournament(sessionId, roomId, tableId); return true; } catch (RemoteException ex) { handleRemoteException(ex); @@ -650,4 +698,5 @@ public class Session { public MageUI getUI() { return ui; } + } \ No newline at end of file diff --git a/Mage.Client/src/main/java/mage/client/table/NewPlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/NewPlayerPanel.java index fd144064f1..17cb50293e 100644 --- a/Mage.Client/src/main/java/mage/client/table/NewPlayerPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/NewPlayerPanel.java @@ -34,30 +34,15 @@ package mage.client.table; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; -import java.util.LinkedHashSet; -import java.util.Set; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JDialog; import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; import javax.swing.filechooser.FileFilter; -import mage.cards.Card; -import mage.cards.ExpansionSet; import mage.client.MageFrame; import mage.client.deck.generator.DeckGenerator; import mage.client.util.Config; -import mage.client.util.gui.ColorsChooser; -import mage.sets.Sets; /** * @@ -119,8 +104,8 @@ public class NewPlayerPanel extends javax.swing.JPanel { * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - // //GEN-END:initComponents + // + // private void initComponents() { lblPlayerName = new javax.swing.JLabel(); 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 d3ab6971f6..f87a3125cc 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form @@ -40,10 +40,10 @@ - + - + @@ -54,7 +54,7 @@ - + @@ -78,12 +78,12 @@ - + - + - + 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 f8b2e21b25..fbd99831b3 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -58,6 +58,9 @@ import java.awt.event.ActionListener; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; +import mage.client.dialog.NewTournamentDialog; +import mage.game.draft.DraftOptions; +import mage.game.tournament.TournamentOptions; /** @@ -73,6 +76,7 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { private TablesWatchdog tablesWatchdog = new TablesWatchdog(); private JoinTableDialog joinTableDialog; private NewTableDialog newTableDialog; + private NewTournamentDialog newTournamentDialog; private TableWaitingDialog tableWaitingDialog; private Session session; @@ -99,7 +103,7 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { joinTableDialog.showDialog(roomId, tableId); if (joinTableDialog.isJoined()) - tableWaitingDialog.showDialog(roomId, tableId); + tableWaitingDialog.showDialog(roomId, tableId, false); } else if (state.equals("Watch")) { logger.info("Watching table " + tableId); if (!session.watchTable(roomId, tableId)) @@ -152,6 +156,10 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { newTableDialog = new NewTableDialog(); MageFrame.getDesktop().add(newTableDialog); } + if (newTournamentDialog == null) { + newTournamentDialog = new NewTournamentDialog(); + MageFrame.getDesktop().add(newTournamentDialog); + } if (joinTableDialog == null) { joinTableDialog = new JoinTableDialog(); MageFrame.getDesktop().add(joinTableDialog); @@ -201,7 +209,7 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { jPanel1 = new javax.swing.JPanel(); btnNewTable = new javax.swing.JButton(); btnQuickStart = new javax.swing.JButton(); - btnNewDraft = new javax.swing.JButton(); + btnNewTournament = new javax.swing.JButton(); jSplitPane1 = new javax.swing.JSplitPane(); chatPanel = new mage.client.chat.ChatPanel(); jScrollPane1 = new javax.swing.JScrollPane(); @@ -221,14 +229,12 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { } }); - btnNewDraft.setText("New Draft"); - btnNewDraft.addActionListener(new java.awt.event.ActionListener() { + btnNewTournament.setText("New Tournament"); + btnNewTournament.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - btnNewDraftActionPerformed(evt); + btnNewTournamentActionPerformed(evt); } }); - //FIXME: removed on released 0.6 version - btnNewDraft.setVisible(false); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -238,10 +244,10 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { .addContainerGap() .addComponent(btnNewTable) .addGap(6, 6, 6) - .addComponent(btnNewDraft) + .addComponent(btnNewTournament) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnQuickStart) - .addContainerGap(450, Short.MAX_VALUE)) + .addContainerGap(416, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -250,7 +256,7 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnNewTable) .addComponent(btnQuickStart) - .addComponent(btnNewDraft)) + .addComponent(btnNewTournament)) .addContainerGap(16, Short.MAX_VALUE)) ); @@ -284,7 +290,7 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed newTableDialog.showDialog(roomId); if (newTableDialog.getTable() != null) { - tableWaitingDialog.showDialog(roomId, newTableDialog.getTable().getTableId()); + tableWaitingDialog.showDialog(roomId, newTableDialog.getTable().getTableId(), false); } }//GEN-LAST:event_btnNewTableActionPerformed @@ -318,9 +324,12 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { } }//GEN-LAST:event_btnQuickStartActionPerformed - private void btnNewDraftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewDraftActionPerformed - - }//GEN-LAST:event_btnNewDraftActionPerformed + private void btnNewTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTournamentActionPerformed + newTournamentDialog.showDialog(roomId); + if (newTournamentDialog.getTable() != null) { + tableWaitingDialog.showDialog(roomId, newTournamentDialog.getTable().getTableId(), true); + } + }//GEN-LAST:event_btnNewTournamentActionPerformed private void handleError(Exception ex) { logger.log(Level.SEVERE, "Error loading deck", ex); @@ -329,8 +338,8 @@ public class TablesPanel extends javax.swing.JPanel implements Observer { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton btnNewDraft; private javax.swing.JButton btnNewTable; + private javax.swing.JButton btnNewTournament; private javax.swing.JButton btnQuickStart; private mage.client.chat.ChatPanel chatPanel; private javax.swing.JPanel jPanel1; diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form new file mode 100644 index 0000000000..4baefc8e21 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java new file mode 100644 index 0000000000..4f0493711b --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java @@ -0,0 +1,168 @@ +/* + * 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. + */ + +/* + * TournamentPlayerPanel.java + * + * Created on Jan 28, 2011, 1:50:29 PM + */ + +package mage.client.table; + +import java.util.UUID; +import javax.swing.DefaultComboBoxModel; +import mage.client.MageFrame; +import mage.client.remote.Session; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentPlayerPanel extends javax.swing.JPanel { + + private Session session; + + /** Creates new form TournamentPlayerPanel */ + public TournamentPlayerPanel() { + initComponents(); + this.pnlPlayerName.setVisible(false); + } + + public void init(int playerNum) { + session = MageFrame.getSession(); + cbPlayerType.setModel(new DefaultComboBoxModel(session.getPlayerTypes())); + this.lblPlayerNum.setText("Player " + playerNum); + } + + public String getPlayerType() { + return (String) this.cbPlayerType.getSelectedItem(); + } + + public boolean joinTournamentTable(UUID roomId, UUID tableId) { + if (!this.cbPlayerType.getSelectedItem().equals("Human")) { + return session.joinTournamentTable(roomId, tableId, this.txtPlayerName.getText()); + } + return true; + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + cbPlayerType = new javax.swing.JComboBox(); + lblPlayerNum = new javax.swing.JLabel(); + pnlPlayerName = new javax.swing.JPanel(); + txtPlayerName = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + + jLabel1.setLabelFor(cbPlayerType); + jLabel1.setText("Type:"); + + cbPlayerType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + cbPlayerType.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cbPlayerTypeActionPerformed(evt); + } + }); + + lblPlayerNum.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + lblPlayerNum.setText("Player Num:"); + + jLabel2.setText("Name:"); + + javax.swing.GroupLayout pnlPlayerNameLayout = new javax.swing.GroupLayout(pnlPlayerName); + pnlPlayerName.setLayout(pnlPlayerNameLayout); + pnlPlayerNameLayout.setHorizontalGroup( + pnlPlayerNameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlPlayerNameLayout.createSequentialGroup() + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) + ); + pnlPlayerNameLayout.setVerticalGroup( + pnlPlayerNameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlPlayerNameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(lblPlayerNum) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbPlayerType, javax.swing.GroupLayout.PREFERRED_SIZE, 175, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(lblPlayerNum) + .addComponent(jLabel1) + .addComponent(cbPlayerType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(pnlPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + }// //GEN-END:initComponents + + private void cbPlayerTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbPlayerTypeActionPerformed + if (!this.cbPlayerType.getSelectedItem().equals("Human")) { + this.pnlPlayerName.setVisible(true); + if (this.txtPlayerName.getText().length() == 0) { + this.txtPlayerName.setText("Computer " + this.lblPlayerNum.getText()); + } + } + else { + this.pnlPlayerName.setVisible(false); + } + this.revalidate(); + this.repaint(); + }//GEN-LAST:event_cbPlayerTypeActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox cbPlayerType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel lblPlayerNum; + private javax.swing.JPanel pnlPlayerName; + private javax.swing.JTextField txtPlayerName; + // End of variables declaration//GEN-END:variables + +} diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.form b/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.form new file mode 100644 index 0000000000..52e530488c --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.form @@ -0,0 +1,35 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.java new file mode 100644 index 0000000000..b4d0d26467 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPane.java @@ -0,0 +1,87 @@ +/* + * 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. + */ + +/* + * TournamentPane.java + * + * Created on 22-Jan-2011, 11:41:47 PM + */ + +package mage.client.tournament; + +import java.util.UUID; +import mage.client.MagePane; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentPane extends MagePane { + + /** Creates new form TournamentPane */ + public TournamentPane() { + initComponents(); + } + + public void showTournament(UUID tournamentId) { + this.setTitle("Tournament " + tournamentId); + this.tournamentPanel1.showTournament(tournamentId); + this.repaint(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + tournamentPanel1 = new mage.client.tournament.TournamentPanel(); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tournamentPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 758, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tournamentPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 522, Short.MAX_VALUE) + ); + + pack(); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private mage.client.tournament.TournamentPanel tournamentPanel1; + // End of variables declaration//GEN-END:variables + +} diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form new file mode 100644 index 0000000000..6b8c260a15 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.form @@ -0,0 +1,76 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java new file mode 100644 index 0000000000..13f3b203ac --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java @@ -0,0 +1,300 @@ +/* + * 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. + */ + +/* + * TournamentPanel.java + * + * Created on 20-Jan-2011, 9:18:30 PM + */ + +package mage.client.tournament; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; +import javax.swing.Timer; +import javax.swing.table.AbstractTableModel; +import mage.client.MageFrame; +import mage.client.remote.MageRemoteException; +import mage.client.remote.Session; +import mage.view.RoundView; +import mage.view.TournamentGameView; +import mage.view.TournamentPlayerView; +import mage.view.TournamentView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentPanel extends javax.swing.JPanel implements Observer { + + private UUID tournamentId; + private Session session; + private TournamentPlayersTableModel playersModel; + private TournamentMatchesTableModel matchesModel; + private TournamentWatchdog tournamentWatchdog = new TournamentWatchdog(); + + /** Creates new form TournamentPanel */ + public TournamentPanel() { + playersModel = new TournamentPlayersTableModel(); + matchesModel = new TournamentMatchesTableModel(); + + initComponents(); + + tablePlayers.createDefaultColumnsFromModel(); + tableMatches.createDefaultColumnsFromModel(); + + } + + public synchronized void showTournament(UUID tournamentId) { + this.tournamentId = tournamentId; + session = MageFrame.getSession(); + session.setTournament(this); + UUID chatRoomId = session.getTournamentChatId(tournamentId); + if (session.joinTournament(tournamentId) && chatRoomId != null) { + this.chatPanel1.connect(chatRoomId); + tournamentWatchdog.addObserver(this); + this.setVisible(true); + this.repaint(); + } + else { + hideTournament(); + } + } + + public void hideTournament() { + this.setVisible(false); + } + + @Override + public void update(Observable arg0, Object arg1) { + TournamentView tournament; + try { + tournament = MageFrame.getSession().getTournament(tournamentId); + playersModel.loadData(tournament); + matchesModel.loadData(tournament); + this.tablePlayers.repaint(); + this.tableMatches.repaint(); + } catch (MageRemoteException ex) { + hideTournament(); + } + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + chatPanel1 = new mage.client.chat.ChatPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + tablePlayers = new javax.swing.JTable(); + jScrollPane2 = new javax.swing.JScrollPane(); + tableMatches = new javax.swing.JTable(); + + tablePlayers.setModel(this.playersModel); + jScrollPane1.setViewportView(tablePlayers); + + tableMatches.setModel(matchesModel); + jScrollPane2.setViewportView(tableMatches); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 573, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 573, Short.MAX_VALUE)) + .addGap(0, 0, 0) + .addComponent(chatPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)) + .addComponent(chatPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 522, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private mage.client.chat.ChatPanel chatPanel1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JTable tableMatches; + private javax.swing.JTable tablePlayers; + // End of variables declaration//GEN-END:variables + +} + +class TournamentPlayersTableModel extends AbstractTableModel { + private String[] columnNames = new String[]{"Player Name", "Points", "Results"}; + private TournamentPlayerView[] players = new TournamentPlayerView[0]; + + public void loadData(TournamentView tournament) { + players = tournament.getPlayers().toArray(new TournamentPlayerView[0]); + this.fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return players.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return players[arg0].getName(); + case 1: + return Integer.toString(players[arg0].getPoints()); + case 2: + return players[arg0].getResults(); + } + 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) { + return false; + } + +} + +class TournamentMatchesTableModel extends AbstractTableModel { + private String[] columnNames = new String[]{"Round Number", "Players", "Match Id", "Game Id", "State", "Result"}; + private TournamentGameView[] games = new TournamentGameView[0]; + + public void loadData(TournamentView tournament) { + List views = new ArrayList(); + for (RoundView round: tournament.getRounds()) { + for (TournamentGameView game: round.getGames()) { + views.add(game); + } + } + games = views.toArray(new TournamentGameView[0]); + this.fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return games.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return Integer.toString(games[arg0].getRoundNum()); + case 1: + return games[arg0].getPlayers(); + case 2: + return games[arg0].getMatchId().toString(); + case 3: + return games[arg0].getGameId().toString(); + case 4: + return games[arg0].getState(); + case 5: + return games[arg0].getResult(); + } + 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) { + return false; + } + +} + +class TournamentWatchdog extends Observable implements ActionListener { + + Timer t = new Timer(1000, this); // check every second + + public TournamentWatchdog() { + t.start(); + } + + @Override + public void actionPerformed(ActionEvent arg0) { + setChanged(); + notifyObservers(); + } + +} \ No newline at end of file diff --git a/Mage.Common/src/mage/interfaces/Server.java b/Mage.Common/src/mage/interfaces/Server.java index 6fc8db6612..d08cb7a48f 100644 --- a/Mage.Common/src/mage/interfaces/Server.java +++ b/Mage.Common/src/mage/interfaces/Server.java @@ -35,10 +35,11 @@ import java.util.List; import java.util.UUID; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.draft.DraftOptions; +import mage.game.tournament.TournamentOptions; import mage.interfaces.callback.CallbackServer; import mage.view.TableView; import mage.view.GameView; +import mage.view.TournamentView; /** * @@ -54,9 +55,9 @@ public interface Server extends Remote, CallbackServer { //table methods public TableView createTable(UUID sessionId, UUID roomId, MatchOptions matchOptions) throws RemoteException, MageException; - public TableView createDraftTable(UUID sessionId, UUID roomId, DraftOptions draftOptions) throws RemoteException, MageException; + public TableView createTournamentTable(UUID sessionId, UUID roomId, TournamentOptions tournamentOptions) throws RemoteException, MageException; public boolean joinTable(UUID sessionId, UUID roomId, UUID tableId, String name, DeckCardLists deckList) throws RemoteException, MageException, GameException; - public boolean joinDraftTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws RemoteException, MageException, GameException; + public boolean joinTournamentTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws RemoteException, MageException, GameException; public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws RemoteException, MageException, GameException; public boolean watchTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException; public boolean replayTable(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException; @@ -74,6 +75,7 @@ public interface Server extends Remote, CallbackServer { public UUID getTableChatId(UUID tableId) throws RemoteException, MageException; public UUID getGameChatId(UUID gameId) throws RemoteException, MageException; public UUID getRoomChatId(UUID roomId) throws RemoteException, MageException; + public UUID getTournamentChatId(UUID tournamentId) throws RemoteException, MageException; //room methods public UUID getMainRoomId() throws RemoteException, MageException; @@ -89,8 +91,12 @@ public interface Server extends Remote, CallbackServer { public void sendPlayerInteger(UUID gameId, UUID sessionId, Integer data) throws RemoteException, MageException; public void concedeGame(UUID gameId, UUID sessionId) throws RemoteException, MageException; + //tournament methods + public void startTournament(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException; + public void joinTournament(UUID draftId, UUID sessionId) throws RemoteException, MageException; + public TournamentView getTournament(UUID tournamentId) throws RemoteException, MageException; + //draft methods - public void startDraft(UUID sessionId, UUID roomId, UUID tableId) throws RemoteException, MageException; public void joinDraft(UUID draftId, UUID sessionId) throws RemoteException, MageException; public void sendCardPick(UUID draftId, UUID sessionId, UUID cardId) throws RemoteException, MageException; diff --git a/Mage.Common/src/mage/interfaces/ServerState.java b/Mage.Common/src/mage/interfaces/ServerState.java index 403616c12f..aa338dc36f 100644 --- a/Mage.Common/src/mage/interfaces/ServerState.java +++ b/Mage.Common/src/mage/interfaces/ServerState.java @@ -31,6 +31,7 @@ package mage.interfaces; import java.io.Serializable; import java.util.List; import mage.view.GameTypeView; +import mage.view.TournamentTypeView; /** * @@ -39,12 +40,14 @@ import mage.view.GameTypeView; public class ServerState implements Serializable { private List gameTypes; + private List tournamentTypes; private String[] playerTypes; private String[] deckTypes; private boolean testMode; - public ServerState(List gameTypes, String[] playerTypes, String[] deckTypes, boolean testMode) { + public ServerState(List gameTypes, List tournamentTypes, String[] playerTypes, String[] deckTypes, boolean testMode) { this.gameTypes = gameTypes; + this.tournamentTypes = tournamentTypes; this.playerTypes = playerTypes; this.deckTypes = deckTypes; this.testMode = testMode; @@ -54,6 +57,10 @@ public class ServerState implements Serializable { return gameTypes; } + public List getTournamentTypes() { + return tournamentTypes; + } + public String[] getPlayerTypes() { return playerTypes; } diff --git a/Mage.Common/src/mage/interfaces/callback/ClientCallback.java b/Mage.Common/src/mage/interfaces/callback/ClientCallback.java index 6160b8a52e..f29d13d06d 100644 --- a/Mage.Common/src/mage/interfaces/callback/ClientCallback.java +++ b/Mage.Common/src/mage/interfaces/callback/ClientCallback.java @@ -47,6 +47,10 @@ public class ClientCallback implements Serializable { this.data = data; } + public ClientCallback(String method) { + this(method, null); + } + public void clear() { method = null; data = null; diff --git a/Mage.Common/src/mage/view/RoundView.java b/Mage.Common/src/mage/view/RoundView.java index 8a147a7b3d..d3515b826b 100644 --- a/Mage.Common/src/mage/view/RoundView.java +++ b/Mage.Common/src/mage/view/RoundView.java @@ -29,7 +29,11 @@ package mage.view; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import mage.game.Game; import mage.game.tournament.Round; +import mage.game.tournament.TournamentPairing; /** * @@ -38,8 +42,20 @@ import mage.game.tournament.Round; public class RoundView implements Serializable { private static final long serialVersionUID = 1L; - public RoundView(Round round) { + List games = new ArrayList(); + public RoundView(Round round) { + for (TournamentPairing pair: round.getPairs()) { + if (pair.getMatch() != null) { + for (Game game: pair.getMatch().getGames()) { + games.add(new TournamentGameView(round.getRoundNumber(), pair, game)); + } + } + } + } + + public List getGames() { + return games; } } diff --git a/Mage.Common/src/mage/view/TournamentGameView.java b/Mage.Common/src/mage/view/TournamentGameView.java new file mode 100644 index 0000000000..67639fa5c5 --- /dev/null +++ b/Mage.Common/src/mage/view/TournamentGameView.java @@ -0,0 +1,89 @@ +/* + * 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.UUID; +import mage.game.Game; +import mage.game.tournament.TournamentPairing; + +/** + * + * @author BetaSteward_at_googlemail.com + */ + +public class TournamentGameView implements Serializable { + private static final long serialVersionUID = 1L; + + private int roundNum; + private UUID matchId; + private UUID gameId; + private String state; + private String result; + private String players; + + TournamentGameView(int roundNum, TournamentPairing pair, Game game) { + this.roundNum = roundNum; + this.matchId = pair.getMatch().getId(); + this.gameId = game.getId(); + this.players = pair.getPlayer1().getPlayer().getName() + " " + pair.getPlayer2().getPlayer().getName(); + if (game.isGameOver()) { + this.state = "Finished"; + this.result = game.getWinner(); + } + else { + this.state = "Dueling"; + this.result = ""; + } + } + + public int getRoundNum() { + return roundNum; + } + + public UUID getMatchId() { + return this.matchId; + } + + public UUID getGameId() { + return this.gameId; + } + + public String getState() { + return this.state; + } + + public String getResult() { + return this.result; + } + + public String getPlayers() { + return this.players; + } +} diff --git a/Mage.Common/src/mage/view/TournamentPlayerView.java b/Mage.Common/src/mage/view/TournamentPlayerView.java index 3a7d628a9a..45f7c66e7b 100644 --- a/Mage.Common/src/mage/view/TournamentPlayerView.java +++ b/Mage.Common/src/mage/view/TournamentPlayerView.java @@ -29,6 +29,10 @@ package mage.view; import java.io.Serializable; +import mage.game.tournament.Round; +import mage.game.tournament.Tournament; +import mage.game.tournament.TournamentPairing; +import mage.game.tournament.TournamentPlayer; /** * @@ -37,4 +41,25 @@ import java.io.Serializable; public class TournamentPlayerView implements Serializable { private static final long serialVersionUID = 1L; + private String name; + private String results; + private int points; + + TournamentPlayerView(TournamentPlayer player) { + this.name = player.getPlayer().getName(); + this.points = player.getPoints(); + this.results = player.getResults(); + } + + public String getName() { + return this.name; + } + + public int getPoints() { + return this.points; + } + + public String getResults() { + return results; + } } diff --git a/Mage.Common/src/mage/view/TournamentTypeView.java b/Mage.Common/src/mage/view/TournamentTypeView.java new file mode 100644 index 0000000000..79b8c98b5c --- /dev/null +++ b/Mage.Common/src/mage/view/TournamentTypeView.java @@ -0,0 +1,79 @@ +/* + * 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 mage.game.tournament.TournamentType; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentTypeView implements Serializable { + private static final long serialVersionUID = 1L; + + private String name; + private int minPlayers; + private int maxPlayers; + private int numBoosters; + private boolean draft; + + public TournamentTypeView(TournamentType tournamentType) { + this.name = tournamentType.getName(); + this.minPlayers = tournamentType.getMinPlayers(); + this.maxPlayers = tournamentType.getMaxPlayers(); + this.numBoosters = tournamentType.getNumBoosters(); + this.draft = tournamentType.isDraft(); + } + + @Override + public String toString() { + return name; + } + + public String getName() { + return name; + } + + public int getMinPlayers() { + return minPlayers; + } + + public int getMaxPlayers() { + return maxPlayers; + } + + public int getNumBoosters() { + return numBoosters; + } + + public boolean isDraft() { + return draft; + } +} diff --git a/Mage.Common/src/mage/view/TournamentView.java b/Mage.Common/src/mage/view/TournamentView.java index 5adf653498..04fa4e3674 100644 --- a/Mage.Common/src/mage/view/TournamentView.java +++ b/Mage.Common/src/mage/view/TournamentView.java @@ -31,7 +31,9 @@ package mage.view; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import mage.game.tournament.Round; import mage.game.tournament.Tournament; +import mage.game.tournament.TournamentPlayer; /** * @@ -41,8 +43,22 @@ public class TournamentView implements Serializable { private static final long serialVersionUID = 1L; List rounds = new ArrayList(); + List players = new ArrayList(); public TournamentView(Tournament tournament) { + for (TournamentPlayer player: tournament.getPlayers()) { + players.add(new TournamentPlayerView(player)); + } + for (Round round: tournament.getRounds()) { + rounds.add(new RoundView(round)); + } + } + public List getPlayers() { + return players; + } + + public List getRounds() { + return rounds; } } diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java index 613fcf6af7..19b16957e1 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAllMatch.java @@ -35,7 +35,7 @@ import mage.game.match.MatchOptions; * * @author BetaSteward_at_googlemail.com */ -public class FreeForAllMatch extends MatchImpl { +public class FreeForAllMatch extends MatchImpl { public FreeForAllMatch(MatchOptions options) { super(options); diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java index c3f7723146..5c9643e69e 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java @@ -35,7 +35,7 @@ import mage.game.match.MatchOptions; * * @author BetaSteward_at_googlemail.com */ -public class TwoPlayerMatch extends MatchImpl { +public class TwoPlayerMatch extends MatchImpl { public TwoPlayerMatch(MatchOptions options) { super(options); diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml new file mode 100644 index 0000000000..c4d8eb0085 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + + org.mage + Mage-Server-Plugins + 0.6 + + + Mage-Tournament-BoosterDraft + jar + Mage Tournament Booster Draft + + + + ${project.groupId} + Mage + ${project.version} + + + + + src + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + maven-resources-plugin + + UTF-8 + + + + + + mage-tournament-booster-draft + + + + + diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java new file mode 100644 index 0000000000..b9df7a19b7 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournament.java @@ -0,0 +1,90 @@ +/* + * 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.tournament; + +import mage.game.draft.BoosterDraft; +import mage.game.draft.Draft; +import mage.game.events.TableEvent.EventType; +import mage.game.tournament.TournamentOptions; +import mage.game.tournament.TournamentPlayer; +import mage.game.tournament.TournamentSingleElimination; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class BoosterDraftEliminationTournament extends TournamentSingleElimination { + + protected enum TournamentStep { + START, DRAFT, CONSTRUCT, COMPETE, WINNERS + } + + protected TournamentStep currentStep; + + public BoosterDraftEliminationTournament(TournamentOptions options) { + super(options); + currentStep = TournamentStep.START; + } + + protected void draft() { + Draft draft = new BoosterDraft(options.getDraftOptions()); + for (TournamentPlayer player: players.values()) { + draft.addPlayer(player.getPlayer()); + } + tableEventSource.fireTableEvent(EventType.START_DRAFT, null, draft); + } + + protected void winners() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void nextStep() { + switch (currentStep) { + case START: + currentStep = TournamentStep.DRAFT; + draft(); + break; + case DRAFT: + currentStep = TournamentStep.CONSTRUCT; + construct(); + break; + case CONSTRUCT: + currentStep = TournamentStep.COMPETE; + runTournament(); + break; + case COMPETE: + currentStep = TournamentStep.WINNERS; + winners(); + break; + } + } + + +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournamentType.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournamentType.java new file mode 100644 index 0000000000..aa67a6c261 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/BoosterDraftEliminationTournamentType.java @@ -0,0 +1,47 @@ +/* + * 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.tournament; + +import mage.game.tournament.TournamentType; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class BoosterDraftEliminationTournamentType extends TournamentType { + + public BoosterDraftEliminationTournamentType() { + this.name = "Elimination Booster Draft"; + this.maxPlayers = 16; + this.minPlayers = 4; + this.numBoosters = 3; + this.draft = true; + } + +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/target/maven-archiver/pom.properties b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/target/maven-archiver/pom.properties new file mode 100644 index 0000000000..de0c2725e7 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Sun Feb 06 08:07:38 EST 2011 +version=0.6 +groupId=org.mage +artifactId=Mage-Tournament-BoosterDraft diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml index a22f05a460..c52d2a0b06 100644 --- a/Mage.Server.Plugins/pom.xml +++ b/Mage.Server.Plugins/pom.xml @@ -22,7 +22,7 @@ Mage.Player.AI Mage.Player.AIMinimax Mage.Player.Human - Mage.Draft.8PlayerBooster + Mage.Tournament.BoosterDraft \ No newline at end of file diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 6afc3b6d8a..f6c0206984 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -12,9 +12,9 @@ - - - + + + diff --git a/Mage.Server/plugins/mage-game-freeforall.jar b/Mage.Server/plugins/mage-game-freeforall.jar index e3673d7d31bdba940ab2fe7723eff5432c89785a..3d3417fd44dced97646e95b2658547f275e10b7d 100644 GIT binary patch delta 1114 zcmdm~xlEHUz?+$civa{|SK8Q3Gr*n@a6Uf zp47tKxn;}U>Zf%!uIRKsAfLKtv-c8(^?waEf1g) z&KC^VJ{J3wwR5db;FE zc3yjSU5Qm(fNq}Ak=Ju`4;o}y&a1eZozMAS_kPjI$=j^V%FTDa*Z6%wa{6w+0|pn5 z-~P~=QSxWj>$W?gY-@!-8vD#$f8IdE8h_ueg)+~hvv)#v!1Jd>Zx^2K_3pO`h}&OeErCKslrnOChV*`@bi z=}+B+gAw0t9$t@?V`LlXzf((aP&nmcG0B#`CzTuKI+K zQzr`feZ}wJOWP6F;S_txcy@I4p=nnivGZp06i?TloA|5gmgk=emQMlk8>^BMvZOL) z6|-C4NWAR~`pNJnyQBZos`h(IY=KT)_lyEX)+xzus#m#kMTq^Ya8lRm)(Q#J|H2!; zFU^;@;cjz_jeo)hucx&cDe9;18;Ts>t-R4hl}S{|$gq+1*F>Ffo#*7c(lX9JvhsX( zqU&;9^M}p}sgsOE{dvA`=s6YD_b>W%#fE9WxnU`l1DsOXy{_yR1*X4;%nS^2z|@%^nhBgrCs*=nLKw?1uu+K1P+S_0{cVC$= z_x7iZVbaP+9slrZev2|)b)ooI?Yr#xH&)BqdN$5EEFHh|Nz5X-!sWLNCwklD%ob4( z@MdHZVTR{5M!U(bg2v$7Hn~R74&vT@g8C4~M?n(^LsQ6w4>i9{t`@R~suq%Btii<22W09`HWm>^3Q2zvQKoPKu*6gmIW{Fhkcj}f!^l1CZF8q@z8rk{KJ``jGM&GrBO{ozeu43%Y`aj9Unyw$SOJI8vW z(n?hd+|{G~EI%=8ELgE{$-*-eqKaz6^^ASQ*RYkhy!_B+ARSYGYxlEVQRY#Xa(^W* z-Enln8nf3;i6@F`KQ6m_L+qgSzPA%oZ)DxNbNf-_>Mzd8LGN}c9@z>tRB4Re0=8Z$Mbg@8nvIiW=l+9SuFKVa>n7NMpv7l zi~YPd2ZNc<2VC5c^1$+i)uwc_w=>?mJmpDtx4XLXKX1Yei}ia;R`yL;9aQu?IOoy^ zr;OLR{=0Ph>qQ-xPd*s&xmGa5R<5mSlXq*)-|6Ja_T`L_gVGz*Cp49J__jnai;gJZQ^OKkBi%;^Xxo5^_)Se<6DY(v z{~5ok9=Kw1$;#uF(M!%rD}#PAyor7yzbLeSO}*=vMJ*<8jS5B9C0RImu3V|gW99!O zID&6dV8}mlA$hO+7dQ8(=v47f*yQ!JHe<>6sr3u&8^61!9G=1<^`FP5Ct1$&&U=Nk z@{`g$`W{*Zrg?f#+S4f46|Nz?L-M5OsgMdzr>e%EQ+4Df)a;n_mmQXBIl!rw-D|T1 zw>J|wg-%ZA)r2sn@ESqV>?z*qOq`%JEBI*{Px0g|0grk|u4V%P)(f=?T;mF_fB=5aeevXRB#=aK=;BcejgIEw0$SsXa_5^WTRV=iZz@VI4PdJJXiHcc&L!l@IV{ zWD;S9Wi+Nawv&wnjlo%Ma;Bgi#KEft^&yOVf+i4#n2-y4X3G$=hpHBmVw9SEOh`8t z(h7$a6jsU~||Jl3@48E=*j=G+HZu+^2WvO}ksE$F^EPI-e*o0}YtW&Zr8aH|sODvw|5r+5DLJfFgFwEWU?HHj`Uf7?{9d;N;{ES+l_2Vd-eS*Fo_JNNS3s!APU=0IWj z1MNohZmQnW+WxmN?cCen=Vn@3+t=6rW_%!KR?73ZtL>)Ziy4;-MKe{`z3fPcQ@`C* z6eE93$w+FGR1wcd(c{HWq@1m?O)H&e@ZJ+io9ta(fBsI;rd!kePJi~^DchE@GgO>s z@wCUC&+n%BmTap$t9p9I)lEBhAGYqh)ZY`h^Z5^+VA~zH<)idt{&|)#y%1`?#`RD# z&3}2i#3$AFC(@s!OPpYPYQm&iDs%Ahx&lql`cD_d6kFPCUapV2+owCvYSn>{|BAYP z|FJbsc);ZRiN&Ly`SFe=3lko&P26;`+?j$>57JSDLF}v#MZ=5OSY|ilpMX* zu7B?5IBdl~X3xar;WFzb>hlemG$Ik26`h z@i#V2sa~DfocOV3sqvY)fz}hhyDRX1RbH*nwCvf$CmfmCOWZShpL4e-%xC_u;c2_! znSiq#=Plosz#SbM8C2J`O*2?gKmWk;4N@I!fivHC>^WI~@BrhYheFmacTS1(EtqH* z@uO=YN8Eo^>BTM!JRH=PZFI>$S;U|DtfQpqnu=Pdk!#eHYnq?@*)@!(tSnI4(HSaY z9`vPT?W1pQugp=Br5!kBLkWH$?duxisO#zHHu(&h= z;sm8vm7cH0rIQcvdDma$YBCUExbXepzlTld`*IVeJeaM@>NLT=;Ph>Y7i!lte|&%Y zan7Q}4n3W274jDz`#E+!IwmJ4abVuTSyAz?Ua?%i&JZT8eAI8xFA1r&T2o(Id zrt%$q>SqJW4sx*CX~AcY_`4}o-UVtT56dSY&>KEhfKP;oH1KtP&_ zlX0>gqx|GG0z6=c>;?)=W&;XIPW~t$rT{V>k+T^XyK!5>IDv4G8wNeC!ncl$=$saz%o1~FC!204bwi2|aN1q8V#D{!*ZUvUummlnCrd*y~E zrfv?U6ZfVlX~l^N#^~Q%(jnM%vEEtIYvXOzw^vRl&y?tx^@G7~%10mXlJLj{_RqfD z+4p{q@$$bvU*G0u_`Krfi=!=V+O`)AS3cHScExb5a%;BL&9o_tFLWz;Nu83?;+g4s zz5J=r;gpM61@1HW@;NpiT)MYDd)=zy-1uF-_G_k@NnYCeY+J&M?J@CtI;5hNZaj#V zi)34~?Cf4&xgB2iM$4YAlQ!zv_8_k&W8aq_>ViiugtD!jdBC`5zR&p!!d`MGo^!3#l}hYeGfcUY`iYbuiN6vwD6%-2d z$>ldI-u7MHZn(PfuO!pq8=k?-R+qNKOq_K4z0l;gRHx`(o0sp7KUwR?w)ov|r4^Mn zJglkHyO*XEm@-YiGyP#nd&sP$X)EFi?+Z$WNz@m8e0|IB?){HS4{w{?T>1avKVBt? z)fHiI%wLxrxMFwdru!|SmztAi7CjYs zQ~c)r^5FipswMS{dt~v0H%h23o;J;3#rzw~H^?k`yy8&#l6zD3FL=%H(xpUR zDS4_k`vs5lVfz-Tw_dM5$)+K=<*&0rA!qT7gJ;Dq9TI#ga5Aw+Aa&jrlaqlZfqR@J z4?m6Q3to1}Tkw+d8QtfFv!Bd;`X?VH)!KnF#N=*naH5^OncEnYW+%Vo_GaGUHEpvw zPcV}pDD8ec60o2IsIn4>?Is`OmY$rzBU4{clwXiqRFaum%zMI-tJy$+;Xt)QeZ+^H z4na+hdt6DX0W0KhT+7wU2)cIU(fiqteJ)N`KjvX<^SpY9E>?|B{z6` zRC8@lLP@A+p}>3Z4|BtMPnF1ADxb0YfM4zl53VOW_IwmAz9o~|FFp0L{+)1}&h?#P zn*Rd$ycwB9nBjSPass~zYNnpNklz&SpPT&B64!xF&rM8E)ek_^#v>qY`3okQo|ucQ zf&)}o*gebtw$>k*YoBs6FvtQ`!oZS7rO62bI$$gM1*DnQumN+mu{AKU(QTDoXlOqyDZxB2prR$docD$aUX+G?@>^J@2#g{ho8rJ8LuShZ$C4 zZRJE;5dYLq)cYjGlKm6)M)kWtY#%{GKBJ?gJzQ5OyL2OZxMlC0tGeOpg`%eJ%I->( zto*FvhykQAYI;^NW%TT34D=jfbo?2cXBJr+L`5AU8i>-D1oAz@$7PWmrEg``yXN90y@ykTDCi@YAL^>6M+hmt1h5q%Ur&UY?vqLTfovue5C8_SF zOpaVLX1Q#U@&v{_Lbr3CYWlwJIlz_q%41F53U({s(v{W0hfXpO7x@{$=Bh58tvCV8GP0KzP5%M3Z=O6OjykGw);IRo71GX0vf3cfpH5aRDzsqny-C zklE&>Ae5hwBXocG9>fD0T2LFr>~#^W1{H83m`~9#K_A5gsbDskO`X{%>&<46GH9?LPbfn zR0<+00C`AG3oh3#DYud9T@xWxnv|Ghhjx1zI76AV;KdMT-JJyG!gL5z?Xz8{zOE77 z&vb;eN!puTWU^JD8WptKQOv&W0jr}BoTI|p`v}4gf;O_23DUU;%7fByAuZY##_XrF z@G`IiD%@G%3DY%%J7LW1hUej2nuG&6jq&(74?=AR?PkrP_GWE=??9h(^OhuSf-=#s z48`MjK^IZeJ0&m))QJ~9=e-Ap{d-_MlF4s6JdR*C&r6U7en+I@|2q$|vF)tIPk1f# LjLA|Zz?=L7QUp5K delta 1161 zcmZ9Me@IhN6vyv-+jOY&EuBrBKSt^N?dEhsiL(`gHmRAWW&U82G|Flj6cL&RS^ZIS zp1C=NLYYxflo^Yd+8-5E7C});2!&AuHPJt^tcdQtlgVrFcF#TU^F8O>bKZNiUiQ0} zm6(hIVHhI6;mIPqBtzJMn^iVYY!vZWHLQdRE?$h&G}Lh9+SD-luE zyC$QU8tIm(fKhC{83^bJD3t1LndAqb`Nz#n4ha4KP>FPbLv^(ol7aO(QG;)--C*kc@Z z8Jz*j>{KuX(C#dznh6YSkYOMhmYq>#j1cKku-ac{;YAGp$_FH9oborG4p>v@K zrSZzR0G+NvD!q@To;s+oCcwkGnBWPfw$WOw4s(v#qEd}bj)`feS zohUH2ZLUyuj?;_NV?fpUM1dJ-z+`qtbuewns0E@o$1y%)0yCUhjzSpR?2gP}5r3|| z8ej&$u_i>s+DuaxERr5<$O>l6j`+X@X7nXTK(xP1-34JR%Lo((OZ}>T%mQXSXqXL_ znq1cmwtVvHW@C`VT)m$y&(HuO-UVRF|+d zo8w0BnvFN^&wlJvtfY3($@q>r#}1+Ft1_wwB_(V4@9~zIm)OdzGyibSa&6co|5G+m zmuH^R`1yO@Ged6^ZnsNZOP8qId7TYdymwE5a_0A7k2zw0GQYA1cr!AIFvG*x4jkAJ zVsdi325Nv$p3!a!cJqaHX_I|GRk?}jsrq<~VBmq9C&2L5@!@3o4r#CfwjI)p+>;|a zu&i3OWeGI6!f3muGJGv4x3&L5!7wK@Dyg1H+O=S(eF$UGkHeIz_=| zNOejxJ!Jz6g+Yb#fI^yFV4+$rc78OYCm#Sxzcd0$D@?XC=Fmoywu_G3$@xl#f#IkKiiyg9eJWjL8b!=3pIB-O@~lQzt8SOHQ89EeRG{0~Bh=01KVV;GO)w zn+GiX4=8-48YnC=*|-Oy(!WQVX;%YSh`o`2vUfKZF!+ErPqyulWd8p@V)DKoNXXv@ zYWV-Zb+TixG*SS7)gmVa20ged1sMMS-wjl63re(;8+)ah*jpwu_L=BahovQZwHA10E$~7KL7v# delta 1198 zcmdlphw17ZCf)#VW)?065Lmp=dLpk1@1lLycK@!vyQTF)%@M)^j@MOv=cwN<54md>2#xM!lFzPP?P1FDgy6_`OLzf%WM zlO-6nK=fu;#z#zGh8D|FCSIV3o&B#USq5eXhW<&$Dw`G9g_*(9W?XwUz>IH3n#_D4 zbzFg$jg?8v3OIl%0<3|N6*upuj$(G>B43(P1@j)2&4A$1po(VGz{43>IW z{g?&JINmTDEHyc`8SJphlbVe|5|d9fdou6vnzmV_C7ekRWUuS|lxZcvFewLOo5>5B zr6Ya!IhQlGPO3?Mba2)=5jM}$>2umt4xW+l(4HbQ|Hlc{ z+Rk5}j`c3F>#-}E^KtoA`2cT5CJ|!(_%zX{LW{Kp~CEGdg+XLC)RA=viK;!NA}a&cL7oHL^C{MNFO;p*i^u)STBqa~hK; zZ|IhsJU3Zza#ar(E7*j|j@{BscT#~8Qj>qC@@S)5AexsnRY;hDp;a5*e={eq?=}X9 zfv~OItEDVJ2k8Hc0SQV0 zGltmY$X*@=VE(b)(QqVz9q7&tYzz#ha1%iBsn7ydtjPg#Cn$eSzR)YiRMiF*2jwm) JHjj3YE&vmlb+!Ni diff --git a/Mage.Server/plugins/mage-player-human.jar b/Mage.Server/plugins/mage-player-human.jar index c05a28a6dd952188c8d314544b74852673910e8b..96322403c9b9aea0b3b39d30612a253010f212eb 100644 GIT binary patch delta 663 zcmcZ zjBT4Ml%3=B;`A6$bv{vG1{yG#olzZ38#3yG=*@|Yo=jlITIT8UV1~Q$G_c6z2dY|N zrMzm!VA@&DmDzmD)Xm*$=1d$wy>{_Wgnmyxr4c1jrhO{pgV&j0gG~VjMq7+FY%wwo zFW}`1oNS}%2iDrFX@ctR$>%gp%|K>=eFi01;T!>mw~qUOyxhd}RQ&*NMkWzvco`sY6y-ryf6>o!<78rBFlT09P=%{uU|7;04{TyMF0Q* delta 533 zcmdlPbt#HBz?+$civa`{@3WrBtHQfzpS9h;t8eeu0fi<`w9Bv)SBtq(lz6^XR{UGs zjlzu|lP(`^ve5a>6E22=Q-|~Xs9o)FV28!48yJNf7;Q5$-DYGE`hoXb*kol*Kd@~jnkK0JnY>lg6fE;r zQ(EFW(1*E+>8bhw-i%Bl%$_-nF_mNZyt6p*JfxlBtD%$ubp%@o2onM+%K z@-;0Hh*>}d3np`F8-aOt+R{u`%9CxCHMEh<1^Ubm6v{Bb4`VP0FuZlVJb9hA9N4$# zwI!L~IxPR!z0eQNU*Q&8k-mAld2(pVhVoWee;9aU}cpErM<$Z%JE zEmJiysDZYG;a_H?c-uHLf#Ht?j=0BxxC8j3nZB9XJ)fH1GC7HvRr!k7O@FE}Ppp5BtjZF}_!j(XF3cwAJF+&i2 zkMTC{i4F*^)AGh3OHq+FB;l@wj$D^FNI4S8qhTv%`O^KkS;e77e3b2&z8c5Vm|;Nh7P;o&L%!dl(S3yyH~)%1lqA++2tdtCN} zAufA)nttz(S4!N$9R`P2ntGfYG-Ou3vhvD<@n)QYH+lCs1v#8{A1#%L<%?>%S@(tn zJmEK7IZ}sN83>(omX+#c4#89D{xII@e!ZO*4GqkLzw6n~nas5P^eKeej$%wmbk-99 zy>z4f9W>x#M*^@MzyU#)*z0TM%}6>wt|xRGn7i|kdmVLQIw?4lCYo(-SIG-V8alP; zML1C%`=Ez#4E|y%PDqx(r<+z0YzKLKkA18zGLsT(zZ9od8le1Ca`>JNmX+pFt9-z4 zLB@WJv(IAO!GobEY&>rWH6Hl1_9I7UJfDnjC05IpjI}N;HLvgYvp6M&S+94&6=Iu{ zxgArObcZ~$ctVTb>u2RFE!~|*@{Fy?Ye{Zg6($!>V12b|*+%8UnrElc#@|iZ6Izd% zDP=dmelMCT#^Yhe{E}5hm2D3>A@hC0VTOPAlEfFRlsd61Lki# z99LfFzn$*6ykyoWCe)}bntT10I1AwBQ_&7ZW2QI&;qp{VUnr)TYwJ81TVNs-|767 zeYAM51+sDM>&9_e`?uJ4OhgleqxX+g1cr1s)``q}aNSe9XxL7bqR22M=i`tVb;;97 z41~(>7Olm&=?`y`eA18xNU>7oe>UobOC;4mWKJ~BDeWyOOY|!~s-FrCIy^DWkzf?p zCD?$fh{8l2klQ0$ddm`_(Q=&9*Um~iF@rOtdN$${7257d11RBuErQl;+lmzeZNK_O zMeS#ZpcnE}WQO(Z&vtYkVAry3@K@54v2vh8iK^bl760JDv5iEVC+^lKd!&MT{6ZG9 zIQ6m$?b+VH;b%Z)xSHu#d1bnYrMpVlX1tfKwDmA6pKsJI-`B3Lu_-oNdapHHK`hyQMG#yKjdFV@*%e+-5KpF}*Y zr5?PUdVyQF{CMu3#`JrxYS_ zfW)5QZtZxGSJtP+2F~q^9kiiml*oKG>06)Co^KgYZPBk;j%Qo&L9GvBp4R}+N4+J1 zpmd+}Xi^^n#JM}}^SlUV6RtuuAqf>r7C3Gf)ia{KsX(&OqLzg&qR4|xQUWO@!#Es7;A*zcYH%> z;T<11pj=qBXUe@#|1Fq*W&b0ak?UMI=2KGO;mQ9F`@hn?$b7|w-U9e#g4VKTG)#*F zY>3rPQj3p!ZC*jF(GG#65Q$pV>DII^*Ffdj(we8%_uwCyBnQ15t(cef#w0$!3@!Yk z<@`~>nLd@v)b4cFxbos8ynjCz-mkcKc(`{?g-{{f>(c7kd=e7ux*AEJF6s6aRc#`s zOAS(8t6CE1hPe(}ds|ALJ`MHOI7&|OK&b>?-6AFCwuVFzq*be?^4;!{WH%1>7LYVc zL!Y^47ccTgsdJWbR`w;~7p5^n`mJJQCV*mMuG^aWCbg|G+5K(-WR0pC!q)fn{Io%9 zn96yg$4e28=?}N7S^RV;MjZ&VEy8n)I{Lt>}OKn zPlh;=uw3j?XXWg8_SCcPt){b`#N#vW+Vn1oOT~;5y?U&ut)VwFe)uj)xao?KH~R#@33#(>>s3y~q8+qL{#nM|QG3Iqyz5y$B!(sz_p(5tD9Vf;MneXbG2}fQk z3zgB@uY1^95Rv!N{VXh?n8*9lXG9fn?69ScuYst@o~$Om42{;ADLXH#Hh;RDl{iWB zO3GTdm4X|yRkqp7yoL7*r7b%(>y_nl7U@+ol?$_`u?ANfbS9o7ZZ0qc2sqH+sD}zb z0|ig<6zyUk08pu*0^dg)C0V@*L&+_T>g>@Ta(mHTqWQ%phXmKmI}B!{g9P7)8CFGA zSuiZHDn0=fFZf~xOtb=Xx1T6Vz7FNCYdlcaB+h>ubMvi#W0AF$qZJp+2C{8&>OVh zD8*Jw4qond8571lhY95{bHrm#r9Cx=nQ2_Vt2w*bdwzW(#31dK z%krj-KY%G36%r;f@{ow`LfFdLp`dg0;_OA$__8v)w;2Trrh&8N^K z5U|616-dw+0S8?!%EjJLmb%0|f>0@0TS+aZf115+UKjZipNY42B8BXoQ0k=aWPYau z^>hJXT00f2_K0}RiNq!pRuu&TT>a7xejWT^wH^9Wb)CO!uR0iA8bBuYB#qEyv0_J2 zE*)(OeZs{n!WzPJ+4fO&nE6(b6P<_66rIX)*Hbbq$H!XHLKY0+h#Cp)h4#JxqWCeh zIsg8`+=ks#_0Akr?Q3Gb2g27C^<(j`dY+JkSc(IZ1z%9np_xA}6)1)g`S8ftE@bla zr?mQAy=4Bl!DuT23n`)c5CqQ3QCL(s1b*6?(CVZ%w5zVno6I_?Ff?p%?GO14^Qpd2 z{QnHPG{(?-Vfc7>1GvwQGrtpbO#{3gzXsl1;~t$hRiLtogTq)!oz>K}kFP!mlD<** znW2a}rH-OtYBhbPkgCU9Y_HOzMSI}`en=Y9%Ubh_J)?l);$+}LuO1jYHHq&I6GBlY zC^PrnCgGthq;#O1rKFeR_s}E5?A^z1HmeSIFGq*@F;5DHA125xSI`ZancncrPgCc6 zoN*YPD6^gH(sAXZk=-2t<)}xyseddzv2`PlU4K?<-@^ndPy$!0;n0_Xe20 zz1W}g9va+>{hru)!2BIOzo$Jv8#DiG?B(k${{N&_vj5_xkITx$j=xOBeoUgi4}=tt zxm*MMTz07Q1dfVSC-Cr;ez!|+FAs5~hkLH6joX+cFgPzXnk=wx-pMg>dLNed^!6zE zTK8mvu*luh*3zk~n8d?98{LHYsx-rmNCX0*lH6~W^2%7r1l^`#=KJ37J;tv|t)x|K zUh1w?0J=JbxN*NuE7J!cAks6=4qO>M_za#5m457(df~Rp*ot+71cmMGnW3_}{O(>RhB}+CVZKc

M`I;Z`EVOi)Rq4 z(~(VSgV|d-zO5y!_Xpb~IM~TPZ03W^S5tnk4x|~GVE;D;N z$lX%$lL>h{_f7&7!ZoK`%nQW=cXnPM?m|l$Pey_w73HnnhR+^|mdTiPH|EEcIq@O; zZNXv_kY-uE_N!{uc@UzhYV>s{?ZrjH^cqxOpJ$WakR_w3HQKr#gqAmsxX#qBRJozY z2lWVFR?6yI;t=KC@~jD&3cl8iDVcgwUuQ?Is1XqKOhG)Oj@E?`s;-Y=QrWI3q$`4*y@gFkml1k&9=V<`t|t}4Yf z^~AJqV93;o3p`sZAHLdP)^3QZ*?Gq`VKE~IOuu5p7d!l_&$HB7hw?)=^D zha%5$4?jnaqYBK|b_CpvyZtL@{PS3kDl%W&k;@G3_D`4psLy=!{&j`sn?EL;1}9^G z_x>@|{A<1DcwWCw#gAc<2!99WIQ$(a=6}chdjfQfiNb}$|9Wa)Rr&8Ae;52?5IoA? z06CWbW1ydzaU?)r8!g_KFQZgHaO;~KeS6D4J0A(svGWP)pPYY?r+@C{NT7~;QTmr& z^#5J1zCrw2u)cv{!ms@<#9#7tyq>=fUB^i4xLx#puYO(6?@RKplQ}{<4rGS9#5kJa Pv={d~s(*IS9sT=1VEFk+ literal 0 HcmV?d00001 diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 7e3cde350c..49cfb33f9c 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -34,7 +34,6 @@ import java.util.Calendar; import java.util.GregorianCalendar; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; import java.util.logging.Logger; import mage.interfaces.callback.ClientCallback; import mage.util.Logging; diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java index 46d66cf3ec..d3f8d01712 100644 --- a/Mage.Server/src/main/java/mage/server/Main.java +++ b/Mage.Server/src/main/java/mage/server/Main.java @@ -36,10 +36,11 @@ import java.net.InetAddress; import java.util.logging.Level; import java.util.logging.Logger; import mage.game.match.MatchType; +import mage.game.tournament.TournamentType; import mage.server.game.DeckValidatorFactory; -import mage.server.game.DraftFactory; import mage.server.game.GameFactory; import mage.server.game.PlayerFactory; +import mage.server.tournament.TournamentFactory; import mage.server.util.ConfigSettings; import mage.server.util.config.Plugin; import mage.server.util.config.GamePlugin; @@ -73,8 +74,8 @@ public class Main { for (GamePlugin plugin: config.getGameTypes()) { GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); } - for (Plugin plugin: config.getDraftTypes()) { - DraftFactory.getInstance().addDraftType(plugin.getName(), loadPlugin(plugin)); + for (GamePlugin plugin: config.getTournamentTypes()) { + TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin)); } for (Plugin plugin: config.getPlayerTypes()) { PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin)); @@ -136,6 +137,19 @@ public class Main { return null; } + private static TournamentType loadTournamentType(GamePlugin plugin) { + try { + classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL()); + logger.info("Loading tournament type: " + plugin.getClassName()); + return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance(); + } catch (ClassNotFoundException ex) { + logger.log(Level.SEVERE, "Tournament type not found:" + plugin.getJar() + " - check plugin folder"); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error loading game type " + plugin.getJar(), ex); + } + return null; + } + private static void deleteSavedGames() { File directory = new File("saved/"); if (!directory.exists()) diff --git a/Mage.Server/src/main/java/mage/server/game/Room.java b/Mage.Server/src/main/java/mage/server/Room.java similarity index 98% rename from Mage.Server/src/main/java/mage/server/game/Room.java rename to Mage.Server/src/main/java/mage/server/Room.java index 61b4210872..7c8c662592 100644 --- a/Mage.Server/src/main/java/mage/server/game/Room.java +++ b/Mage.Server/src/main/java/mage/server/Room.java @@ -26,7 +26,7 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server; import java.rmi.Remote; import java.util.UUID; diff --git a/Mage.Server/src/main/java/mage/server/game/RoomImpl.java b/Mage.Server/src/main/java/mage/server/RoomImpl.java similarity index 98% rename from Mage.Server/src/main/java/mage/server/game/RoomImpl.java rename to Mage.Server/src/main/java/mage/server/RoomImpl.java index f1391caa42..182540a353 100644 --- a/Mage.Server/src/main/java/mage/server/game/RoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/RoomImpl.java @@ -26,7 +26,7 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server; import java.util.UUID; import mage.server.ChatManager; diff --git a/Mage.Server/src/main/java/mage/server/ServerImpl.java b/Mage.Server/src/main/java/mage/server/ServerImpl.java index d29e1a2179..ff671bee16 100644 --- a/Mage.Server/src/main/java/mage/server/ServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/ServerImpl.java @@ -41,25 +41,27 @@ import java.util.logging.Level; import java.util.logging.Logger; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.draft.DraftOptions; import mage.interfaces.MageException; import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; import mage.interfaces.Server; import mage.interfaces.ServerState; import mage.interfaces.callback.ClientCallback; import mage.server.game.DeckValidatorFactory; -import mage.server.game.DraftManager; +import mage.server.draft.DraftManager; import mage.server.game.GameFactory; import mage.server.game.GameManager; import mage.server.game.GamesRoomManager; import mage.server.game.PlayerFactory; import mage.server.game.ReplayManager; -import mage.server.game.TableManager; +import mage.server.tournament.TournamentFactory; +import mage.server.tournament.TournamentManager; import mage.server.util.ThreadExecutor; import mage.util.Logging; import mage.view.ChatMessage.MessageColor; import mage.view.GameView; import mage.view.TableView; +import mage.view.TournamentView; /** * @@ -130,10 +132,10 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public TableView createDraftTable(UUID sessionId, UUID roomId, DraftOptions options) throws MageException { + public TableView createTournamentTable(UUID sessionId, UUID roomId, TournamentOptions options) throws MageException { try { - TableView table = GamesRoomManager.getInstance().getRoom(roomId).createDraftTable(sessionId, options); - logger.info("Draft table " + table.getTableId() + " created"); + TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTournamentTable(sessionId, options); + logger.log(Level.INFO, "Tournament table {0} created", table.getTableId()); return table; } catch (Exception ex) { @@ -175,9 +177,9 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public boolean joinDraftTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws MageException, GameException { + public boolean joinTournamentTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws MageException, GameException { try { - boolean ret = GamesRoomManager.getInstance().getRoom(roomId).joinDraftTable(sessionId, tableId, name); + boolean ret = GamesRoomManager.getInstance().getRoom(roomId).joinTournamentTable(sessionId, tableId, name); logger.info("Session " + sessionId + " joined table " + tableId); return ret; } @@ -262,13 +264,13 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public void startDraft(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException { + public void startTournament(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException { try { rmiExecutor.execute( new Runnable() { @Override public void run() { - TableManager.getInstance().startDraft(sessionId, roomId, tableId); + TableManager.getInstance().startTournament(sessionId, roomId, tableId); } } ); @@ -278,6 +280,17 @@ public class ServerImpl extends RemoteServer implements Server { } } + @Override + public TournamentView getTournament(UUID tournamentId) throws RemoteException, MageException { + try { + return TournamentManager.getInstance().getTournamentView(tournamentId); + } + catch (Exception ex) { + handleException(ex); + } + return null; + } + @Override public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException { try { @@ -441,6 +454,23 @@ public class ServerImpl extends RemoteServer implements Server { } } + @Override + public void joinTournament(final UUID tournamentId, final UUID sessionId) throws MageException { + try { + rmiExecutor.execute( + new Runnable() { + @Override + public void run() { + TournamentManager.getInstance().joinTournament(tournamentId, sessionId); + } + } + ); + } + catch (Exception ex) { + handleException(ex); + } + } + @Override public UUID getGameChatId(UUID gameId) throws MageException { try { @@ -452,6 +482,17 @@ public class ServerImpl extends RemoteServer implements Server { return null; } + @Override + public UUID getTournamentChatId(UUID tournamentId) throws MageException { + try { + return TournamentManager.getInstance().getChatId(tournamentId); + } + catch (Exception ex) { + handleException(ex); + } + return null; + } + @Override public void sendPlayerUUID(final UUID gameId, final UUID sessionId, final UUID data) throws MageException { try { @@ -683,6 +724,7 @@ public class ServerImpl extends RemoteServer implements Server { try { return new ServerState( GameFactory.getInstance().getGameTypes(), + TournamentFactory.getInstance().getTournamentTypes(), PlayerFactory.getInstance().getPlayerTypes().toArray(new String[0]), DeckValidatorFactory.getInstance().getDeckTypes().toArray(new String[0]), testMode); @@ -722,7 +764,7 @@ public class ServerImpl extends RemoteServer implements Server { public void handleException(Exception ex) throws MageException { logger.log(Level.SEVERE, "", ex); - throw new MageException("Server error"); + throw new MageException("Server error: " + ex.getMessage()); } public GameView getGameView(final UUID gameId, final UUID sessionId, final UUID playerId) { diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index c020dc3ca5..6e0cc2480c 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -35,7 +35,6 @@ import mage.cards.decks.Deck; import mage.interfaces.callback.CallbackServerSession; import mage.interfaces.callback.ClientCallback; import mage.server.game.GameManager; -import mage.server.game.TableManager; import mage.util.Logging; import mage.view.TableClientMessage; @@ -99,6 +98,10 @@ public class Session { fireCallback(new ClientCallback("startDraft", new TableClientMessage(draftId, playerId))); } + public void tournamentStarted(final UUID tournamentId, final UUID playerId) { + fireCallback(new ClientCallback("startTournament", new TableClientMessage(tournamentId, playerId))); + } + public void sideboard(final Deck deck, final UUID tableId) { fireCallback(new ClientCallback("sideboard", new TableClientMessage(deck, tableId))); } diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java index ee0311fef8..673de9b406 100644 --- a/Mage.Server/src/main/java/mage/server/SessionManager.java +++ b/Mage.Server/src/main/java/mage/server/SessionManager.java @@ -30,6 +30,7 @@ package mage.server; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import mage.interfaces.MageException; /** * @@ -49,15 +50,25 @@ public class SessionManager { return sessions.get(sessionId); } - public UUID createSession(String userName, UUID clientId) { - Session session = new Session(userName, clientId); - sessions.put(session.getId(), session); - return session.getId(); + public UUID createSession(String userName, UUID clientId) throws MageException { + if (!isNameUsed(userName)) { + Session session = new Session(userName, clientId); + sessions.put(session.getId(), session); + return session.getId(); + } + throw new MageException("User name already in use"); } public void removeSession(UUID sessionId) { sessions.remove(sessionId); } + private boolean isNameUsed(String name) { + for (Session session: sessions.values()) { + if (session.getUsername().equals(name)) + return true; + } + return false; + } } diff --git a/Mage.Server/src/main/java/mage/server/game/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java similarity index 82% rename from Mage.Server/src/main/java/mage/server/game/TableController.java rename to Mage.Server/src/main/java/mage/server/TableController.java index 2e2be277ed..446872431d 100644 --- a/Mage.Server/src/main/java/mage/server/game/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -26,8 +26,11 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server; +import mage.server.draft.DraftManager; +import mage.server.tournament.TournamentFactory; +import mage.server.tournament.TournamentManager; import mage.game.Table; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -56,16 +59,24 @@ import mage.game.GameStates; import mage.game.match.Match; import mage.game.Seat; import mage.game.draft.Draft; -import mage.game.draft.DraftOptions; import mage.game.draft.DraftPlayer; import mage.game.events.Listener; import mage.game.events.TableEvent; import mage.game.match.MatchOptions; import mage.game.match.MatchPlayer; +import mage.game.tournament.Tournament; +import mage.game.tournament.TournamentOptions; +import mage.game.tournament.TournamentPlayer; import mage.players.Player; import mage.server.ChatManager; import mage.server.Main; import mage.server.SessionManager; +import mage.server.game.DeckValidatorFactory; +import mage.server.game.GameFactory; +import mage.server.game.GameManager; +import mage.server.game.GameReplay; +import mage.server.game.PlayerFactory; +import mage.server.game.ReplayManager; import mage.util.CopierObjectInputStream; import mage.util.Logging; @@ -82,8 +93,8 @@ public class TableController { private Table table; private Match match; private MatchOptions options; - private Draft draft; - private DraftOptions draftOptions; + private Tournament tournament; + private TournamentOptions tournamentOptions; private ConcurrentHashMap sessionPlayerMap = new ConcurrentHashMap(); public TableController(UUID sessionId, MatchOptions options) { @@ -95,12 +106,12 @@ public class TableController { init(); } - public TableController(UUID sessionId, DraftOptions options) { + public TableController(UUID sessionId, TournamentOptions options) { this.sessionId = sessionId; chatId = ChatManager.getInstance().createChatSession(); - this.draftOptions = options; - draft = DraftFactory.getInstance().createDraft(options.getDraftType(), options); - table = new Table(options.getDraftType(), options.getName(), DeckValidatorFactory.getInstance().createDeckValidator("Limited"), options.getPlayerTypes()); + this.tournamentOptions = options; + tournament = TournamentFactory.getInstance().createTournament(options.getTournamentType(), options); + table = new Table(options.getTournamentType(), options.getName(), DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes()); init(); } @@ -125,7 +136,7 @@ public class TableController { ); } - public synchronized boolean joinDraft(UUID sessionId, String name) throws GameException { + public synchronized boolean joinTournament(UUID sessionId, String name) throws GameException { if (table.getState() != TableState.WAITING) { return false; } @@ -134,7 +145,7 @@ public class TableController { throw new GameException("No available seats."); } Player player = createPlayer(name, seat.getPlayerType()); - draft.addPlayer(player); + tournament.addPlayer(player, seat.getPlayerType()); table.joinTable(player, seat); logger.info("player joined " + player.getId()); //only add human players to sessionPlayerMap @@ -170,6 +181,21 @@ public class TableController { return true; } + public void addPlayer(UUID sessionId, Player player, Deck deck) throws GameException { + if (table.getState() != TableState.WAITING) { + return; + } + Seat seat = table.getNextAvailableSeat(); + if (seat == null) { + throw new GameException("No available seats."); + } + match.addPlayer(player, deck); + table.joinTable(player, seat); + if (player.isHuman()) { + sessionPlayerMap.put(sessionId, player.getId()); + } + } + public synchronized boolean submitDeck(UUID sessionId, DeckCardLists deckList) throws GameException { if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) { return false; @@ -180,7 +206,7 @@ public class TableController { playerName = player.getPlayer().getName(); } else { - DraftPlayer player = draft.getPlayer(sessionPlayerMap.get(sessionId)); + TournamentPlayer player = tournament.getPlayer(sessionPlayerMap.get(sessionId)); playerName = player.getPlayer().getName(); } Deck deck = Deck.load(deckList); @@ -196,9 +222,8 @@ public class TableController { MatchPlayer player = match.getPlayer(playerId); player.submitDeck(deck); } - else if (table.getState() == TableState.CONSTRUCTING) { - DraftPlayer player = draft.getPlayer(playerId); - player.submitDeck(deck); + else { + tournament.submitDeck(playerId, deck); } } @@ -267,17 +292,25 @@ public class TableController { } } - public synchronized void startDraft(UUID sessionId) { + public synchronized void startTournament(UUID sessionId) { if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) { - table.initDraft(); - DraftManager.getInstance().createDraftSession(draft, sessionPlayerMap, table.getId()); + TournamentManager.getInstance().createTournamentSession(tournament, sessionPlayerMap, table.getId()); SessionManager sessionManager = SessionManager.getInstance(); for (Entry entry: sessionPlayerMap.entrySet()) { - sessionManager.getSession(entry.getKey()).draftStarted(draft.getId(), entry.getValue()); + sessionManager.getSession(entry.getKey()).tournamentStarted(tournament.getId(), entry.getValue()); } } } + public void startDraft(Draft draft) { + table.initDraft(); + DraftManager.getInstance().createDraftSession(draft, sessionPlayerMap, table.getId()); + SessionManager sessionManager = SessionManager.getInstance(); + for (Entry entry: sessionPlayerMap.entrySet()) { + sessionManager.getSession(entry.getKey()).draftStarted(draft.getId(), entry.getValue()); + } + } + private void sideboard() { table.sideboard(); for (MatchPlayer player: match.getPlayers()) { @@ -297,13 +330,12 @@ public class TableController { } } - private void construct() { + public void construct() { table.construct(); - for (DraftPlayer player: draft.getPlayers()) { + for (TournamentPlayer player: tournament.getPlayers()) { player.setConstructing(); player.getPlayer().construct(table, player.getDeck()); } - while (!draft.isDoneConstructing()){} } private void construct(UUID playerId, Deck deck) { @@ -332,9 +364,11 @@ public class TableController { } } - public void endDraft() { - construct(); - + public void endDraft(Draft draft) { + for (DraftPlayer player: draft.getPlayers()) { + tournament.getPlayer(player.getPlayer().getId()).setDeck(player.getDeck()); + } + tournament.nextStep(); } public void swapSeats(int seatNum1, int seatNum2) { @@ -405,4 +439,7 @@ public class TableController { return chatId; } + public Match getMatch() { + return match; + } } diff --git a/Mage.Server/src/main/java/mage/server/game/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java similarity index 81% rename from Mage.Server/src/main/java/mage/server/game/TableManager.java rename to Mage.Server/src/main/java/mage/server/TableManager.java index 22e22dec3f..64baa8ea55 100644 --- a/Mage.Server/src/main/java/mage/server/game/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -26,17 +26,22 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server; import mage.game.Table; import java.util.Collection; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.draft.DraftOptions; +import mage.game.draft.Draft; +import mage.game.match.Match; import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; +import mage.players.Player; +import mage.server.game.GameReplay; import mage.util.Logging; /** @@ -62,7 +67,7 @@ public class TableManager { return tableController.getTable(); } - public Table createDraftTable(UUID sessionId, DraftOptions options) { + public Table createTournamentTable(UUID sessionId, TournamentOptions options) { TableController tableController = new TableController(sessionId, options); controllers.put(tableController.getTable().getId(), tableController); tables.put(tableController.getTable().getId(), tableController.getTable()); @@ -73,6 +78,10 @@ public class TableManager { return tables.get(tableId); } + public Match getMatch(UUID tableId) { + return controllers.get(tableId).getMatch(); + } + public Collection getTables() { return tables.values(); } @@ -81,8 +90,8 @@ public class TableManager { return controllers.get(tableId).joinTable(sessionId, name, deckList); } - public boolean joinDraft(UUID sessionId, UUID tableId, String name) throws GameException { - return controllers.get(tableId).joinDraft(sessionId, name); + public boolean joinTournament(UUID sessionId, UUID tableId, String name) throws GameException { + return controllers.get(tableId).joinTournament(sessionId, name); } public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws GameException { @@ -118,8 +127,12 @@ public class TableManager { controllers.get(tableId).startMatch(sessionId); } - public void startDraft(UUID sessionId, UUID roomId, UUID tableId) { - controllers.get(tableId).startDraft(sessionId); + public void startTournament(UUID sessionId, UUID roomId, UUID tableId) { + controllers.get(tableId).startTournament(sessionId); + } + + public void startDraft(UUID tableId, Draft draft) { + controllers.get(tableId).startDraft(draft); } public boolean watchTable(UUID sessionId, UUID tableId) { @@ -129,13 +142,13 @@ public class TableManager { public boolean replayTable(UUID sessionId, UUID tableId) { return controllers.get(tableId).replayTable(sessionId); } - + public void endGame(UUID tableId) { controllers.get(tableId).endGame(); } - public void endDraft(UUID tableId) { - controllers.get(tableId).endDraft(); + public void endDraft(UUID tableId, Draft draft) { + controllers.get(tableId).endDraft(draft); } public GameReplay createReplay(UUID tableId) { @@ -147,4 +160,12 @@ public class TableManager { controllers.get(tableId).swapSeats(seatNum1, seatNum2); } } + + public void construct(UUID tableId) { + controllers.get(tableId).construct(); + } + + public void addPlayer(UUID sessionId, UUID tableId, Player player, Deck deck) throws GameException { + controllers.get(tableId).addPlayer(sessionId, player, deck); + } } diff --git a/Mage.Server/src/main/java/mage/server/game/DraftController.java b/Mage.Server/src/main/java/mage/server/draft/DraftController.java similarity index 88% rename from Mage.Server/src/main/java/mage/server/game/DraftController.java rename to Mage.Server/src/main/java/mage/server/draft/DraftController.java index 0c8a177c2c..59b98789b3 100644 --- a/Mage.Server/src/main/java/mage/server/game/DraftController.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftController.java @@ -26,13 +26,12 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server.draft; import java.io.File; import java.util.UUID; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; import java.util.logging.Logger; import mage.game.draft.Draft; @@ -40,11 +39,11 @@ import mage.game.draft.DraftPlayer; import mage.game.events.Listener; import mage.game.events.PlayerQueryEvent; import mage.game.events.TableEvent; -import mage.server.ChatManager; +import mage.server.game.GameController; +import mage.server.TableManager; import mage.server.util.ThreadExecutor; import mage.util.Logging; import mage.view.DraftPickView; -import mage.view.ChatMessage.MessageColor; import mage.view.DraftView; /** @@ -60,13 +59,11 @@ public class DraftController { private ConcurrentHashMap sessionPlayerMap; private UUID draftSessionId; private Draft draft; - private UUID chatId; private UUID tableId; public DraftController(Draft draft, ConcurrentHashMap sessionPlayerMap, UUID tableId) { draftSessionId = UUID.randomUUID(); this.sessionPlayerMap = sessionPlayerMap; - chatId = ChatManager.getInstance().createChatSession(); this.draft = draft; this.tableId = tableId; init(); @@ -100,6 +97,13 @@ public class DraftController { } } ); + for (DraftPlayer player: draft.getPlayers()) { + if (!player.getPlayer().isHuman()) { + player.setJoined(); + logger.info("player " + player.getPlayer().getId() + " has joined draft " + draft.getId()); + } + } + checkStart(); } private UUID getPlayerId(UUID sessionId) { @@ -111,16 +115,8 @@ public class DraftController { DraftSession draftSession = new DraftSession(draft, sessionId, playerId); draftSessions.put(playerId, draftSession); logger.info("player " + playerId + " has joined draft " + draft.getId()); - ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(playerId).getPlayer().getName() + " has joined the draft", MessageColor.BLACK); - if (allJoined()) { - ThreadExecutor.getInstance().getRMIExecutor().execute( - new Runnable() { - @Override - public void run() { - startDraft(); - } - }); - } + draft.getPlayer(playerId).setJoined(); + checkStart(); } private synchronized void startDraft() { @@ -134,7 +130,21 @@ public class DraftController { draft.start(); } + private void checkStart() { + if (allJoined()) { + ThreadExecutor.getInstance().getRMIExecutor().execute( + new Runnable() { + @Override + public void run() { + startDraft(); + } + }); + } + } + private boolean allJoined() { + if (!draft.allJoined()) + return false; for (DraftPlayer player: draft.getPlayers()) { if (player.getPlayer().isHuman() && draftSessions.get(player.getPlayer().getId()) == null) { return false; @@ -148,7 +158,10 @@ public class DraftController { } private void endDraft() { - TableManager.getInstance().endDraft(tableId); + for (final DraftSession draftSession: draftSessions.values()) { + draftSession.draftOver(); + } + TableManager.getInstance().endDraft(tableId, draft); } public void kill(UUID sessionId) { @@ -162,26 +175,15 @@ public class DraftController { public void timeout(UUID sessionId) { if (sessionPlayerMap.containsKey(sessionId)) { - ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(sessionPlayerMap.get(sessionId)).getPlayer().getName() + " has timed out. Auto picking.", MessageColor.BLACK); +// ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(sessionPlayerMap.get(sessionId)).getPlayer().getName() + " has timed out. Auto picking.", MessageColor.BLACK); draft.autoPick(sessionPlayerMap.get(sessionId)); } } - public void endDraft(final String message) { - for (final DraftSession draftSession: draftSessions.values()) { - draftSession.gameOver(message); - } - TableManager.getInstance().endDraft(tableId); - } - public UUID getSessionId() { return this.draftSessionId; } - public UUID getChatId() { - return chatId; - } - public void sendCardPick(UUID sessionId, UUID cardId) { draftSessions.get(sessionPlayerMap.get(sessionId)).sendCardPick(cardId); } diff --git a/Mage.Server/src/main/java/mage/server/game/DraftManager.java b/Mage.Server/src/main/java/mage/server/draft/DraftManager.java similarity index 96% rename from Mage.Server/src/main/java/mage/server/game/DraftManager.java rename to Mage.Server/src/main/java/mage/server/draft/DraftManager.java index b0b65aab7a..a218b5aca7 100644 --- a/Mage.Server/src/main/java/mage/server/game/DraftManager.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftManager.java @@ -26,7 +26,7 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server.draft; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -61,10 +61,6 @@ public class DraftManager { draftControllers.remove(gameId); } - public UUID getChatId(UUID draftId) { - return draftControllers.get(draftId).getChatId(); - } - public void sendCardPick(UUID draftId, UUID sessionId, UUID cardId) { draftControllers.get(draftId).sendCardPick(sessionId, cardId); } diff --git a/Mage.Server/src/main/java/mage/server/game/DraftSession.java b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java similarity index 94% rename from Mage.Server/src/main/java/mage/server/game/DraftSession.java rename to Mage.Server/src/main/java/mage/server/draft/DraftSession.java index c8f5820ef4..f4d2c4eaf0 100644 --- a/Mage.Server/src/main/java/mage/server/game/DraftSession.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java @@ -26,7 +26,7 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server.draft; import java.rmi.RemoteException; import java.util.UUID; @@ -44,7 +44,6 @@ import mage.util.Logging; import mage.view.DraftClientMessage; import mage.view.DraftPickView; import mage.view.DraftView; -import mage.view.GameClientMessage; /** * @@ -52,7 +51,7 @@ import mage.view.GameClientMessage; */ public class DraftSession { - protected final static Logger logger = Logging.getLogger(GameWatcher.class.getName()); + protected final static Logger logger = Logging.getLogger(DraftSession.class.getName()); protected UUID sessionId; protected UUID playerId; @@ -105,11 +104,11 @@ public class DraftSession { } } - public void gameOver(final String message) { + public void draftOver() { if (!killed) { Session session = SessionManager.getInstance().getSession(sessionId); if (session != null) - session.fireCallback(new ClientCallback("gameOver", message)); + session.fireCallback(new ClientCallback("draftOver")); } } diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 9db2ac8cb6..1b596b3549 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -28,6 +28,7 @@ package mage.server.game; +import mage.server.TableManager; import java.io.File; import java.io.Serializable; import java.util.*; @@ -43,7 +44,6 @@ import java.util.regex.Pattern; import mage.Constants.Zone; import mage.abilities.Ability; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; @@ -153,6 +153,12 @@ public class GameController implements GameCallback { } } ); + for (Player player: game.getPlayers().values()) { + if (!player.isHuman()) { + ChatManager.getInstance().broadcast(chatId, "", player.getName() + " has joined the game", MessageColor.BLACK); + } + } + checkStart(); } private UUID getPlayerId(UUID sessionId) { @@ -165,15 +171,7 @@ public class GameController implements GameCallback { gameSessions.put(playerId, gameSession); logger.info("player " + playerId + " has joined game " + game.getId()); ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getName() + " has joined the game", MessageColor.BLACK); - if (allJoined()) { - ThreadExecutor.getInstance().getRMIExecutor().execute( - new Runnable() { - @Override - public void run() { - startGame(); - } - }); - } + checkStart(); } private synchronized void startGame() { @@ -190,6 +188,18 @@ public class GameController implements GameCallback { } } + private void checkStart() { + if (allJoined()) { + ThreadExecutor.getInstance().getRMIExecutor().execute( + new Runnable() { + @Override + public void run() { + startGame(); + } + }); + } + } + private boolean allJoined() { for (Player player: game.getPlayers().values()) { if (player.isHuman() && gameSessions.get(player.getId()) == null) { diff --git a/Mage.Server/src/main/java/mage/server/game/GameManager.java b/Mage.Server/src/main/java/mage/server/game/GameManager.java index dd44bf5eaf..e162fff23f 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameManager.java +++ b/Mage.Server/src/main/java/mage/server/game/GameManager.java @@ -117,11 +117,11 @@ public class GameManager { return gameControllers.get(gameId).cheat(sessionId, playerId, cardName); } - void timeout(UUID gameId, UUID sessionId) { + public void timeout(UUID gameId, UUID sessionId) { gameControllers.get(gameId).timeout(sessionId); } - void removeGame(UUID gameId) { + public void removeGame(UUID gameId) { gameControllers.remove(gameId); } 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 8d1ce7c5f1..a991fe792a 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java @@ -28,12 +28,13 @@ package mage.server.game; +import mage.server.Room; import java.util.List; import java.util.UUID; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.draft.DraftOptions; import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; import mage.view.TableView; /** @@ -44,9 +45,9 @@ public interface GamesRoom extends Room { public List getTables(); public boolean joinTable(UUID sessionId, UUID tableId, String name, DeckCardLists deckList) throws GameException; - public boolean joinDraftTable(UUID sessionId, UUID tableId, String name) throws GameException; + public boolean joinTournamentTable(UUID sessionId, UUID tableId, String name) throws GameException; public TableView createTable(UUID sessionId, MatchOptions options); - public TableView createDraftTable(UUID sessionId, DraftOptions options); + public TableView createTournamentTable(UUID sessionId, TournamentOptions options); public void removeTable(UUID sessionId, UUID tableId); public TableView getTable(UUID tableId); public void leaveTable(UUID sessionId, UUID tableId); 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 5fdd808bc4..7170db13e6 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java @@ -28,6 +28,8 @@ package mage.server.game; +import mage.server.TableManager; +import mage.server.RoomImpl; import mage.game.Table; import java.io.Serializable; import java.util.ArrayList; @@ -39,6 +41,7 @@ import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.game.draft.DraftOptions; import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; import mage.util.Logging; import mage.view.TableView; @@ -78,17 +81,17 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } @Override - public boolean joinDraftTable(UUID sessionId, UUID tableId, String name) throws GameException { + public boolean joinTournamentTable(UUID sessionId, UUID tableId, String name) throws GameException { if (tables.containsKey(tableId)) { - return TableManager.getInstance().joinDraft(sessionId, tableId, name); + return TableManager.getInstance().joinTournament(sessionId, tableId, name); } else { return false; } } @Override - public TableView createDraftTable(UUID sessionId, DraftOptions options) { - Table table = TableManager.getInstance().createDraftTable(sessionId, options); + public TableView createTournamentTable(UUID sessionId, TournamentOptions options) { + Table table = TableManager.getInstance().createTournamentTable(sessionId, options); tables.put(table.getId(), table); return new TableView(table); } diff --git a/Mage.Server/src/main/java/mage/server/game/ReplaySession.java b/Mage.Server/src/main/java/mage/server/game/ReplaySession.java index 14d295175e..ac050e8af4 100644 --- a/Mage.Server/src/main/java/mage/server/game/ReplaySession.java +++ b/Mage.Server/src/main/java/mage/server/game/ReplaySession.java @@ -28,6 +28,7 @@ package mage.server.game; +import mage.server.TableManager; import java.util.UUID; import java.util.logging.Logger; import mage.game.Game; diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java new file mode 100644 index 0000000000..e5e2d3ca12 --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -0,0 +1,214 @@ +/* +* 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.server.tournament; + +import java.util.Map.Entry; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import mage.game.GameException; +import mage.game.Table; +import mage.game.draft.Draft; +import mage.game.events.Listener; +import mage.game.events.TableEvent; +import mage.game.match.MatchOptions; +import mage.game.tournament.Tournament; +import mage.game.tournament.TournamentPairing; +import mage.game.tournament.TournamentPlayer; +import mage.server.ChatManager; +import mage.server.TableManager; +import mage.server.util.ThreadExecutor; +import mage.util.Logging; +import mage.view.ChatMessage.MessageColor; +import mage.view.TournamentView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentController { + + private final static Logger logger = Logging.getLogger(TournamentController.class.getName()); + + private UUID sessionId; + private UUID chatId; + private UUID tableId; + private Tournament tournament; + private ConcurrentHashMap sessionPlayerMap = new ConcurrentHashMap(); + private ConcurrentHashMap tournamentSessions = new ConcurrentHashMap(); + + public TournamentController(Tournament tournament, ConcurrentHashMap sessionPlayerMap, UUID tableId) { + sessionId = UUID.randomUUID(); + this.sessionPlayerMap = sessionPlayerMap; + chatId = ChatManager.getInstance().createChatSession(); + this.tournament = tournament; + this.tableId = tableId; + init(); + } + + private void init() { + tournament.addTableEventListener( + new Listener () { + @Override + public void event(TableEvent event) { + switch (event.getEventType()) { + case INFO: + ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK); + logger.finest(tournament.getId() + " " + event.getMessage()); + break; + case CONSTRUCT: + construct(); + break; + case START_DRAFT: + startDraft(event.getDraft()); + break; + case START_MATCH: + startMatch(event.getPair(), event.getMatchOptions()); + break; + } + } + } + ); + for (TournamentPlayer player: tournament.getPlayers()) { + if (!player.getPlayer().isHuman()) { + player.setJoined(); + logger.info("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId()); + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK); + } + } + checkStart(); + } + + public void join(UUID sessionId) { + UUID playerId = sessionPlayerMap.get(sessionId); + TournamentSession tournamentSession = new TournamentSession(tournament, sessionId, playerId); + tournamentSessions.put(playerId, tournamentSession); + TournamentPlayer player = tournament.getPlayer(playerId); + player.setJoined(); + logger.info("player " + playerId + " has joined tournament " + tournament.getId()); + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK); + checkStart(); + } + + private void checkStart() { + if (allJoined()) { + ThreadExecutor.getInstance().getRMIExecutor().execute( + new Runnable() { + @Override + public void run() { + startTournament(); + } + }); + } + } + + private boolean allJoined() { + if (!tournament.allJoined()) + return false; + for (TournamentPlayer player: tournament.getPlayers()) { + if (player.getPlayer().isHuman() && tournamentSessions.get(player.getPlayer().getId()) == null) { + return false; + } + } + return true; + } + + private synchronized void startTournament() { + for (final Entry entry: tournamentSessions.entrySet()) { + if (!entry.getValue().init(getTournamentView())) { + logger.severe("Unable to initialize client"); + //TODO: generate client error message + return; + } + } + tournament.nextStep(); + } + + private void startMatch(TournamentPairing pair, MatchOptions matchOptions) { + try { + TableManager tableManager = TableManager.getInstance(); + Table table = tableManager.createTable(sessionId, matchOptions); + TournamentPlayer player1 = pair.getPlayer1(); + TournamentPlayer player2 = pair.getPlayer2(); + tableManager.addPlayer(getPlayerSessionId(player1.getPlayer().getId()), table.getId(), player1.getPlayer(), player1.getDeck()); + tableManager.addPlayer(getPlayerSessionId(player2.getPlayer().getId()), table.getId(), player2.getPlayer(), player2.getDeck()); + tableManager.startMatch(sessionId, null, table.getId()); + pair.setMatch(tableManager.getMatch(table.getId())); + } catch (GameException ex) { + Logger.getLogger(TournamentController.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private void startDraft(Draft draft) { + TableManager.getInstance().startDraft(tableId, draft); + } + + private void construct() { + TableManager.getInstance().construct(tableId); + } + + public UUID getSessionId() { + return this.sessionId; + } + + public UUID getChatId() { + return chatId; + } + + public void kill(UUID sessionId) { + if (sessionPlayerMap.containsKey(sessionId)) { + tournamentSessions.get(sessionPlayerMap.get(sessionId)).setKilled(); + tournamentSessions.remove(sessionPlayerMap.get(sessionId)); + leave(sessionId); + sessionPlayerMap.remove(sessionId); + } + } + + private void leave(UUID sessionId) { + tournament.leave(getPlayerId(sessionId)); + } + + private UUID getPlayerId(UUID sessionId) { + return sessionPlayerMap.get(sessionId); + } + + private UUID getPlayerSessionId(UUID playerId) { + for (Entry entry: sessionPlayerMap.entrySet()) { + if (entry.getValue().equals(playerId)) + return entry.getKey(); + } + return null; + } + + public TournamentView getTournamentView() { + return new TournamentView(tournament); + } + +} diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java new file mode 100644 index 0000000000..f602dc5fb6 --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java @@ -0,0 +1,91 @@ +/* + * 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.server.tournament; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import mage.game.tournament.Tournament; +import mage.game.tournament.TournamentOptions; +import mage.game.tournament.TournamentType; +import mage.util.Logging; +import mage.view.TournamentTypeView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentFactory { + private final static TournamentFactory INSTANCE = new TournamentFactory(); + private final static Logger logger = Logging.getLogger(TournamentFactory.class.getName()); + + private Map> tournaments = new HashMap>(); + private Map tournamentTypes = new HashMap(); + private List tournamentTypeViews = new ArrayList(); + + public static TournamentFactory getInstance() { + return INSTANCE; + } + + private TournamentFactory() {} + + public Tournament createTournament(String tournamentType, TournamentOptions options) { + + Tournament tournament; + Constructor con; + try { + con = tournaments.get(tournamentType).getConstructor(new Class[]{TournamentOptions.class}); + tournament = con.newInstance(new Object[] {options}); + } catch (Exception ex) { + logger.log(Level.SEVERE, null, ex); + return null; + } + logger.info("Tournament created: " + tournamentType); // + game.getId().toString()); + + return tournament; + } + + public List getTournamentTypes() { + return tournamentTypeViews; + } + + + public void addTournamentType(String name, TournamentType tournamentType, Class tournament) { + if (tournament != null) { + this.tournaments.put(name, tournament); + this.tournamentTypes.put(name, tournamentType); + this.tournamentTypeViews.add(new TournamentTypeView(tournamentType)); + } + } + +} \ No newline at end of file diff --git a/Mage.Server/src/main/java/mage/server/game/DraftFactory.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java similarity index 55% rename from Mage.Server/src/main/java/mage/server/game/DraftFactory.java rename to Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java index 8b528c0008..60bd35c705 100644 --- a/Mage.Server/src/main/java/mage/server/game/DraftFactory.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java @@ -1,5 +1,5 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* 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: @@ -26,54 +26,47 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.server.game; +package mage.server.tournament; -import java.lang.reflect.Constructor; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import mage.game.draft.Draft; -import mage.game.draft.DraftOptions; -import mage.util.Logging; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import mage.game.tournament.Tournament; +import mage.view.TournamentView; /** * * @author BetaSteward_at_googlemail.com */ -public class DraftFactory { +public class TournamentManager { - private final static DraftFactory INSTANCE = new DraftFactory(); - private final static Logger logger = Logging.getLogger(DraftFactory.class.getName()); + private final static TournamentManager INSTANCE = new TournamentManager(); - private Map> drafts = new HashMap>(); + private ConcurrentHashMap controllers = new ConcurrentHashMap(); - public static DraftFactory getInstance() { + public static TournamentManager getInstance() { return INSTANCE; } - private DraftFactory() {} - - public Draft createDraft(String draftType, DraftOptions options) { - - Draft draft; - Constructor con; - try { - con = drafts.get(draftType).getConstructor(new Class[]{DraftOptions.class}); - draft = con.newInstance(new Object[] {options}); - } catch (Exception ex) { - logger.log(Level.SEVERE, null, ex); - return null; - } - logger.info("Draft created: " + draftType); // + game.getId().toString()); - - return draft; + public UUID createTournamentSession(Tournament tournament, ConcurrentHashMap sessionPlayerMap, UUID tableId) { + TournamentController tournamentController = new TournamentController(tournament, sessionPlayerMap, tableId); + controllers.put(tournament.getId(), tournamentController); + return tournamentController.getSessionId(); } - public void addDraftType(String name, Class draft) { - if (draft != null) { - this.drafts.put(name, draft); - } + public void joinTournament(UUID tournamentId, UUID sessionId) { + controllers.get(tournamentId).join(sessionId); + } + + public void kill(UUID tournamentId, UUID sessionId) { + controllers.get(tournamentId).kill(sessionId); + } + + public TournamentView getTournamentView(UUID tournamentId) { + return controllers.get(tournamentId).getTournamentView(); + } + + public UUID getChatId(UUID tournamentId) { + return controllers.get(tournamentId).getChatId(); } } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java new file mode 100644 index 0000000000..bfd4f7ac22 --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -0,0 +1,106 @@ +/* +* 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.server.tournament; + +import java.rmi.RemoteException; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import mage.game.tournament.Tournament; +import mage.interfaces.callback.ClientCallback; +import mage.server.Session; +import mage.server.SessionManager; +import mage.util.Logging; +import mage.view.TournamentView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentSession { + protected final static Logger logger = Logging.getLogger(TournamentSession.class.getName()); + + protected UUID sessionId; + protected UUID playerId; + protected Tournament tournament; + protected boolean killed = false; + + public TournamentSession(Tournament tournament, UUID sessionId, UUID playerId) { + this.sessionId = sessionId; + this.tournament = tournament; + this.playerId = playerId; + } + + public boolean init(final TournamentView tournamentView) { + if (!killed) { + Session session = SessionManager.getInstance().getSession(sessionId); + if (session != null) { + session.clearAck(); + session.fireCallback(new ClientCallback("tournamentInit", tournamentView)); + if (waitForAck("tournamentInit")) + return true; + } + } + return false; + } + + public boolean waitForAck(String message) { + Session session = SessionManager.getInstance().getSession(sessionId); + do { + //TODO: add timeout + } while (!session.getAckMessage().equals(message) && !killed); + return true; + } + + public void update(final TournamentView tournamentView) { + if (!killed) { + Session session = SessionManager.getInstance().getSession(sessionId); + if (session != null) + session.fireCallback(new ClientCallback("tournamentUpdate", tournamentView)); + } + } + + public void gameOver(final String message) { + if (!killed) { + Session session = SessionManager.getInstance().getSession(sessionId); + if (session != null) + session.fireCallback(new ClientCallback("tournamentOver", message)); + } + } + + protected void handleRemoteException(RemoteException ex) { + logger.log(Level.SEVERE, null, ex); + TournamentManager.getInstance().kill(tournament.getId(), sessionId); + } + + public void setKilled() { + killed = true; + } + +} diff --git a/Mage.Server/src/main/java/mage/server/util/ConfigSettings.java b/Mage.Server/src/main/java/mage/server/util/ConfigSettings.java index 06a0cf19f7..4301f69fd2 100644 --- a/Mage.Server/src/main/java/mage/server/util/ConfigSettings.java +++ b/Mage.Server/src/main/java/mage/server/util/ConfigSettings.java @@ -92,8 +92,8 @@ public class ConfigSettings { return config.getGameTypes().getGameType(); } - public List getDraftTypes() { - return config.getDraftTypes().getDraftType(); + public List getTournamentTypes() { + return config.getTournamentTypes().getTournamentType(); } public List getDeckTypes() { diff --git a/Mage.Server/src/main/xml-resources/jaxb/Config/Config.xsd b/Mage.Server/src/main/xml-resources/jaxb/Config/Config.xsd index c9a949dd56..e83f1f6a45 100644 --- a/Mage.Server/src/main/xml-resources/jaxb/Config/Config.xsd +++ b/Mage.Server/src/main/xml-resources/jaxb/Config/Config.xsd @@ -8,7 +8,7 @@ - + @@ -54,10 +54,10 @@ - + - + diff --git a/Mage.Tests/config/config.xml b/Mage.Tests/config/config.xml index 6afc3b6d8a..62c7d6854f 100644 --- a/Mage.Tests/config/config.xml +++ b/Mage.Tests/config/config.xml @@ -12,9 +12,9 @@ - - - + + + diff --git a/Mage.Server.Plugins/Mage.Draft.8PlayerBooster/src/mage/draft/BoosterDraft.java b/Mage/src/mage/game/draft/BoosterDraft.java similarity index 95% rename from Mage.Server.Plugins/Mage.Draft.8PlayerBooster/src/mage/draft/BoosterDraft.java rename to Mage/src/mage/game/draft/BoosterDraft.java index c55e17621e..6ad74fb8d4 100644 --- a/Mage.Server.Plugins/Mage.Draft.8PlayerBooster/src/mage/draft/BoosterDraft.java +++ b/Mage/src/mage/game/draft/BoosterDraft.java @@ -26,10 +26,7 @@ * or implied, of BetaSteward_at_googlemail.com. */ -package mage.draft; - -import mage.game.draft.DraftImpl; -import mage.game.draft.DraftOptions; +package mage.game.draft; /** * diff --git a/Mage/src/mage/game/draft/Draft.java b/Mage/src/mage/game/draft/Draft.java index fa3bcd44bf..07ec023b24 100644 --- a/Mage/src/mage/game/draft/Draft.java +++ b/Mage/src/mage/game/draft/Draft.java @@ -53,9 +53,9 @@ public interface Draft extends MageItem, Serializable { public int getCardNum(); public void addPick(UUID playerId, UUID cardId); public void start(); + public boolean allJoined(); public void leave(UUID playerId); public void autoPick(UUID playerId); - public boolean isDoneConstructing(); public void addTableEventListener(Listener listener); public void fireUpdatePlayersEvent(); diff --git a/Mage/src/mage/game/draft/DraftImpl.java b/Mage/src/mage/game/draft/DraftImpl.java index b27ec9a9e2..34ec4c434d 100644 --- a/Mage/src/mage/game/draft/DraftImpl.java +++ b/Mage/src/mage/game/draft/DraftImpl.java @@ -33,8 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.game.draft.DraftOptions.TimingOption; @@ -177,12 +175,11 @@ public abstract class DraftImpl> implements Draft { player.setPicking(); player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this); } - while (!donePicking()) { - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - Logger.getLogger(DraftImpl.class.getName()).log(Level.SEVERE, null, ex); - break; + synchronized(this) { + while (!donePicking()) { + try { + this.wait(); + } catch (InterruptedException ex) { } } } return true; @@ -190,7 +187,16 @@ public abstract class DraftImpl> implements Draft { protected boolean donePicking() { for (DraftPlayer player: players.values()) { - if (player.picking) + if (player.isPicking()) + return false; + } + return true; + } + + @Override + public boolean allJoined() { + for (DraftPlayer player: this.players.values()) { + if (!player.isJoined()) return false; } return true; @@ -235,19 +241,9 @@ public abstract class DraftImpl> implements Draft { break; } } - } - - protected void startTournament() { - //TODO: implement this - } - - @Override - public boolean isDoneConstructing() { - for (DraftPlayer player: this.players.values()) { - if (!player.isDoneConstructing()) - return false; + synchronized(this) { + this.notifyAll(); } - return true; } } diff --git a/Mage/src/mage/game/draft/DraftOptions.java b/Mage/src/mage/game/draft/DraftOptions.java index 269e6c35d1..da82bcea58 100644 --- a/Mage/src/mage/game/draft/DraftOptions.java +++ b/Mage/src/mage/game/draft/DraftOptions.java @@ -39,10 +39,8 @@ import mage.cards.ExpansionSet; */ public class DraftOptions implements Serializable { - protected String name; protected String draftType; protected List sets = new ArrayList(); - protected List playerTypes = new ArrayList(); protected TimingOption timing; public enum TimingOption { @@ -61,22 +59,10 @@ public class DraftOptions implements Serializable { } } - public DraftOptions(String name) { - this.name = name; - } - - public String getName() { - return name; - } - public List getSets() { return sets; } - public List getPlayerTypes() { - return playerTypes; - } - public String getDraftType() { return draftType; } diff --git a/Mage/src/mage/game/draft/DraftPlayer.java b/Mage/src/mage/game/draft/DraftPlayer.java index 6d08995270..0e7bbbb9c2 100644 --- a/Mage/src/mage/game/draft/DraftPlayer.java +++ b/Mage/src/mage/game/draft/DraftPlayer.java @@ -46,7 +46,7 @@ public class DraftPlayer { protected Deck deck; protected List booster; protected boolean picking; - protected boolean doneConstructing; + protected boolean joined = false; public DraftPlayer(Player player) { id = UUID.randomUUID(); @@ -92,17 +92,12 @@ public class DraftPlayer { return picking; } - public void setConstructing() { - this.doneConstructing = false; + public boolean isJoined() { + return joined; } - public void submitDeck(Deck deck) { - this.deck = deck; - this.doneConstructing = true; - } - - public boolean isDoneConstructing() { - return this.doneConstructing; + public void setJoined() { + this.joined = true; } } diff --git a/Mage/src/mage/game/events/TableEvent.java b/Mage/src/mage/game/events/TableEvent.java index 6e798b11c2..4d17710e19 100644 --- a/Mage/src/mage/game/events/TableEvent.java +++ b/Mage/src/mage/game/events/TableEvent.java @@ -35,6 +35,8 @@ import mage.cards.Cards; import mage.cards.decks.Deck; import mage.game.Game; import mage.game.draft.Draft; +import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentPairing; /** * @@ -43,8 +45,7 @@ import mage.game.draft.Draft; public class TableEvent extends EventObject implements ExternalEvent, Serializable { public enum EventType { - UPDATE, INFO, REVEAL, LOOK, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END - } + UPDATE, INFO, REVEAL, LOOK, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END} private Game game; private Draft draft; @@ -53,6 +54,13 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab private Cards cards; private UUID playerId; private Deck deck; + private TournamentPairing pair; + private MatchOptions options; + + public TableEvent(EventType eventType) { + super(eventType); + this.eventType = eventType; + } public TableEvent(EventType eventType, String message, Cards cards, Game game) { super(game); @@ -76,6 +84,13 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab this.eventType = eventType; } + public TableEvent(EventType eventType, TournamentPairing pair, MatchOptions options) { + super(options); + this.pair = pair; + this.options = options; + this.eventType = eventType; + } + public Game getGame() { return game; } @@ -103,4 +118,12 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab public Deck getDeck() { return deck; } + + public TournamentPairing getPair() { + return pair; + } + + public MatchOptions getMatchOptions() { + return options; + } } diff --git a/Mage/src/mage/game/events/TableEventSource.java b/Mage/src/mage/game/events/TableEventSource.java index a2a07b721c..acd66a3184 100644 --- a/Mage/src/mage/game/events/TableEventSource.java +++ b/Mage/src/mage/game/events/TableEventSource.java @@ -35,6 +35,8 @@ import mage.cards.decks.Deck; import mage.game.Game; import mage.game.draft.Draft; import mage.game.events.TableEvent.EventType; +import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentPairing; /** * @@ -49,6 +51,10 @@ public class TableEventSource implements EventSource, Serializable { dispatcher.addListener(listener); } + public void fireTableEvent(EventType eventType) { + dispatcher.fireEvent(new TableEvent(eventType)); + } + public void fireTableEvent(EventType eventType, String message, Game game) { dispatcher.fireEvent(new TableEvent(eventType, message, null, game)); } @@ -64,4 +70,8 @@ public class TableEventSource implements EventSource, Serializable { public void fireTableEvent(EventType eventType, UUID playerId, Deck deck) { dispatcher.fireEvent(new TableEvent(eventType, playerId, deck)); } + + public void fireTableEvent(EventType eventType, TournamentPairing pair, MatchOptions options) { + dispatcher.fireEvent(new TableEvent(eventType, pair, options)); + } } diff --git a/Mage/src/mage/game/match/Match.java b/Mage/src/mage/game/match/Match.java index 7364ab5763..032edac9ea 100644 --- a/Mage/src/mage/game/match/Match.java +++ b/Mage/src/mage/game/match/Match.java @@ -50,6 +50,8 @@ public interface Match { public void startGame() throws GameException; public void endGame(); public Game getGame(); + public List getGames(); + public int getWinsNeeded(); public int getNumGames(); public boolean isDoneSideboarding(); public UUID getChooser(); diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java index 3d780f0c39..01c3988e48 100644 --- a/Mage/src/mage/game/match/MatchImpl.java +++ b/Mage/src/mage/game/match/MatchImpl.java @@ -31,20 +31,24 @@ 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; import mage.players.Player; +import mage.util.Logging; /** * * @author BetaSteward_at_googlemail.com */ -public abstract class MatchImpl implements Match { +public abstract class MatchImpl implements Match { + + private final static Logger logger = Logging.getLogger(MatchImpl.class.getName()); protected UUID id = UUID.randomUUID(); protected List players = new ArrayList(); - protected List games = new ArrayList(); + protected List games = new ArrayList(); protected MatchOptions options; public MatchImpl(MatchOptions options) { @@ -92,15 +96,25 @@ public abstract class MatchImpl implements Match { } @Override - public T getGame() { + public Game getGame() { return games.get(games.size() -1); } + @Override + public List getGames() { + return games; + } + @Override public int getNumGames() { return games.size(); } + @Override + public int getWinsNeeded() { + return options.getWinsNeeded(); + } + protected void initGame(Game game) throws GameException { for (MatchPlayer matchPlayer: this.players) { game.loadCards(matchPlayer.getDeck().getCards(), matchPlayer.getPlayer().getId()); diff --git a/Mage/src/mage/game/match/MatchType.java b/Mage/src/mage/game/match/MatchType.java index d3c58fece0..8446965791 100644 --- a/Mage/src/mage/game/match/MatchType.java +++ b/Mage/src/mage/game/match/MatchType.java @@ -29,8 +29,6 @@ package mage.game.match; import java.io.Serializable; -import mage.Constants.MultiplayerAttackOption; -import mage.Constants.RangeOfInfluence; /** * diff --git a/Mage/src/mage/game/tournament/Round.java b/Mage/src/mage/game/tournament/Round.java index d156ea46ef..e75aefdc8a 100644 --- a/Mage/src/mage/game/tournament/Round.java +++ b/Mage/src/mage/game/tournament/Round.java @@ -30,8 +30,7 @@ package mage.game.tournament; import java.util.ArrayList; import java.util.List; -import mage.game.match.Match; -import mage.players.Player; +import java.util.UUID; /** * @@ -40,15 +39,39 @@ import mage.players.Player; public class Round { private int roundNum; - private List matches = new ArrayList(); + private List pairs = new ArrayList(); - public Round(int roundNum, List players) { + public Round(int roundNum) { this.roundNum = roundNum; - } - public List getMatches() { - return matches; + public void addPairing(TournamentPairing match) { + this.pairs.add(match); } + public TournamentPairing getPairing(UUID pairId) { + for (TournamentPairing pair: pairs) { + if (pair.getId().equals(pairId)) { + return pair; + } + } + return null; + } + + public List getPairs() { + return pairs; + } + + public int getRoundNumber() { + return this.roundNum; + } + + public boolean isRoundOver() { + for (TournamentPairing pair: pairs) { + if (!pair.getMatch().isMatchOver()) { + return false; + } + } + return true; + } } diff --git a/Mage/src/mage/game/tournament/Tournament.java b/Mage/src/mage/game/tournament/Tournament.java index 403369b786..48d267d64d 100644 --- a/Mage/src/mage/game/tournament/Tournament.java +++ b/Mage/src/mage/game/tournament/Tournament.java @@ -28,12 +28,30 @@ package mage.game.tournament; +import java.util.Collection; +import java.util.UUID; +import mage.cards.decks.Deck; +import mage.game.events.Listener; +import mage.game.events.TableEvent; +import mage.players.Player; + /** * * @author BetaSteward_at_googlemail.com */ public interface Tournament { - public void playRound(); + public UUID getId(); + public void addPlayer(Player player, String playerType); + public TournamentPlayer getPlayer(UUID playerId); + public Collection getPlayers(); + public Collection getRounds(); + public void submitDeck(UUID playerId, Deck deck); + public boolean allJoined(); + public boolean isDoneConstructing(); + public void leave(UUID playerId); + public void nextStep(); + + public void addTableEventListener(Listener listener); } diff --git a/Mage/src/mage/game/tournament/TournamentImpl.java b/Mage/src/mage/game/tournament/TournamentImpl.java index 7e6ab86ed1..b5ab65afed 100644 --- a/Mage/src/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/mage/game/tournament/TournamentImpl.java @@ -29,24 +29,191 @@ package mage.game.tournament; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; +import mage.cards.decks.Deck; +import mage.game.events.Listener; +import mage.game.events.TableEvent; +import mage.game.events.TableEvent.EventType; +import mage.game.events.TableEventSource; +import mage.game.match.Match; import mage.players.Player; /** * * @author BetaSteward_at_googlemail.com */ -public class TournamentImpl implements Tournament { +public abstract class TournamentImpl implements Tournament { - List rounds = new ArrayList(); - List players = new ArrayList(); + protected UUID id = UUID.randomUUID(); + protected List rounds = new CopyOnWriteArrayList(); + protected Map players = new HashMap(); + protected static Random rnd = new Random(); + protected String matchName; + protected TournamentOptions options; + + protected transient TableEventSource tableEventSource = new TableEventSource(); + + public TournamentImpl(TournamentOptions options) { + this.options = options; + } @Override - public void playRound() { - throw new UnsupportedOperationException("Not supported yet."); + public UUID getId() { + return id; } - protected void createRound() { + @Override + public void addPlayer(Player player, String playerType) { + players.put(player.getId(), new TournamentPlayer(player, playerType)); + } + + @Override + public TournamentPlayer getPlayer(UUID playerId) { + return players.get(playerId); + } + + @Override + public Collection getPlayers() { + return players.values(); + } + + @Override + public Collection getRounds() { + return rounds; + } + + @Override + public void leave(UUID playerId) { + //TODO: implement this + } + + @Override + public void submitDeck(UUID playerId, Deck deck) { + if (players.containsKey(playerId)) { + players.get(playerId).submitDeck(deck); + } + synchronized (this) { + this.notifyAll(); + } + } + + protected Round createRoundRandom() { + Round round = new Round(rounds.size() + 1); + rounds.add(round); + List roundPlayers = getActivePlayers(); + while (roundPlayers.size() > 1) { + int i = rnd.nextInt(roundPlayers.size()); + TournamentPlayer player1 = roundPlayers.get(i); + roundPlayers.remove(i); + i = rnd.nextInt(roundPlayers.size()); + TournamentPlayer player2 = roundPlayers.get(i); + roundPlayers.remove(i); + round.addPairing(new TournamentPairing(player1, player2)); + } + return round; + } + + protected void playRound(Round round) { + for (TournamentPairing pair: round.getPairs()) { + playMatch(pair); + } + + while (!round.isRoundOver()) { + try { + //TODO: improve this + Thread.sleep(1000); + } catch (InterruptedException ex) { + Logger.getLogger(TournamentImpl.class.getName()).log(Level.SEVERE, null, ex); + break; + } + } + updateResults(); + } + + protected List getActivePlayers() { + List activePlayers = new ArrayList(); + for (TournamentPlayer player: players.values()) { + if (!player.getEliminated()) { + activePlayers.add(player); + } + } + return activePlayers; + } + + protected void updateResults() { + for (TournamentPlayer player: players.values()) { + player.setResults(""); + } + for (Round round: rounds) { + for (TournamentPairing pair: round.getPairs()) { + UUID player1Id = pair.getPlayer1().getPlayer().getId(); + UUID player2Id = pair.getPlayer2().getPlayer().getId(); + Match match = pair.getMatch(); + StringBuilder sb1 = new StringBuilder(players.get(player1Id).getResults()); + StringBuilder sb2 = new StringBuilder(players.get(player2Id).getResults()); + sb1.append(pair.getPlayer2().getPlayer().getName()); + sb1.append(" (").append(match.getPlayer(player1Id).getWins()); + sb1.append("-").append(match.getPlayer(player2Id).getWins()).append(") "); + sb2.append(pair.getPlayer1().getPlayer().getName()); + sb2.append(" (").append(match.getPlayer(player2Id).getWins()); + sb2.append("-").append(match.getPlayer(player1Id).getWins()).append(") "); + players.get(player1Id).setResults(sb1.toString()); + players.get(player2Id).setResults(sb2.toString()); + } + } } + + @Override + public boolean isDoneConstructing() { + for (TournamentPlayer player: this.players.values()) { + if (!player.isDoneConstructing()) + return false; + } + return true; + } + + @Override + public boolean allJoined() { + for (TournamentPlayer player: this.players.values()) { + if (!player.isJoined()) + return false; + } + return true; + } + + @Override + public void addTableEventListener(Listener listener) { + tableEventSource.addListener(listener); + } + + public void construct() { + tableEventSource.fireTableEvent(EventType.CONSTRUCT); + synchronized(this) { + while (!isDoneConstructing()) { + try { + this.wait(); + } catch (InterruptedException ex) { } + } + } + nextStep(); + } + + public void playMatch(TournamentPairing pair) { + options.getMatchOptions().getPlayerTypes().clear(); + options.getMatchOptions().getPlayerTypes().add(pair.getPlayer1().getPlayerType()); + options.getMatchOptions().getPlayerTypes().add(pair.getPlayer2().getPlayerType()); + tableEventSource.fireTableEvent(EventType.START_MATCH, pair, options.getMatchOptions()); + } + + protected abstract void runTournament(); + } diff --git a/Mage/src/mage/game/tournament/TournamentOptions.java b/Mage/src/mage/game/tournament/TournamentOptions.java new file mode 100644 index 0000000000..d4ab631b12 --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentOptions.java @@ -0,0 +1,77 @@ +/* + * 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.game.tournament; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import mage.game.draft.DraftOptions; +import mage.game.match.MatchOptions; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentOptions implements Serializable { + + protected String name; + protected String tournamentType; + protected List playerTypes = new ArrayList(); + protected MatchOptions matchOptions = new MatchOptions("", "Two Player Duel"); + protected DraftOptions draftOptions = new DraftOptions(); + + public TournamentOptions(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String getTournamentType() { + return tournamentType; + } + + public void setTournamentType(String tournamentType) { + this.tournamentType = tournamentType; + } + + public List getPlayerTypes() { + return playerTypes; + } + + public MatchOptions getMatchOptions() { + return matchOptions; + } + + public DraftOptions getDraftOptions() { + return draftOptions; + } + +} diff --git a/Mage/src/mage/game/tournament/TournamentPairing.java b/Mage/src/mage/game/tournament/TournamentPairing.java new file mode 100644 index 0000000000..818e2a5540 --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentPairing.java @@ -0,0 +1,78 @@ +/* + * 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.game.tournament; + +import java.util.UUID; +import mage.game.match.Match; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentPairing { + + UUID id = UUID.randomUUID(); + Match match; + TournamentPlayer player1; + TournamentPlayer player2; + + public TournamentPairing(TournamentPlayer player1, TournamentPlayer player2) { + this.player1 = player1; + this.player2 = player2; + } + + public UUID getId() { + return id; + } + + public TournamentPlayer getPlayer1() { + return this.player1; + } + + public TournamentPlayer getPlayer2() { + return this.player2; + } + + public Match getMatch() { + return match; + } + + public void setMatch(Match match) { + this.match = match; + } + + public void eliminatePlayers() { + if (match.getPlayer(player1.getPlayer().getId()).getWins() < match.getWinsNeeded()) { + player1.setEliminated(); + } + if (match.getPlayer(player2.getPlayer().getId()).getWins() < match.getWinsNeeded()) { + player2.setEliminated(); + } + } +} diff --git a/Mage/src/mage/game/tournament/TournamentPlayer.java b/Mage/src/mage/game/tournament/TournamentPlayer.java index 0d78685f5f..778fed3d38 100644 --- a/Mage/src/mage/game/tournament/TournamentPlayer.java +++ b/Mage/src/mage/game/tournament/TournamentPlayer.java @@ -28,6 +28,7 @@ package mage.game.tournament; +import mage.cards.decks.Deck; import mage.players.Player; /** @@ -38,16 +39,31 @@ public class TournamentPlayer { protected int points; protected String name; + protected String playerType; protected Player player; + protected Deck deck; + protected String results = ""; + protected boolean eliminated = false; + protected boolean doneConstructing; + protected boolean joined = false; - public TournamentPlayer(Player player) { + public TournamentPlayer(Player player, String playerType) { this.player = player; + this.playerType = playerType; } public Player getPlayer() { return player; } + public String getPlayerType() { + return playerType; + } + + public Deck getDeck() { + return deck; + } + public int getPoints() { return points; } @@ -56,4 +72,44 @@ public class TournamentPlayer { this.points = points; } + public boolean getEliminated() { + return eliminated; + } + + public void setEliminated() { + this.eliminated = true; + } + + public boolean isJoined() { + return joined; + } + + public void setJoined() { + this.joined = true; + } + + public void setConstructing() { + this.doneConstructing = false; + } + + public void submitDeck(Deck deck) { + this.deck = deck; + this.doneConstructing = true; + } + + public boolean isDoneConstructing() { + return this.doneConstructing; + } + + public void setDeck(Deck deck) { + this.deck = deck; + } + + public String getResults() { + return this.results; + } + + public void setResults(String results) { + this.results = results; + } } diff --git a/Mage/src/mage/game/tournament/TournamentSealedOptions.java b/Mage/src/mage/game/tournament/TournamentSealedOptions.java new file mode 100644 index 0000000000..4d9628ea69 --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentSealedOptions.java @@ -0,0 +1,41 @@ +/* + * 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.game.tournament; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentSealedOptions extends TournamentOptions { + + public TournamentSealedOptions(String name) { + super(name); + } + +} diff --git a/Mage/src/mage/game/tournament/TournamentSingleElimination.java b/Mage/src/mage/game/tournament/TournamentSingleElimination.java new file mode 100644 index 0000000000..ed018b7b5f --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentSingleElimination.java @@ -0,0 +1,58 @@ +/* + * 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.game.tournament; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public abstract class TournamentSingleElimination extends TournamentImpl { + + public TournamentSingleElimination(TournamentOptions options) { + super(options); + } + + @Override + protected void runTournament() { + while (this.getActivePlayers().size() > 1) { + Round round = createRoundRandom(); + playRound(round); + eliminatePlayers(round); + } + nextStep(); + } + + private void eliminatePlayers(Round round) { + for (TournamentPairing pair: round.getPairs()) { + pair.eliminatePlayers(); + } + } + + +} diff --git a/Mage/src/mage/game/tournament/TournamentSwiss.java b/Mage/src/mage/game/tournament/TournamentSwiss.java new file mode 100644 index 0000000000..6b3c2a1407 --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentSwiss.java @@ -0,0 +1,45 @@ +/* + * 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.game.tournament; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public abstract class TournamentSwiss extends TournamentImpl { + + public TournamentSwiss(TournamentOptions options) { + super(options); + } + + @Override + protected void runTournament() { + //TODO: implement this + } + +} diff --git a/Mage/src/mage/game/tournament/TournamentType.java b/Mage/src/mage/game/tournament/TournamentType.java new file mode 100644 index 0000000000..5a6b4172a1 --- /dev/null +++ b/Mage/src/mage/game/tournament/TournamentType.java @@ -0,0 +1,72 @@ +/* + * 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.game.tournament; + +import java.io.Serializable; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentType > implements Serializable { + + protected String name; + protected int minPlayers; + protected int maxPlayers; + protected int numBoosters; + protected boolean draft; + + protected TournamentType() {} + + @Override + public String toString() { + return name; + } + + public String getName() { + return name; + } + + public int getMinPlayers() { + return minPlayers; + } + + public int getMaxPlayers() { + return maxPlayers; + } + + public int getNumBoosters() { + return numBoosters; + } + + public boolean isDraft() { + return draft; + } + +} diff --git a/src/mage/game/tournament/TournamentImpl.java b/src/mage/game/tournament/TournamentImpl.java new file mode 100644 index 0000000000..8c5769ff8c --- /dev/null +++ b/src/mage/game/tournament/TournamentImpl.java @@ -0,0 +1,219 @@ +/* + * 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.game.tournament; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; +import mage.cards.decks.Deck; +import mage.game.events.Listener; +import mage.game.events.TableEvent; +import mage.game.events.TableEvent.EventType; +import mage.game.events.TableEventSource; +import mage.game.match.Match; +import mage.players.Player; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public abstract class TournamentImpl implements Tournament { + + protected UUID id = UUID.randomUUID(); + protected List rounds = new CopyOnWriteArrayList(); + protected Map players = new HashMap(); + protected static Random rnd = new Random(); + protected String matchName; + protected TournamentOptions options; + + protected transient TableEventSource tableEventSource = new TableEventSource(); + + public TournamentImpl(TournamentOptions options) { + this.options = options; + } + + @Override + public UUID getId() { + return id; + } + + @Override + public void addPlayer(Player player, String playerType) { + players.put(player.getId(), new TournamentPlayer(player, playerType)); + } + + @Override + public TournamentPlayer getPlayer(UUID playerId) { + return players.get(playerId); + } + + @Override + public Collection getPlayers() { + return players.values(); + } + + @Override + public Collection getRounds() { + return rounds; + } + + @Override + public void leave(UUID playerId) { + //TODO: implement this + } + + @Override + public void submitDeck(UUID playerId, Deck deck) { + if (players.containsKey(playerId)) { + players.get(playerId).submitDeck(deck); + } + synchronized (this) { + this.notifyAll(); + } + } + + protected Round createRoundRandom() { + Round round = new Round(rounds.size() + 1); + rounds.add(round); + List roundPlayers = getActivePlayers(); + while (roundPlayers.size() > 1) { + int i = rnd.nextInt(roundPlayers.size()); + TournamentPlayer player1 = roundPlayers.get(i); + roundPlayers.remove(i); + i = rnd.nextInt(roundPlayers.size()); + TournamentPlayer player2 = roundPlayers.get(i); + roundPlayers.remove(i); + round.addPairing(new TournamentPairing(player1, player2)); + } + return round; + } + + protected void playRound(Round round) { + for (TournamentPairing pair: round.getPairs()) { + playMatch(pair); + } + + while (!round.isRoundOver()) { + try { + //TODO: improve this + Thread.sleep(1000); + } catch (InterruptedException ex) { + Logger.getLogger(TournamentImpl.class.getName()).log(Level.SEVERE, null, ex); + break; + } + } + updateResults(); + } + + protected List getActivePlayers() { + List activePlayers = new ArrayList(); + for (TournamentPlayer player: players.values()) { + if (!player.getEliminated()) { + activePlayers.add(player); + } + } + return activePlayers; + } + + protected void updateResults() { + for (TournamentPlayer player: players.values()) { + player.setResults(""); + } + for (Round round: rounds) { + for (TournamentPairing pair: round.getPairs()) { + UUID player1Id = pair.getPlayer1().getPlayer().getId(); + UUID player2Id = pair.getPlayer2().getPlayer().getId(); + Match match = pair.getMatch(); + StringBuilder sb1 = new StringBuilder(players.get(player1Id).getResults()); + StringBuilder sb2 = new StringBuilder(players.get(player2Id).getResults()); + sb1.append(pair.getPlayer2().getPlayer().getName()); + sb1.append(" (").append(match.getPlayer(player1Id).getWins()); + sb1.append("-").append(match.getPlayer(player2Id).getWins()).append(")"); + sb2.append(pair.getPlayer1().getPlayer().getName()); + sb2.append(" (").append(match.getPlayer(player2Id).getWins()); + sb2.append("-").append(match.getPlayer(player1Id).getWins()).append(") "); + players.get(player1Id).setResults(sb1.toString()); + players.get(player2Id).setResults(sb2.toString()); + } + } + + } + + @Override + public boolean isDoneConstructing() { + for (TournamentPlayer player: this.players.values()) { + if (!player.isDoneConstructing()) + return false; + } + return true; + } + + @Override + public boolean allJoined() { + for (TournamentPlayer player: this.players.values()) { + if (!player.isJoined()) + return false; + } + return true; + } + + @Override + public void addTableEventListener(Listener listener) { + tableEventSource.addListener(listener); + } + + public void construct() { + tableEventSource.fireTableEvent(EventType.CONSTRUCT); + synchronized(this) { + while (!isDoneConstructing()) { + try { + this.wait(); + } catch (InterruptedException ex) { } + } + } + nextStep(); + } + + public void playMatch(TournamentPairing pair) { + options.getMatchOptions().getPlayerTypes().clear(); + options.getMatchOptions().getPlayerTypes().add(pair.getPlayer1().getPlayerType()); + options.getMatchOptions().getPlayerTypes().add(pair.getPlayer2().getPlayerType()); + tableEventSource.fireTableEvent(EventType.START_MATCH, pair, options.getMatchOptions()); + } + + protected abstract void runTournament(); + +} diff --git a/src/mage/game/tournament/TournamentPlayer.java b/src/mage/game/tournament/TournamentPlayer.java new file mode 100644 index 0000000000..778fed3d38 --- /dev/null +++ b/src/mage/game/tournament/TournamentPlayer.java @@ -0,0 +1,115 @@ +/* + * 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.game.tournament; + +import mage.cards.decks.Deck; +import mage.players.Player; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TournamentPlayer { + + protected int points; + protected String name; + protected String playerType; + protected Player player; + protected Deck deck; + protected String results = ""; + protected boolean eliminated = false; + protected boolean doneConstructing; + protected boolean joined = false; + + public TournamentPlayer(Player player, String playerType) { + this.player = player; + this.playerType = playerType; + } + + public Player getPlayer() { + return player; + } + + public String getPlayerType() { + return playerType; + } + + public Deck getDeck() { + return deck; + } + + public int getPoints() { + return points; + } + + public void setPoints(int points) { + this.points = points; + } + + public boolean getEliminated() { + return eliminated; + } + + public void setEliminated() { + this.eliminated = true; + } + + public boolean isJoined() { + return joined; + } + + public void setJoined() { + this.joined = true; + } + + public void setConstructing() { + this.doneConstructing = false; + } + + public void submitDeck(Deck deck) { + this.deck = deck; + this.doneConstructing = true; + } + + public boolean isDoneConstructing() { + return this.doneConstructing; + } + + public void setDeck(Deck deck) { + this.deck = deck; + } + + public String getResults() { + return this.results; + } + + public void setResults(String results) { + this.results = results; + } +} diff --git a/src/mage/game/tournament/TournamentSingleElimination.java b/src/mage/game/tournament/TournamentSingleElimination.java new file mode 100644 index 0000000000..ed018b7b5f --- /dev/null +++ b/src/mage/game/tournament/TournamentSingleElimination.java @@ -0,0 +1,58 @@ +/* + * 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.game.tournament; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public abstract class TournamentSingleElimination extends TournamentImpl { + + public TournamentSingleElimination(TournamentOptions options) { + super(options); + } + + @Override + protected void runTournament() { + while (this.getActivePlayers().size() > 1) { + Round round = createRoundRandom(); + playRound(round); + eliminatePlayers(round); + } + nextStep(); + } + + private void eliminatePlayers(Round round) { + for (TournamentPairing pair: round.getPairs()) { + pair.eliminatePlayers(); + } + } + + +}