diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index ec45800b9a5..e56fcf0a5ea 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -93,6 +93,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;
+import mage.view.GameEndView;
/**
* @author BetaSteward_at_googlemail.com
@@ -611,6 +612,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
}
+ public void showGameEndDialog(GameEndView gameEndView) {
+ GameEndDialog gameEndDialog = new GameEndDialog(gameEndView);
+ desktopPane.add(gameEndDialog, JLayeredPane.POPUP_LAYER);
+ gameEndDialog.showDialog();
+ }
+
public void showTableWaitingDialog(UUID roomId, UUID tableId, boolean isTournament) {
TableWaitingDialog tableWaitingDialog = new TableWaitingDialog();
desktopPane.add(tableWaitingDialog, JLayeredPane.MODAL_LAYER);
diff --git a/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.form b/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.form
new file mode 100644
index 00000000000..256cc2251aa
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.form
@@ -0,0 +1,303 @@
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.java b/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.java
new file mode 100644
index 00000000000..2888b329118
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/GameEndDialog.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2010 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.
+ */
+
+/*
+ * GameEndDialog.java
+ *
+ * Created on Jul 31, 2013, 9:41:00 AM
+ */
+
+package mage.client.dialog;
+
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import javax.swing.ImageIcon;
+import mage.client.util.AudioManager;
+import mage.client.util.Format;
+import mage.client.util.ImageHelper;
+import mage.client.util.gui.BufferedImageBuilder;
+import mage.view.GameEndView;
+import mage.view.PlayerView;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class GameEndDialog extends MageDialog {
+
+ private final DateFormat df = DateFormat.getDateTimeInstance();;
+
+
+ /** Creates new form GameEndDialog */
+ public GameEndDialog(GameEndView gameEndView) {
+
+ initComponents();
+ this.modal = true;
+
+ pnlText.setOpaque(true);
+ pnlText.setBackground(new Color(240,240,240,140));
+
+ Rectangle r = new Rectangle(610, 250);
+ Image image = ImageHelper.getImageFromResources(gameEndView.hasWon() ?"/game_won.jpg":"/game_lost.jpg");
+ BufferedImage imageResult = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
+ ImageIcon icon = new ImageIcon(imageResult);
+ lblResultImage.setIcon(icon);
+
+ this.lblResultText.setText(gameEndView.getResultMessage());
+
+ // game duration
+ txtDurationGame.setText(Format.getDuration(gameEndView.getStartTime(), gameEndView.getEndTime()));
+ txtDurationGame.setToolTipText(new StringBuilder(df.format(gameEndView.getStartTime())).append(" - ").append(df.format(gameEndView.getEndTime())).toString() );
+
+ // match duration
+ Calendar cal = Calendar.getInstance();
+ txtDurationMatch.setText(Format.getDuration(gameEndView.getMatchView().getStartTime(), cal.getTime()));
+ txtDurationMatch.setToolTipText(new StringBuilder(df.format(gameEndView.getMatchView().getStartTime())).append(" - ").append(df.format(cal.getTime())).toString() );
+
+ StringBuilder sb = new StringBuilder();
+ for (PlayerView player : gameEndView.getPlayers()) {
+ sb.append(player.getName()).append(" Life: ").append(player.getLife()).append(" ");
+ }
+ this.txtLife.setText(sb.toString());
+
+ if (gameEndView.hasWon()) {
+ AudioManager.playPlayerJoinedTable();
+ } else {
+ AudioManager.playButtonCancel();
+ }
+
+ txtMatchScore.setText(gameEndView.getMatchView().getResult());
+
+ if (gameEndView.getNameMatchWinner() != null) {
+ if (gameEndView.getClientPlayer().getName().equals(gameEndView.getNameMatchWinner())) {
+ lblMatchInfo.setText("You won the match!");
+ } else {
+ lblMatchInfo.setText(new StringBuilder(gameEndView.getNameMatchWinner()).append(" won the match!").toString());
+ }
+ } else {
+ int winsNeeded = gameEndView.getWinsNeeded() - gameEndView.getWins();
+ lblMatchInfo.setText(new StringBuilder("You need ").append(winsNeeded == 1 ? "one win ":winsNeeded + " wins ").append("to win the match.").toString());
+ }
+
+
+ }
+
+ public void showDialog() {
+ this.setLocation(100, 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() {
+
+ jPanel2 = new javax.swing.JPanel();
+ tabPane = new javax.swing.JTabbedPane();
+ tabResult = new javax.swing.JLayeredPane();
+ pnlText = new javax.swing.JLayeredPane();
+ lblMatchInfo = new javax.swing.JLabel();
+ lblResultText = new javax.swing.JLabel();
+ lblResultImage = new javax.swing.JLabel();
+ tabStatistics = new javax.swing.JPanel();
+ lblDurationGame = new javax.swing.JLabel();
+ txtDurationGame = new javax.swing.JLabel();
+ lblLife = new javax.swing.JLabel();
+ txtLife = new javax.swing.JLabel();
+ lblDurationMatch = new javax.swing.JLabel();
+ txtDurationMatch = new javax.swing.JLabel();
+ lblMatchScore = new javax.swing.JLabel();
+ txtMatchScore = new javax.swing.JLabel();
+ lblPlayerInfo = new javax.swing.JLabel();
+ txtPlayerInfo = new javax.swing.JLabel();
+ btnOk = new javax.swing.JButton();
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 100, Short.MAX_VALUE)
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 100, Short.MAX_VALUE)
+ );
+
+ setTitle("Game end information");
+
+ pnlText.setBackground(new java.awt.Color(200, 100, 100));
+ pnlText.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+ pnlText.setOpaque(true);
+
+ lblMatchInfo.setFont(new java.awt.Font("Tahoma", 3, 24)); // NOI18N
+ lblMatchInfo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ lblMatchInfo.setText("matchInfo");
+ lblMatchInfo.setBounds(11, 42, 550, 40);
+ pnlText.add(lblMatchInfo, javax.swing.JLayeredPane.DEFAULT_LAYER);
+
+ lblResultText.setFont(new java.awt.Font("Tahoma", 3, 24)); // NOI18N
+ lblResultText.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ lblResultText.setText("result text");
+ lblResultText.setBounds(11, 1, 550, 40);
+ pnlText.add(lblResultText, javax.swing.JLayeredPane.DEFAULT_LAYER);
+
+ pnlText.setBounds(20, 150, 570, 90);
+ tabResult.add(pnlText, javax.swing.JLayeredPane.DEFAULT_LAYER);
+
+ lblResultImage.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
+ lblResultImage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ lblResultImage.setBounds(0, 0, 610, 250);
+ tabResult.add(lblResultImage, javax.swing.JLayeredPane.DEFAULT_LAYER);
+
+ tabPane.addTab("Result", tabResult);
+
+ lblDurationGame.setText("Duration game:");
+
+ txtDurationGame.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ lblLife.setText("Life at end:");
+
+ txtLife.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ lblDurationMatch.setText("Duration match:");
+
+ txtDurationMatch.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ lblMatchScore.setText("Match score:");
+
+ txtMatchScore.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ lblPlayerInfo.setText("Player info:");
+
+ txtPlayerInfo.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ javax.swing.GroupLayout tabStatisticsLayout = new javax.swing.GroupLayout(tabStatistics);
+ tabStatistics.setLayout(tabStatisticsLayout);
+ tabStatisticsLayout.setHorizontalGroup(
+ tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabStatisticsLayout.createSequentialGroup()
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabStatisticsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblDurationMatch, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblMatchScore, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGroup(tabStatisticsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblDurationGame, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblLife, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtPlayerInfo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(txtDurationGame, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
+ .addComponent(txtLife, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
+ .addComponent(txtDurationMatch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE)
+ .addComponent(txtMatchScore, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ tabStatisticsLayout.setVerticalGroup(
+ tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabStatisticsLayout.createSequentialGroup()
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblDurationGame, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtDurationGame, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(lblLife, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtLife, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(lblDurationMatch, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtDurationMatch, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(lblMatchScore, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtMatchScore, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(tabStatisticsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtPlayerInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(99, Short.MAX_VALUE))
+ );
+
+ tabPane.addTab("Statistics", tabStatistics);
+
+ btnOk.setText("OK");
+ btnOk.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnOkActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btnOk)
+ .addContainerGap())
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(tabPane, javax.swing.GroupLayout.PREFERRED_SIZE, 626, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(tabPane, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnOk)
+ .addGap(0, 25, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
+ this.removeDialog();
+ }//GEN-LAST:event_btnOkActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnOk;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JLabel lblDurationGame;
+ private javax.swing.JLabel lblDurationMatch;
+ private javax.swing.JLabel lblLife;
+ private javax.swing.JLabel lblMatchInfo;
+ private javax.swing.JLabel lblMatchScore;
+ private javax.swing.JLabel lblPlayerInfo;
+ private javax.swing.JLabel lblResultImage;
+ private javax.swing.JLabel lblResultText;
+ private javax.swing.JLayeredPane pnlText;
+ private javax.swing.JTabbedPane tabPane;
+ private javax.swing.JLayeredPane tabResult;
+ private javax.swing.JPanel tabStatistics;
+ private javax.swing.JLabel txtDurationGame;
+ private javax.swing.JLabel txtDurationMatch;
+ private javax.swing.JLabel txtLife;
+ private javax.swing.JLabel txtMatchScore;
+ private javax.swing.JLabel txtPlayerInfo;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java
index cac7b90cd95..21694f92aa5 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/MageDialog.java
@@ -40,6 +40,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
+import mage.client.MageFrame;
/**
*
@@ -157,6 +158,11 @@ public class MageDialog extends javax.swing.JInternalFrame {
this.setVisible(false);
}
+ public void removeDialog() {
+ this.setVisible(false);
+ MageFrame.getDesktop().remove(this);
+ }
+
public void setTitelBarToolTip(final String text) {
desktopIcon.setToolTipText(text); //tooltip on icon
Component[] children = desktopIcon.getComponents();
diff --git a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java
index b8738221bf3..1831240e0a5 100644
--- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java
+++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java
@@ -51,6 +51,7 @@ import mage.view.DeckView;
import mage.view.DraftClientMessage;
import mage.view.DraftView;
import mage.view.GameClientMessage;
+import mage.view.GameEndView;
import mage.view.GameView;
import mage.view.TableClientMessage;
import org.apache.log4j.Logger;
@@ -240,6 +241,9 @@ public class CallbackClientImpl implements CallbackClient {
panel.updateGame((GameView) callback.getData());
}
}
+ else if (callback.getMethod().equals("endGameInfo")) {
+ MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData());
+ }
else if (callback.getMethod().equals("gameInform")) {
if (callback.getMessageId() > messageId) {
diff --git a/Mage.Client/src/main/java/mage/client/util/Format.java b/Mage.Client/src/main/java/mage/client/util/Format.java
new file mode 100644
index 00000000000..d13423d58b8
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/util/Format.java
@@ -0,0 +1,76 @@
+/*
+* 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.client.util;
+
+import java.util.Date;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class Format {
+
+ /**
+ * calculates the duration between two dates and returns a string in the format hhh:mm:ss
+ *
+ * @param fromDate - start date
+ * @param toDate - end date
+ * @return a string in the format hhh:mm:ss
+ */
+ public static String getDuration(Date fromDate, Date toDate) {
+ if (fromDate == null || toDate == null || fromDate.getTime() > toDate.getTime()) {
+ return "";
+ }
+
+ return getDuration((toDate.getTime() - fromDate.getTime()) / 1000);
+ }
+ /**
+ * Converts seconds to a string with hours, minutes and seconds
+ *
+ * @param seconds - seconds of the duration
+ * @return a string in the format hhh:mm:ss
+ */
+ public static String getDuration(long seconds) {
+ StringBuilder sb = new StringBuilder();
+ long h = seconds / 3600;
+ seconds = seconds % 3600;
+ long m = seconds / 60;
+ long s = seconds % 60;
+ sb.append(h).append(":");
+ if (m<10) {
+ sb.append("0");
+ }
+ sb.append(m).append(":");
+ if (s<10) {
+ sb.append("0");
+ }
+ sb.append(s);
+ return sb.toString();
+ }
+}
diff --git a/Mage.Client/src/main/resources/game_lost.jpg b/Mage.Client/src/main/resources/game_lost.jpg
new file mode 100644
index 00000000000..e2fcd36136d
Binary files /dev/null and b/Mage.Client/src/main/resources/game_lost.jpg differ
diff --git a/Mage.Client/src/main/resources/game_won.jpg b/Mage.Client/src/main/resources/game_won.jpg
new file mode 100644
index 00000000000..241f8952f13
Binary files /dev/null and b/Mage.Client/src/main/resources/game_won.jpg differ
diff --git a/Mage.Common/src/mage/view/GameEndView.java b/Mage.Common/src/mage/view/GameEndView.java
new file mode 100644
index 00000000000..7aab1501c1b
--- /dev/null
+++ b/Mage.Common/src/mage/view/GameEndView.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.view;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import mage.game.Game;
+import mage.game.GameState;
+import mage.game.match.Match;
+import mage.game.match.MatchPlayer;
+import mage.players.Player;
+
+/**
+ * @author LevelX2
+ */
+public class GameEndView implements Serializable {
+
+ private PlayerView clientPlayer = null;
+ private List players = new ArrayList();
+ private Date startTime;
+ private Date endTime;
+ private String resultMessage;
+ private boolean won;
+ private MatchView matchView;
+ private int wins;
+ private int loses;
+ private int winsNeeded;
+ private String nameMatchWinner = null;
+
+ public GameEndView(GameState state, Game game, UUID playerId, Match match) {
+ startTime = game.getStartTime();
+ endTime = game.getEndTime();
+
+ // set result message
+ int winner = 0;
+ Player you = null;
+ for (Player player: state.getPlayers().values()) {
+ PlayerView playerView = new PlayerView(player, state, game);
+ if (playerView.getPlayerId().equals(playerId)) {
+ clientPlayer = playerView;
+ you = player;
+ }
+ players.add(playerView);
+ if (player.hasWon()) {
+ winner++;
+ }
+ }
+ if (you != null) {
+ won = you.hasWon();
+ if (you.hasWon()) {
+ resultMessage = new StringBuilder("You won the game on turn ").append(game.getTurnNum()).append(".").toString();
+ } else if (winner > 0) {
+ resultMessage = new StringBuilder("You lost the game on turn ").append(game.getTurnNum()).append(".").toString();
+ } else {
+ resultMessage = new StringBuilder("Game is a draw on Turn ").append(game.getTurnNum()).append(".").toString();
+ }
+ }
+ matchView = new MatchView(match);
+
+ winsNeeded = match.getOptions().getWinsNeeded();
+ for (MatchPlayer mPlayer: match.getPlayers()) {
+ if (mPlayer.getPlayer().equals(you)) {
+ wins = mPlayer.getWins();
+ loses = mPlayer.getLoses();
+
+ }
+ if (mPlayer.getWins() == winsNeeded) {
+ nameMatchWinner = mPlayer.getPlayer().getName();
+ }
+ }
+
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public List getPlayers() {
+ return players;
+ }
+
+ public String getResultMessage() {
+ return resultMessage;
+ }
+
+ public boolean hasWon() {
+ return won;
+ }
+
+ public MatchView getMatchView() {
+ return matchView;
+ }
+
+ public int getWins() {
+ return wins;
+ }
+
+ public int getLoses() {
+ return loses;
+ }
+
+ public int getWinsNeeded() {
+ return winsNeeded;
+ }
+
+ public String getNameMatchWinner() {
+ return nameMatchWinner;
+ }
+
+ public PlayerView getClientPlayer() {
+ return clientPlayer;
+ }
+
+}
diff --git a/Mage.Common/src/mage/view/PlayerView.java b/Mage.Common/src/mage/view/PlayerView.java
index 9b10b0d376e..f549114171f 100644
--- a/Mage.Common/src/mage/view/PlayerView.java
+++ b/Mage.Common/src/mage/view/PlayerView.java
@@ -127,14 +127,17 @@ public class PlayerView implements Serializable {
private boolean showInBattlefield(Permanent permanent, GameState state) {
//show permanents controlled by player or attachments to permanents controlled by player
- if (permanent.getAttachedTo() == null)
+ if (permanent.getAttachedTo() == null) {
return permanent.getControllerId().equals(playerId);
+ }
else {
Permanent attachedTo = state.getPermanent(permanent.getAttachedTo());
- if (attachedTo != null)
+ if (attachedTo != null) {
return attachedTo.getControllerId().equals(playerId);
- else
+ }
+ else {
return permanent.getControllerId().equals(playerId);
+ }
}
}
diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java
index 11968b95327..c79af48f7ba 100644
--- a/Mage.Server/src/main/java/mage/server/TableController.java
+++ b/Mage.Server/src/main/java/mage/server/TableController.java
@@ -155,6 +155,10 @@ public class TableController {
tournament.addPlayer(player, seat.getPlayerType());
table.joinTable(player, seat);
User user = UserManager.getInstance().getUser(userId);
+ if (user == null) {
+ logger.fatal(new StringBuilder("couldn't get user ").append(name).append(" for join tornament userId = ").append(userId).toString());
+ return false;
+ }
user.addTable(player.getId(), table);
logger.info("player joined " + player.getId());
//only inform human players and add them to sessionPlayerMap
diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java
index 0fb03fa0a10..a87c4a061a5 100644
--- a/Mage.Server/src/main/java/mage/server/User.java
+++ b/Mage.Server/src/main/java/mage/server/User.java
@@ -160,6 +160,10 @@ public class User {
fireCallback(new ClientCallback("showTournament", tournamentId));
}
+ public void showGameEndDialog(final UUID gameId) {
+ fireCallback(new ClientCallback("showGameEndDialog", gameId));
+ }
+
public void watchGame(final UUID gameId) {
fireCallback(new ClientCallback("watchGame", gameId));
}
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 b3abf298815..cd5b1610aab 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameController.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameController.java
@@ -57,6 +57,7 @@ import mage.cards.repository.CardRepository;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.GameException;
+import mage.game.Table;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.TableEvent;
@@ -141,6 +142,9 @@ public class GameController implements GameCallback {
case ERROR:
error(event.getMessage(), event.getException());
break;
+ case END_GAME_INFO:
+ endGameInfo();
+ break;
case INIT_TIMER:
final UUID initPlayerId = event.getPlayerId();
if (initPlayerId == null) {
@@ -475,6 +479,21 @@ public class GameController implements GameCallback {
}
}
+ private synchronized void endGameInfo() {
+ Table table = TableManager.getInstance().getTable(tableId);
+ if (table != null) {
+ if (table.getMatch() != null) {
+ for (final GameSession gameSession: gameSessions.values()) {
+ gameSession.endGameInfo(table.getMatch());
+ }
+ }
+ }
+ // TODO: inform watchers
+// for (final GameWatcher gameWatcher: watchers.values()) {
+// gameWatcher.update();
+// }
+ }
+
private synchronized void ask(UUID playerId, final String question) throws MageException {
perform(playerId, new Command() {
@Override
diff --git a/Mage.Server/src/main/java/mage/server/game/GameSession.java b/Mage.Server/src/main/java/mage/server/game/GameSession.java
index 1eee2b538f3..28a5cfecae2 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameSession.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameSession.java
@@ -36,6 +36,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.Cards;
import mage.game.Game;
+import mage.game.match.Match;
import mage.interfaces.callback.ClientCallback;
import mage.players.Player;
import mage.players.net.UserData;
@@ -160,6 +161,15 @@ public class GameSession extends GameWatcher {
}
}
+ public void endGameInfo(Match match) {
+ if (!killed) {
+ User user = UserManager.getInstance().getUser(userId);
+ if (user != null) {
+ user.fireCallback(new ClientCallback("endGameInfo", game.getId(), getGameEndView(playerId, match)));
+ }
+ }
+ }
+
private synchronized void setupTimeout() {
if (!useTimeout) {
return;
diff --git a/Mage.Server/src/main/java/mage/server/game/GameWatcher.java b/Mage.Server/src/main/java/mage/server/game/GameWatcher.java
index ac458181121..7193e82faa0 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameWatcher.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameWatcher.java
@@ -38,6 +38,8 @@ import org.apache.log4j.Logger;
import java.rmi.RemoteException;
import java.util.UUID;
+import mage.game.match.Match;
+import mage.view.GameEndView;
/**
*
@@ -124,5 +126,9 @@ public class GameWatcher {
public GameView getGameView() {
return new GameView(game.getState(), game);
}
+
+ public GameEndView getGameEndView(UUID playerId, Match match) {
+ return new GameEndView(game.getState(), game, playerId, match);
+ }
}
diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java
index cf8f6347d2c..45bc2de77ec 100644
--- a/Mage/src/mage/game/Game.java
+++ b/Mage/src/mage/game/Game.java
@@ -151,6 +151,7 @@ public interface Game extends MageItem, Serializable {
void informPlayer(Player player, String message);
void debugMessage(String message);
void fireErrorEvent(String message, Exception ex);
+ void fireGameEndInfo();
//game event methods
void fireEvent(GameEvent event);
diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java
index 7f9b7b84bb9..230784c941a 100644
--- a/Mage/src/mage/game/GameImpl.java
+++ b/Mage/src/mage/game/GameImpl.java
@@ -1551,6 +1551,15 @@ public abstract class GameImpl> implements Game, Serializa
tableEventSource.fireTableEvent(EventType.UPDATE, null, this);
}
+ @Override
+ public void fireGameEndInfo() {
+ if (simulation) {
+ return;
+ }
+ logger.trace("fireGameEndIfo");
+ tableEventSource.fireTableEvent(EventType.END_GAME_INFO, null, this);
+ }
+
@Override
public void fireErrorEvent(String message, Exception ex) {
tableEventSource.fireTableEvent(EventType.ERROR, message, ex, this);
diff --git a/Mage/src/mage/game/events/TableEvent.java b/Mage/src/mage/game/events/TableEvent.java
index a359155095b..eaf2568a0c9 100644
--- a/Mage/src/mage/game/events/TableEvent.java
+++ b/Mage/src/mage/game/events/TableEvent.java
@@ -45,7 +45,7 @@ import mage.game.tournament.TournamentPairing;
public class TableEvent extends EventObject implements ExternalEvent, Serializable {
public enum EventType {
- UPDATE, INFO, STATUS, REVEAL, LOOK, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END, ERROR,
+ UPDATE, INFO, STATUS, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END, END_GAME_INFO, ERROR,
INIT_TIMER, RESUME_TIMER, PAUSE_TIMER
}
diff --git a/Mage/src/mage/game/match/MatchImpl.java b/Mage/src/mage/game/match/MatchImpl.java
index 8df1ee07903..d44d7ac4b4a 100644
--- a/Mage/src/mage/game/match/MatchImpl.java
+++ b/Mage/src/mage/game/match/MatchImpl.java
@@ -208,6 +208,7 @@ public abstract class MatchImpl implements Match {
}
}
}
+ game.fireGameEndInfo();
}
@Override