Merge pull request #8 from magefree/master

Pull request
This commit is contained in:
Cameron Miller 2015-07-04 12:26:15 +01:00
commit e5c5f7f72e
872 changed files with 28395 additions and 7503 deletions

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>

View file

@ -71,7 +71,7 @@ public class ChatPanel extends javax.swing.JPanel {
/** /**
* Chat message color for opponents. * Chat message color for opponents.
*/ */
private static final String OPPONENT_COLOR = "#FF7F50"; private static final String OPPONENT_COLOR = "#FF7F50";
/** /**
* Chat message color for client player. * Chat message color for client player.
*/ */
@ -142,6 +142,7 @@ public class ChatPanel extends javax.swing.JPanel {
*/ */
/** /**
* Creates new form ChatPanel * Creates new form ChatPanel
*
* @param addPlayersTab * @param addPlayersTab
*/ */
public ChatPanel(boolean addPlayersTab) { public ChatPanel(boolean addPlayersTab) {
@ -262,6 +263,7 @@ public class ChatPanel extends javax.swing.JPanel {
sb.append("</font>"); sb.append("</font>");
return sb.toString(); return sb.toString();
} }
public String getText() { public String getText() {
return txtConversation.getText(); return txtConversation.getText();
} }
@ -326,7 +328,7 @@ public class ChatPanel extends javax.swing.JPanel {
class UserTableModel extends AbstractTableModel { class UserTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{" ","Players", "Info", "Games", "Connection"}; private final String[] columnNames = new String[]{"Loc", "Players", "Info", "Games", "Connection"};
private UsersView[] players = new UsersView[0]; private UsersView[] players = new UsersView[0];
public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException { public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException {
@ -337,9 +339,9 @@ public class ChatPanel extends javax.swing.JPanel {
tcm.getColumn(jTablePlayers.convertColumnIndexToView(1)).setHeaderValue("Players (" + this.players.length + ")"); tcm.getColumn(jTablePlayers.convertColumnIndexToView(1)).setHeaderValue("Players (" + this.players.length + ")");
tcm.getColumn(jTablePlayers.convertColumnIndexToView(3)).setHeaderValue( tcm.getColumn(jTablePlayers.convertColumnIndexToView(3)).setHeaderValue(
"Games " + roomUserInfo.getNumberActiveGames() + "Games " + roomUserInfo.getNumberActiveGames()
(roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads():" (") + + (roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads() : " (")
" limit: " + roomUserInfo.getNumberMaxGames() + ")"); + " limit: " + roomUserInfo.getNumberMaxGames() + ")");
th.repaint(); th.repaint();
this.fireTableDataChanged(); this.fireTableDataChanged();
} }
@ -397,8 +399,6 @@ public class ChatPanel extends javax.swing.JPanel {
return false; return false;
} }
} }
public void clear() { public void clear() {
@ -486,9 +486,9 @@ public class ChatPanel extends javax.swing.JPanel {
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPaneTxt, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE) .addComponent(jScrollPaneTxt, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))); .addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)));
jTablePlayers = null; jTablePlayers = null;
jScrollPanePlayers = null; jScrollPanePlayers = null;
} }

View file

@ -1,12 +1,17 @@
package mage.client.components; package mage.client.components;
import mage.client.util.Command; import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*; import java.awt.Font;
import java.awt.*; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import javax.swing.JPanel;
import mage.client.util.Command;
/** /**
* Image button with hover. * Image button with hover.
@ -48,6 +53,8 @@ public class HoverButton extends JPanel implements MouseListener {
static final Font textSetFontBold = new Font("Arial", Font.BOLD, 14); static final Font textSetFontBold = new Font("Arial", Font.BOLD, 14);
private boolean useMiniFont = false; private boolean useMiniFont = false;
private boolean alignTextLeft = false;
public HoverButton(String text, Image image, Rectangle size) { public HoverButton(String text, Image image, Rectangle size) {
this(text, image, image, null, image, size); this(text, image, image, null, image, size);
if (image == null) { if (image == null) {
@ -113,7 +120,7 @@ public class HoverButton extends JPanel implements MouseListener {
} }
topTextOffsetX = calculateOffsetForTop(g2d, topText); topTextOffsetX = calculateOffsetForTop(g2d, topText);
g2d.setColor(textBGColor); g2d.setColor(textBGColor);
g2d.drawString(topText, topTextOffsetX+1, 13); g2d.drawString(topText, topTextOffsetX + 1, 13);
g2d.setColor(textColor); g2d.setColor(textColor);
g2d.drawString(topText, topTextOffsetX, 12); g2d.drawString(topText, topTextOffsetX, 12);
} }
@ -148,7 +155,11 @@ public class HoverButton extends JPanel implements MouseListener {
frc = g2d.getFontRenderContext(); frc = g2d.getFontRenderContext();
textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth(); textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth();
} }
textOffsetX = (imageSize.width - textWidth) / 2; if (alignTextLeft) {
textOffsetX = 0;
} else {
textOffsetX = (imageSize.width - textWidth) / 2;
}
} }
return textOffsetX; return textOffsetX;
} }
@ -277,4 +288,8 @@ public class HoverButton extends JPanel implements MouseListener {
this.textAlwaysVisible = textAlwaysVisible; this.textAlwaysVisible = textAlwaysVisible;
} }
public void setAlignTextLeft(boolean alignTextLeft) {
this.alignTextLeft = alignTextLeft;
}
} }

View file

@ -1,19 +1,16 @@
package mage.client.components; package mage.client.components;
import java.awt.Color;
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.ManaSymbols;
import org.mage.card.arcane.UI; import org.mage.card.arcane.UI;
import javax.swing.*;
import java.awt.*;
import javax.swing.text.JTextComponent;
/** /**
* Component for displaying text in mage. * Component for displaying text in mage. Supports drawing mana symbols.
* Supports drawing mana symbols.
* *
* @author nantuko * @author nantuko
*/ */
public class MageTextArea extends JEditorPane { public class MageTextArea extends JEditorPane {
public MageTextArea() { public MageTextArea() {
@ -27,10 +24,10 @@ public class MageTextArea extends JEditorPane {
@Override @Override
public void setText(String text) { public void setText(String text) {
setText(text, 16); setText(text, 0);
} }
public void setText(String text, int fontSize) { public void setText(String text, final int panelWidth) {
if (text == null) { if (text == null) {
return; return;
} }
@ -38,23 +35,36 @@ public class MageTextArea extends JEditorPane {
final StringBuilder buffer = new StringBuilder(512); final StringBuilder buffer = new StringBuilder(512);
// Dialog is a java logical font family, so it should work on all systems // Dialog is a java logical font family, so it should work on all systems
buffer.append("<html><body style='font-family:Dialog;font-size:"); buffer.append("<html><body style='font-family:Dialog;font-size:");
buffer.append(fontSize); buffer.append(16);
buffer.append("pt;margin:3px 3px 3px 3px;color: #FFFFFF'><b><center>"); buffer.append("pt;margin:3px 3px 3px 3px;color: #FFFFFF'><b><center>");
text = text.replaceAll("#([^#]+)#", "<i>$1</i>"); // Don't know what it does (easy italc?) but it bugs with multiple #HTML color codes (LevelX2)
//text = text.replaceAll("#([^#]+)#", "<i>$1</i>");
//text = text.replaceAll("\\s*//\\s*", "<hr width='50%'>"); //text = text.replaceAll("\\s*//\\s*", "<hr width='50%'>");
text = text.replace("\r\n", "<div style='font-size:5pt'></div>"); text = text.replace("\r\n", "<div style='font-size:5pt'></div>");
final String basicText = ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY);
if (text.length() > 0) { if (text.length() > 0) {
buffer.append(ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY)); buffer.append(basicText);
} }
buffer.append("</b></center></body></html>"); buffer.append("</b></center></body></html>");
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() { public void run() {
MageTextArea.super.setText(buffer.toString()); String promptText = buffer.toString();
//System.out.println(buffer.toString()); MageTextArea.super.setText(promptText);
// in case the text don't fit in the panel a tooltip with the text is added
if (panelWidth > 0 && MageTextArea.this.getPreferredSize().getWidth() > panelWidth) {
// String tooltip = promptText
// .replace("color: #FFFFFF'>", "color: #111111'><p width='400'>")
// .replace("</body>", "</p></body>");
String tooltip = "<html><center><body style='font-family:Dialog;font-size:14;color: #FFFFFF'><p width='500'>" + basicText + "</p></body></html>";
MageTextArea.super.setToolTipText(tooltip);
} else {
MageTextArea.super.setToolTipText(null);
}
setCaretPosition(0); setCaretPosition(0);
} }
}); });

View file

@ -1,30 +1,30 @@
/* /*
* Copyright 2011 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 * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.client.dialog; package mage.client.dialog;
import java.util.HashSet; import java.util.HashSet;
@ -46,6 +46,7 @@ import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.constants.Constants.DeckEditorMode; import mage.client.constants.Constants.DeckEditorMode;
import mage.constants.Rarity; import mage.constants.Rarity;
import org.apache.log4j.Logger;
/** /**
* *
@ -53,12 +54,16 @@ import mage.constants.Rarity;
*/ */
public class AddLandDialog extends MageDialog { public class AddLandDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(MageDialog.class);
private Deck deck; private Deck deck;
private final Set<String> setCodesland = new HashSet<>(); private final Set<String> setCodesland = new HashSet<>();
private static final int DEFAULT_SEALED_DECK_CARD_NUMBER = 40; private static final int DEFAULT_SEALED_DECK_CARD_NUMBER = 40;
/** Creates new form AddLandDialog */ /**
* Creates new form AddLandDialog
*/
public AddLandDialog() { public AddLandDialog() {
initComponents(); initComponents();
this.setModal(true); this.setModal(true);
@ -69,7 +74,7 @@ public class AddLandDialog extends MageDialog {
SortedSet<String> landSets = new TreeSet<>(); SortedSet<String> landSets = new TreeSet<>();
if (!mode.equals(DeckEditorMode.FREE_BUILDING)) { if (!mode.equals(DeckEditorMode.FREE_BUILDING)) {
// decide from which sets basic lands are taken from // decide from which sets basic lands are taken from
for (String setCode :deck.getExpansionSetCodes()) { for (String setCode : deck.getExpansionSetCodes()) {
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode); ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
if (expansionInfo != null && expansionInfo.hasBasicLands()) { if (expansionInfo != null && expansionInfo.hasBasicLands()) {
this.setCodesland.add(expansionInfo.getCode()); this.setCodesland.add(expansionInfo.getCode());
@ -79,11 +84,11 @@ public class AddLandDialog extends MageDialog {
// if sets have no basic land, take land from block // if sets have no basic land, take land from block
if (this.setCodesland.isEmpty()) { if (this.setCodesland.isEmpty()) {
for (String setCode :deck.getExpansionSetCodes()) { for (String setCode : deck.getExpansionSetCodes()) {
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode); ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
if (expansionInfo != null) { if (expansionInfo != null) {
List<ExpansionInfo> blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName()); List<ExpansionInfo> blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName());
for (ExpansionInfo blockSet: blockSets) { for (ExpansionInfo blockSet : blockSets) {
if (blockSet.hasBasicLands()) { if (blockSet.hasBasicLands()) {
this.setCodesland.add(blockSet.getCode()); this.setCodesland.add(blockSet.getCode());
landSets.add(blockSet.getName()); landSets.add(blockSet.getName());
@ -96,14 +101,14 @@ public class AddLandDialog extends MageDialog {
// if still no set with lands found, add list of all available // if still no set with lands found, add list of all available
if (this.setCodesland.isEmpty()) { if (this.setCodesland.isEmpty()) {
List<ExpansionInfo> basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate(); List<ExpansionInfo> basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate();
for (ExpansionInfo expansionInfo: basicLandSets) { for (ExpansionInfo expansionInfo : basicLandSets) {
landSets.add(expansionInfo.getName()); landSets.add(expansionInfo.getName());
} }
} }
if (landSets.isEmpty()) { if (landSets.isEmpty()) {
throw new IllegalArgumentException("No set with basic land was found"); throw new IllegalArgumentException("No set with basic land was found");
} }
if(landSets.size() > 1) { if (landSets.size() > 1) {
landSets.add("<Random lands>"); landSets.add("<Random lands>");
} }
cbLandSet.setModel(new DefaultComboBoxModel(landSets.toArray())); cbLandSet.setModel(new DefaultComboBoxModel(landSets.toArray()));
@ -129,7 +134,11 @@ public class AddLandDialog extends MageDialog {
criteria.rarities(Rarity.LAND).name(landName); criteria.rarities(Rarity.LAND).name(landName);
List<CardInfo> cards = CardRepository.instance.findCards(criteria); List<CardInfo> cards = CardRepository.instance.findCards(criteria);
if (cards.isEmpty()) { if (cards.isEmpty()) {
throw new IllegalArgumentException("No basic lands found in Set: " + landSetName); logger.error("No basic lands found in Set: " + landSetName);
criteria = new CardCriteria();
criteria.rarities(Rarity.LAND).name(landName);
criteria.setCodes("M15");
cards = CardRepository.instance.findCards(criteria);
} }
for (int i = 0; i < number; i++) { for (int i = 0; i < number; i++) {
@ -138,10 +147,10 @@ public class AddLandDialog extends MageDialog {
} }
} }
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -298,11 +307,11 @@ public class AddLandDialog extends MageDialog {
}//GEN-LAST:event_btnCancelActionPerformed }//GEN-LAST:event_btnCancelActionPerformed
private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
int nForest = ((Number)spnForest.getValue()).intValue(); int nForest = ((Number) spnForest.getValue()).intValue();
int nIsland = ((Number)spnIsland.getValue()).intValue(); int nIsland = ((Number) spnIsland.getValue()).intValue();
int nMountain = ((Number)spnMountain.getValue()).intValue(); int nMountain = ((Number) spnMountain.getValue()).intValue();
int nPlains = ((Number)spnPlains.getValue()).intValue(); int nPlains = ((Number) spnPlains.getValue()).intValue();
int nSwamp = ((Number)spnSwamp.getValue()).intValue(); int nSwamp = ((Number) spnSwamp.getValue()).intValue();
addLands("Forest", nForest); addLands("Forest", nForest);
addLands("Island", nIsland); addLands("Island", nIsland);
@ -316,7 +325,7 @@ public class AddLandDialog extends MageDialog {
autoAddLands(); autoAddLands();
}//GEN-LAST:event_btnAutoAddActionPerformed }//GEN-LAST:event_btnAutoAddActionPerformed
private void autoAddLands(){ private void autoAddLands() {
int red = 0; int red = 0;
int green = 0; int green = 0;
int black = 0; int black = 0;
@ -324,7 +333,9 @@ public class AddLandDialog extends MageDialog {
int white = 0; int white = 0;
Set<Card> cards = deck.getCards(); Set<Card> cards = deck.getCards();
int land_number = DEFAULT_SEALED_DECK_CARD_NUMBER - cards.size(); int land_number = DEFAULT_SEALED_DECK_CARD_NUMBER - cards.size();
if(land_number < 0) land_number = 0; if (land_number < 0) {
land_number = 0;
}
for (Card cd : cards) { for (Card cd : cards) {
Mana m = cd.getManaCost().getMana(); Mana m = cd.getManaCost().getMana();
red += m.getRed(); red += m.getRed();
@ -334,14 +345,18 @@ public class AddLandDialog extends MageDialog {
white += m.getWhite(); white += m.getWhite();
} }
int total = red + green + black + blue + white; int total = red + green + black + blue + white;
int redcards = Math.round(land_number*((float)red/(float)total)); int redcards = Math.round(land_number * ((float) red / (float) total));
total -= red; land_number -= redcards; total -= red;
int greencards = Math.round(land_number*((float)green/(float)total)); land_number -= redcards;
total -= green; land_number -= greencards; int greencards = Math.round(land_number * ((float) green / (float) total));
int blackcards = Math.round(land_number*((float)black/(float)total)); total -= green;
total -= black; land_number -= blackcards; land_number -= greencards;
int bluecards = Math.round(land_number*((float)blue/(float)total)); int blackcards = Math.round(land_number * ((float) black / (float) total));
total -= blue; land_number -= bluecards; total -= black;
land_number -= blackcards;
int bluecards = Math.round(land_number * ((float) blue / (float) total));
total -= blue;
land_number -= bluecards;
int whitecards = land_number; int whitecards = land_number;
spnMountain.setValue(redcards); spnMountain.setValue(redcards);
spnForest.setValue(greencards); spnForest.setValue(greencards);

View file

@ -112,6 +112,25 @@ public class CardInfoWindowDialog extends MageDialog {
cards.cleanUp(); cards.cleanUp();
} }
public void loadCards(ExileView exile, BigCard bigCard, UUID gameId) {
boolean changed = cards.loadCards(exile, bigCard, gameId, null);
String titel = name + " (" + exile.size() + ")";
setTitle(titel);
this.setTitelBarToolTip(titel);
if (exile.size() > 0) {
show();
if (changed) {
try {
this.setIcon(false);
} catch (PropertyVetoException ex) {
Logger.getLogger(CardInfoWindowDialog.class.getName()).log(Level.SEVERE, null, ex);
}
}
} else {
this.hideDialog();
}
}
public void loadCards(SimpleCardsView showCards, BigCard bigCard, UUID gameId) { public void loadCards(SimpleCardsView showCards, BigCard bigCard, UUID gameId) {
cards.loadCards(showCards, bigCard, gameId); cards.loadCards(showCards, bigCard, gameId);
showAndPositionWindow(); showAndPositionWindow();
@ -120,8 +139,9 @@ public class CardInfoWindowDialog extends MageDialog {
public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) { public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) {
cards.loadCards(showCards, bigCard, gameId, null); cards.loadCards(showCards, bigCard, gameId, null);
if (showType.equals(ShowType.GRAVEYARD)) { if (showType.equals(ShowType.GRAVEYARD)) {
setTitle(name + "'s Graveyard (" + showCards.size() + ")"); String titel = name + "'s Graveyard (" + showCards.size() + ")";
this.setTitelBarToolTip(name); setTitle(titel);
this.setTitelBarToolTip(titel);
} }
showAndPositionWindow(); showAndPositionWindow();
} }
@ -160,22 +180,6 @@ public class CardInfoWindowDialog extends MageDialog {
}); });
} }
public void loadCards(ExileView exile, BigCard bigCard, UUID gameId) {
boolean changed = cards.loadCards(exile, bigCard, gameId, null);
if (exile.size() > 0) {
show();
if (changed) {
try {
this.setIcon(false);
} catch (PropertyVetoException ex) {
Logger.getLogger(CardInfoWindowDialog.class.getName()).log(Level.SEVERE, null, ex);
}
}
} else {
this.hideDialog();
}
}
/** /**
* This method is called from within the constructor to initialize the form. * 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 * WARNING: Do NOT modify this code. The content of this method is always

View file

@ -40,6 +40,7 @@ import java.awt.EventQueue;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.MenuComponent; import java.awt.MenuComponent;
import java.awt.TrayIcon; import java.awt.TrayIcon;
import java.awt.event.InvocationEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -119,10 +120,10 @@ public class MageDialog extends javax.swing.JInternalFrame {
Object source = event.getSource(); Object source = event.getSource();
boolean dispatch = true; boolean dispatch = true;
if (event.getSource() != null && event.getSource() instanceof TrayIcon) { // https://github.com/magefree/mage/issues/584 - Let's hope this will fix the Linux window problem
if (event.getSource() != null && event.getSource() instanceof TrayIcon && !(event instanceof InvocationEvent)) {
return; return;
} }
if (event instanceof MouseEvent && event.getSource() instanceof Component) { if (event instanceof MouseEvent && event.getSource() instanceof Component) {
MouseEvent e = (MouseEvent) event; MouseEvent e = (MouseEvent) event;
MouseEvent m = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, this); MouseEvent m = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, this);
@ -226,7 +227,6 @@ public class MageDialog extends javax.swing.JInternalFrame {
pack(); pack();
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View file

@ -35,17 +35,15 @@
package mage.client.dialog; package mage.client.dialog;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.swing.ComboBoxModel; import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel; import javax.swing.JButton;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JScrollPane; import javax.swing.JTextArea;
import static javax.swing.ListSelectionModel.SINGLE_SELECTION;
import javax.swing.SpinnerNumberModel; import javax.swing.SpinnerNumberModel;
import mage.cards.decks.importer.DeckImporterUtil; import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.repository.ExpansionInfo; import mage.cards.repository.ExpansionInfo;
@ -80,12 +78,12 @@ public class NewTournamentDialog extends MageDialog {
private UUID roomId; private UUID roomId;
private final Session session; private final Session session;
private String lastSessionId; private String lastSessionId;
private JList randomList = new JList(); private RandomPacksSelectorDialog randomPackSelector;
private JTextArea txtRandomPacks;
private final List<TournamentPlayerPanel> players = new ArrayList<>(); private final List<TournamentPlayerPanel> players = new ArrayList<>();
private final List<JComboBox> packs = new ArrayList<>(); private final List<JComboBox> packs = new ArrayList<>();
private final int CONSTRUCTION_TIME_MIN = 6; private final int CONSTRUCTION_TIME_MIN = 6;
private final int CONSTRUCTION_TIME_MAX = 30; private final int CONSTRUCTION_TIME_MAX = 30;
private final String randomDraftDescription = ("The selected packs will be randomly distributed to players. Each player may open different packs. Duplicates will be avoided.");
private boolean automaticChange = false; private boolean automaticChange = false;
@ -534,15 +532,8 @@ public class NewTournamentDialog extends MageDialog {
if (tournamentType.isCubeBooster()) { if (tournamentType.isCubeBooster()) {
tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString()); tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString());
} else if (tournamentType.isRandom()) { } else if (tournamentType.isRandom()) {
for (Object pack : randomList.getSelectedValuesList()) { tOptions.getLimitedOptions().getSetCodes().clear();
String packStr = (String) pack; tOptions.getLimitedOptions().getSetCodes().addAll(randomPackSelector.getSelectedPacks());
String code = packStr.substring(0, 3);
tOptions.getLimitedOptions().getSetCodes().add(code);
}
if (tOptions.getLimitedOptions().getSetCodes().size() < 2) {
// At least two sets must be chosen.
return;
}
} else { } else {
for (JComboBox pack: packs) { for (JComboBox pack: packs) {
tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode()); tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode());
@ -724,60 +715,54 @@ public class NewTournamentDialog extends MageDialog {
private void createRandomPacks() { private void createRandomPacks() {
if (pnlRandomPacks.getComponentCount() == 0) { if (pnlRandomPacks.getComponentCount() == 0) {
if (randomPackSelector == null) {
DefaultListModel randomListModel = new DefaultListModel(); randomPackSelector = new RandomPacksSelectorDialog();
randomList = new JList(randomListModel);
randomList.setToolTipText(randomDraftDescription);
ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate();
for (ExpansionInfo expansion : allExpansions) {
String exp = expansion.getCode() + " - " + expansion.getName();
randomListModel.addElement(exp);
} }
randomList.setSelectionModel(new DefaultListSelectionModel() { txtRandomPacks = new JTextArea();
private boolean mGestureStarted; txtRandomPacks.setEnabled(false);
txtRandomPacks.setLineWrap(true);
@Override
public void setSelectionInterval(int index0, int index1) {
// Toggle only one element while the user is dragging the mouse
if (!mGestureStarted) {
if (isSelectedIndex(index0)) {
super.removeSelectionInterval(index0, index1);
} else {
if (getSelectionMode() == SINGLE_SELECTION) {
super.setSelectionInterval(index0, index1);
} else {
super.addSelectionInterval(index0, index1);
}
}
}
// Disable toggling till the adjusting is over, or keep it
// enabled in case setSelectionInterval was called directly.
mGestureStarted = getValueIsAdjusting();
}
@Override
public void setValueIsAdjusting(boolean isAdjusting) {
super.setValueIsAdjusting(isAdjusting);
if (isAdjusting == false) {
// Enable toggling
mGestureStarted = false;
}
}
});
String randomPrefs = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT, ""); String randomPrefs = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT, "");
if (randomPrefs.length() > 0) { if (randomPrefs.length() > 0) {
for (String exp : randomPrefs.split(";")) { txtRandomPacks.setText(randomPrefs);
randomList.setSelectedValue(exp, false); ArrayList<String> theList = new ArrayList<>();
} theList.addAll(Arrays.asList(randomPrefs.split(";")));
randomPackSelector.setSelectedPacks(theList);
} else { } else {
randomList.setSelectionInterval(0, randomListModel.size() - 1); ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate();
StringBuilder packList = new StringBuilder();
for (ExpansionInfo exp : allExpansions) {
packList.append(exp.getCode());
packList.append(";");
}
txtRandomPacks.setText(packList.toString());
} }
JScrollPane list1scr = new JScrollPane(randomList);
randomList.setVisibleRowCount(4); pnlRandomPacks.add(txtRandomPacks);
pnlRandomPacks.add(list1scr); JButton btnSelectRandomPacks = new JButton();
btnSelectRandomPacks.setText("Select packs to be included in the pool");
btnSelectRandomPacks.setToolTipText(RandomPacksSelectorDialog.randomDraftDescription);
btnSelectRandomPacks.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
showRandomPackSelectorDialog();
}
});
pnlRandomPacks.add(btnSelectRandomPacks);
}
this.pack();
this.revalidate();
this.repaint();
}
private void showRandomPackSelectorDialog() {
randomPackSelector.showDialog();
StringBuilder packList = new StringBuilder();
for (String str : randomPackSelector.getSelectedPacks()) {
packList.append(str);
packList.append(";");
} }
this.txtRandomPacks.setText(packList.toString());
this.pack(); this.pack();
this.revalidate(); this.revalidate();
this.repaint(); this.repaint();
@ -1006,8 +991,8 @@ public class NewTournamentDialog extends MageDialog {
if (tOptions.getLimitedOptions().getIsRandom()){ if (tOptions.getLimitedOptions().getIsRandom()){
// save random boosters to prefs // save random boosters to prefs
StringBuilder packlist = new StringBuilder(); StringBuilder packlist = new StringBuilder();
for (Object pack: randomList.getSelectedValuesList()){ for (String pack : this.randomPackSelector.getSelectedPacks()){
packlist.append((String)pack); packlist.append(pack);
packlist.append(";"); packlist.append(";");
} }
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT, packlist.toString()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT, packlist.toString());

View file

@ -155,7 +155,7 @@
<Component class="javax.swing.JCheckBox" name="showToolTipsInAnyZone"> <Component class="javax.swing.JCheckBox" name="showToolTipsInAnyZone">
<Properties> <Properties>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Show card tooltips while hoovering with the mouse pointer over a card"/> <Property name="text" type="java.lang.String" value="Show card tooltips while hovering with the mouse pointer over a card"/>
<Property name="toolTipText" type="java.lang.String" value=""/> <Property name="toolTipText" type="java.lang.String" value=""/>
<Property name="actionCommand" type="java.lang.String" value=""/> <Property name="actionCommand" type="java.lang.String" value=""/>
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor"> <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
@ -253,7 +253,7 @@
<Properties> <Properties>
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Show player names on avatar permanently"/> <Property name="text" type="java.lang.String" value="Show player names on avatar permanently"/>
<Property name="toolTipText" type="java.lang.String" value="Instead showing the names only if you hoover over the avatar with the mouse, the name is shown all the time."/> <Property name="toolTipText" type="java.lang.String" value="Instead showing the names only if you hover over the avatar with the mouse, the name is shown all the time."/>
<Property name="horizontalAlignment" type="int" value="2"/> <Property name="horizontalAlignment" type="int" value="2"/>
</Properties> </Properties>
<Events> <Events>
@ -1150,21 +1150,21 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="590" max="32767" attributes="0"/> <Component id="avatarPane" alignment="0" pref="590" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="359" max="32767" attributes="0"/> <Component id="avatarPane" alignment="0" pref="359" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> <Container class="javax.swing.JScrollPane" name="avatarPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="jPanel9"> <Container class="javax.swing.JPanel" name="avatarPanel">
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
@ -1256,6 +1256,14 @@
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JLabel" name="jLabel12">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" value="Choose your avatar:"/>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="jPanel10"> <Container class="javax.swing.JPanel" name="jPanel10">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
@ -1328,14 +1336,6 @@
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
</Container> </Container>
<Component class="javax.swing.JLabel" name="jLabel12">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" value="Choose your avatar:"/>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="jPanel12"> <Container class="javax.swing.JPanel" name="jPanel12">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">

View file

@ -1,30 +1,30 @@
/* /*
* Copyright 2011 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 * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* PreferencesDialog.java * PreferencesDialog.java
@ -63,10 +63,11 @@ import mage.client.MageFrame;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder; import mage.client.util.gui.BufferedImageBuilder;
import mage.players.net.UserData;
import mage.players.net.UserGroup;
import mage.players.net.UserSkipPrioritySteps; import mage.players.net.UserSkipPrioritySteps;
import mage.remote.Connection; import mage.remote.Connection;
import mage.remote.Connection.ProxyType; import mage.remote.Connection.ProxyType;
import mage.view.UserDataView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
@ -112,7 +113,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_BIG_CARD_TOGGLED = "bigCardToggled"; public static final String KEY_BIG_CARD_TOGGLED = "bigCardToggled";
// Phases // Phases
public static final String UPKEEP_YOU = "upkeepYou"; public static final String UPKEEP_YOU = "upkeepYou";
public static final String DRAW_YOU = "drawYou"; public static final String DRAW_YOU = "drawYou";
@ -155,11 +155,20 @@ public class PreferencesDialog extends javax.swing.JDialog {
// user list // user list
public static final String KEY_USERS_COLUMNS_WIDTH = "userPanelColumnWidth"; public static final String KEY_USERS_COLUMNS_WIDTH = "userPanelColumnWidth";
public static final String KEY_USERS_COLUMNS_ORDER = "userPanelColumnSort"; public static final String KEY_USERS_COLUMNS_ORDER = "userPanelColumnSort";
// table waiting dialog
public static final String KEY_TABLE_WAITING_WIDTH = "tableWaitingPanelWidth";
public static final String KEY_TABLE_WAITING_HEIGHT = "tableWaitingPanelHeight";
public static final String KEY_TABLE_WAITING_COLUMNS_WIDTH = "tableWaitingPanelColumnWidth";
public static final String KEY_TABLE_WAITING_COLUMNS_ORDER = "tableWaitingPanelColumnSort";
public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_0 = "gamepanelDividerLocation0"; public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_0 = "gamepanelDividerLocation0";
public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_1 = "gamepanelDividerLocation1"; public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_1 = "gamepanelDividerLocation1";
public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_2 = "gamepanelDividerLocation2"; public static final String KEY_GAMEPANEL_DIVIDER_LOCATION_2 = "gamepanelDividerLocation2";
public static final String KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH = "tournamentPlayerPanelColumnWidth";
public static final String KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER = "tournamentPlayerPanelColumnSort";
public static final String KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH = "tournamentMatchPanelColumnWidth";
public static final String KEY_TOURNAMENT_MATCH_COLUMNS_ORDER = "tournamentMatchPanelColumnSort";
public static final String KEY_TOURNAMENT_DIVIDER_LOCATION_1 = "tournamentPanelDividerLocation1"; public static final String KEY_TOURNAMENT_DIVIDER_LOCATION_1 = "tournamentPanelDividerLocation1";
public static final String KEY_TOURNAMENT_DIVIDER_LOCATION_2 = "tournamentPanelDividerLocation2"; public static final String KEY_TOURNAMENT_DIVIDER_LOCATION_2 = "tournamentPanelDividerLocation2";
@ -238,7 +247,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_CONNECT_AUTO_CONNECT = "autoConnect"; public static final String KEY_CONNECT_AUTO_CONNECT = "autoConnect";
public static final String KEY_CONNECT_FLAG = "connectFlag"; public static final String KEY_CONNECT_FLAG = "connectFlag";
private static final Map<String, String> cache = new HashMap<>(); private static final Map<String, String> cache = new HashMap<>();
private static final Boolean UPDATE_CACHE_POLICY = Boolean.TRUE; private static final Boolean UPDATE_CACHE_POLICY = Boolean.TRUE;
@ -280,23 +288,24 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
private final JFileChooser fc_i = new JFileChooser(); private final JFileChooser fc_i = new JFileChooser();
{ {
fc_i.setAcceptAllFileFilterUsed(false); fc_i.setAcceptAllFileFilterUsed(false);
fc_i.addChoosableFileFilter(new ImageFileFilter()); fc_i.addChoosableFileFilter(new ImageFileFilter());
} }
private static class ImageFileFilter extends FileFilter{ private static class ImageFileFilter extends FileFilter {
@Override @Override
public boolean accept(File f) { public boolean accept(File f) {
String filename = f.getName(); String filename = f.getName();
if(f.isDirectory()){ if (f.isDirectory()) {
return true; return true;
} }
if(filename != null){ if (filename != null) {
if(filename.endsWith(".jpg") || filename.endsWith(".jpeg") || if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")
filename.endsWith(".png") || filename.endsWith(".bmp")){ || filename.endsWith(".png") || filename.endsWith(".bmp")) {
return true; return true;
} }
} }
return false; return false;
@ -304,12 +313,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
@Override @Override
public String getDescription() { public String getDescription() {
return "*.png | *.bmp |*.jpg | *.jpeg"; return "*.png | *.bmp |*.jpg | *.jpeg";
} }
} }
/** /**
* Creates new form PreferencesDialog * Creates new form PreferencesDialog
* *
@ -323,14 +330,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbProxyType.setModel(new DefaultComboBoxModel<>(Connection.ProxyType.values())); cbProxyType.setModel(new DefaultComboBoxModel<>(Connection.ProxyType.values()));
addAvatars(); addAvatars();
cbPreferedImageLanguage.setModel(new DefaultComboBoxModel<>(new String[] {"en","de","fr","it","es","pt","jp","cn","ru","tw","ko"})); cbPreferedImageLanguage.setModel(new DefaultComboBoxModel<>(new String[]{"en", "de", "fr", "it", "es", "pt", "jp", "cn", "ru", "tw", "ko"}));
} }
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -413,12 +420,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
txtBattlefieldIBGMPath = new javax.swing.JTextField(); txtBattlefieldIBGMPath = new javax.swing.JTextField();
btnBattlefieldBGMBrowse = new javax.swing.JButton(); btnBattlefieldBGMBrowse = new javax.swing.JButton();
tabAvatars = new javax.swing.JPanel(); tabAvatars = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane(); avatarPane = new javax.swing.JScrollPane();
jPanel9 = new javax.swing.JPanel(); avatarPanel = new javax.swing.JPanel();
jLabel12 = new javax.swing.JLabel();
jPanel10 = new javax.swing.JPanel(); jPanel10 = new javax.swing.JPanel();
jPanel13 = new javax.swing.JPanel(); jPanel13 = new javax.swing.JPanel();
jPanel11 = new javax.swing.JPanel(); jPanel11 = new javax.swing.JPanel();
jLabel12 = new javax.swing.JLabel();
jPanel12 = new javax.swing.JPanel(); jPanel12 = new javax.swing.JPanel();
jPanel14 = new javax.swing.JPanel(); jPanel14 = new javax.swing.JPanel();
jPanel15 = new javax.swing.JPanel(); jPanel15 = new javax.swing.JPanel();
@ -467,7 +474,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
}); });
showToolTipsInAnyZone.setSelected(true); showToolTipsInAnyZone.setSelected(true);
showToolTipsInAnyZone.setText("Show card tooltips while hoovering with the mouse pointer over a card"); showToolTipsInAnyZone.setText("Show card tooltips while hovering with the mouse pointer over a card");
showToolTipsInAnyZone.setToolTipText(""); showToolTipsInAnyZone.setToolTipText("");
showToolTipsInAnyZone.setActionCommand(""); showToolTipsInAnyZone.setActionCommand("");
showToolTipsInAnyZone.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); showToolTipsInAnyZone.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
@ -526,7 +533,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
showPlayerNamesPermanently.setSelected(true); showPlayerNamesPermanently.setSelected(true);
showPlayerNamesPermanently.setText("Show player names on avatar permanently"); showPlayerNamesPermanently.setText("Show player names on avatar permanently");
showPlayerNamesPermanently.setToolTipText("Instead showing the names only if you hoover over the avatar with the mouse, the name is shown all the time."); showPlayerNamesPermanently.setToolTipText("Instead showing the names only if you hover over the avatar with the mouse, the name is shown all the time.");
showPlayerNamesPermanently.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); showPlayerNamesPermanently.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
showPlayerNamesPermanently.addActionListener(new java.awt.event.ActionListener() { showPlayerNamesPermanently.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -1183,6 +1190,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Sounds", tabSounds); tabsPanel.addTab("Sounds", tabSounds);
jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
jLabel12.setText("Choose your avatar:");
jPanel10.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); jPanel10.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10); javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10);
@ -1222,9 +1232,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGap(0, 100, Short.MAX_VALUE) .addGap(0, 100, Short.MAX_VALUE)
); );
jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
jLabel12.setText("Choose your avatar:");
jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12); javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12);
@ -1345,68 +1352,68 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGap(0, 100, Short.MAX_VALUE) .addGap(0, 100, Short.MAX_VALUE)
); );
javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9); javax.swing.GroupLayout avatarPanelLayout = new javax.swing.GroupLayout(avatarPanel);
jPanel9.setLayout(jPanel9Layout); avatarPanel.setLayout(avatarPanelLayout);
jPanel9Layout.setHorizontalGroup( avatarPanelLayout.setHorizontalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jLabel12)) .addComponent(jLabel12))
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGap(30, 30, 30) .addGap(30, 30, 30)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel19, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel19, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(33, 33, 33) .addGap(33, 33, 33)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGap(20, 20, 20) .addGap(20, 20, 20)
.addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(33, 33, 33) .addGap(33, 33, 33)
.addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jLabel13)))) .addComponent(jLabel13))))
.addGap(32, 32, 32) .addGap(32, 32, 32)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
jPanel9Layout.setVerticalGroup( avatarPanelLayout.setVerticalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jLabel12) .addComponent(jLabel12)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(26, 26, 26) .addGap(26, 26, 26)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(23, 23, 23) .addGap(23, 23, 23)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jPanel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addComponent(jLabel13) .addComponent(jLabel13)
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
@ -1415,17 +1422,17 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGap(25, 25, 25)) .addGap(25, 25, 25))
); );
jScrollPane1.setViewportView(jPanel9); avatarPane.setViewportView(avatarPanel);
javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars); javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars);
tabAvatars.setLayout(tabAvatarsLayout); tabAvatars.setLayout(tabAvatarsLayout);
tabAvatarsLayout.setHorizontalGroup( tabAvatarsLayout.setHorizontalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 590, Short.MAX_VALUE) .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 590, Short.MAX_VALUE)
); );
tabAvatarsLayout.setVerticalGroup( tabAvatarsLayout.setVerticalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE)
); );
tabsPanel.addTab("Avatars", tabAvatars); tabsPanel.addTab("Avatars", tabAvatars);
@ -1803,30 +1810,30 @@ public class PreferencesDialog extends javax.swing.JDialog {
}//GEN-LAST:event_cbEnableGameSoundsActionPerformed }//GEN-LAST:event_cbEnableGameSoundsActionPerformed
private void cbEnableBattlefieldBGMActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbEnableBattlefieldBGMActionPerformed private void cbEnableBattlefieldBGMActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbEnableBattlefieldBGMActionPerformed
if(cbEnableBattlefieldBGM.isSelected()){ if (cbEnableBattlefieldBGM.isSelected()) {
txtBattlefieldIBGMPath.setEnabled(true); txtBattlefieldIBGMPath.setEnabled(true);
btnBattlefieldBGMBrowse.setEnabled(true); btnBattlefieldBGMBrowse.setEnabled(true);
}else{ } else {
txtBattlefieldIBGMPath.setEnabled(false); txtBattlefieldIBGMPath.setEnabled(false);
btnBattlefieldBGMBrowse.setEnabled(false); btnBattlefieldBGMBrowse.setEnabled(false);
} }
}//GEN-LAST:event_cbEnableBattlefieldBGMActionPerformed }//GEN-LAST:event_cbEnableBattlefieldBGMActionPerformed
private void cbUseDefaultBackgroundActionPerformed(java.awt.event.ActionEvent evt) { private void cbUseDefaultBackgroundActionPerformed(java.awt.event.ActionEvent evt) {
if(cbUseDefaultBackground.isSelected()){ if (cbUseDefaultBackground.isSelected()) {
useDefaultBackgroundImage(); useDefaultBackgroundImage();
}else{ } else {
useSelectBackgroundImage(); useSelectBackgroundImage();
} }
} }
private void useDefaultBackgroundImage(){ private void useDefaultBackgroundImage() {
txtBackgroundImagePath.setEnabled(false); txtBackgroundImagePath.setEnabled(false);
btnBrowseBackgroundImage.setEnabled(false); btnBrowseBackgroundImage.setEnabled(false);
txtBackgroundImagePath.setText(""); txtBackgroundImagePath.setText("");
} }
private void useSelectBackgroundImage(){ private void useSelectBackgroundImage() {
String path = cache.get(KEY_BACKGROUND_IMAGE); String path = cache.get(KEY_BACKGROUND_IMAGE);
dialog.txtBackgroundImagePath.setText(path); dialog.txtBackgroundImagePath.setText(path);
txtBackgroundImagePath.setEnabled(true); txtBackgroundImagePath.setEnabled(true);
@ -1834,50 +1841,50 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
private void cbUseDefaultBattleImageActionPerformed(java.awt.event.ActionEvent evt) { private void cbUseDefaultBattleImageActionPerformed(java.awt.event.ActionEvent evt) {
if(cbUseDefaultBattleImage.isSelected()){ if (cbUseDefaultBattleImage.isSelected()) {
useDefaultBattlefield(); useDefaultBattlefield();
}else{ } else {
useSelectedOrRandom(); useSelectedOrRandom();
} }
} }
private void useDefaultBattlefield(){ private void useDefaultBattlefield() {
cbUseRandomBattleImage.setEnabled(false); cbUseRandomBattleImage.setEnabled(false);
txtBattlefieldImagePath.setEnabled(false); txtBattlefieldImagePath.setEnabled(false);
btnBrowseBattlefieldImage.setEnabled(false); btnBrowseBattlefieldImage.setEnabled(false);
} }
private void useSelectedOrRandom(){ private void useSelectedOrRandom() {
cbUseRandomBattleImage.setEnabled(true); cbUseRandomBattleImage.setEnabled(true);
String temp = cache.get(KEY_BATTLEFIELD_IMAGE_RANDOM); String temp = cache.get(KEY_BATTLEFIELD_IMAGE_RANDOM);
if(temp != null){ if (temp != null) {
if(temp.equals("true")){ if (temp.equals("true")) {
useRandomBattleField(); useRandomBattleField();
cbUseRandomBattleImage.setSelected(true); cbUseRandomBattleImage.setSelected(true);
}else{ } else {
useSelectedBattleField(); useSelectedBattleField();
cbUseRandomBattleImage.setSelected(false); cbUseRandomBattleImage.setSelected(false);
} }
}else{ } else {
useSelectedBattleField(); useSelectedBattleField();
cbUseRandomBattleImage.setSelected(false); cbUseRandomBattleImage.setSelected(false);
} }
} }
private void cbUseRandomBattleImageActionPerformed(java.awt.event.ActionEvent evt) { private void cbUseRandomBattleImageActionPerformed(java.awt.event.ActionEvent evt) {
if(cbUseRandomBattleImage.isSelected()){ if (cbUseRandomBattleImage.isSelected()) {
useRandomBattleField(); useRandomBattleField();
}else{ } else {
useSelectedBattleField(); useSelectedBattleField();
} }
} }
private void useRandomBattleField(){ private void useRandomBattleField() {
txtBattlefieldImagePath.setEnabled(false); txtBattlefieldImagePath.setEnabled(false);
btnBrowseBattlefieldImage.setEnabled(false); btnBrowseBattlefieldImage.setEnabled(false);
} }
private void useSelectedBattleField(){ private void useSelectedBattleField() {
txtBattlefieldImagePath.setEnabled(true); txtBattlefieldImagePath.setEnabled(true);
btnBrowseBattlefieldImage.setEnabled(true); btnBrowseBattlefieldImage.setEnabled(true);
} }
@ -1995,12 +2002,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) { if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) {
this.pnlProxy.setVisible(true); this.pnlProxy.setVisible(true);
this.pnlProxySettings.setVisible(true); this.pnlProxySettings.setVisible(true);
} } else if (cbProxyType.getSelectedItem() == Connection.ProxyType.HTTP) {
else if (cbProxyType.getSelectedItem() == Connection.ProxyType.HTTP) {
this.pnlProxy.setVisible(true); this.pnlProxy.setVisible(true);
this.pnlProxySettings.setVisible(true); this.pnlProxySettings.setVisible(true);
} } else if (cbProxyType.getSelectedItem() == Connection.ProxyType.NONE) {
else if (cbProxyType.getSelectedItem() == Connection.ProxyType.NONE) {
this.pnlProxy.setVisible(false); this.pnlProxy.setVisible(false);
this.pnlProxySettings.setVisible(false); this.pnlProxySettings.setVisible(false);
} }
@ -2059,7 +2064,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
private static void loadPhases(Preferences prefs) { private static void loadPhases(Preferences prefs) {
load(prefs, dialog.displayBigCardsInHand, KEY_HAND_USE_BIG_CARDS, "true","true"); load(prefs, dialog.displayBigCardsInHand, KEY_HAND_USE_BIG_CARDS, "true", "true");
load(prefs, dialog.showToolTipsInAnyZone, KEY_SHOW_TOOLTIPS_ANY_ZONE, "true"); load(prefs, dialog.showToolTipsInAnyZone, KEY_SHOW_TOOLTIPS_ANY_ZONE, "true");
load(prefs, dialog.showCardName, KEY_SHOW_CARD_NAMES, "true"); load(prefs, dialog.showCardName, KEY_SHOW_CARD_NAMES, "true");
load(prefs, dialog.nonLandPermanentsInOnePile, KEY_PERMANENTS_IN_ONE_PILE, "true"); load(prefs, dialog.nonLandPermanentsInOnePile, KEY_PERMANENTS_IN_ONE_PILE, "true");
@ -2072,21 +2077,21 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true"); load(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true");
load(prefs, dialog.checkBoxUpkeepYou, UPKEEP_YOU, "on","on"); load(prefs, dialog.checkBoxUpkeepYou, UPKEEP_YOU, "on", "on");
load(prefs, dialog.checkBoxDrawYou, DRAW_YOU, "on","on"); load(prefs, dialog.checkBoxDrawYou, DRAW_YOU, "on", "on");
load(prefs, dialog.checkBoxMainYou, MAIN_YOU, "on","on"); load(prefs, dialog.checkBoxMainYou, MAIN_YOU, "on", "on");
load(prefs, dialog.checkBoxBeforeCYou, BEFORE_COMBAT_YOU, "on","on"); load(prefs, dialog.checkBoxBeforeCYou, BEFORE_COMBAT_YOU, "on", "on");
load(prefs, dialog.checkBoxEndOfCYou, END_OF_COMBAT_YOU, "on","on"); load(prefs, dialog.checkBoxEndOfCYou, END_OF_COMBAT_YOU, "on", "on");
load(prefs, dialog.checkBoxMain2You, MAIN_2_YOU, "on","on"); load(prefs, dialog.checkBoxMain2You, MAIN_2_YOU, "on", "on");
load(prefs, dialog.checkBoxEndTurnYou, END_OF_TURN_YOU, "on","on"); load(prefs, dialog.checkBoxEndTurnYou, END_OF_TURN_YOU, "on", "on");
load(prefs, dialog.checkBoxUpkeepOthers, UPKEEP_OTHERS, "on","on"); load(prefs, dialog.checkBoxUpkeepOthers, UPKEEP_OTHERS, "on", "on");
load(prefs, dialog.checkBoxDrawOthers, DRAW_OTHERS, "on","on"); load(prefs, dialog.checkBoxDrawOthers, DRAW_OTHERS, "on", "on");
load(prefs, dialog.checkBoxMainOthers, MAIN_OTHERS, "on","on"); load(prefs, dialog.checkBoxMainOthers, MAIN_OTHERS, "on", "on");
load(prefs, dialog.checkBoxBeforeCOthers, BEFORE_COMBAT_OTHERS, "on","on"); load(prefs, dialog.checkBoxBeforeCOthers, BEFORE_COMBAT_OTHERS, "on", "on");
load(prefs, dialog.checkBoxEndOfCOthers, END_OF_COMBAT_OTHERS, "on","on"); load(prefs, dialog.checkBoxEndOfCOthers, END_OF_COMBAT_OTHERS, "on", "on");
load(prefs, dialog.checkBoxMain2Others, MAIN_2_OTHERS, "on","on"); load(prefs, dialog.checkBoxMain2Others, MAIN_2_OTHERS, "on", "on");
load(prefs, dialog.checkBoxEndTurnOthers, END_OF_TURN_OTHERS, "on","on"); load(prefs, dialog.checkBoxEndTurnOthers, END_OF_TURN_OTHERS, "on", "on");
load(prefs, dialog.cbStopAttack, KEY_STOP_ATTACK, "true", "true"); load(prefs, dialog.cbStopAttack, KEY_STOP_ATTACK, "true", "true");
load(prefs, dialog.cbStopBlock, KEY_STOP_BLOCK, "true", "true"); load(prefs, dialog.cbStopBlock, KEY_STOP_BLOCK, "true", "true");
@ -2113,10 +2118,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
//add background load precedure //add background load precedure
prop = prefs.get(KEY_BACKGROUND_IMAGE_DEFAULT, "true"); prop = prefs.get(KEY_BACKGROUND_IMAGE_DEFAULT, "true");
if(prop.equals("true")){ if (prop.equals("true")) {
dialog.cbUseDefaultBackground.setSelected(true); dialog.cbUseDefaultBackground.setSelected(true);
dialog.useDefaultBackgroundImage(); dialog.useDefaultBackgroundImage();
}else{ } else {
dialog.cbUseDefaultBackground.setSelected(false); dialog.cbUseDefaultBackground.setSelected(false);
dialog.useSelectBackgroundImage(); dialog.useSelectBackgroundImage();
String path = prefs.get(KEY_BACKGROUND_IMAGE, ""); String path = prefs.get(KEY_BACKGROUND_IMAGE, "");
@ -2124,20 +2129,20 @@ public class PreferencesDialog extends javax.swing.JDialog {
updateCache(KEY_BACKGROUND_IMAGE, path); updateCache(KEY_BACKGROUND_IMAGE, path);
} }
prop = prefs.get(KEY_BATTLEFIELD_IMAGE_DEFAULT, "true"); prop = prefs.get(KEY_BATTLEFIELD_IMAGE_DEFAULT, "true");
if(prop.equals("true")){ if (prop.equals("true")) {
dialog.cbUseDefaultBattleImage.setSelected(true); dialog.cbUseDefaultBattleImage.setSelected(true);
dialog.useDefaultBattlefield(); dialog.useDefaultBattlefield();
}else{ } else {
dialog.cbUseDefaultBattleImage.setSelected(false); dialog.cbUseDefaultBattleImage.setSelected(false);
dialog.useSelectedOrRandom(); dialog.useSelectedOrRandom();
} }
prop = prefs.get(KEY_BATTLEFIELD_IMAGE_RANDOM, "true"); prop = prefs.get(KEY_BATTLEFIELD_IMAGE_RANDOM, "true");
if(dialog.cbUseRandomBattleImage.isEnabled()) { if (dialog.cbUseRandomBattleImage.isEnabled()) {
if(prop.equals("true")){ if (prop.equals("true")) {
dialog.cbUseRandomBattleImage.setSelected(true); dialog.cbUseRandomBattleImage.setSelected(true);
dialog.useRandomBattleField(); dialog.useRandomBattleField();
}else{ } else {
dialog.cbUseRandomBattleImage.setSelected(false); dialog.cbUseRandomBattleImage.setSelected(false);
dialog.useSelectedBattleField(); dialog.useSelectedBattleField();
String path = prefs.get(KEY_BATTLEFIELD_IMAGE, ""); String path = prefs.get(KEY_BATTLEFIELD_IMAGE, "");
@ -2235,7 +2240,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
} }
private static void saveImagesPath(Preferences prefs) { private static void saveImagesPath(Preferences prefs) {
if (!dialog.cbUseDefaultImageFolder.isSelected()) { if (!dialog.cbUseDefaultImageFolder.isSelected()) {
String path = dialog.txtImageFolderPath.getText(); String path = dialog.txtImageFolderPath.getText();
@ -2243,19 +2247,19 @@ public class PreferencesDialog extends javax.swing.JDialog {
updateCache(KEY_CARD_IMAGES_PATH, path); updateCache(KEY_CARD_IMAGES_PATH, path);
} }
// background path save precedure // background path save precedure
if(!dialog.cbUseDefaultBackground.isSelected()){ if (!dialog.cbUseDefaultBackground.isSelected()) {
String path = dialog.txtBackgroundImagePath.getText(); String path = dialog.txtBackgroundImagePath.getText();
prefs.put(KEY_BACKGROUND_IMAGE, path); prefs.put(KEY_BACKGROUND_IMAGE, path);
updateCache(KEY_BACKGROUND_IMAGE, path); updateCache(KEY_BACKGROUND_IMAGE, path);
} }
if(!dialog.cbUseDefaultBattleImage.isSelected() && !dialog.cbUseRandomBattleImage.isSelected()){ if (!dialog.cbUseDefaultBattleImage.isSelected() && !dialog.cbUseRandomBattleImage.isSelected()) {
String path = dialog.txtBattlefieldImagePath.getText(); String path = dialog.txtBattlefieldImagePath.getText();
prefs.put(KEY_BATTLEFIELD_IMAGE, path); prefs.put(KEY_BATTLEFIELD_IMAGE, path);
updateCache(KEY_BATTLEFIELD_IMAGE, path); updateCache(KEY_BATTLEFIELD_IMAGE, path);
} }
} }
private static void saveSoundPath(Preferences prefs){ private static void saveSoundPath(Preferences prefs) {
String path = dialog.txtBattlefieldIBGMPath.getText(); String path = dialog.txtBattlefieldIBGMPath.getText();
prefs.put(KEY_SOUNDS_MATCH_MUSIC_PATH, path); prefs.put(KEY_SOUNDS_MATCH_MUSIC_PATH, path);
updateCache(KEY_SOUNDS_MATCH_MUSIC_PATH, path); updateCache(KEY_SOUNDS_MATCH_MUSIC_PATH, path);
@ -2294,13 +2298,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
public static void setPrefValue(String key, boolean value) { public static void setPrefValue(String key, boolean value) {
switch(key) { switch (key) {
case KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS: case KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS:
dialog.cbAllowRequestToShowHandCards.setSelected(value); dialog.cbAllowRequestToShowHandCards.setSelected(value);
save(MageFrame.getPreferences(), dialog.cbAllowRequestToShowHandCards, KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, "true", "false", UPDATE_CACHE_POLICY); save(MageFrame.getPreferences(), dialog.cbAllowRequestToShowHandCards, KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, "true", "false", UPDATE_CACHE_POLICY);
break; break;
} }
} }
private static void save(Preferences prefs, JCheckBox checkBox, String propName, String yesValue, String noValue, boolean updateCache) { private static void save(Preferences prefs, JCheckBox checkBox, String propName, String yesValue, String noValue, boolean updateCache) {
prefs.put(propName, checkBox.isSelected() ? yesValue : noValue); prefs.put(propName, checkBox.isSelected() ? yesValue : noValue);
if (updateCache) { if (updateCache) {
@ -2356,7 +2361,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
try { try {
addAvatar(jPanel10, 51, true, false); addAvatar(jPanel10, 51, true, false);
addAvatar(jPanel13, 13, false, false); addAvatar(jPanel13, 13, false, false);
addAvatar(jPanel11, 9, false, false); addAvatar(jPanel11, 9, false, false);
addAvatar(jPanel12, 53, false, false); addAvatar(jPanel12, 53, false, false);
addAvatar(jPanel14, 10, false, false); addAvatar(jPanel14, 10, false, false);
addAvatar(jPanel15, 39, false, false); addAvatar(jPanel15, 39, false, false);
@ -2416,19 +2421,23 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
} }
public static UserDataView getUserData(){ public static UserData getUserData() {
return new UserDataView( return new UserData(UserGroup.PLAYER,
getSelectedAvatar(), PreferencesDialog.selectedAvatarId,
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_ANY_ZONE, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_ANY_ZONE, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_CONFIRM_EMPTY_MANA_POOL, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_CONFIRM_EMPTY_MANA_POOL, "true").equals("true"),
getUserSkipPrioritySteps(), getUserSkipPrioritySteps(),
MageFrame.getPreferences().get(KEY_CONNECT_FLAG, "world"), MageFrame.getPreferences().get(KEY_CONNECT_FLAG, "world"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER, "true").equals("true") PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true")
); );
} }
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane avatarPane;
private javax.swing.JPanel avatarPanel;
private javax.swing.JButton btnBattlefieldBGMBrowse; private javax.swing.JButton btnBattlefieldBGMBrowse;
private javax.swing.JButton btnBrowseBackgroundImage; private javax.swing.JButton btnBrowseBackgroundImage;
private javax.swing.JButton btnBrowseBattlefieldImage; private javax.swing.JButton btnBrowseBattlefieldImage;
@ -2501,8 +2510,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JPanel jPanel19; private javax.swing.JPanel jPanel19;
private javax.swing.JPanel jPanel20; private javax.swing.JPanel jPanel20;
private javax.swing.JPanel jPanel21; private javax.swing.JPanel jPanel21;
private javax.swing.JPanel jPanel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel labelPreferedImageLanguage; private javax.swing.JLabel labelPreferedImageLanguage;
private javax.swing.JLabel lblProxyPassword; private javax.swing.JLabel lblProxyPassword;
private javax.swing.JLabel lblProxyPort; private javax.swing.JLabel lblProxyPort;

View file

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="title" type="java.lang.String" value="Random Booster Draft Packs Selector"/>
<Property name="modal" type="boolean" value="true"/>
<Property name="modalExclusionType" type="java.awt.Dialog$ModalExclusionType" editor="org.netbeans.modules.form.editors.EnumEditor">
<Value id="APPLICATION_EXCLUDE"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 450]"/>
</Property>
<Property name="resizable" type="boolean" value="false"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="pnlSelect" min="-2" pref="241" max="-2" attributes="0"/>
<EmptySpace pref="300" max="32767" attributes="0"/>
<Component id="pnlApply" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="pnlPacks" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="pnlPacks" min="-2" pref="372" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnlApply" min="-2" pref="32" max="-2" attributes="0"/>
<Component id="pnlSelect" min="-2" pref="32" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="java.awt.Panel" name="pnlPacks">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="12"/>
<Property name="rows" type="int" value="11"/>
</Layout>
</Container>
<Container class="javax.swing.JPanel" name="pnlSelect">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="btnNone">
<Properties>
<Property name="text" type="java.lang.String" value="Select none"/>
<Property name="actionCommand" type="java.lang.String" value="none"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnNoneActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnAll">
<Properties>
<Property name="text" type="java.lang.String" value="Select all"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAllActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnlApply">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="btnApply">
<Properties>
<Property name="text" type="java.lang.String" value="Apply"/>
<Property name="toolTipText" type="java.lang.String" value="At least two packs must be selected"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnApplyActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View file

@ -0,0 +1,199 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.dialog;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.JCheckBox;
import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
/**
*
* @author BrodyL
*/
public class RandomPacksSelectorDialog extends javax.swing.JDialog {
/**
* Creates new form RandomPacksSelectorDialog
*/
private boolean boxesCreated;
public final static String randomDraftDescription = ("The selected packs will be randomly distributed to players. Each player may open different packs. Duplicates will be avoided.");
public RandomPacksSelectorDialog() {
initComponents();
this.pnlApply.setToolTipText(randomDraftDescription);
this.pnlSelect.setToolTipText(randomDraftDescription);
boxesCreated = false;
}
public void showDialog() {
createCheckboxes();
pnlPacks.setVisible(true);
pnlPacks.revalidate();
pnlPacks.repaint();
this.pack();
this.revalidate();
this.repaint();
this.setVisible(true);
this.setModal(true);
}
public void setSelectedPacks(ArrayList<String> packs){
if (!boxesCreated){
createCheckboxes();
}
for (Component pack : pnlPacks.getComponents()) {
JCheckBox thePack = (JCheckBox) pack;
if (packs.contains(thePack.getText())) {
thePack.setSelected(true);
} else{
thePack.setSelected(false);
}
}
}
public ArrayList<String> getSelectedPacks() {
ArrayList<String> returnVal = new ArrayList<>();
for (Component pack: pnlPacks.getComponents()){
JCheckBox thePack = (JCheckBox) pack;
if (thePack.isSelected()){
returnVal.add(thePack.getText());
}
}
return returnVal;
}
private void createCheckboxes() {
if (!boxesCreated) {
ExpansionInfo[] allExpansions = ExpansionRepository.instance.getWithBoostersSortedByReleaseDate();
for (ExpansionInfo exp : allExpansions) {
JCheckBox pack = new JCheckBox();
pack.setSelected(true);
pack.setText(exp.getCode());
pack.setToolTipText(exp.getName());
pnlPacks.add(pack);
}
pnlPacks.setVisible(true);
this.pack();
boxesCreated = true;
pnlPacks.validate();
}
}
/**
* 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
pnlPacks = new java.awt.Panel();
pnlSelect = new javax.swing.JPanel();
btnNone = new javax.swing.JButton();
btnAll = new javax.swing.JButton();
pnlApply = new javax.swing.JPanel();
btnApply = new javax.swing.JButton();
setTitle("Random Booster Draft Packs Selector");
setModal(true);
setModalExclusionType(java.awt.Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
setPreferredSize(new java.awt.Dimension(600, 450));
setResizable(false);
pnlPacks.setLayout(new java.awt.GridLayout(11, 12));
pnlSelect.setLayout(new javax.swing.BoxLayout(pnlSelect, javax.swing.BoxLayout.LINE_AXIS));
btnNone.setText("Select none");
btnNone.setActionCommand("none");
btnNone.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnNoneActionPerformed(evt);
}
});
pnlSelect.add(btnNone);
btnAll.setText("Select all");
btnAll.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnAllActionPerformed(evt);
}
});
pnlSelect.add(btnAll);
pnlApply.setLayout(new javax.swing.BoxLayout(pnlApply, javax.swing.BoxLayout.LINE_AXIS));
btnApply.setText("Apply");
btnApply.setToolTipText("At least two packs must be selected");
btnApply.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnApplyActionPerformed(evt);
}
});
pnlApply.add(btnApply);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(pnlSelect, javax.swing.GroupLayout.PREFERRED_SIZE, 241, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 300, Short.MAX_VALUE)
.addComponent(pnlApply, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, 372, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnlApply, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(pnlSelect, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAllActionPerformed
setAllCheckBoxes(true);
}//GEN-LAST:event_btnAllActionPerformed
private void btnNoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNoneActionPerformed
setAllCheckBoxes(false);
}//GEN-LAST:event_btnNoneActionPerformed
private void btnApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnApplyActionPerformed
if (getSelectedPacks().size() < 2) {
// at least 2 packs must be selected.
} else {
this.setVisible(false);
}
}//GEN-LAST:event_btnApplyActionPerformed
private void setAllCheckBoxes(boolean value) {
for (Component pack : pnlPacks.getComponents()) {
JCheckBox thePack = (JCheckBox) pack;
thePack.setSelected(value);
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnAll;
private javax.swing.JButton btnApply;
private javax.swing.JButton btnNone;
private javax.swing.JPanel pnlApply;
private java.awt.Panel pnlPacks;
private javax.swing.JPanel pnlSelect;
// End of variables declaration//GEN-END:variables
}

View file

@ -1,50 +1,54 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* TableWaitingDialog.java * TableWaitingDialog.java
* *
* Created on Dec 16, 2009, 10:27:44 AM * Created on Dec 16, 2009, 10:27:44 AM
*/ */
package mage.client.dialog; package mage.client.dialog;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import javax.swing.Icon;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.chat.ChatPanel; import mage.client.chat.ChatPanel;
import mage.client.components.MageComponents; import mage.client.components.MageComponents;
import mage.client.components.tray.MageTray; import mage.client.components.tray.MageTray;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH;
import mage.client.util.audio.AudioManager; import mage.client.util.audio.AudioManager;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.remote.Session; import mage.remote.Session;
import mage.view.SeatView; import mage.view.SeatView;
import mage.view.TableView; import mage.view.TableView;
@ -64,8 +68,11 @@ public class TableWaitingDialog extends MageDialog {
private Session session; private Session session;
private final TableWaitModel tableWaitModel; private final TableWaitModel tableWaitModel;
private UpdateSeatsTask updateTask; private UpdateSeatsTask updateTask;
private static final int[] defaultColumnsWidth = {20, 50, 100, 100};
/** Creates new form TableWaitingDialog */ /**
* Creates new form TableWaitingDialog
*/
public TableWaitingDialog() { public TableWaitingDialog() {
session = MageFrame.getSession(); session = MageFrame.getSession();
@ -73,8 +80,17 @@ public class TableWaitingDialog extends MageDialog {
initComponents(); initComponents();
int prefWidth = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLE_WAITING_WIDTH, "500"));
int prefHeight = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLE_WAITING_HEIGHT, "400"));
if (prefWidth > 40 && prefHeight > 40) {
this.setSize(prefWidth, prefHeight);
}
chatPanel.useExtendedView(ChatPanel.VIEW_MODE.NONE); chatPanel.useExtendedView(ChatPanel.VIEW_MODE.NONE);
tableSeats.createDefaultColumnsFromModel(); tableSeats.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableSeats, defaultColumnsWidth, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer());
MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart); MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart);
} }
@ -97,11 +113,14 @@ public class TableWaitingDialog extends MageDialog {
return; return;
} }
int row = this.tableSeats.getSelectedRow(); int row = this.tableSeats.getSelectedRow();
if (getTitle().equals("Waiting for players")) {
this.title = getTitle() + " - " + table.getDeckType() + " / " + table.getGameType();
this.repaint();
}
tableWaitModel.loadData(table); tableWaitModel.loadData(table);
this.tableSeats.repaint(); this.tableSeats.repaint();
this.tableSeats.getSelectionModel().setSelectionInterval(row, row); this.tableSeats.getSelectionModel().setSelectionInterval(row, row);
} } else {
else {
closeDialog(); closeDialog();
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -131,8 +150,7 @@ public class TableWaitingDialog extends MageDialog {
this.setModal(false); this.setModal(false);
this.setLocation(100, 100); this.setLocation(100, 100);
this.setVisible(true); this.setVisible(true);
} } else {
else {
closeDialog(); closeDialog();
} }
} }
@ -144,14 +162,15 @@ public class TableWaitingDialog extends MageDialog {
this.chatPanel.disconnect(); this.chatPanel.disconnect();
MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON); MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON);
this.removeDialog(); this.removeDialog();
TableUtil.saveColumnWidthAndOrderToPrefs(tableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER);
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_WIDTH, Integer.toString(getWidth()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_HEIGHT, Integer.toString(getHeight()));
} }
/**
* This method is called from within the constructor to initialize the form.
/** This method is called from within the constructor to * WARNING: Do NOT modify this code. The content of this method is always
* initialize the form. * regenerated by the Form Editor.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -248,8 +267,7 @@ public class TableWaitingDialog extends MageDialog {
if (session.startMatch(roomId, tableId)) { if (session.startMatch(roomId, tableId)) {
closeDialog(); closeDialog();
} }
} } else {
else {
if (session.startTournament(roomId, tableId)) { if (session.startTournament(roomId, tableId)) {
closeDialog(); closeDialog();
} }
@ -285,7 +303,6 @@ public class TableWaitingDialog extends MageDialog {
} }
}//GEN-LAST:event_btnMoveUpActionPerformed }//GEN-LAST:event_btnMoveUpActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel; private javax.swing.JButton btnCancel;
private javax.swing.JButton btnMoveDown; private javax.swing.JButton btnMoveDown;
@ -300,7 +317,8 @@ public class TableWaitingDialog extends MageDialog {
} }
class TableWaitModel extends AbstractTableModel { class TableWaitModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Seat Num", "Player Name", "Player Type"};
private final String[] columnNames = new String[]{"Seat", "Loc", "Player Name", "Player Type"};
private SeatView[] seats = new SeatView[0]; private SeatView[] seats = new SeatView[0];
public void loadData(TableView table) { public void loadData(TableView table) {
@ -324,14 +342,15 @@ class TableWaitModel extends AbstractTableModel {
if (arg1 == 0) { if (arg1 == 0) {
return Integer.toString(arg0 + 1); return Integer.toString(arg0 + 1);
} }
} } else {
else {
switch (arg1) { switch (arg1) {
case 0: case 0:
return Integer.toString(arg0 + 1); return Integer.toString(arg0 + 1);
case 1: case 1:
return seats[arg0].getPlayerName(); return seats[arg0].getFlagName();
case 2: case 2:
return seats[arg0].getPlayerName();
case 3:
return seats[arg0].getPlayerType(); return seats[arg0].getPlayerType();
} }
} }
@ -350,8 +369,13 @@ class TableWaitModel extends AbstractTableModel {
} }
@Override @Override
public Class getColumnClass(int columnIndex){ public Class getColumnClass(int columnIndex) {
return String.class; switch (columnIndex) {
case 1:
return Icon.class;
default:
return String.class;
}
} }
@Override @Override
@ -413,7 +437,7 @@ class UpdateSeatsTask extends SwingWorker<Void, TableView> {
private int getPlayersCount(TableView tableView) { private int getPlayersCount(TableView tableView) {
int playerCount = 0; int playerCount = 0;
if (tableView != null) { if (tableView != null) {
for (SeatView seatView: tableView.getSeats()) { for (SeatView seatView : tableView.getSeats()) {
if (seatView.getPlayerId() != null && seatView.getPlayerType().equals("Human")) { if (seatView.getPlayerId() != null && seatView.getPlayerType().equals("Human")) {
playerCount++; playerCount++;
} }
@ -422,7 +446,6 @@ class UpdateSeatsTask extends SwingWorker<Void, TableView> {
return playerCount; return playerCount;
} }
@Override @Override
protected void done() { protected void done() {
try { try {
@ -431,7 +454,8 @@ class UpdateSeatsTask extends SwingWorker<Void, TableView> {
logger.fatal("Update Seats Task error", ex); logger.fatal("Update Seats Task error", ex);
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
logger.fatal("Update Seats Task error", ex); logger.fatal("Update Seats Task error", ex);
} catch (CancellationException ex) {} } catch (CancellationException ex) {
}
} }
} }

View file

@ -1,37 +1,36 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* FeedbackPanel.java * FeedbackPanel.java
* *
* Created on 23-Dec-2009, 9:54:01 PM * Created on 23-Dec-2009, 9:54:01 PM
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Component; import java.awt.Component;
@ -48,6 +47,7 @@ import mage.client.components.MageTextArea;
import mage.client.dialog.MageDialog; import mage.client.dialog.MageDialog;
import mage.client.util.audio.AudioManager; import mage.client.util.audio.AudioManager;
import mage.client.util.gui.ArrowBuilder; import mage.client.util.gui.ArrowBuilder;
import mage.constants.Constants;
import mage.constants.PlayerAction; import mage.constants.PlayerAction;
import mage.remote.Session; import mage.remote.Session;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -61,6 +61,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(FeedbackPanel.class); private static final Logger logger = Logger.getLogger(FeedbackPanel.class);
public enum FeedbackMode { public enum FeedbackMode {
INFORM, QUESTION, CONFIRM, CANCEL, SELECT, END INFORM, QUESTION, CONFIRM, CANCEL, SELECT, END
} }
@ -73,7 +74,9 @@ public class FeedbackPanel extends javax.swing.JPanel {
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
/** Creates new form FeedbackPanel */ /**
* Creates new form FeedbackPanel
*/
public FeedbackPanel() { public FeedbackPanel() {
//initComponents(); //initComponents();
customInitComponents(); customInitComponents();
@ -138,14 +141,21 @@ public class FeedbackPanel extends javax.swing.JPanel {
endWithTimeout(); endWithTimeout();
break; break;
} }
this.btnSpecial.setVisible(special); if (options != null && options.containsKey(Constants.Option.SPECIAL_BUTTON)) {
this.btnSpecial.setText("Special"); String specialText = (String) options.get(Constants.Option.SPECIAL_BUTTON);
this.helper.setSpecial("Special", special);
// Handling Phyrexian mana
if (message.contains("P}")) {
this.btnSpecial.setVisible(true); this.btnSpecial.setVisible(true);
this.btnSpecial.setText("Pay 2 life"); this.btnSpecial.setText(specialText);
this.helper.setSpecial("Pay 2 life", true); this.helper.setSpecial(specialText, true);
} else {
this.btnSpecial.setVisible(special);
this.btnSpecial.setText("Special");
this.helper.setSpecial("Special", special);
// Handling Phyrexian mana
if (message.contains("P}")) {
this.btnSpecial.setVisible(true);
this.btnSpecial.setText("Pay 2 life");
this.helper.setSpecial("Pay 2 life", true);
}
} }
requestFocusIfPossible(); requestFocusIfPossible();
@ -170,7 +180,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
while (c != null && !(c instanceof GamePane)) { while (c != null && !(c instanceof GamePane)) {
c = c.getParent(); c = c.getParent();
} }
if (c != null && ((GamePane)c).isVisible()) { // check if GamePanel still visible if (c != null && ((GamePane) c).isVisible()) { // check if GamePanel still visible
FeedbackPanel.this.btnRight.doClick(); FeedbackPanel.this.btnRight.doClick();
} }
} }
@ -181,8 +191,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
private void handleOptions(Map<String, Serializable> options) { private void handleOptions(Map<String, Serializable> options) {
if (options != null) { if (options != null) {
if (options.containsKey("UI.right.btn.text")) { if (options.containsKey("UI.right.btn.text")) {
this.btnRight.setText((String)options.get("UI.right.btn.text")); this.btnRight.setText((String) options.get("UI.right.btn.text"));
this.helper.setRight((String)options.get("UI.right.btn.text"), true); this.helper.setRight((String) options.get("UI.right.btn.text"), true);
} }
if (options.containsKey("dialog")) { if (options.containsKey("dialog")) {
connectedDialog = (MageDialog) options.get("dialog"); connectedDialog = (MageDialog) options.get("dialog");
@ -224,7 +234,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
btnUndo = new javax.swing.JButton(); btnUndo = new javax.swing.JButton();
btnUndo.setVisible(true); btnUndo.setVisible(true);
setBackground(new java.awt.Color(0,0,0,80)); setBackground(new java.awt.Color(0, 0, 0, 80));
btnRight.setText("Cancel"); btnRight.setText("Cancel");
btnRight.addActionListener(new java.awt.event.ActionListener() { btnRight.addActionListener(new java.awt.event.ActionListener() {

View file

@ -1020,6 +1020,9 @@ public final class GamePanel extends javax.swing.JPanel {
} }
Map<String, Serializable> panelOptions = new HashMap<>(); Map<String, Serializable> panelOptions = new HashMap<>();
if (options != null) {
panelOptions.putAll(options);
}
panelOptions.put("your_turn", true); panelOptions.put("your_turn", true);
String activePlayerText; String activePlayerText;
if (gameView.getActivePlayerId().equals(playerId)) { if (gameView.getActivePlayerId().equals(playerId)) {

View file

@ -1,40 +1,43 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import mage.client.components.MageTextArea; import mage.client.components.MageTextArea;
/** /**
@ -58,18 +61,25 @@ public class HelperPanel extends JPanel {
private javax.swing.JButton linkSpecial; private javax.swing.JButton linkSpecial;
private javax.swing.JButton linkUndo; private javax.swing.JButton linkUndo;
private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final Object tooltipBackground = UIManager.get("info");
public HelperPanel() { public HelperPanel() {
initComponents(); initComponents();
} }
private void initComponents() { private void initComponents() {
setBackground(new Color(0, 0, 0, 100)); setBackground(new Color(0, 0, 0, 100));
//setLayout(new GridBagLayout()); //setLayout(new GridBagLayout());
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setOpaque(false); setOpaque(false);
JPanel container = new JPanel(); JPanel container = new JPanel();
container.setPreferredSize(new Dimension(100, 30)); container.setPreferredSize(new Dimension(100, 30));
container.setMinimumSize(new Dimension(20, 20));
container.setMaximumSize(new Dimension(2000, 100));
container.setLayout(new GridBagLayout()); container.setLayout(new GridBagLayout());
container.setOpaque(false); container.setOpaque(false);
@ -101,22 +111,24 @@ public class HelperPanel extends JPanel {
btnLeft.addActionListener(new java.awt.event.ActionListener() { btnLeft.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkLeft != null) {{ if (linkLeft != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
setState("",false,"",false); public void run() {
setSpecial("", false); setState("", false, "", false);
linkLeft.doClick(); setSpecial("", false);
} linkLeft.doClick();
}); }
} });
}; }
worker.start(); };
}} worker.start();
}
}
} }
}); });
@ -124,13 +136,13 @@ public class HelperPanel extends JPanel {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkRight != null) { if (linkRight != null) {
Thread worker = new Thread(){ Thread worker = new Thread() {
@Override @Override
public void run(){ public void run() {
SwingUtilities.invokeLater(new Runnable(){ SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run(){ public void run() {
setState("",false,"",false); setState("", false, "", false);
setSpecial("", false); setSpecial("", false);
linkRight.doClick(); linkRight.doClick();
} }
@ -145,42 +157,62 @@ public class HelperPanel extends JPanel {
btnSpecial.addActionListener(new java.awt.event.ActionListener() { btnSpecial.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkSpecial != null) {{ if (linkSpecial != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
setState("",false,"",false); public void run() {
setSpecial("", false); setState("", false, "", false);
linkSpecial.doClick(); setSpecial("", false);
} linkSpecial.doClick();
}); }
} });
}; }
worker.start(); };
}} worker.start();
}
}
} }
}); });
btnUndo.addActionListener(new java.awt.event.ActionListener() { btnUndo.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkUndo != null) {{ if (linkUndo != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
linkUndo.doClick(); public void run() {
} linkUndo.doClick();
}); }
} });
}; }
worker.start(); };
}} worker.start();
}
}
}
});
// sets a darker background and higher simiss time fpr tooltip in the feedback / helper panel
textArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
ToolTipManager.sharedInstance().setDismissDelay(100000);
UIManager.put("info", Color.DARK_GRAY);
}
@Override
public void mouseExited(MouseEvent me) {
ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout);
UIManager.put("info", tooltipBackground);
} }
}); });
} }
@ -220,17 +252,18 @@ public class HelperPanel extends JPanel {
} }
public void setMessage(String message) { public void setMessage(String message) {
if (message.startsWith("Use alternative cost")) { // if (message.startsWith("Use alternative cost")) {
message = "Use alternative cost?"; // message = "Use alternative cost?";
} else if (message.contains("Use ")) { // } else if (message.contains("Use ")) {
if (message.length() < this.getWidth() / 10) { // if (message.length() < this.getWidth() / 10) {
message = getSmallText(message); // message = getSmallText(message);
} else { // } else {
message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10)); // message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10));
} // }
} // }
textArea.setText(message); textArea.setText(message, this.getWidth());
} }
protected String getSmallText(String text) { protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>"; return "<div style='font-size:11pt'>" + text + "</div>";
} }

View file

@ -1,30 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Color; import java.awt.Color;
@ -37,7 +37,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.UUID; import java.util.UUID;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.GroupLayout; import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment; import javax.swing.GroupLayout.Alignment;
@ -80,7 +79,9 @@ public class PlayAreaPanel extends javax.swing.JPanel {
public static final int PANEL_HEIGHT = 242; public static final int PANEL_HEIGHT = 242;
public static final int PANEL_HEIGHT_SMALL = 190; public static final int PANEL_HEIGHT_SMALL = 190;
/** Creates new form PlayAreaPanel /**
* Creates new form PlayAreaPanel
*
* @param player * @param player
* @param bigCard * @param bigCard
* @param gameId * @param gameId
@ -97,7 +98,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
popupMenu = new JPopupMenu(); popupMenu = new JPopupMenu();
if (options.isPlayer) { if (options.isPlayer) {
addPopupMenuPlayer(player.getUserData().allowRequestShowHandCards()); addPopupMenuPlayer(player.getUserData().isAllowRequestShowHandCards());
} else { } else {
addPopupMenuWatcher(); addPopupMenuWatcher();
} }
@ -110,14 +111,13 @@ public class PlayAreaPanel extends javax.swing.JPanel {
battlefieldPanel.cleanUp(); battlefieldPanel.cleanUp();
playerPanel.cleanUp(); playerPanel.cleanUp();
for (ActionListener al : btnCheat.getActionListeners()) {
for (ActionListener al : btnCheat.getActionListeners() ) {
btnCheat.removeActionListener(al); btnCheat.removeActionListener(al);
} }
// Taken form : https://community.oracle.com/thread/2183145 // Taken form : https://community.oracle.com/thread/2183145
// removed the internal focus of a popupMenu data to allow GC before another popup menu is selected // removed the internal focus of a popupMenu data to allow GC before another popup menu is selected
for(ChangeListener listener : MenuSelectionManager.defaultManager().getChangeListeners()) { for (ChangeListener listener : MenuSelectionManager.defaultManager().getChangeListeners()) {
if (listener.getClass().getName().contains("MenuKeyboardHelper")) { if (listener.getClass().getName().contains("MenuKeyboardHelper")) {
try { try {
Field field = listener.getClass().getDeclaredField("menuInputMap"); Field field = listener.getClass().getDeclaredField("menuInputMap");
@ -130,7 +130,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
} }
} }
for (MouseListener ml :battlefieldPanel.getMainPanel().getMouseListeners()) { for (MouseListener ml : battlefieldPanel.getMainPanel().getMouseListeners()) {
battlefieldPanel.getMainPanel().removeMouseListener(ml); battlefieldPanel.getMainPanel().removeMouseListener(ml);
} }
popupMenu.getUI().uninstallUI(this); popupMenu.getUI().uninstallUI(this);
@ -187,7 +187,6 @@ public class PlayAreaPanel extends javax.swing.JPanel {
popupMenu.add(menuItem); popupMenu.add(menuItem);
menuItem.addActionListener(skipListener); menuItem.addActionListener(skipListener);
JMenu skipMenu = new JMenu("Skip"); JMenu skipMenu = new JMenu("Skip");
skipMenu.setMnemonic(KeyEvent.VK_S); skipMenu.setMnemonic(KeyEvent.VK_S);
popupMenu.add(skipMenu); popupMenu.add(skipMenu);
@ -230,35 +229,36 @@ public class PlayAreaPanel extends javax.swing.JPanel {
manaPoolMenuItem1 = new JCheckBoxMenuItem("Automatically", true); manaPoolMenuItem1 = new JCheckBoxMenuItem("Automatically", true);
manaPoolMenuItem1.setMnemonic(KeyEvent.VK_A); manaPoolMenuItem1.setMnemonic(KeyEvent.VK_A);
manaPoolMenuItem1.setToolTipText("<html>If not active, produced mana goes only to the mana pool<br>" manaPoolMenuItem1.setToolTipText("<html>If not active, produced mana goes only to the mana pool<br>"
+ "and you have to click the type of mana you want to use <br>" + "and you have to click the type of mana you want to use <br>"
+ "in the player mana pool panel for payment."); + "in the player mana pool panel for payment.");
manaPoolMenu.add(manaPoolMenuItem1); manaPoolMenu.add(manaPoolMenuItem1);
// Auto pay mana from mana pool // Auto pay mana from mana pool
manaPoolMenuItem1.addActionListener(new ActionListener() { manaPoolMenuItem1.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
boolean manaPoolAutomatic = ((JCheckBoxMenuItem)e.getSource()).getState(); boolean manaPoolAutomatic = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT, manaPoolAutomatic ? "true": "false"); PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT, manaPoolAutomatic ? "true" : "false");
gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState()); gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState());
gamePanel.getSession().sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON: PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null); gamePanel.getSession().sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON : PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null);
} }
}); });
manaPoolMenuItem2 = new JCheckBoxMenuItem("No automatic usage for mana already in the pool", true); manaPoolMenuItem2 = new JCheckBoxMenuItem("No automatic usage for mana already in the pool", true);
manaPoolMenuItem2.setMnemonic(KeyEvent.VK_N); manaPoolMenuItem2.setMnemonic(KeyEvent.VK_N);
manaPoolMenuItem2.setToolTipText("<html>Mana that is already in the mana pool as you start casting a spell or activating an ability<br>" manaPoolMenuItem2.setToolTipText("<html>Mana that is already in the mana pool as you start casting a spell or activating an ability<br>"
+ " needs to be payed manually. So you use the mana in the pool only by clicking on the related<br>" + " needs to be payed manually. So you use the mana in the pool only by clicking on the related<br>"
+ " mana symbols of mana pool area."); + " mana symbols of mana pool area.");
manaPoolMenu.add(manaPoolMenuItem2); manaPoolMenu.add(manaPoolMenuItem2);
// Auto pay mana from mana pool // Auto pay mana from mana pool
manaPoolMenuItem2.addActionListener(new ActionListener() { manaPoolMenuItem2.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
boolean manaPoolAutomaticRestricted = ((JCheckBoxMenuItem)e.getSource()).getState(); boolean manaPoolAutomaticRestricted = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, manaPoolAutomaticRestricted ? "true": "false"); PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, manaPoolAutomaticRestricted ? "true" : "false");
gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted); gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted);
gamePanel.getSession().sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON: PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null); gamePanel.getSession().sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON : PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null);
} }
}); });
@ -304,9 +304,9 @@ public class PlayAreaPanel extends javax.swing.JPanel {
allowViewHandCardsMenuItem.addActionListener(new ActionListener() { allowViewHandCardsMenuItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
boolean requestsAllowed = ((JCheckBoxMenuItem)e.getSource()).getState(); boolean requestsAllowed = ((JCheckBoxMenuItem) e.getSource()).getState();
PreferencesDialog.setPrefValue(KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, requestsAllowed); PreferencesDialog.setPrefValue(KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, requestsAllowed);
gamePanel.getSession().sendPlayerAction(requestsAllowed ? PlayerAction.PERMISSION_REQUESTS_ALLOWED_ON: PlayerAction.PERMISSION_REQUESTS_ALLOWED_OFF, gameId, null); gamePanel.getSession().sendPlayerAction(requestsAllowed ? PlayerAction.PERMISSION_REQUESTS_ALLOWED_ON : PlayerAction.PERMISSION_REQUESTS_ALLOWED_OFF, gameId, null);
} }
}); });
@ -364,8 +364,6 @@ public class PlayAreaPanel extends javax.swing.JPanel {
} }
JMenu concedeMenu = new JMenu("Concede"); JMenu concedeMenu = new JMenu("Concede");
concedeMenu.setMnemonic(KeyEvent.VK_C); concedeMenu.setMnemonic(KeyEvent.VK_C);
popupMenu.add(concedeMenu); popupMenu.add(concedeMenu);
@ -406,7 +404,6 @@ public class PlayAreaPanel extends javax.swing.JPanel {
concedeMenu.add(menuItem); concedeMenu.add(menuItem);
menuItem.addActionListener(concedeListener); menuItem.addActionListener(concedeListener);
battlefieldPanel.getMainPanel().addMouseListener(new MouseAdapter() { battlefieldPanel.getMainPanel().addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseReleased(MouseEvent Me) { public void mouseReleased(MouseEvent Me) {
@ -419,7 +416,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.checkMenu(Me); this.checkMenu(Me);
} }
private void checkMenu(MouseEvent Me){ private void checkMenu(MouseEvent Me) {
if (Me.isPopupTrigger() && playingMode) { if (Me.isPopupTrigger() && playingMode) {
popupMenu.show(Me.getComponent(), Me.getX(), Me.getY()); popupMenu.show(Me.getComponent(), Me.getX(), Me.getY());
} }
@ -461,13 +458,14 @@ public class PlayAreaPanel extends javax.swing.JPanel {
public void mouseReleased(MouseEvent Me) { public void mouseReleased(MouseEvent Me) {
this.checkMenu(Me); this.checkMenu(Me);
} }
// neccessary for linux and mac systems // neccessary for linux and mac systems
@Override @Override
public void mousePressed(MouseEvent Me) { public void mousePressed(MouseEvent Me) {
this.checkMenu(Me); this.checkMenu(Me);
} }
private void checkMenu(MouseEvent Me){ private void checkMenu(MouseEvent Me) {
if (Me.isPopupTrigger() && playingMode) { if (Me.isPopupTrigger() && playingMode) {
popupMenu.show(Me.getComponent(), Me.getX(), Me.getY()); popupMenu.show(Me.getComponent(), Me.getX(), Me.getY());
} }
@ -483,8 +481,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
if (MageFrame.getSession().isTestMode()) { if (MageFrame.getSession().isTestMode()) {
this.playerId = player.getPlayerId(); this.playerId = player.getPlayerId();
this.btnCheat.setVisible(true); this.btnCheat.setVisible(true);
} } else {
else {
this.btnCheat.setVisible(false); this.btnCheat.setVisible(false);
} }
} }
@ -493,7 +490,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.playerPanel.update(player); this.playerPanel.update(player);
this.battlefieldPanel.update(player.getBattlefield()); this.battlefieldPanel.update(player.getBattlefield());
if (this.allowViewHandCardsMenuItem != null) { if (this.allowViewHandCardsMenuItem != null) {
this.allowViewHandCardsMenuItem.setSelected(player.getUserData().allowRequestShowHandCards()); this.allowViewHandCardsMenuItem.setSelected(player.getUserData().isAllowRequestShowHandCards());
} }
} }
@ -506,7 +503,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
} }
private void initComponents() { private void initComponents() {
setBorder(BorderFactory.createLineBorder(new Color(0,0,0,0))); setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0, 0)));
playerPanel = new PlayerPanelExt(); playerPanel = new PlayerPanelExt();
btnCheat = new javax.swing.JButton(); btnCheat = new javax.swing.JButton();
//jScrollPane1 = new javax.swing.JScrollPane(); //jScrollPane1 = new javax.swing.JScrollPane();
@ -525,16 +522,15 @@ public class PlayAreaPanel extends javax.swing.JPanel {
//Border empty = new EmptyBorder(0,0,0,0); //Border empty = new EmptyBorder(0,0,0,0);
//jScrollPane1.setBorder(empty); //jScrollPane1.setBorder(empty);
//jScrollPane1.setViewportBorder(empty); //jScrollPane1.setViewportBorder(empty);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createSequentialGroup() layout.createSequentialGroup()
.addComponent(playerPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(playerPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(battlefieldPanel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(battlefieldPanel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(Alignment.LEADING) layout.createParallelGroup(Alignment.LEADING)
.addComponent(playerPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(playerPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(battlefieldPanel, GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE) .addComponent(battlefieldPanel, GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE)
); );
@ -548,8 +544,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.playerPanel.setPreferredSize(new Dimension(92, PANEL_HEIGHT_SMALL)); this.playerPanel.setPreferredSize(new Dimension(92, PANEL_HEIGHT_SMALL));
//this.jScrollPane1.setPreferredSize(new Dimension(160, 160)); //this.jScrollPane1.setPreferredSize(new Dimension(160, 160));
this.battlefieldPanel.setPreferredSize(new Dimension(160, PANEL_HEIGHT_SMALL)); this.battlefieldPanel.setPreferredSize(new Dimension(160, PANEL_HEIGHT_SMALL));
} } else {
else {
this.playerPanel.setPreferredSize(new Dimension(92, PANEL_HEIGHT)); this.playerPanel.setPreferredSize(new Dimension(92, PANEL_HEIGHT));
//this.jScrollPane1.setPreferredSize(new Dimension(160, 212)); //this.jScrollPane1.setPreferredSize(new Dimension(160, 212));
this.battlefieldPanel.setPreferredSize(new Dimension(160, PANEL_HEIGHT)); this.battlefieldPanel.setPreferredSize(new Dimension(160, PANEL_HEIGHT));

View file

@ -36,6 +36,7 @@ package mage.client.game;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image; import java.awt.Image;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -67,6 +68,7 @@ import mage.client.util.CardsViewUtil;
import mage.client.util.Command; import mage.client.util.Command;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder; import mage.client.util.gui.BufferedImageBuilder;
import mage.client.util.gui.countryBox.CountryUtil;
import mage.components.ImagePanel; import mage.components.ImagePanel;
import mage.constants.ManaType; import mage.constants.ManaType;
import mage.remote.Session; import mage.remote.Session;
@ -103,6 +105,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
private static final Border emptyBorder = BorderFactory.createEmptyBorder(0, 0, 0, 0); private static final Border emptyBorder = BorderFactory.createEmptyBorder(0, 0, 0, 0);
private int avatarId = -1; private int avatarId = -1;
private String flagName = "";
private PriorityTimer timer; private PriorityTimer timer;
@ -234,6 +237,11 @@ public class PlayerPanelExt extends javax.swing.JPanel {
BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
this.avatar.update("player", resized, resized, resized, resized, r); this.avatar.update("player", resized, resized, resized, resized, r);
} }
if (!player.getUserData().getFlagName().equals(flagName)) {
flagName = player.getUserData().getFlagName();
this.avatarFlag.setIcon(CountryUtil.getCountryFlagIcon(flagName));
avatar.repaint();
}
} }
this.avatar.setText(player.getName()); this.avatar.setText(player.getName());
if (this.timer != null) { if (this.timer != null) {
@ -298,6 +306,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
panelBackground = new MageRoundPane(); panelBackground = new MageRoundPane();
panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT)); panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT));
Rectangle r = new Rectangle(80, 80); Rectangle r = new Rectangle(80, 80);
avatarFlag = new JLabel();
timerLabel = new JLabel(); timerLabel = new JLabel();
lifeLabel = new JLabel(); lifeLabel = new JLabel();
handLabel = new JLabel(); handLabel = new JLabel();
@ -315,6 +324,14 @@ public class PlayerPanelExt extends javax.swing.JPanel {
BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r); BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
avatar = new HoverButton("player", resized, resized, resized, r); avatar = new HoverButton("player", resized, resized, resized, r);
avatar.setLayout(new GridLayout(4, 1, 0, 0));
avatar.add(new JLabel());
avatar.add(new JLabel());
avatar.add(avatarFlag);
avatar.setAlignTextLeft(true);
avatarFlag.setHorizontalAlignment(JLabel.LEFT);
avatarFlag.setVerticalAlignment(JLabel.BOTTOM);
avatar.add(new JLabel());
String showPlayerNamePermanently = MageFrame.getPreferences().get(PreferencesDialog.KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true"); String showPlayerNamePermanently = MageFrame.getPreferences().get(PreferencesDialog.KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true");
if (showPlayerNamePermanently.equals("true")) { if (showPlayerNamePermanently.equals("true")) {
avatar.setTextAlwaysVisible(true); avatar.setTextAlwaysVisible(true);
@ -326,6 +343,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
session.sendPlayerUUID(gameId, playerId); session.sendPlayerUUID(gameId, playerId);
} }
}); });
// timer area /small layout) // timer area /small layout)
timerLabel.setToolTipText("Time left"); timerLabel.setToolTipText("Time left");
timerLabel.setSize(80, 12); timerLabel.setSize(80, 12);
@ -637,6 +655,8 @@ public class PlayerPanelExt extends javax.swing.JPanel {
.addComponent(btnPlayer, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnPlayer, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(timerLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(timerLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(avatar, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) .addComponent(avatar, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE))
// .addGroup(gl_panelBackground.createSequentialGroup()
// .addComponent(avatarFlag, GroupLayout.PREFERRED_SIZE, 16, GroupLayout.PREFERRED_SIZE))
.addGap(14)) .addGap(14))
.addGroup(gl_panelBackground.createSequentialGroup() .addGroup(gl_panelBackground.createSequentialGroup()
.addGap(6) .addGap(6)
@ -748,12 +768,14 @@ public class PlayerPanelExt extends javax.swing.JPanel {
protected void sizePlayerPanel(boolean smallMode) { protected void sizePlayerPanel(boolean smallMode) {
if (smallMode) { if (smallMode) {
avatar.setVisible(false); avatar.setVisible(false);
avatarFlag.setVisible(false);
btnPlayer.setVisible(true); btnPlayer.setVisible(true);
timerLabel.setVisible(true); timerLabel.setVisible(true);
panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT_SMALL)); panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT_SMALL));
panelBackground.setBounds(0, 0, PANEL_WIDTH - 2, PANEL_HEIGHT_SMALL); panelBackground.setBounds(0, 0, PANEL_WIDTH - 2, PANEL_HEIGHT_SMALL);
} else { } else {
avatar.setVisible(true); avatar.setVisible(true);
avatarFlag.setVisible(true);
btnPlayer.setVisible(false); btnPlayer.setVisible(false);
timerLabel.setVisible(false); timerLabel.setVisible(false);
panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT)); panelBackground.setPreferredSize(new Dimension(PANEL_WIDTH - 2, PANEL_HEIGHT));
@ -791,6 +813,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
} }
private HoverButton avatar; private HoverButton avatar;
private JLabel avatarFlag;
private JButton btnPlayer; private JButton btnPlayer;
private ImagePanel life; private ImagePanel life;
private ImagePanel poison; private ImagePanel poison;

View file

@ -456,7 +456,7 @@ public class MageActionCallback implements ActionCallback {
} }
/** /**
* Show the big card image on mouse position while hoovering over a card * Show the big card image on mouse position while hovering over a card
* *
* @param showAlternative defines if the original image (if it's a copied card) or the opposite side of a transformable card will be shown * @param showAlternative defines if the original image (if it's a copied card) or the opposite side of a transformable card will be shown
*/ */

View file

@ -31,7 +31,6 @@
* *
* Created on 20-Jan-2011, 9:18:30 PM * Created on 20-Jan-2011, 9:18:30 PM
*/ */
package mage.client.tournament; package mage.client.tournament;
import java.awt.Component; import java.awt.Component;
@ -45,14 +44,21 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.chat.ChatPanel; import mage.client.chat.ChatPanel;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import static mage.client.dialog.PreferencesDialog.KEY_TOURNAMENT_MATCH_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH;
import static mage.client.dialog.PreferencesDialog.KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER;
import static mage.client.dialog.PreferencesDialog.KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH;
import mage.client.util.ButtonColumn; import mage.client.util.ButtonColumn;
import mage.client.util.Format; import mage.client.util.Format;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.remote.Session; import mage.remote.Session;
import mage.view.RoundView; import mage.view.RoundView;
import mage.view.TournamentGameView; import mage.view.TournamentGameView;
@ -76,7 +82,12 @@ public class TournamentPanel extends javax.swing.JPanel {
private UpdateTournamentTask updateTask; private UpdateTournamentTask updateTask;
private final DateFormat df; private final DateFormat df;
/** Creates new form TournamentPanel */ private static final int[] defaultColumnsWidthPlayers = {30, 150, 150, 60, 400};
private static final int[] defaultColumnsWidthMatches = {60, 140, 140, 400, 80};
/**
* Creates new form TournamentPanel
*/
public TournamentPanel() { public TournamentPanel() {
playersModel = new TournamentPlayersTableModel(); playersModel = new TournamentPlayersTableModel();
matchesModel = new TournamentMatchesTableModel(); matchesModel = new TournamentMatchesTableModel();
@ -88,23 +99,24 @@ public class TournamentPanel extends javax.swing.JPanel {
df = DateFormat.getDateTimeInstance(); df = DateFormat.getDateTimeInstance();
tablePlayers.createDefaultColumnsFromModel(); tablePlayers.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tablePlayers, defaultColumnsWidthPlayers, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER);
tablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
tableMatches.createDefaultColumnsFromModel(); tableMatches.createDefaultColumnsFromModel();
TableUtil.setColumnWidthAndOrder(tableMatches, defaultColumnsWidthMatches, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER);
chatPanel1.useExtendedView(ChatPanel.VIEW_MODE.NONE); chatPanel1.useExtendedView(ChatPanel.VIEW_MODE.NONE);
chatPanel1.setChatType(ChatPanel.ChatType.TOURNAMENT); chatPanel1.setChatType(ChatPanel.ChatType.TOURNAMENT);
Action action = new AbstractAction() Action action = new AbstractAction() {
{
@Override @Override
public void actionPerformed(ActionEvent e) public void actionPerformed(ActionEvent e) {
{ int modelRow = Integer.valueOf(e.getActionCommand());
int modelRow = Integer.valueOf( e.getActionCommand() );
String state = (String)tableMatches.getValueAt(modelRow, 2);
String actionText = (String)tableMatches.getValueAt(modelRow, TournamentMatchesTableModel.ACTION_COLUMN);
UUID tableId = UUID.fromString((String)matchesModel.getValueAt(modelRow, TournamentMatchesTableModel.ACTION_COLUMN +1));
UUID gameId = UUID.fromString((String)matchesModel.getValueAt(modelRow, TournamentMatchesTableModel.ACTION_COLUMN +3));
String state = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(2));
String actionText = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN));
UUID tableId = UUID.fromString((String) matchesModel.getValueAt(modelRow, TournamentMatchesTableModel.ACTION_COLUMN + 1));
UUID gameId = UUID.fromString((String) matchesModel.getValueAt(modelRow, TournamentMatchesTableModel.ACTION_COLUMN + 3));
// if (state.equals("Finished") && action.equals("Replay")) { // if (state.equals("Finished") && action.equals("Replay")) {
// logger.info("Replaying game " + gameId); // logger.info("Replaying game " + gameId);
@ -118,7 +130,7 @@ public class TournamentPanel extends javax.swing.JPanel {
}; };
// action button, don't delete this // action button, don't delete this
ButtonColumn buttonColumn = new ButtonColumn(tableMatches, action, TournamentMatchesTableModel.ACTION_COLUMN); ButtonColumn buttonColumn = new ButtonColumn(tableMatches, action, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN));
} }
@ -127,6 +139,7 @@ public class TournamentPanel extends javax.swing.JPanel {
if (this.chatPanel1 != null) { if (this.chatPanel1 != null) {
this.chatPanel1.disconnect(); this.chatPanel1.disconnect();
} }
} }
private void saveDividerLocations() { private void saveDividerLocations() {
@ -167,8 +180,7 @@ public class TournamentPanel extends javax.swing.JPanel {
startTasks(); startTasks();
this.setVisible(true); this.setVisible(true);
this.repaint(); this.repaint();
} } else {
else {
hideTournament(); hideTournament();
} }
@ -182,12 +194,15 @@ public class TournamentPanel extends javax.swing.JPanel {
stopTasks(); stopTasks();
this.chatPanel1.disconnect(); this.chatPanel1.disconnect();
this.saveDividerLocations(); this.saveDividerLocations();
TableUtil.saveColumnWidthAndOrderToPrefs(tablePlayers, KEY_TOURNAMENT_PLAYER_COLUMNS_WIDTH, KEY_TOURNAMENT_PLAYER_COLUMNS_ORDER);
TableUtil.saveColumnWidthAndOrderToPrefs(tableMatches, KEY_TOURNAMENT_MATCH_COLUMNS_WIDTH, KEY_TOURNAMENT_MATCH_COLUMNS_ORDER);
Component c = this.getParent(); Component c = this.getParent();
while (c != null && !(c instanceof TournamentPane)) { while (c != null && !(c instanceof TournamentPane)) {
c = c.getParent(); c = c.getParent();
} }
if (c != null) { if (c != null) {
((TournamentPane)c).removeTournament(); ((TournamentPane) c).removeTournament();
} }
} }
@ -201,7 +216,7 @@ public class TournamentPanel extends javax.swing.JPanel {
c = c.getParent(); c = c.getParent();
} }
if (c != null) { if (c != null) {
((TournamentPane)c).setTitle("Tournament [" + tournament.getTournamentName() +"]"); ((TournamentPane) c).setTitle("Tournament [" + tournament.getTournamentName() + "]");
} }
txtName.setText(tournament.getTournamentName()); txtName.setText(tournament.getTournamentName());
txtType.setText(tournament.getTournamentType()); txtType.setText(tournament.getTournamentType());
@ -215,7 +230,7 @@ public class TournamentPanel extends javax.swing.JPanel {
case "Constructing": case "Constructing":
String timeLeft = ""; String timeLeft = "";
if (tournament.getStepStartTime() != null) { if (tournament.getStepStartTime() != null) {
timeLeft = Format.getDuration(tournament.getConstructionTime() - (tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime())/1000); timeLeft = Format.getDuration(tournament.getConstructionTime() - (tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime()) / 1000);
} }
txtTournamentState.setText(new StringBuilder(tournament.getTournamentState()).append(" (").append(timeLeft).append(")").toString()); txtTournamentState.setText(new StringBuilder(tournament.getTournamentState()).append(" (").append(timeLeft).append(")").toString());
break; break;
@ -223,7 +238,7 @@ public class TournamentPanel extends javax.swing.JPanel {
case "Drafting": case "Drafting":
String usedTime = ""; String usedTime = "";
if (tournament.getStepStartTime() != null) { if (tournament.getStepStartTime() != null) {
usedTime = Format.getDuration((tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime())/1000); usedTime = Format.getDuration((tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime()) / 1000);
} }
txtTournamentState.setText(tournament.getTournamentState() + " (" + usedTime + ") " + tournament.getRunningInfo()); txtTournamentState.setText(tournament.getTournamentState() + " (" + usedTime + ") " + tournament.getRunningInfo());
break; break;
@ -274,10 +289,10 @@ public class TournamentPanel extends javax.swing.JPanel {
} }
} }
/** This method is called from within the constructor to /**
* initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is * WARNING: Do NOT modify this code. The content of this method is always
* always regenerated by the Form Editor. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@ -505,7 +520,6 @@ public class TournamentPanel extends javax.swing.JPanel {
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_txtNameActionPerformed }//GEN-LAST:event_txtNameActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel actionPanel; private javax.swing.JPanel actionPanel;
private javax.swing.JButton btnCloseWindow; private javax.swing.JButton btnCloseWindow;
@ -532,7 +546,8 @@ public class TournamentPanel extends javax.swing.JPanel {
} }
class TournamentPlayersTableModel extends AbstractTableModel { class TournamentPlayersTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Player Name", "State", "Points", "Results"};
private final String[] columnNames = new String[]{"Loc", "Player Name", "State", "Points", "Results"};
private TournamentPlayerView[] players = new TournamentPlayerView[0]; private TournamentPlayerView[] players = new TournamentPlayerView[0];
public void loadData(TournamentView tournament) { public void loadData(TournamentView tournament) {
@ -554,12 +569,14 @@ class TournamentPlayersTableModel extends AbstractTableModel {
public Object getValueAt(int arg0, int arg1) { public Object getValueAt(int arg0, int arg1) {
switch (arg1) { switch (arg1) {
case 0: case 0:
return players[arg0].getName(); return players[arg0].getFlagName();
case 1: case 1:
return players[arg0].getState(); return players[arg0].getName();
case 2: case 2:
return Integer.toString(players[arg0].getPoints()); return players[arg0].getState();
case 3: case 3:
return Integer.toString(players[arg0].getPoints());
case 4:
return players[arg0].getResults(); return players[arg0].getResults();
} }
return ""; return "";
@ -577,8 +594,13 @@ class TournamentPlayersTableModel extends AbstractTableModel {
} }
@Override @Override
public Class getColumnClass(int columnIndex){ public Class getColumnClass(int columnIndex) {
return String.class; switch (columnIndex) {
case 0:
return Icon.class;
default:
return String.class;
}
} }
@Override @Override
@ -599,8 +621,8 @@ class TournamentMatchesTableModel extends AbstractTableModel {
public void loadData(TournamentView tournament) { public void loadData(TournamentView tournament) {
List<TournamentGameView> views = new ArrayList<>(); List<TournamentGameView> views = new ArrayList<>();
watchingAllowed = tournament.isWatchingAllowed(); watchingAllowed = tournament.isWatchingAllowed();
for (RoundView round: tournament.getRounds()) { for (RoundView round : tournament.getRounds()) {
for (TournamentGameView game: round.getGames()) { for (TournamentGameView game : round.getGames()) {
views.add(game); views.add(game);
} }
} }
@ -660,7 +682,7 @@ class TournamentMatchesTableModel extends AbstractTableModel {
} }
@Override @Override
public Class getColumnClass(int columnIndex){ public Class getColumnClass(int columnIndex) {
return String.class; return String.class;
} }
@ -709,7 +731,8 @@ class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
logger.fatal("Update Tournament Task error", ex); logger.fatal("Update Tournament Task error", ex);
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
logger.fatal("Update Tournament Task error", ex); logger.fatal("Update Tournament Task error", ex);
} catch (CancellationException ex) {} } catch (CancellationException ex) {
}
} }
} }

View file

@ -8,7 +8,6 @@ package mage.client.util.gui;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import org.mage.card.arcane.Util;
/** /**
* *
@ -33,9 +32,13 @@ public class TableUtil {
if (widths != null && widths.length > i) { if (widths != null && widths.length > i) {
width = widths[i]; width = widths[i];
} }
TableColumn column = table.getColumnModel().getColumn(i++); if (table.getColumnModel().getColumnCount() >= i) {
column.setWidth(width); TableColumn column = table.getColumnModel().getColumn(i++);
column.setPreferredWidth(width); column.setWidth(width);
column.setPreferredWidth(width);
} else {
break;
}
} }
// set the column order // set the column order
@ -69,7 +72,6 @@ public class TableUtil {
} }
public static int[] getIntArrayFromString(String stringData) { public static int[] getIntArrayFromString(String stringData) {
int[] intArray = null; int[] intArray = null;
if (stringData != null && !stringData.isEmpty()) { if (stringData != null && !stringData.isEmpty()) {
@ -79,7 +81,8 @@ public class TableUtil {
for (int i = 0; i < lengthW; i++) { for (int i = 0; i < lengthW; i++) {
try { try {
intArray[i] = Integer.parseInt(items[i]); intArray[i] = Integer.parseInt(items[i]);
} catch (NumberFormatException nfe) {} } catch (NumberFormatException nfe) {
}
} }
} }
return intArray; return intArray;

View file

@ -25,17 +25,12 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.client.util.gui.countryBox; package mage.client.util.gui.countryBox;
import java.awt.Component; import java.awt.Component;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import org.apache.log4j.Logger;
/** /**
* *
@ -43,38 +38,15 @@ import org.apache.log4j.Logger;
*/ */
public class CountryCellRenderer extends DefaultTableCellRenderer { public class CountryCellRenderer extends DefaultTableCellRenderer {
private static final Logger logger = Logger.getLogger(CountryCellRenderer.class);
private final Map<String, ImageIcon> flagIconCache = new HashMap<>();
private final Map<String, String> countryMap = new HashMap<>();
public CountryCellRenderer() {
for( int i = 0; i <= CountryComboBox.countryList.length - 1; i++) {
countryMap.put(CountryComboBox.countryList[i][1],CountryComboBox.countryList[i][0]);
}
}
@Override @Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(table.convertColumnIndexToView(0) == column) { if (value == null || ((String) value).isEmpty()) {
label.setToolTipText(countryMap.get((String)value)); value = (String) "world";
label.setIcon(getCountryFlagIcon((String)value));
label.setText("");
}
return label;
}
private ImageIcon getCountryFlagIcon(String countryCode) {
ImageIcon flagIcon = flagIconCache.get(countryCode);
if (flagIcon == null) {
flagIcon = new javax.swing.ImageIcon(getClass().getResource("/flags/" + countryCode + (countryCode.endsWith(".png") ? "" :".png")));
if (flagIcon.getImage() == null) {
logger.warn("Country flag resource not found: " + countryCode);
} else {
flagIconCache.put(countryCode, flagIcon);
}
} }
return flagIcon; label.setToolTipText(CountryUtil.getCountryName((String) value));
label.setIcon(CountryUtil.getCountryFlagIcon((String) value));
label.setText("");
return label;
} }
} }

View file

@ -0,0 +1,49 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.util.gui.countryBox;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
import org.apache.log4j.Logger;
/**
*
* @author LevelX2
*/
public class CountryUtil {
private static final Logger logger = Logger.getLogger(CountryUtil.class);
private static final Map<String, ImageIcon> flagIconCache = new HashMap<>();
private static final Map<String, String> countryMap = new HashMap<>();
public static ImageIcon getCountryFlagIcon(String countryCode) {
ImageIcon flagIcon = flagIconCache.get(countryCode);
if (flagIcon == null) {
URL url = CountryUtil.class.getResource("/flags/" + countryCode + (countryCode.endsWith(".png") ? "" : ".png"));
if (url != null) {
flagIcon = new javax.swing.ImageIcon(url);
}
if (flagIcon == null || flagIcon.getImage() == null) {
logger.warn("Country flag resource not found: " + countryCode);
flagIconCache.put(countryCode, flagIcon);
} else {
flagIconCache.put(countryCode, flagIcon);
}
}
return flagIcon;
}
public static String getCountryName(String countryCode) {
if (countryMap.isEmpty()) {
for (int i = 0; i <= CountryComboBox.countryList.length - 1; i++) {
countryMap.put(CountryComboBox.countryList[i][1], CountryComboBox.countryList[i][0]);
}
}
return countryMap.get(countryCode);
}
}

View file

@ -242,7 +242,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
showCopySourceButton = new JButton(""); showCopySourceButton = new JButton("");
showCopySourceButton.setLocation(2, 2); showCopySourceButton.setLocation(2, 2);
showCopySourceButton.setSize(25, 25); showCopySourceButton.setSize(25, 25);
showCopySourceButton.setToolTipText("This permanent is copying a target. To see original image, push this button or turn mouse wheel down while hoovering with the mouse pointer over the permanent."); showCopySourceButton.setToolTipText("This permanent is copying a target. To see original image, push this button or turn mouse wheel down while hovering with the mouse pointer over the permanent.");
copyIconPanel.setVisible(((PermanentView) this.gameCard).isCopy()); copyIconPanel.setVisible(((PermanentView) this.gameCard).isCopy());
showCopySourceButton.setIcon(new ImageIcon(ImageManagerImpl.getInstance().getCopyInformIconImage())); showCopySourceButton.setIcon(new ImageIcon(ImageManagerImpl.getInstance().getCopyInformIconImage()));

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-common</artifactId> <artifactId>mage-common</artifactId>

View file

@ -1,39 +1,38 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.constants; package mage.constants;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class Constants { public final class Constants {
private Constants() { private Constants() {
throw new AssertionError(); throw new AssertionError();
} }
@ -74,13 +73,16 @@ public final class Constants {
public static final int PRIORITY_TIME_SEC = 1200; public static final int PRIORITY_TIME_SEC = 1200;
public enum SessionState { public enum SessionState {
DISCONNECTED, CONNECTED, CONNECTING, DISCONNECTING, SERVER_STARTING; DISCONNECTED, CONNECTED, CONNECTING, DISCONNECTING, SERVER_STARTING;
} }
public enum Option { public enum Option {
; ;
public static final String POSSIBLE_ATTACKERS = "possibleAttackers"; public static final String POSSIBLE_ATTACKERS = "possibleAttackers";
public static final String SPECIAL_BUTTON = "specialButton";
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.interfaces; package mage.interfaces;
import java.util.List; import java.util.List;
@ -40,14 +39,14 @@ import mage.constants.PlayerAction;
import mage.game.GameException; import mage.game.GameException;
import mage.game.match.MatchOptions; import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentOptions;
import mage.players.net.UserData;
import mage.utils.MageVersion; import mage.utils.MageVersion;
import mage.view.DraftPickView; import mage.view.DraftPickView;
import mage.view.GameView; import mage.view.GameView;
import mage.view.MatchView; import mage.view.MatchView;
import mage.view.RoomUsersView;
import mage.view.TableView; import mage.view.TableView;
import mage.view.TournamentView; import mage.view.TournamentView;
import mage.view.UserDataView;
import mage.view.RoomUsersView;
import mage.view.UserView; import mage.view.UserView;
/** /**
@ -58,22 +57,28 @@ public interface MageServer {
// connection methods // connection methods
boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException; boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException;
boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException; boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException;
// Not used // Not used
// void deregisterClient(String sessionId) throws MageException; // void deregisterClient(String sessionId) throws MageException;
// update methods // update methods
List<ExpansionInfo> getMissingExpansionData(List<String> codes); List<ExpansionInfo> getMissingExpansionData(List<String> codes);
List<CardInfo> getMissingCardsData(List<String> classNames); List<CardInfo> getMissingCardsData(List<String> classNames);
// user methods // user methods
boolean setUserData(String userName, String sessionId, UserDataView userDataView) throws MageException; boolean setUserData(String userName, String sessionId, UserData userData) throws MageException;
void sendFeedbackMessage(String sessionId, String username, String title, String type, String message, String email) throws MageException; void sendFeedbackMessage(String sessionId, String username, String title, String type, String message, String email) throws MageException;
// server state methods // server state methods
ServerState getServerState() throws MageException; ServerState getServerState() throws MageException;
List<RoomUsersView> getRoomUsers(UUID roomId) throws MageException; List<RoomUsersView> getRoomUsers(UUID roomId) throws MageException;
List<MatchView> getFinishedMatches(UUID roomId) throws MageException; List<MatchView> getFinishedMatches(UUID roomId) throws MageException;
Object getServerMessagesCompressed(String sessionId) throws MageException; // messages of the day Object getServerMessagesCompressed(String sessionId) throws MageException; // messages of the day
// ping - extends session // ping - extends session
@ -81,27 +86,46 @@ public interface MageServer {
//table methods //table methods
TableView createTable(String sessionId, UUID roomId, MatchOptions matchOptions) throws MageException; TableView createTable(String sessionId, UUID roomId, MatchOptions matchOptions) throws MageException;
TableView createTournamentTable(String sessionId, UUID roomId, TournamentOptions tournamentOptions) throws MageException; TableView createTournamentTable(String sessionId, UUID roomId, TournamentOptions tournamentOptions) throws MageException;
boolean joinTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; boolean joinTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException;
boolean joinTournamentTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; boolean joinTournamentTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException;
boolean submitDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException; boolean submitDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException;
void updateDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException; void updateDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException;
boolean watchTable(String sessionId, UUID roomId, UUID tableId) throws MageException; boolean watchTable(String sessionId, UUID roomId, UUID tableId) throws MageException;
boolean watchTournamentTable(String sessionId, UUID tableId) throws MageException; boolean watchTournamentTable(String sessionId, UUID tableId) throws MageException;
boolean leaveTable(String sessionId, UUID roomId, UUID tableId) throws MageException; boolean leaveTable(String sessionId, UUID roomId, UUID tableId) throws MageException;
void swapSeats(String sessionId, UUID roomId, UUID tableId, int seatNum1, int seatNum2) throws MageException; void swapSeats(String sessionId, UUID roomId, UUID tableId, int seatNum1, int seatNum2) throws MageException;
void removeTable(String sessionId, UUID roomId, UUID tableId) throws MageException; void removeTable(String sessionId, UUID roomId, UUID tableId) throws MageException;
boolean isTableOwner(String sessionId, UUID roomId, UUID tableId) throws MageException; boolean isTableOwner(String sessionId, UUID roomId, UUID tableId) throws MageException;
TableView getTable(UUID roomId, UUID tableId) throws MageException; TableView getTable(UUID roomId, UUID tableId) throws MageException;
List<TableView> getTables(UUID roomId) throws MageException; List<TableView> getTables(UUID roomId) throws MageException;
//chat methods //chat methods
void sendChatMessage(UUID chatId, String userName, String message) throws MageException; void sendChatMessage(UUID chatId, String userName, String message) throws MageException;
void joinChat(UUID chatId, String sessionId, String userName) throws MageException; void joinChat(UUID chatId, String sessionId, String userName) throws MageException;
void leaveChat(UUID chatId, String sessionId) throws MageException; void leaveChat(UUID chatId, String sessionId) throws MageException;
UUID getTableChatId(UUID tableId) throws MageException; UUID getTableChatId(UUID tableId) throws MageException;
UUID getGameChatId(UUID gameId) throws MageException; UUID getGameChatId(UUID gameId) throws MageException;
UUID getRoomChatId(UUID roomId) throws MageException; UUID getRoomChatId(UUID roomId) throws MageException;
UUID getTournamentChatId(UUID tournamentId) throws MageException; UUID getTournamentChatId(UUID tournamentId) throws MageException;
//room methods //room methods
@ -109,50 +133,77 @@ public interface MageServer {
//game methods //game methods
boolean startMatch(String sessionId, UUID roomId, UUID tableId) throws MageException; boolean startMatch(String sessionId, UUID roomId, UUID tableId) throws MageException;
void joinGame(UUID gameId, String sessionId) throws MageException; void joinGame(UUID gameId, String sessionId) throws MageException;
void watchGame(UUID gameId, String sessionId) throws MageException; void watchGame(UUID gameId, String sessionId) throws MageException;
void stopWatching(UUID gameId, String sessionId) throws MageException; void stopWatching(UUID gameId, String sessionId) throws MageException;
void sendPlayerUUID(UUID gameId, String sessionId, UUID data) throws MageException; void sendPlayerUUID(UUID gameId, String sessionId, UUID data) throws MageException;
void sendPlayerString(UUID gameId, String sessionId, String data) throws MageException; void sendPlayerString(UUID gameId, String sessionId, String data) throws MageException;
void sendPlayerBoolean(UUID gameId, String sessionId, Boolean data) throws MageException; void sendPlayerBoolean(UUID gameId, String sessionId, Boolean data) throws MageException;
void sendPlayerInteger(UUID gameId, String sessionId, Integer data) throws MageException; void sendPlayerInteger(UUID gameId, String sessionId, Integer data) throws MageException;
void sendPlayerManaType(UUID gameId, UUID playerId, String sessionId, ManaType data) throws MageException; void sendPlayerManaType(UUID gameId, UUID playerId, String sessionId, ManaType data) throws MageException;
void quitMatch(UUID gameId, String sessionId) throws MageException; void quitMatch(UUID gameId, String sessionId) throws MageException;
GameView getGameView(UUID gameId, String sessionId, UUID playerId) throws MageException; GameView getGameView(UUID gameId, String sessionId, UUID playerId) throws MageException;
// priority, undo, concede, mana pool // priority, undo, concede, mana pool
void sendPlayerAction(PlayerAction playerAction, UUID gameId, String sessionId, Object data) throws MageException; void sendPlayerAction(PlayerAction playerAction, UUID gameId, String sessionId, Object data) throws MageException;
//tournament methods //tournament methods
boolean startTournament(String sessionId, UUID roomId, UUID tableId) throws MageException; boolean startTournament(String sessionId, UUID roomId, UUID tableId) throws MageException;
void joinTournament(UUID draftId, String sessionId) throws MageException; void joinTournament(UUID draftId, String sessionId) throws MageException;
void quitTournament(UUID tournamentId, String sessionId) throws MageException; void quitTournament(UUID tournamentId, String sessionId) throws MageException;
TournamentView getTournament(UUID tournamentId) throws MageException; TournamentView getTournament(UUID tournamentId) throws MageException;
//draft methods //draft methods
void joinDraft(UUID draftId, String sessionId) throws MageException; void joinDraft(UUID draftId, String sessionId) throws MageException;
void quitDraft(UUID draftId, String sessionId) throws MageException; void quitDraft(UUID draftId, String sessionId) throws MageException;
DraftPickView sendCardPick(UUID draftId, String sessionId, UUID cardId, Set<UUID> hiddenCards) throws MageException; DraftPickView sendCardPick(UUID draftId, String sessionId, UUID cardId, Set<UUID> hiddenCards) throws MageException;
void sendCardMark(UUID draftId, String sessionId, UUID cardId) throws MageException; void sendCardMark(UUID draftId, String sessionId, UUID cardId) throws MageException;
//challenge methods //challenge methods
// void startChallenge(String sessionId, UUID roomId, UUID tableId, UUID challengeId) throws MageException; // void startChallenge(String sessionId, UUID roomId, UUID tableId, UUID challengeId) throws MageException;
//replay methods //replay methods
void replayGame(UUID gameId, String sessionId) throws MageException; void replayGame(UUID gameId, String sessionId) throws MageException;
void startReplay(UUID gameId, String sessionId) throws MageException; void startReplay(UUID gameId, String sessionId) throws MageException;
void stopReplay(UUID gameId, String sessionId) throws MageException; void stopReplay(UUID gameId, String sessionId) throws MageException;
void nextPlay(UUID gameId, String sessionId) throws MageException; void nextPlay(UUID gameId, String sessionId) throws MageException;
void previousPlay(UUID gameId, String sessionId) throws MageException; void previousPlay(UUID gameId, String sessionId) throws MageException;
void skipForward(UUID gameId, String sessionId, int moves) throws MageException; void skipForward(UUID gameId, String sessionId, int moves) throws MageException;
//test methods //test methods
void cheat(UUID gameId, String sessionId, UUID playerId, DeckCardLists deckList) throws MageException; void cheat(UUID gameId, String sessionId, UUID playerId, DeckCardLists deckList) throws MageException;
boolean cheat(UUID gameId, String sessionId, UUID playerId, String cardName) throws MageException; boolean cheat(UUID gameId, String sessionId, UUID playerId, String cardName) throws MageException;
//admin methods //admin methods
List<UserView> getUsers(String sessionId) throws MageException; List<UserView> getUsers(String sessionId) throws MageException;
void disconnectUser(String sessionId, String userSessionId) throws MageException; void disconnectUser(String sessionId, String userSessionId) throws MageException;
void endUserSession(String sessionId, String userSessionId) throws MageException; void endUserSession(String sessionId, String userSessionId) throws MageException;
void removeTable(String sessionId, UUID tableId) throws MageException; void removeTable(String sessionId, UUID tableId) throws MageException;
void sendBroadcastMessage(String sessionId, String message) throws MageException; void sendBroadcastMessage(String sessionId, String message) throws MageException;
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2011 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 * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.remote; package mage.remote;
import java.net.Inet4Address; import java.net.Inet4Address;
@ -34,8 +33,7 @@ import java.net.InterfaceAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.util.Enumeration; import java.util.Enumeration;
import mage.players.net.UserSkipPrioritySteps; import mage.players.net.UserData;
import mage.view.UserDataView;
/** /**
* *
@ -55,7 +53,7 @@ public class Connection {
private int clientCardDatabaseVersion; private int clientCardDatabaseVersion;
private boolean forceDBComparison; private boolean forceDBComparison;
private UserDataView userData; private UserData userData;
// private int avatarId; // private int avatarId;
// private boolean showAbilityPickerForced; // private boolean showAbilityPickerForced;
@ -63,7 +61,6 @@ public class Connection {
// private boolean confirmEmptyManaPool; // private boolean confirmEmptyManaPool;
// private String flagName; // private String flagName;
// private UserSkipPrioritySteps userSkipPrioritySteps; // private UserSkipPrioritySteps userSkipPrioritySteps;
private static final String serialization = "?serializationtype=jboss"; private static final String serialization = "?serializationtype=jboss";
private static final String transport = "bisocket"; private static final String transport = "bisocket";
@ -84,7 +81,7 @@ public class Connection {
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (! (object instanceof Connection)) { if (!(object instanceof Connection)) {
return false; return false;
} }
Connection otherConnection = (Connection) object; Connection otherConnection = (Connection) object;
@ -119,6 +116,7 @@ public class Connection {
} }
public enum ProxyType { public enum ProxyType {
SOCKS("Socks"), HTTP("HTTP"), NONE("None"); SOCKS("Socks"), HTTP("HTTP"), NONE("None");
private final String text; private final String text;
@ -207,12 +205,12 @@ public class Connection {
} }
public static InetAddress getLocalAddress() throws SocketException { public static InetAddress getLocalAddress() throws SocketException {
for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements(); ) { for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) {
NetworkInterface iface = interfaces.nextElement( ); NetworkInterface iface = interfaces.nextElement();
if (iface.isLoopback()) { if (iface.isLoopback()) {
continue; continue;
} }
for (InterfaceAddress addr: iface.getInterfaceAddresses()) { for (InterfaceAddress addr : iface.getInterfaceAddresses()) {
if (addr != null) { if (addr != null) {
InetAddress iaddr = addr.getAddress(); InetAddress iaddr = addr.getAddress();
if (iaddr != null && iaddr instanceof Inet4Address) { if (iaddr != null && iaddr instanceof Inet4Address) {
@ -224,11 +222,11 @@ public class Connection {
return null; return null;
} }
public void setUserData(UserDataView userData) { public void setUserData(UserData userData) {
this.userData= userData; this.userData = userData;
} }
public UserDataView getUserData() { public UserData getUserData() {
return userData; return userData;
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.remote; package mage.remote;
import java.io.IOException; import java.io.IOException;
@ -61,8 +60,8 @@ import mage.interfaces.MageClient;
import mage.interfaces.MageServer; import mage.interfaces.MageServer;
import mage.interfaces.ServerState; import mage.interfaces.ServerState;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
import mage.players.net.UserData;
import mage.utils.CompressUtil; import mage.utils.CompressUtil;
import mage.players.net.UserSkipPrioritySteps;
import mage.view.DraftPickView; import mage.view.DraftPickView;
import mage.view.GameTypeView; import mage.view.GameTypeView;
import mage.view.MatchView; import mage.view.MatchView;
@ -70,7 +69,6 @@ import mage.view.RoomUsersView;
import mage.view.TableView; import mage.view.TableView;
import mage.view.TournamentTypeView; import mage.view.TournamentTypeView;
import mage.view.TournamentView; import mage.view.TournamentView;
import mage.view.UserDataView;
import mage.view.UserView; import mage.view.UserView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jboss.remoting.CannotConnectException; import org.jboss.remoting.CannotConnectException;
@ -168,17 +166,17 @@ public class SessionImpl implements Session {
Map<String, String> metadata = new HashMap<>(); Map<String, String> metadata = new HashMap<>();
/* /*
5.8.3.1.1. Write timeouts 5.8.3.1.1. Write timeouts
The socket timeout facility offered by the JDK applies only to read operations on the socket. As of release 2.5.2, The socket timeout facility offered by the JDK applies only to read operations on the socket. As of release 2.5.2,
the socket and bisocket (and also sslsocket and sslbisocket) transports offer a write timeout facility. When a client the socket and bisocket (and also sslsocket and sslbisocket) transports offer a write timeout facility. When a client
or server is configured, in any of the usual ways, with the parameter org.jboss.remoting.transport.socket.SocketWrapper.WRITE_TIMEOUT or server is configured, in any of the usual ways, with the parameter org.jboss.remoting.transport.socket.SocketWrapper.WRITE_TIMEOUT
(actual value "writeTimeout") set to a positive value (in milliseconds), all write operations will time out if they do (actual value "writeTimeout") set to a positive value (in milliseconds), all write operations will time out if they do
not complete within the configured period. When a write operation times out, the socket upon which the write was invoked not complete within the configured period. When a write operation times out, the socket upon which the write was invoked
will be closed, which is likely to result in a java.net.SocketException. will be closed, which is likely to result in a java.net.SocketException.
Note. A SocketException is considered to be a "retriable" exception, so, if the parameter "numberOfCallRetries" is set Note. A SocketException is considered to be a "retriable" exception, so, if the parameter "numberOfCallRetries" is set
to a value greater than 1, an invocation interrupted by a write timeout can be retried. to a value greater than 1, an invocation interrupted by a write timeout can be retried.
Note. The write timeout facility applies to writing of both invocations and responses. It applies to push callbacks as well. Note. The write timeout facility applies to writing of both invocations and responses. It applies to push callbacks as well.
*/ */
metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000"); metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
metadata.put("generalizeSocketException", "true"); metadata.put("generalizeSocketException", "true");
server = (MageServer) TransporterClient.createTransporterClient(clientLocator.getLocatorURI(), MageServer.class, metadata); server = (MageServer) TransporterClient.createTransporterClient(clientLocator.getLocatorURI(), MageServer.class, metadata);
@ -187,60 +185,66 @@ public class SessionImpl implements Session {
Map<String, String> clientMetadata = new HashMap<>(); Map<String, String> clientMetadata = new HashMap<>();
clientMetadata.put(SocketWrapper.WRITE_TIMEOUT, "2000"); clientMetadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
/* generalizeSocketException /* generalizeSocketException
* If set to false, a failed invocation will be retried in the case of * If set to false, a failed invocation will be retried in the case of
* SocketExceptions. If set to true, a failed invocation will be retried in the case of * SocketExceptions. If set to true, a failed invocation will be retried in the case of
* <classname>SocketException</classname>s and also any <classname>IOException</classname> * <classname>SocketException</classname>s and also any <classname>IOException</classname>
* whose message matches the regular expression * whose message matches the regular expression
* <code>^.*(?:connection.*reset|connection.*closed|broken.*pipe).*$</code>. * <code>^.*(?:connection.*reset|connection.*closed|broken.*pipe).*$</code>.
* See also the "numberOfCallRetries" parameter, above. The default value is false.*/ * See also the "numberOfCallRetries" parameter, above. The default value is false.*/
clientMetadata.put("generalizeSocketException", "true"); clientMetadata.put("generalizeSocketException", "true");
/* A remoting server also has the capability to detect when a client is no longer available. /* A remoting server also has the capability to detect when a client is no longer available.
* This is done by estabilishing a lease with the remoting clients that connect to a server. * This is done by estabilishing a lease with the remoting clients that connect to a server.
* On the client side, an org.jboss.remoting.LeasePinger periodically sends PING messages to * On the client side, an org.jboss.remoting.LeasePinger periodically sends PING messages to
* the server, and on the server side an org.jboss.remoting.Lease informs registered listeners * the server, and on the server side an org.jboss.remoting.Lease informs registered listeners
* if the PING doesn't arrive withing the specified timeout period. */ * if the PING doesn't arrive withing the specified timeout period. */
clientMetadata.put(Client.ENABLE_LEASE, "true"); clientMetadata.put(Client.ENABLE_LEASE, "true");
/* /*
When the socket client invoker makes its first invocation, it will check to see if there is an available When the socket client invoker makes its first invocation, it will check to see if there is an available
socket connection in its pool. Since is the first invocation, there will not be and will create a new socket socket connection in its pool. Since is the first invocation, there will not be and will create a new socket
connection and use it for making the invocation. Then when finished making invocation, will return the still connection and use it for making the invocation. Then when finished making invocation, will return the still
active socket connection to the pool. As more client invocations are made, is possible for the number of active socket connection to the pool. As more client invocations are made, is possible for the number of
socket connections to reach the maximum allowed (which is controlled by 'clientMaxPoolSize' property). At this socket connections to reach the maximum allowed (which is controlled by 'clientMaxPoolSize' property). At this
point, when the next client invocation is made, it will wait up to some configured number of milliseconds, at point, when the next client invocation is made, it will wait up to some configured number of milliseconds, at
which point it will throw an org.jboss.remoting.CannotConnectException. The number of milliseconds is given by which point it will throw an org.jboss.remoting.CannotConnectException. The number of milliseconds is given by
the parameter MicroSocketClientInvoker.CONNECTION_WAIT (actual value "connectionWait"), with a default of the parameter MicroSocketClientInvoker.CONNECTION_WAIT (actual value "connectionWait"), with a default of
30000 milliseconds. Note that if more than one call retry is configured (see next paragraph), 30000 milliseconds. Note that if more than one call retry is configured (see next paragraph),
the CannotConnectException will be swallowed. the CannotConnectException will be swallowed.
Once the socket client invoker get an available socket connection from the pool, are not out of the woods yet. Once the socket client invoker get an available socket connection from the pool, are not out of the woods yet.
For example, a network problem could cause a java.net.SocketException. There is also a possibility that the socket For example, a network problem could cause a java.net.SocketException. There is also a possibility that the socket
connection, while still appearing to be valid, has "gone stale" while sitting in the pool. For example, a ServerThread connection, while still appearing to be valid, has "gone stale" while sitting in the pool. For example, a ServerThread
on the other side of the connection could time out and close its socket. If the attempt to complete an invocation on the other side of the connection could time out and close its socket. If the attempt to complete an invocation
fails, then MicroSocketClientInvoker will make a number of attempts, according to the parameter "numberOfCallRetries", fails, then MicroSocketClientInvoker will make a number of attempts, according to the parameter "numberOfCallRetries",
with a default value of 3. Once the configured number of retries has been exhausted, with a default value of 3. Once the configured number of retries has been exhausted,
an org.jboss.remoting.InvocationFailureException will be thrown. an org.jboss.remoting.InvocationFailureException will be thrown.
*/ */
clientMetadata.put("numberOfCallRetries", "1"); clientMetadata.put("numberOfCallRetries", "1");
/** /**
* I'll explain the meaning of "secondaryBindPort" and "secondaryConnectPort", and maybe that will help. * I'll explain the meaning of "secondaryBindPort" and
* The Remoting bisocket transport creates two ServerSockets on the server. The "primary" ServerSocket is used to create * "secondaryConnectPort", and maybe that will help. The Remoting
* connections used for ordinary invocations, e.g., a request to create a JMS consumer, and the "secondary" ServerSocket * bisocket transport creates two ServerSockets on the server. The
* is used to create "control" connections for internal Remoting messages. The port for the primary ServerSocket is configured * "primary" ServerSocket is used to create connections used for
* by the "serverBindPort" parameter, and the port for the secondary ServerSocket is, by default, chosen randomly. * ordinary invocations, e.g., a request to create a JMS consumer,
* The "secondaryBindPort" parameter can be used to assign a specific port to the secondary ServerSocket. Now, if there is a * and the "secondary" ServerSocket is used to create "control"
* translating firewall between the client and server, the client should be given the value of the port that is translated * connections for internal Remoting messages. The port for the
* to the actual binding port of the secondary ServerSocket. * primary ServerSocket is configured by the "serverBindPort"
* For example, your configuration will tell the secondary ServerSocket to bind to port 14000, and it will tell the client to * parameter, and the port for the secondary ServerSocket is, by
* connect to port 14001. It assumes that there is a firewall which will translate 14001 to 14000. Apparently, that's not happening. * default, chosen randomly. The "secondaryBindPort" parameter can
* be used to assign a specific port to the secondary ServerSocket.
* Now, if there is a translating firewall between the client and
* server, the client should be given the value of the port that is
* translated to the actual binding port of the secondary
* ServerSocket. For example, your configuration will tell the
* secondary ServerSocket to bind to port 14000, and it will tell
* the client to connect to port 14001. It assumes that there is a
* firewall which will translate 14001 to 14000. Apparently, that's
* not happening.
*/ */
// secondaryBindPort - the port to which the secondary server socket is to be bound. By default, an arbitrary port is selected. // secondaryBindPort - the port to which the secondary server socket is to be bound. By default, an arbitrary port is selected.
// secondaryConnectPort - the port clients are to use to connect to the secondary server socket. // secondaryConnectPort - the port clients are to use to connect to the secondary server socket.
// By default, the value of secondaryBindPort is used. secondaryConnectPort is useful if the server is behind a translating firewall. // By default, the value of secondaryBindPort is used. secondaryConnectPort is useful if the server is behind a translating firewall.
// Indicated the max number of threads used within oneway thread pool. // Indicated the max number of threads used within oneway thread pool.
clientMetadata.put(Client.MAX_NUM_ONEWAY_THREADS, "10"); clientMetadata.put(Client.MAX_NUM_ONEWAY_THREADS, "10");
clientMetadata.put(Remoting.USE_CLIENT_CONNECTION_IDENTITY, "true"); clientMetadata.put(Remoting.USE_CLIENT_CONNECTION_IDENTITY, "true");
@ -269,7 +273,7 @@ public class SessionImpl implements Session {
logger.warn("There should be one callback Connector (number existing = " + callbackConnectors.size() + ")"); logger.warn("There should be one callback Connector (number existing = " + callbackConnectors.size() + ")");
} }
logger.info("Trying to connect as " + (this.getUserName() == null ? "":this.getUserName()) + " to XMAGE server at " + connection.getHost() + ":" + connection.getPort()); logger.info("Trying to connect as " + (this.getUserName() == null ? "" : this.getUserName()) + " to XMAGE server at " + connection.getHost() + ":" + connection.getPort());
callbackClient.invoke(null); callbackClient.invoke(null);
this.sessionId = callbackClient.getSessionId(); this.sessionId = callbackClient.getSessionId();
@ -289,15 +293,15 @@ public class SessionImpl implements Session {
if (!connection.getUsername().equals("Admin")) { if (!connection.getUsername().equals("Admin")) {
updateDatabase(connection.isForceDBComparison(), serverState); updateDatabase(connection.isForceDBComparison(), serverState);
} }
logger.info("Connected as " + (this.getUserName() == null ? "":this.getUserName()) + " to MAGE server at " + connection.getHost() + ":" + connection.getPort()); logger.info("Connected as " + (this.getUserName() == null ? "" : this.getUserName()) + " to MAGE server at " + connection.getHost() + ":" + connection.getPort());
client.connected(this.getUserName() == null ? "":this.getUserName() +"@" + connection.getHost() + ":" + connection.getPort() +" "); client.connected(this.getUserName() == null ? "" : this.getUserName() + "@" + connection.getHost() + ":" + connection.getPort() + " ");
return true; return true;
} }
disconnect(false); disconnect(false);
// client.showMessage("Unable to connect to server."); // client.showMessage("Unable to connect to server.");
} catch (MalformedURLException ex) { } catch (MalformedURLException ex) {
logger.fatal("", ex); logger.fatal("", ex);
client.showMessage("Unable to connect to server. " + ex.getMessage()); client.showMessage("Unable to connect to server. " + ex.getMessage());
} catch (UndeclaredThrowableException ex) { } catch (UndeclaredThrowableException ex) {
String addMessage = ""; String addMessage = "";
if (ex.getCause() instanceof InvocationFailureException) { if (ex.getCause() instanceof InvocationFailureException) {
@ -311,17 +315,17 @@ public class SessionImpl implements Session {
if (addMessage.isEmpty()) { if (addMessage.isEmpty()) {
logger.fatal("", ex); logger.fatal("", ex);
} }
client.showMessage("Unable to connect to server. " + addMessage + (ex.getMessage() != null ? ex.getMessage():"")); client.showMessage("Unable to connect to server. " + addMessage + (ex.getMessage() != null ? ex.getMessage() : ""));
} catch (IOException ex) { } catch (IOException ex) {
logger.fatal("", ex); logger.fatal("", ex);
String addMessage = ""; String addMessage = "";
if (ex.getMessage() != null && ex.getMessage().startsWith("Unable to perform invocation")) { if (ex.getMessage() != null && ex.getMessage().startsWith("Unable to perform invocation")) {
addMessage = "Maybe the server version is not compatible. "; addMessage = "Maybe the server version is not compatible. ";
} }
client.showMessage("Unable to connect to server. " + addMessage + ex.getMessage() != null ? ex.getMessage():""); client.showMessage("Unable to connect to server. " + addMessage + ex.getMessage() != null ? ex.getMessage() : "");
} catch (MageVersionException ex) { } catch (MageVersionException ex) {
if (!canceled) { if (!canceled) {
client.showMessage("Unable to connect to server. " + ex.getMessage()); client.showMessage("Unable to connect to server. " + ex.getMessage());
} }
disconnect(false); disconnect(false);
} catch (CannotConnectException ex) { } catch (CannotConnectException ex) {
@ -334,7 +338,7 @@ public class SessionImpl implements Session {
disconnect(false); disconnect(false);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Unable to connect to server.\n"); sb.append("Unable to connect to server.\n");
for (StackTraceElement element :t.getStackTrace()) { for (StackTraceElement element : t.getStackTrace()) {
sb.append(element.toString()).append("\n"); sb.append(element.toString()).append("\n");
} }
client.showMessage(sb.toString()); client.showMessage(sb.toString());
@ -350,8 +354,8 @@ public class SessionImpl implements Session {
List<CardInfo> cards = server.getMissingCardsData(classNames); List<CardInfo> cards = server.getMissingCardsData(classNames);
CardRepository.instance.addCards(cards); CardRepository.instance.addCards(cards);
CardRepository.instance.setContentVersion(serverState.getCardsContentVersion()); CardRepository.instance.setContentVersion(serverState.getCardsContentVersion());
logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size() + logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size()
" content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion); + " content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion);
} }
long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB(); long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB();
@ -362,8 +366,8 @@ public class SessionImpl implements Session {
ExpansionRepository.instance.add(expansion); ExpansionRepository.instance.add(expansion);
} }
ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion()); ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion());
logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size()+ logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size()
" content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion); + " content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion);
} }
} }
@ -399,7 +403,8 @@ public class SessionImpl implements Session {
/** /**
* *
* @param askForReconnect - true = connection was lost because of error and ask the user if he want to try to reconnect * @param askForReconnect - true = connection was lost because of error and
* ask the user if he want to try to reconnect
*/ */
@Override @Override
public synchronized void disconnect(boolean askForReconnect) { public synchronized void disconnect(boolean askForReconnect) {
@ -450,10 +455,11 @@ public class SessionImpl implements Session {
} }
class CallbackHandler implements InvokerCallbackHandler { class CallbackHandler implements InvokerCallbackHandler {
@Override @Override
public void handleCallback(Callback callback) throws HandleCallbackException { public void handleCallback(Callback callback) throws HandleCallbackException {
//logger.info("callback handler"); //logger.info("callback handler");
client.processCallback((ClientCallback)callback.getCallbackObject()); client.processCallback((ClientCallback) callback.getCallbackObject());
} }
} }
@ -502,7 +508,6 @@ public class SessionImpl implements Session {
return serverState.getDraftCubes(); return serverState.getDraftCubes();
} }
@Override @Override
public List<TournamentTypeView> getTournamentTypes() { public List<TournamentTypeView> getTournamentTypes() {
return serverState.getTournamentTypes(); return serverState.getTournamentTypes();
@ -1020,6 +1025,7 @@ public class SessionImpl implements Session {
/** /**
* Remove table - called from admin console * Remove table - called from admin console
*
* @param tableId * @param tableId
* @return * @return
*/ */
@ -1107,7 +1113,6 @@ public class SessionImpl implements Session {
// } // }
// return false; // return false;
// } // }
@Override @Override
public boolean submitDeck(UUID tableId, DeckCardLists deck) { public boolean submitDeck(UUID tableId, DeckCardLists deck) {
try { try {
@ -1384,14 +1389,13 @@ public class SessionImpl implements Session {
client.showError(ex.getMessage()); client.showError(ex.getMessage());
} }
@Override @Override
public String getUserName() { public String getUserName() {
return connection.getUsername(); return connection.getUsername();
} }
@Override @Override
public boolean updatePreferencesForServer(UserDataView userData) { public boolean updatePreferencesForServer(UserData userData) {
try { try {
if (isConnected()) { if (isConnected()) {
server.setUserData(connection.getUsername(), sessionId, userData); server.setUserData(connection.getUsername(), sessionId, userData);
@ -1411,26 +1415,26 @@ public class SessionImpl implements Session {
if (isConnected()) { if (isConnected()) {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
if (!server.ping(sessionId, pingInfo)) { if (!server.ping(sessionId, pingInfo)) {
logger.error("Ping failed: " + this.getUserName() + " Session: " + sessionId + " to MAGE server at " + connection.getHost() +":" + connection.getPort()); logger.error("Ping failed: " + this.getUserName() + " Session: " + sessionId + " to MAGE server at " + connection.getHost() + ":" + connection.getPort());
throw new MageException("Ping failed"); throw new MageException("Ping failed");
} }
pingTime.add(System.nanoTime() - startTime); pingTime.add(System.nanoTime() - startTime);
long milliSeconds = TimeUnit.MILLISECONDS.convert(pingTime.getLast(), TimeUnit.NANOSECONDS); long milliSeconds = TimeUnit.MILLISECONDS.convert(pingTime.getLast(), TimeUnit.NANOSECONDS);
String lastPing = milliSeconds > 0 ? milliSeconds+"ms" : "<1ms"; String lastPing = milliSeconds > 0 ? milliSeconds + "ms" : "<1ms";
if (pingTime.size() > PING_CYCLES) { if (pingTime.size() > PING_CYCLES) {
pingTime.poll(); pingTime.poll();
} }
long sum = 0; long sum = 0;
for (Long time :pingTime) { for (Long time : pingTime) {
sum += time; sum += time;
} }
milliSeconds = TimeUnit.MILLISECONDS.convert(sum / pingTime.size(), TimeUnit.NANOSECONDS); milliSeconds = TimeUnit.MILLISECONDS.convert(sum / pingTime.size(), TimeUnit.NANOSECONDS);
pingInfo = lastPing + " (Av: " + (milliSeconds > 0 ? milliSeconds + "ms":"<1ms")+")"; pingInfo = lastPing + " (Av: " + (milliSeconds > 0 ? milliSeconds + "ms" : "<1ms") + ")";
} }
return true; return true;
} catch (MageException ex) { } catch (MageException ex) {
handleMageException(ex); handleMageException(ex);
disconnect(true); disconnect(true);
} catch (Throwable t) { } catch (Throwable t) {
handleThrowable(t); handleThrowable(t);
} }
@ -1448,7 +1452,6 @@ public class SessionImpl implements Session {
} }
class MageAuthenticator extends Authenticator { class MageAuthenticator extends Authenticator {
private final String username; private final String username;
@ -1460,7 +1463,7 @@ class MageAuthenticator extends Authenticator {
} }
@Override @Override
public PasswordAuthentication getPasswordAuthentication () { public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication (username, password.toCharArray()); return new PasswordAuthentication(username, password.toCharArray());
} }
} }

View file

@ -1,33 +1,33 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.remote.interfaces; package mage.remote.interfaces;
import mage.view.UserDataView; import mage.players.net.UserData;
/** /**
* @author noxx * @author noxx
@ -36,5 +36,5 @@ public interface ClientData {
String getUserName(); String getUserName();
boolean updatePreferencesForServer(UserDataView userData); boolean updatePreferencesForServer(UserData userData);
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2011 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 * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.utils; package mage.utils;
import java.io.Serializable; import java.io.Serializable;
@ -41,8 +40,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
*/ */
public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 1; public final static int MAGE_VERSION_PATCH = 2;
public final static String MAGE_VERSION_MINOR_PATCH = "v3"; public final static String MAGE_VERSION_MINOR_PATCH = "v0";
public final static String MAGE_VERSION_INFO = ""; public final static String MAGE_VERSION_INFO = "";
private final int major; private final int major;

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.view; package mage.view;
import java.io.Serializable; import java.io.Serializable;
@ -44,12 +43,14 @@ import mage.game.command.Commander;
import mage.game.command.Emblem; import mage.game.command.Emblem;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.players.net.UserData;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class PlayerView implements Serializable { public class PlayerView implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final UUID playerId; private final UUID playerId;
@ -67,7 +68,7 @@ public class PlayerView implements Serializable {
private final CardsView exile = new CardsView(); private final CardsView exile = new CardsView();
private final Map<UUID, PermanentView> battlefield = new LinkedHashMap<>(); private final Map<UUID, PermanentView> battlefield = new LinkedHashMap<>();
private final CardView topCard; private final CardView topCard;
private final UserDataView userDataView; private final UserData userData;
private final List<CommandObjectView> commandList = new ArrayList<>(); private final List<CommandObjectView> commandList = new ArrayList<>();
private final List<UUID> attachments = new ArrayList<>(); private final List<UUID> attachments = new ArrayList<>();
private final int statesSavedSize; private final int statesSavedSize;
@ -89,12 +90,12 @@ public class PlayerView implements Serializable {
this.isActive = (player.getId().equals(state.getActivePlayerId())); this.isActive = (player.getId().equals(state.getActivePlayerId()));
this.hasPriority = player.getId().equals(state.getPriorityPlayerId()); this.hasPriority = player.getId().equals(state.getPriorityPlayerId());
this.priorityTimeLeft = player.getPriorityTimeLeft(); this.priorityTimeLeft = player.getPriorityTimeLeft();
this.timerActive = (this.hasPriority && player.isGameUnderControl()) || this.timerActive = (this.hasPriority && player.isGameUnderControl())
(player.getPlayersUnderYourControl().contains(state.getPriorityPlayerId())) || || (player.getPlayersUnderYourControl().contains(state.getPriorityPlayerId()))
player.getId().equals(game.getState().getChoosingPlayerId()); || player.getId().equals(game.getState().getChoosingPlayerId());
this.hasLeft = player.hasLeft(); this.hasLeft = player.hasLeft();
for (Card card: player.getGraveyard().getCards(game)) { for (Card card : player.getGraveyard().getCards(game)) {
graveyard.put(card.getId(), new CardView(card, game, false)); graveyard.put(card.getId(), new CardView(card, game, false));
} }
for (ExileZone exileZone : game.getExile().getExileZones()) { for (ExileZone exileZone : game.getExile().getExileZones()) {
@ -104,35 +105,34 @@ public class PlayerView implements Serializable {
} }
} }
} }
for (Permanent permanent: state.getBattlefield().getAllPermanents()) { for (Permanent permanent : state.getBattlefield().getAllPermanents()) {
if (showInBattlefield(permanent, state)) { if (showInBattlefield(permanent, state)) {
PermanentView view = new PermanentView(permanent, game.getCard(permanent.getId()), createdForPlayerId, game); PermanentView view = new PermanentView(permanent, game.getCard(permanent.getId()), createdForPlayerId, game);
battlefield.put(view.getId(), view); battlefield.put(view.getId(), view);
} }
} }
this.topCard = player.isTopCardRevealed() && player.getLibrary().size() > 0 ? this.topCard = player.isTopCardRevealed() && player.getLibrary().size() > 0
new CardView(player.getLibrary().getFromTop(game)) : null; ? new CardView(player.getLibrary().getFromTop(game)) : null;
if (player.getUserData() != null) { if (player.getUserData() != null) {
this.userDataView = new UserDataView(player.getUserData()); this.userData = player.getUserData();
} else { } else {
this.userDataView = UserDataView.getDefaultUserDataView(); this.userData = UserData.getDefaultUserDataView();
} }
for (CommandObject commandObject : game.getState().getCommand()) { for (CommandObject commandObject : game.getState().getCommand()) {
if (commandObject instanceof Emblem) { if (commandObject instanceof Emblem) {
Emblem emblem = (Emblem) commandObject; Emblem emblem = (Emblem) commandObject;
if (emblem.getControllerId().equals(this.playerId)) { if (emblem.getControllerId().equals(this.playerId)) {
Card sourceCard = game.getCard(((CommandObject)emblem).getSourceId()); Card sourceCard = game.getCard(((CommandObject) emblem).getSourceId());
if (sourceCard != null) { if (sourceCard != null) {
commandList.add(new EmblemView(emblem, sourceCard)); commandList.add(new EmblemView(emblem, sourceCard));
} }
} }
} } else if (commandObject instanceof Commander) {
else if(commandObject instanceof Commander){ Commander commander = (Commander) commandObject;
Commander commander = (Commander)commandObject; if (commander.getControllerId().equals(this.playerId)) {
if(commander.getControllerId().equals(this.playerId)){
Card sourceCard = game.getCard(commander.getSourceId()); Card sourceCard = game.getCard(commander.getSourceId());
if(sourceCard != null){ if (sourceCard != null) {
commandList.add(new CommanderView(commander, sourceCard, game)); commandList.add(new CommanderView(commander, sourceCard, game));
} }
} }
@ -157,13 +157,11 @@ public class PlayerView implements Serializable {
//show permanents controlled by player or attachments to permanents controlled by player //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); return permanent.getControllerId().equals(playerId);
} } else {
else {
Permanent attachedTo = state.getPermanent(permanent.getAttachedTo()); Permanent attachedTo = state.getPermanent(permanent.getAttachedTo());
if (attachedTo != null) { if (attachedTo != null) {
return attachedTo.getControllerId().equals(playerId); return attachedTo.getControllerId().equals(playerId);
} } else {
else {
return permanent.getControllerId().equals(playerId); return permanent.getControllerId().equals(playerId);
} }
} }
@ -221,8 +219,8 @@ public class PlayerView implements Serializable {
return this.topCard; return this.topCard;
} }
public UserDataView getUserData() { public UserData getUserData() {
return this.userDataView; return this.userData;
} }
public List<CommandObjectView> getCommadObjectList() { public List<CommandObjectView> getCommadObjectList() {

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.view; package mage.view;
import java.io.Serializable; import java.io.Serializable;
@ -37,16 +36,23 @@ import mage.game.Seat;
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class SeatView implements Serializable { public class SeatView implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String flagName;
private UUID playerId; private UUID playerId;
private String playerName; private final String playerName;
private String playerType; private final String playerType;
public SeatView(Seat seat) { public SeatView(Seat seat) {
if (seat.getPlayer() != null) { if (seat.getPlayer() != null) {
this.playerId = seat.getPlayer().getId(); this.playerId = seat.getPlayer().getId();
this.playerName = seat.getPlayer().getName(); this.playerName = seat.getPlayer().getName();
this.flagName = seat.getPlayer().getUserData().getFlagName();
} else {
// Empty seat
this.playerName = "";
this.flagName = "";
} }
this.playerType = seat.getPlayerType(); this.playerType = seat.getPlayerType();
} }
@ -63,4 +69,8 @@ public class SeatView implements Serializable {
return playerType; return playerType;
} }
public String getFlagName() {
return flagName;
}
} }

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.view; package mage.view;
import java.io.Serializable; import java.io.Serializable;
@ -35,9 +34,11 @@ import mage.game.tournament.TournamentPlayer;
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TournamentPlayerView implements Serializable, Comparable{ public class TournamentPlayerView implements Serializable, Comparable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String flagName;
private final String name; private final String name;
private final String state; private final String state;
private final String results; private final String results;
@ -46,7 +47,7 @@ public class TournamentPlayerView implements Serializable, Comparable{
TournamentPlayerView(TournamentPlayer tournamentPlayer) { TournamentPlayerView(TournamentPlayer tournamentPlayer) {
this.name = tournamentPlayer.getPlayer().getName(); this.name = tournamentPlayer.getPlayer().getName();
StringBuilder sb = new StringBuilder(tournamentPlayer.getState().toString()); StringBuilder sb = new StringBuilder(tournamentPlayer.getState().toString());
String stateInfo = tournamentPlayer.getStateInfo(); String stateInfo = tournamentPlayer.getStateInfo();
if (!stateInfo.isEmpty()) { if (!stateInfo.isEmpty()) {
sb.append(" (").append(stateInfo).append(")"); sb.append(" (").append(stateInfo).append(")");
@ -56,6 +57,7 @@ public class TournamentPlayerView implements Serializable, Comparable{
this.points = tournamentPlayer.getPoints(); this.points = tournamentPlayer.getPoints();
this.results = tournamentPlayer.getResults(); this.results = tournamentPlayer.getResults();
this.quit = !tournamentPlayer.isInTournament(); this.quit = !tournamentPlayer.isInTournament();
this.flagName = tournamentPlayer.getPlayer().getUserData().getFlagName();
} }
public String getName() { public String getName() {
@ -83,4 +85,7 @@ public class TournamentPlayerView implements Serializable, Comparable{
return ((TournamentPlayerView) t).getPoints() - this.getPoints(); return ((TournamentPlayerView) t).getPoints() - this.getPoints();
} }
public String getFlagName() {
return flagName;
}
} }

View file

@ -20,8 +20,8 @@ public class UserDataView implements Serializable {
String flagName; String flagName;
protected boolean askMoveToGraveOrder; protected boolean askMoveToGraveOrder;
static UserDataView getDefaultUserDataView() { static UserData getDefaultUserDataView() {
return new UserDataView(0, false, false, true, null,"world.png", false); return UserData.getDefaultUserDataView();
} }
public UserDataView(int avatarId, boolean showAbilityPickerForced, boolean allowRequestShowHandCards, public UserDataView(int avatarId, boolean showAbilityPickerForced, boolean allowRequestShowHandCards,

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-counter-plugin</artifactId> <artifactId>mage-counter-plugin</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-theme-plugin</artifactId> <artifactId>mage-theme-plugin</artifactId>
@ -29,7 +29,7 @@
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>mage-client</artifactId> <artifactId>mage-client</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
@ -28,7 +28,54 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${manifest.file}</manifestFile>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>mage.server.console.ConsoleFrame</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
<finalName>mage-console</finalName>
</build>
<properties>
<manifest.file>src/main/resources/META-INF/MANIFEST.MF</manifest.file>
</properties>
</project> </project>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-deck-constructed</artifactId> <artifactId>mage-deck-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-deck-limited</artifactId> <artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-game-commanderduel</artifactId> <artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-game-commanderfreeforall</artifactId> <artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-game-freeforall</artifactId> <artifactId>mage-game-freeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-game-tinyleadersduel</artifactId> <artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-game-twoplayerduel</artifactId> <artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-ai-draftbot</artifactId> <artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-ai-ma</artifactId> <artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-ai</artifactId> <artifactId>mage-player-ai</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-ai-mcts</artifactId> <artifactId>mage-player-ai-mcts</artifactId>

View file

@ -27,13 +27,24 @@
*/ */
package mage.player.ai; package mage.player.ai;
import mage.constants.Outcome; import java.io.Serializable;
import mage.abilities.*; import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.Modes;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.PassAbility; import mage.abilities.common.PassAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.choices.Choice; import mage.choices.Choice;
import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -44,9 +55,6 @@ import mage.target.TargetAmount;
import mage.target.TargetCard; import mage.target.TargetCard;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
/** /**
* *
* plays randomly * plays randomly
@ -58,7 +66,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
private boolean isSimulatedPlayer; private boolean isSimulatedPlayer;
private static Random rnd = new Random(); private static Random rnd = new Random();
private int actionCount = 0; private int actionCount = 0;
private static final transient Logger logger = Logger.getLogger(SimulatedPlayerMCTS.class); private static final transient Logger logger = Logger.getLogger(SimulatedPlayerMCTS.class);
public SimulatedPlayerMCTS(UUID id, boolean isSimulatedPlayer) { public SimulatedPlayerMCTS(UUID id, boolean isSimulatedPlayer) {
super(id); super(id);
@ -83,14 +91,15 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
return actionCount; return actionCount;
} }
@Override @Override
public boolean priority(Game game) { public boolean priority(Game game) {
// logger.info("priority"); // logger.info("priority");
boolean didSomething = false; boolean didSomething = false;
Ability ability = getAction(game); Ability ability = getAction(game);
// logger.info("simulate " + ability.toString()); // logger.info("simulate " + ability.toString());
if (!(ability instanceof PassAbility)) if (!(ability instanceof PassAbility)) {
didSomething = true; didSomething = true;
}
activateAbility((ActivatedAbility) ability, game); activateAbility((ActivatedAbility) ability, game);
@ -102,16 +111,18 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
List<Ability> playables = getPlayableAbilities(game); List<Ability> playables = getPlayableAbilities(game);
Ability ability; Ability ability;
while (true) { while (true) {
if (playables.size() == 1) if (playables.size() == 1) {
ability = playables.get(0); ability = playables.get(0);
else } else {
ability = playables.get(rnd.nextInt(playables.size())); ability = playables.get(rnd.nextInt(playables.size()));
}
List<Ability> options = getPlayableOptions(ability, game); List<Ability> options = getPlayableOptions(ability, game);
if (!options.isEmpty()) { if (!options.isEmpty()) {
if (options.size() == 1) if (options.size() == 1) {
ability = options.get(0); ability = options.get(0);
else } else {
ability = options.get(rnd.nextInt(options.size())); ability = options.get(rnd.nextInt(options.size()));
}
} }
if (ability.getManaCosts().getVariableCosts().size() > 0) { if (ability.getManaCosts().getVariableCosts().size() > 0) {
int amount = getAvailableManaProducers(game).size() - ability.getManaCosts().convertedManaCost(); int amount = getAvailableManaProducers(game).size() - ability.getManaCosts().convertedManaCost();
@ -133,7 +144,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
// } // }
// } // }
// else { // else {
break; break;
// } // }
} }
return ability; return ability;
@ -147,12 +158,12 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
List<Ability> options = getPlayableOptions(source, game); List<Ability> options = getPlayableOptions(source, game);
if (options.isEmpty()) { if (options.isEmpty()) {
ability = source; ability = source;
} } else {
else { if (options.size() == 1) {
if (options.size() == 1)
ability = options.get(0); ability = options.get(0);
else } else {
ability = options.get(rnd.nextInt(options.size())); ability = options.get(rnd.nextInt(options.size()));
}
} }
if (ability.isUsesStack()) { if (ability.isUsesStack()) {
game.getStack().push(new StackAbility(ability, playerId)); game.getStack().push(new StackAbility(ability, playerId));
@ -205,7 +216,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
List<Permanent> blockers = getAvailableBlockers(game); List<Permanent> blockers = getAvailableBlockers(game);
for (Permanent blocker: blockers) { for (Permanent blocker : blockers) {
int check = rnd.nextInt(numGroups + 1); int check = rnd.nextInt(numGroups + 1);
if (check < numGroups) { if (check < numGroups) {
CombatGroup group = game.getCombat().getGroups().get(check); CombatGroup group = game.getCombat().getGroups().get(check);
@ -242,9 +253,10 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
protected boolean chooseRandomTarget(Target target, Ability source, Game game) { protected boolean chooseRandomTarget(Target target, Ability source, Game game) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
if (possibleTargets.isEmpty()) if (possibleTargets.isEmpty()) {
return false; return false;
}
if (!target.isRequired(source)) { if (!target.isRequired(source)) {
if (rnd.nextInt(possibleTargets.size() + 1) == 0) { if (rnd.nextInt(possibleTargets.size() + 1) == 0) {
return false; return false;
@ -266,8 +278,9 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override @Override
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
if (this.isHuman()) if (this.isHuman()) {
return chooseRandom(target, game); return chooseRandom(target, game);
}
return super.choose(outcome, target, sourceId, game); return super.choose(outcome, target, sourceId, game);
} }
@ -318,7 +331,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override @Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
if (possibleTargets.isEmpty()) { if (possibleTargets.isEmpty()) {
return !target.isRequired(source); return !target.isRequired(source);
} }
@ -347,11 +360,11 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
@Override @Override
public boolean chooseUse(Outcome outcome, String message, Game game) { public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
if (this.isHuman()) { if (this.isHuman()) {
return rnd.nextBoolean(); return rnd.nextBoolean();
} }
return super.chooseUse(outcome, message, game); return super.chooseUse(outcome, message, source, game);
} }
@Override @Override
@ -396,12 +409,12 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override @Override
public Mode chooseMode(Modes modes, Ability source, Game game) { public Mode chooseMode(Modes modes, Ability source, Game game) {
if (this.isHuman()) { if (this.isHuman()) {
Iterator<Mode> it = modes.values().iterator(); Iterator<Mode> it = modes.getAvailableModes(source, game).iterator();
Mode mode = it.next(); Mode mode = it.next();
if (modes.size() == 1) { if (modes.size() == 1) {
return mode; return mode;
} }
int modeNum = rnd.nextInt(modes.values().size()); int modeNum = rnd.nextInt(modes.getAvailableModes(source, game).size());
for (int i = 0; i < modeNum; i++) { for (int i = 0; i < modeNum; i++) {
mode = it.next(); mode = it.next();
} }
@ -436,8 +449,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
if (targets.size() == 1) { if (targets.size() == 1) {
targetId = targets.get(0); targetId = targets.get(0);
amount = remainingDamage; amount = remainingDamage;
} } else {
else {
targetId = targets.get(rnd.nextInt(targets.size())); targetId = targets.get(rnd.nextInt(targets.size()));
amount = rnd.nextInt(damage + 1); amount = rnd.nextInt(damage + 1);
} }
@ -445,8 +457,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
if (permanent != null) { if (permanent != null) {
permanent.damage(amount, sourceId, game, false, true); permanent.damage(amount, sourceId, game, false, true);
remainingDamage -= amount; remainingDamage -= amount;
} } else {
else {
Player player = game.getPlayer(targetId); Player player = game.getPlayer(targetId);
if (player != null) { if (player != null) {
player.damage(amount, sourceId, game, false, true); player.damage(amount, sourceId, game, false, true);
@ -455,8 +466,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
targets.remove(targetId); targets.remove(targetId);
} }
} } else {
else {
super.assignDamage(damage, targets, singleTargetName, sourceId, game); super.assignDamage(damage, targets, singleTargetName, sourceId, game);
} }
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-aiminimax</artifactId> <artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-player-human</artifactId> <artifactId>mage-player-human</artifactId>

View file

@ -1,35 +1,50 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.player.human; package mage.player.human;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.*; import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.Modes;
import mage.abilities.PlayLandAbility;
import mage.abilities.SpecialAction;
import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
@ -42,7 +57,14 @@ import mage.cards.Cards;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.*; import mage.constants.AbilityType;
import mage.constants.Constants;
import mage.constants.ManaType;
import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.PlayerAction;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterAttackingCreature;
import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterBlockingCreature;
import mage.filter.common.FilterCreatureForCombat; import mage.filter.common.FilterCreatureForCombat;
@ -51,6 +73,7 @@ import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.draft.Draft; import mage.game.draft.Draft;
import mage.game.events.GameEvent;
import mage.game.match.Match; import mage.game.match.Match;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.tournament.Tournament; import mage.game.tournament.Tournament;
@ -63,13 +86,10 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetAttackingCreature; import mage.target.common.TargetAttackingCreature;
import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreatureOrPlayer;
import mage.target.common.TargetDefender; import mage.target.common.TargetDefender;
import mage.util.GameLog;
import mage.util.ManaUtil; import mage.util.ManaUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import mage.util.GameLog;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -85,6 +105,7 @@ public class HumanPlayer extends PlayerImpl {
protected static final Choice replacementEffectChoice = new ChoiceImpl(true); protected static final Choice replacementEffectChoice = new ChoiceImpl(true);
private static final Logger log = Logger.getLogger(HumanPlayer.class); private static final Logger log = Logger.getLogger(HumanPlayer.class);
static { static {
replacementEffectChoice.setMessage("Choose replacement effect to resolve first"); replacementEffectChoice.setMessage("Choose replacement effect to resolve first");
} }
@ -104,7 +125,7 @@ public class HumanPlayer extends PlayerImpl {
response.clear(); response.clear();
log.debug("Waiting response from player: " + getId()); log.debug("Waiting response from player: " + getId());
game.resumeTimer(getTurnControlledBy()); game.resumeTimer(getTurnControlledBy());
synchronized(response) { synchronized (response) {
try { try {
response.wait(); response.wait();
log.debug("Got response from player: " + getId()); log.debug("Got response from player: " + getId());
@ -145,9 +166,9 @@ public class HumanPlayer extends PlayerImpl {
updateGameStatePriority("chooseMulligan", game); updateGameStatePriority("chooseMulligan", game);
int nextHandSize = game.mulliganDownTo(playerId); int nextHandSize = game.mulliganDownTo(playerId);
game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ") game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ")
.append(getHand().size() > nextHandSize?"down to ":"for free, draw ") .append(getHand().size() > nextHandSize ? "down to " : "for free, draw ")
.append(nextHandSize) .append(nextHandSize)
.append(nextHandSize == 1?" card?":" cards?").toString()); .append(nextHandSize == 1 ? " card?" : " cards?").toString());
waitForBooleanResponse(game); waitForBooleanResponse(game);
if (!abort) { if (!abort) {
return response.getBoolean(); return response.getBoolean();
@ -156,9 +177,9 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public boolean chooseUse(Outcome outcome, String message, Game game) { public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
updateGameStatePriority("chooseUse", game); updateGameStatePriority("chooseUse", game);
game.fireAskPlayerEvent(playerId, message); game.fireAskPlayerEvent(playerId, addSecondLineWithObjectName(message, source == null ? null : source.getSourceId(), game));
waitForBooleanResponse(game); waitForBooleanResponse(game);
if (!abort) { if (!abort) {
return response.getBoolean(); return response.getBoolean();
@ -166,6 +187,19 @@ public class HumanPlayer extends PlayerImpl {
return false; return false;
} }
private String addSecondLineWithObjectName(String message, UUID sourceId, Game game) {
if (sourceId != null) {
MageObject mageObject = game.getPermanent(sourceId);
if (mageObject == null) {
mageObject = game.getCard(sourceId);
}
if (mageObject != null) {
message += "<div style='font-size:11pt'>" + mageObject.getLogName() + "</div>";
}
}
return message;
}
@Override @Override
public int chooseReplacementEffect(Map<String, String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
updateGameStatePriority("chooseEffect", game); updateGameStatePriority("chooseEffect", game);
@ -173,7 +207,7 @@ public class HumanPlayer extends PlayerImpl {
return 0; return 0;
} }
if (!autoSelectReplacementEffects.isEmpty()) { if (!autoSelectReplacementEffects.isEmpty()) {
for (String autoKey :autoSelectReplacementEffects) { for (String autoKey : autoSelectReplacementEffects) {
int count = 0; int count = 0;
for (String effectKey : rEffects.keySet()) { for (String effectKey : rEffects.keySet()) {
if (effectKey.equals(autoKey)) { if (effectKey.equals(autoKey)) {
@ -230,7 +264,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
return choose(outcome, target, sourceId, game, null); return choose(outcome, target, sourceId, game, null);
} }
@Override @Override
@ -254,18 +288,18 @@ public class HumanPlayer extends PlayerImpl {
} }
List<UUID> chosen = target.getTargets(); List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable)chosen); options.put("chosen", (Serializable) chosen);
game.fireSelectTargetEvent(getId(), target.getMessage(), targetIds, required, getOptions(target, options)); game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), sourceId, game), targetIds, required, getOptions(target, options));
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
if (!targetIds.contains(response.getUUID())) { if (!targetIds.contains(response.getUUID())) {
continue; continue;
} }
if (target instanceof TargetPermanent) { if (target instanceof TargetPermanent) {
if (((TargetPermanent)target).canTarget(abilityControllerId, response.getUUID(), sourceId, game, false)) { if (((TargetPermanent) target).canTarget(abilityControllerId, response.getUUID(), sourceId, game, false)) {
target.add(response.getUUID(), game); target.add(response.getUUID(), game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -276,8 +310,8 @@ public class HumanPlayer extends PlayerImpl {
if (target.getTargets().contains(response.getUUID())) { // if already included remove it with if (target.getTargets().contains(response.getUUID())) { // if already included remove it with
target.remove(response.getUUID()); target.remove(response.getUUID());
} else { } else {
target.addTarget(response.getUUID(), (Ability)object, game); target.addTarget(response.getUUID(), (Ability) object, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -288,7 +322,7 @@ public class HumanPlayer extends PlayerImpl {
target.remove(response.getUUID()); target.remove(response.getUUID());
} else { } else {
target.addTarget(response.getUUID(), null, game); target.addTarget(response.getUUID(), null, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -316,12 +350,13 @@ public class HumanPlayer extends PlayerImpl {
abilityControllerId = target.getAbilityController(); abilityControllerId = target.getAbilityController();
} }
while (!abort) { while (!abort) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), abilityControllerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
boolean required = target.isRequired(source); boolean required = target.isRequired(source);
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) { if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
required = false; required = false;
} }
game.fireSelectTargetEvent(getId(), target.getMessage(), possibleTargets, required, getOptions(target, null));
game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), possibleTargets, required, getOptions(target, null));
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
if (target.getTargets().contains(response.getUUID())) { if (target.getTargets().contains(response.getUUID())) {
@ -331,7 +366,7 @@ public class HumanPlayer extends PlayerImpl {
if (possibleTargets.contains(response.getUUID())) { if (possibleTargets.contains(response.getUUID())) {
if (target.canTarget(abilityControllerId, response.getUUID(), source, game)) { if (target.canTarget(abilityControllerId, response.getUUID(), source, game)) {
target.addTarget(response.getUUID(), source, game); target.addTarget(response.getUUID(), source, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -348,7 +383,7 @@ public class HumanPlayer extends PlayerImpl {
return false; return false;
} }
private Map<String, Serializable> getOptions(Target target, Map<String, Serializable> options ) { private Map<String, Serializable> getOptions(Target target, Map<String, Serializable> options) {
if (options == null) { if (options == null) {
options = new HashMap<>(); options = new HashMap<>();
} }
@ -356,7 +391,7 @@ public class HumanPlayer extends PlayerImpl {
options.put("UI.right.btn.text", "Done"); options.put("UI.right.btn.text", "Done");
} }
options.put("targetZone", target.getZone()); options.put("targetZone", target.getZone());
return options; return options;
} }
@Override @Override
@ -378,7 +413,7 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable)chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(cardId, cards, game)) { if (target.canTarget(cardId, cards, game)) {
@ -432,7 +467,7 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable)chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(cardId, cards, game)) { if (target.canTarget(cardId, cards, game)) {
@ -442,7 +477,7 @@ public class HumanPlayer extends PlayerImpl {
if (!choosable.isEmpty()) { if (!choosable.isEmpty()) {
options.put("choosable", (Serializable) choosable); options.put("choosable", (Serializable) choosable);
} }
game.fireSelectTargetEvent(playerId, target.getMessage(), cards, required, options); game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), cards, required, options);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
if (target.getTargets().contains(response.getUUID())) { // if already included remove it if (target.getTargets().contains(response.getUUID())) { // if already included remove it
@ -471,8 +506,8 @@ public class HumanPlayer extends PlayerImpl {
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
updateGameStatePriority("chooseTargetAmount", game); updateGameStatePriority("chooseTargetAmount", game);
while (!abort) { while (!abort) {
game.fireSelectTargetEvent(playerId, target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), source.getSourceId(), game),
target.possibleTargets(source==null?null:source.getSourceId(), playerId, game), target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game),
target.isRequired(source), target.isRequired(source),
getOptions(target, null)); getOptions(target, null));
waitForResponse(game); waitForResponse(game);
@ -495,7 +530,7 @@ public class HumanPlayer extends PlayerImpl {
passed = false; passed = false;
if (!abort) { if (!abort) {
if (passedAllTurns) { if (passedAllTurns) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -503,7 +538,7 @@ public class HumanPlayer extends PlayerImpl {
passedUntilStackResolved = false; passedUntilStackResolved = false;
boolean dontCheckPassStep = false; boolean dontCheckPassStep = false;
if (passedTurn) { if (passedTurn) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -512,7 +547,7 @@ public class HumanPlayer extends PlayerImpl {
// it's a main phase // it's a main phase
if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) { if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -521,7 +556,7 @@ public class HumanPlayer extends PlayerImpl {
} }
} else { } else {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -531,7 +566,7 @@ public class HumanPlayer extends PlayerImpl {
// It's end of turn phase // It's end of turn phase
if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) { if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -540,20 +575,20 @@ public class HumanPlayer extends PlayerImpl {
} }
} else { } else {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
} }
if (!dontCheckPassStep && checkPassStep(game)) { if (!dontCheckPassStep && checkPassStep(game)) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
} else if (passedUntilStackResolved) { } else if (passedUntilStackResolved) {
if (dateLastAddedToStack == game.getStack().getDateLastAdded()) { if (dateLastAddedToStack == game.getStack().getDateLastAdded()) {
dateLastAddedToStack = game.getStack().getDateLastAdded(); dateLastAddedToStack = game.getStack().getDateLastAdded();
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -564,7 +599,7 @@ public class HumanPlayer extends PlayerImpl {
updateGameStatePriority("priority", game); updateGameStatePriority("priority", game);
game.firePriorityEvent(playerId); game.firePriorityEvent(playerId);
waitForResponse(game); waitForResponse(game);
if(game.executingRollback()) { if (game.executingRollback()) {
return true; return true;
} }
if (response.getBoolean() != null || response.getInteger() != null) { if (response.getBoolean() != null || response.getInteger() != null) {
@ -628,7 +663,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities); game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (TriggeredAbility ability: abilities) { for (TriggeredAbility ability : abilities) {
if (ability.getId().equals(response.getUUID())) { if (ability.getId().equals(response.getUUID())) {
return ability; return ability;
} }
@ -638,7 +673,6 @@ public class HumanPlayer extends PlayerImpl {
return null; return null;
} }
@Override @Override
public boolean playMana(ManaCost unpaid, String promptText, Game game) { public boolean playMana(ManaCost unpaid, String promptText, Game game) {
payManaMode = true; payManaMode = true;
@ -647,7 +681,6 @@ public class HumanPlayer extends PlayerImpl {
return result; return result;
} }
protected boolean playManaHandling(ManaCost unpaid, String promptText, Game game) { protected boolean playManaHandling(ManaCost unpaid, String promptText, Game game) {
updateGameStatePriority("playMana", game); updateGameStatePriority("playMana", game);
game.firePlayManaEvent(playerId, "Pay " + promptText); game.firePlayManaEvent(playerId, "Pay " + promptText);
@ -666,9 +699,9 @@ public class HumanPlayer extends PlayerImpl {
ManaCostsImpl<ManaCost> costs = (ManaCostsImpl<ManaCost>) unpaid; ManaCostsImpl<ManaCost> costs = (ManaCostsImpl<ManaCost>) unpaid;
for (ManaCost cost : costs.getUnpaid()) { for (ManaCost cost : costs.getUnpaid()) {
if (cost instanceof PhyrexianManaCost) { if (cost instanceof PhyrexianManaCost) {
PhyrexianManaCost ph = (PhyrexianManaCost)cost; PhyrexianManaCost ph = (PhyrexianManaCost) cost;
if (ph.canPay(null, null, playerId, game)) { if (ph.canPay(null, null, playerId, game)) {
((PhyrexianManaCost)cost).pay(null, game, null, playerId, false); ((PhyrexianManaCost) cost).pay(null, game, null, playerId, false);
} }
break; break;
} }
@ -686,6 +719,7 @@ public class HumanPlayer extends PlayerImpl {
/** /**
* Gets the amount of mana the player want to spent for a x spell * Gets the amount of mana the player want to spent for a x spell
*
* @param min * @param min
* @param max * @param max
* @param message * @param message
@ -700,7 +734,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetAmountEvent(playerId, message, min, max); game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game); waitForIntegerResponse(game);
if (response != null && response.getInteger() != null) { if (response != null && response.getInteger() != null) {
xValue = response.getInteger(); xValue = response.getInteger();
} }
return xValue; return xValue;
} }
@ -712,7 +746,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetAmountEvent(playerId, message, min, max); game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game); waitForIntegerResponse(game);
if (response != null && response.getInteger() != null) { if (response != null && response.getInteger() != null) {
xValue = response.getInteger(); xValue = response.getInteger();
} }
return xValue; return xValue;
} }
@ -739,8 +773,8 @@ public class HumanPlayer extends PlayerImpl {
FilterCreatureForCombat filter = filterCreatureForCombat.copy(); FilterCreatureForCombat filter = filterCreatureForCombat.copy();
filter.add(new ControllerIdPredicate(attackingPlayerId)); filter.add(new ControllerIdPredicate(attackingPlayerId));
while (!abort) { while (!abort) {
if (passedAllTurns || if (passedAllTurns
(!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain) )) { || (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain))) {
return; return;
} }
Map<String, Serializable> options = new HashMap<>(); Map<String, Serializable> options = new HashMap<>();
@ -751,17 +785,36 @@ public class HumanPlayer extends PlayerImpl {
possibleAttackers.add(possibleAttacker.getId()); possibleAttackers.add(possibleAttacker.getId());
} }
} }
options.put(Constants.Option.POSSIBLE_ATTACKERS, (Serializable)possibleAttackers); options.put(Constants.Option.POSSIBLE_ATTACKERS, (Serializable) possibleAttackers);
if (possibleAttackers.size() > 0) {
options.put(Constants.Option.SPECIAL_BUTTON, (Serializable) "All attack");
}
game.fireSelectEvent(playerId, "Select attackers", options); game.fireSelectEvent(playerId, "Select attackers", options);
waitForResponse(game); waitForResponse(game);
if (response.getBoolean() != null) { if (response.getString() != null && response.getString().equals("special")) { // All attack
setStoredBookmark(game.bookmarkState());
UUID attackedDefender = null;
if (game.getCombat().getDefenders().size() > 1) {
attackedDefender = selectDefenderForAllAttack(game.getCombat().getDefenders(), game);
} else if (game.getCombat().getDefenders().size() == 1) {
attackedDefender = game.getCombat().getDefenders().iterator().next();
}
for (Permanent attacker : game.getBattlefield().getAllActivePermanents(filterCreatureForCombat, getId(), game)) {
if (game.getContinuousEffects().checkIfThereArePayCostToAttackBlockEffects(
GameEvent.getEvent(GameEvent.EventType.DECLARE_ATTACKER,
attackedDefender, attacker.getId(), attacker.getControllerId()), game)) {
continue;
}
declareAttacker(attacker.getId(), attackedDefender, game, false);
}
} else if (response.getBoolean() != null) {
// check if enough attackers are declared // check if enough attackers are declared
if (!game.getCombat().getCreaturesForcedToAttack().isEmpty()) { if (!game.getCombat().getCreaturesForcedToAttack().isEmpty()) {
if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) { if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) {
int forcedAttackers = 0; int forcedAttackers = 0;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (UUID creatureId :game.getCombat().getCreaturesForcedToAttack().keySet()) { for (UUID creatureId : game.getCombat().getCreaturesForcedToAttack().keySet()) {
boolean validForcedAttacker = false; boolean validForcedAttacker = false;
if (game.getCombat().getAttackers().contains(creatureId)) { if (game.getCombat().getAttackers().contains(creatureId)) {
Set<UUID> possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId); Set<UUID> possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId);
@ -780,7 +833,7 @@ public class HumanPlayer extends PlayerImpl {
} }
if (game.getCombat().getMaxAttackers() > forcedAttackers) { if (game.getCombat().getMaxAttackers() > forcedAttackers) {
game.informPlayer(this, sb.insert(0," more attacker(s) that are forced to attack.\nCreatures forced to attack: ") game.informPlayer(this, sb.insert(0, " more attacker(s) that are forced to attack.\nCreatures forced to attack: ")
.insert(0, Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers)) .insert(0, Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers))
.insert(0, "You have to attack with ").toString()); .insert(0, "You have to attack with ").toString());
continue; continue;
@ -799,18 +852,17 @@ public class HumanPlayer extends PlayerImpl {
if (attacker != null) { if (attacker != null) {
if (filterCreatureForCombat.match(attacker, null, playerId, game)) { if (filterCreatureForCombat.match(attacker, null, playerId, game)) {
selectDefender(game.getCombat().getDefenders(), attacker.getId(), game); selectDefender(game.getCombat().getDefenders(), attacker.getId(), game);
} } else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) {
else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) {
removeAttackerIfPossible(game, attacker); removeAttackerIfPossible(game, attacker);
} }
} }
} }
} }
} }
private void removeAttackerIfPossible(Game game, Permanent attacker) { private void removeAttackerIfPossible(Game game, Permanent attacker) {
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) { for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) {
RequirementEffect effect = (RequirementEffect)entry.getKey(); RequirementEffect effect = (RequirementEffect) entry.getKey();
if (effect.mustAttack(game)) { if (effect.mustAttack(game)) {
if (game.getCombat().getMaxAttackers() >= game.getCombat().getCreaturesForcedToAttack().size() && game.getCombat().getDefenders().size() == 1) { if (game.getCombat().getMaxAttackers() >= game.getCombat().getCreaturesForcedToAttack().size() && game.getCombat().getDefenders().size() == 1) {
return; // we can't change creatures forced to attack if only one possible defender exists and all forced creatures can attack return; // we can't change creatures forced to attack if only one possible defender exists and all forced creatures can attack
@ -840,8 +892,7 @@ public class HumanPlayer extends PlayerImpl {
if (possibleDefender.size() == 1) { if (possibleDefender.size() == 1) {
declareAttacker(attackerId, defenders.iterator().next(), game, true); declareAttacker(attackerId, defenders.iterator().next(), game, true);
return true; return true;
} } else {
else {
TargetDefender target = new TargetDefender(possibleDefender, attackerId); TargetDefender target = new TargetDefender(possibleDefender, attackerId);
target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player
if (forcedToAttack) { if (forcedToAttack) {
@ -860,6 +911,15 @@ public class HumanPlayer extends PlayerImpl {
return false; return false;
} }
protected UUID selectDefenderForAllAttack(Set<UUID> defenders, Game game) {
TargetDefender target = new TargetDefender(defenders, null);
target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player
if (chooseTarget(Outcome.Damage, target, null, game)) {
return response.getUUID();
}
return null;
}
@Override @Override
public void selectBlockers(Game game, UUID defendingPlayerId) { public void selectBlockers(Game game, UUID defendingPlayerId) {
updateGameStatePriority("selectBlockers", game); updateGameStatePriority("selectBlockers", game);
@ -903,7 +963,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true); game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (Permanent perm: attackers) { for (Permanent perm : attackers) {
if (perm.getId().equals(response.getUUID())) { if (perm.getId().equals(response.getUUID())) {
return perm.getId(); return perm.getId();
} }
@ -913,7 +973,6 @@ public class HumanPlayer extends PlayerImpl {
return null; return null;
} }
@Override @Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) { public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
updateGameStatePriority("chooseBlockerOrder", game); updateGameStatePriority("chooseBlockerOrder", game);
@ -921,7 +980,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true); game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (Permanent perm: blockers) { for (Permanent perm : blockers) {
if (perm.getId().equals(response.getUUID())) { if (perm.getId().equals(response.getUUID())) {
return perm.getId(); return perm.getId();
} }
@ -934,7 +993,7 @@ public class HumanPlayer extends PlayerImpl {
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) { protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
updateGameStatePriority("selectCombatGroup", game); updateGameStatePriority("selectCombatGroup", game);
TargetAttackingCreature target = new TargetAttackingCreature(); TargetAttackingCreature target = new TargetAttackingCreature();
game.fireSelectTargetEvent(playerId, "Select attacker to block", target.possibleTargets(null, playerId, game), false, getOptions(target, null)); game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName("Select attacker to block", blockerId, game), target.possibleTargets(null, playerId, game), false, getOptions(target, null));
waitForResponse(game); waitForResponse(game);
if (response.getBoolean() != null) { if (response.getBoolean() != null) {
// do nothing // do nothing
@ -967,8 +1026,7 @@ public class HumanPlayer extends PlayerImpl {
if (permanent != null) { if (permanent != null) {
permanent.damage(damageAmount, sourceId, game, false, true); permanent.damage(damageAmount, sourceId, game, false, true);
remainingDamage -= damageAmount; remainingDamage -= damageAmount;
} } else {
else {
Player player = game.getPlayer(target.getFirstTarget()); Player player = game.getPlayer(target.getFirstTarget());
if (player != null) { if (player != null) {
player.damage(damageAmount, sourceId, game, false, true); player.damage(damageAmount, sourceId, game, false, true);
@ -1081,7 +1139,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) { public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
switch(ability.getSpellAbilityType()) { switch (ability.getSpellAbilityType()) {
case SPLIT: case SPLIT:
case SPLIT_FUSED: case SPLIT_FUSED:
MageObject object = game.getObject(ability.getSourceId()); MageObject object = game.getObject(ability.getSourceId());
@ -1111,7 +1169,7 @@ public class HumanPlayer extends PlayerImpl {
if (modes.size() > 1) { if (modes.size() > 1) {
MageObject obj = game.getObject(source.getSourceId()); MageObject obj = game.getObject(source.getSourceId());
Map<UUID, String> modeMap = new LinkedHashMap<>(); Map<UUID, String> modeMap = new LinkedHashMap<>();
for (Mode mode: modes.values()) { for (Mode mode : modes.getAvailableModes(source, game)) {
if (!modes.getSelectedModes().contains(mode.getId()) // show only modes not already selected if (!modes.getSelectedModes().contains(mode.getId()) // show only modes not already selected
&& mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available && mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available
String modeText = mode.getEffects().getText(mode); String modeText = mode.getEffects().getText(mode);
@ -1122,14 +1180,23 @@ public class HumanPlayer extends PlayerImpl {
} }
} }
if (modeMap.size() > 0) { if (modeMap.size() > 0) {
game.fireGetModeEvent(playerId, "Choose Mode", modeMap); boolean done = false;
waitForResponse(game); while (!done) {
if (response.getUUID() != null) { game.fireGetModeEvent(playerId, "Choose Mode", modeMap);
for (Mode mode: modes.values()) { waitForResponse(game);
if (mode.getId().equals(response.getUUID())) { if (response.getUUID() != null) {
return mode; for (Mode mode : modes.getAvailableModes(source, game)) {
if (mode.getId().equals(response.getUUID())) {
return mode;
}
} }
} }
if (!source.getAbilityType().equals(AbilityType.TRIGGERED)) {
done = true;
}
if (!isInGame()) {
return null;
}
} }
} }
return null; return null;
@ -1150,7 +1217,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseString(String responseString) { public void setResponseString(String responseString) {
synchronized(response) { synchronized (response) {
response.setString(responseString); response.setString(responseString);
response.notify(); response.notify();
log.debug("Got response string from player: " + getId()); log.debug("Got response string from player: " + getId());
@ -1159,7 +1226,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseManaType(UUID manaTypePlayerId, ManaType manaType) { public void setResponseManaType(UUID manaTypePlayerId, ManaType manaType) {
synchronized(response) { synchronized (response) {
response.setManaType(manaType); response.setManaType(manaType);
response.setResponseManaTypePlayerId(manaTypePlayerId); response.setResponseManaTypePlayerId(manaTypePlayerId);
response.notify(); response.notify();
@ -1169,7 +1236,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseUUID(UUID responseUUID) { public void setResponseUUID(UUID responseUUID) {
synchronized(response) { synchronized (response) {
response.setUUID(responseUUID); response.setUUID(responseUUID);
response.notify(); response.notify();
log.debug("Got response UUID from player: " + getId()); log.debug("Got response UUID from player: " + getId());
@ -1178,7 +1245,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseBoolean(Boolean responseBoolean) { public void setResponseBoolean(Boolean responseBoolean) {
synchronized(response) { synchronized (response) {
response.setBoolean(responseBoolean); response.setBoolean(responseBoolean);
response.notify(); response.notify();
log.debug("Got response boolean from player: " + getId()); log.debug("Got response boolean from player: " + getId());
@ -1187,7 +1254,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseInteger(Integer responseInteger) { public void setResponseInteger(Integer responseInteger) {
synchronized(response) { synchronized (response) {
response.setInteger(responseInteger); response.setInteger(responseInteger);
response.notify(); response.notify();
log.debug("Got response integer from player: " + getId()); log.debug("Got response integer from player: " + getId());
@ -1197,7 +1264,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void abort() { public void abort() {
abort = true; abort = true;
synchronized(response) { synchronized (response) {
response.notify(); response.notify();
log.debug("Got cancel action from player: " + getId()); log.debug("Got cancel action from player: " + getId());
} }
@ -1205,7 +1272,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void skip() { public void skip() {
synchronized(response) { synchronized (response) {
response.setInteger(0); response.setInteger(0);
response.notify(); response.notify();
log.debug("Got skip action from player: " + getId()); log.debug("Got skip action from player: " + getId());
@ -1234,8 +1301,8 @@ public class HumanPlayer extends PlayerImpl {
} }
protected boolean passWithManaPoolCheck(Game game) { protected boolean passWithManaPoolCheck(Game game) {
if (userData.confirmEmptyManaPool() && if (userData.confirmEmptyManaPool()
game.getStack().isEmpty() && getManaPool().count() > 0) { && game.getStack().isEmpty() && getManaPool().count() > 0) {
String activePlayerText; String activePlayerText;
if (game.getActivePlayerId().equals(playerId)) { if (game.getActivePlayerId().equals(playerId)) {
activePlayerText = "Your turn"; activePlayerText = "Your turn";
@ -1247,7 +1314,7 @@ public class HumanPlayer extends PlayerImpl {
priorityPlayerText = " / priority " + game.getPlayer(game.getPriorityPlayerId()).getName(); priorityPlayerText = " / priority " + game.getPlayer(game.getPriorityPlayerId()).getName();
} }
if (!chooseUse(Outcome.Detriment, GameLog.getPlayerConfirmColoredText("You have still mana in your mana pool. Pass regardless?") if (!chooseUse(Outcome.Detriment, GameLog.getPlayerConfirmColoredText("You have still mana in your mana pool. Pass regardless?")
+ GameLog.getSmallSecondLineText(activePlayerText + " / " + game.getStep().getType().toString() + priorityPlayerText), game)) { + GameLog.getSmallSecondLineText(activePlayerText + " / " + game.getStep().getType().toString() + priorityPlayerText), null, game)) {
sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game); sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game);
return false; return false;
} }

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-tournament-boosterdraft</artifactId> <artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-tournament-constructed</artifactId> <artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-tournament-sealed</artifactId> <artifactId>mage-tournament-sealed</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<artifactId>mage-server</artifactId> <artifactId>mage-server</artifactId>

View file

@ -27,15 +27,17 @@
<gameType name="Free For All" jar="mage-game-freeforall-${project.version}.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/> <gameType name="Free For All" jar="mage-game-freeforall-${project.version}.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/>
<gameType name="Commander Two Player Duel" jar="mage-game-commanderduel-${project.version}.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/> <gameType name="Commander Two Player Duel" jar="mage-game-commanderduel-${project.version}.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/>
<gameType name="Commander Free For All" jar="mage-game-commanderfreeforall-${project.version}.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/> <gameType name="Commander Free For All" jar="mage-game-commanderfreeforall-${project.version}.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/>
<gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel-${project.version}.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/> <gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel-${project.version}.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/>
</gameTypes> </gameTypes>
<tournamentTypes> <tournamentTypes>
<tournamentType name="Constructed Elimination" jar="mage-tournament-constructed-${project.version}.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/> <tournamentType name="Constructed Elimination" jar="mage-tournament-constructed-${project.version}.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/>
<tournamentType name="Constructed Swiss" jar="mage-tournament-constructed-${project.version}.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/> <tournamentType name="Constructed Swiss" jar="mage-tournament-constructed-${project.version}.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/>
<tournamentType name="Booster Draft Elimination" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/> <tournamentType name="Booster Draft Elimination" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/> <tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/> <tournamentType name="Booster Draft Swiss" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/> <tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-boosterdraft-${project.version}.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Sealed Elimination" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/> <tournamentType name="Sealed Elimination" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/>
<tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/> <tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/>
<tournamentType name="Sealed Swiss" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/> <tournamentType name="Sealed Swiss" jar="mage-tournament-sealed-${project.version}.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/>
@ -64,7 +66,7 @@
<deckType name="Constructed - Pauper" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Pauper"/> <deckType name="Constructed - Pauper" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Pauper"/>
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Commander"/> <deckType name="Variant Magic - Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Commander"/>
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.DuelCommander"/> <deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.DuelCommander"/>
<deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.TinyLeaders"/> <deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.TinyLeaders"/>
<deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.InnistradBlock"/> <deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.InnistradBlock"/>
<deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.KamigawaBlock"/> <deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.KamigawaBlock"/>
<deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.KhansOfTarkirBlock"/> <deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.KhansOfTarkirBlock"/>

View file

@ -1,4 +1,4 @@
Welcome! You are playing XMage version 1.4.1 Welcome! You are playing XMage version 1.4.2
Find what was changed since previous versions on project Wiki https://github.com/magefree/mage/wiki Find what was changed since previous versions on project Wiki https://github.com/magefree/mage/wiki
Contact us on the XMAGE board of http://www.slightlymagic.net/forum/viewforum.php?f=70 for bug reports or enhancement requests. Contact us on the XMAGE board of http://www.slightlymagic.net/forum/viewforum.php?f=70 for bug reports or enhancement requests.
Download newest version from http://XMage.de Download newest version from http://XMage.de

View file

@ -2,5 +2,5 @@ HotKeys: Alt+E - Enlarge card image
Wheel zoom in/out - Enlarge card image Wheel zoom in/out - Enlarge card image
F4 - end current turn, response to stack F4 - end current turn, response to stack
F9 - skip all opponents' turns, no response to stack F9 - skip all opponents' turns, no response to stack
Welcome! You are playing Mage version 1.4.1 Welcome! You are playing Mage version 1.4.2
Contact us on www.slightlymagic.net Contact us on www.slightlymagic.net

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server; package mage.server;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,6 +51,7 @@ import mage.interfaces.ActionWithResult;
import mage.interfaces.MageServer; import mage.interfaces.MageServer;
import mage.interfaces.ServerState; import mage.interfaces.ServerState;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
import mage.players.net.UserData;
import mage.remote.MageVersionException; import mage.remote.MageVersionException;
import mage.server.draft.CubeFactory; import mage.server.draft.CubeFactory;
import mage.server.draft.DraftManager; import mage.server.draft.DraftManager;
@ -83,7 +83,6 @@ import mage.view.MatchView;
import mage.view.RoomUsersView; import mage.view.RoomUsersView;
import mage.view.TableView; import mage.view.TableView;
import mage.view.TournamentView; import mage.view.TournamentView;
import mage.view.UserDataView;
import mage.view.UserView; import mage.view.UserView;
import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -117,7 +116,7 @@ public class MageServerImpl implements MageServer {
return SessionManager.getInstance().registerUser(sessionId, userName); return SessionManager.getInstance().registerUser(sessionId, userName);
} catch (MageException ex) { } catch (MageException ex) {
if (ex instanceof MageVersionException) { if (ex instanceof MageVersionException) {
throw (MageVersionException)ex; throw (MageVersionException) ex;
} }
handleException(ex); handleException(ex);
} }
@ -125,11 +124,11 @@ public class MageServerImpl implements MageServer {
} }
@Override @Override
public boolean setUserData(final String userName, final String sessionId, final UserDataView userDataView) throws MageException { public boolean setUserData(final String userName, final String sessionId, final UserData userData) throws MageException {
return executeWithResult("setUserData", sessionId, new ActionWithBooleanResult() { return executeWithResult("setUserData", sessionId, new ActionWithBooleanResult() {
@Override @Override
public Boolean execute() throws MageException { public Boolean execute() throws MageException {
return SessionManager.getInstance().setUserData(userName, sessionId, userDataView); return SessionManager.getInstance().setUserData(userName, sessionId, userData);
} }
}); });
} }
@ -293,8 +292,7 @@ public class MageServerImpl implements MageServer {
} else { } else {
return null; return null;
} }
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -310,8 +308,7 @@ public class MageServerImpl implements MageServer {
} else { } else {
return null; return null;
} }
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -326,8 +323,7 @@ public class MageServerImpl implements MageServer {
} else { } else {
return null; return null;
} }
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -343,8 +339,7 @@ public class MageServerImpl implements MageServer {
} else { } else {
return null; return null;
} }
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -365,7 +360,6 @@ public class MageServerImpl implements MageServer {
// } // }
// }); // });
// } // }
@Override @Override
public boolean startMatch(final String sessionId, final UUID roomId, final UUID tableId) throws MageException { public boolean startMatch(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
if (!TableManager.getInstance().getController(tableId).changeTableState(TableState.STARTING)) { if (!TableManager.getInstance().getController(tableId).changeTableState(TableState.STARTING)) {
@ -391,7 +385,6 @@ public class MageServerImpl implements MageServer {
// } // }
// }); // });
// } // }
@Override @Override
public boolean startTournament(final String sessionId, final UUID roomId, final UUID tableId) throws MageException { public boolean startTournament(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
if (!TableManager.getInstance().getController(tableId).changeTableState(TableState.STARTING)) { if (!TableManager.getInstance().getController(tableId).changeTableState(TableState.STARTING)) {
@ -412,8 +405,7 @@ public class MageServerImpl implements MageServer {
public TournamentView getTournament(UUID tournamentId) throws MageException { public TournamentView getTournament(UUID tournamentId) throws MageException {
try { try {
return TournamentManager.getInstance().getTournamentView(tournamentId); return TournamentManager.getInstance().getTournamentView(tournamentId);
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -424,15 +416,14 @@ public class MageServerImpl implements MageServer {
public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException { public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException {
try { try {
callExecutor.execute( callExecutor.execute(
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE); ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE);
}
} }
}
); );
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
} }
@ -464,8 +455,7 @@ public class MageServerImpl implements MageServer {
public UUID getMainRoomId() throws MageException { public UUID getMainRoomId() throws MageException {
try { try {
return GamesRoomManager.getInstance().getMainRoomId(); return GamesRoomManager.getInstance().getMainRoomId();
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -476,8 +466,7 @@ public class MageServerImpl implements MageServer {
public UUID getRoomChatId(UUID roomId) throws MageException { public UUID getRoomChatId(UUID roomId) throws MageException {
try { try {
return GamesRoomManager.getInstance().getRoom(roomId).getChatId(); return GamesRoomManager.getInstance().getRoom(roomId).getChatId();
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -527,8 +516,7 @@ public class MageServerImpl implements MageServer {
public UUID getTableChatId(UUID tableId) throws MageException { public UUID getTableChatId(UUID tableId) throws MageException {
try { try {
return TableManager.getInstance().getChatId(tableId); return TableManager.getInstance().getChatId(tableId);
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -572,8 +560,7 @@ public class MageServerImpl implements MageServer {
public UUID getGameChatId(UUID gameId) throws MageException { public UUID getGameChatId(UUID gameId) throws MageException {
try { try {
return GameManager.getInstance().getChatId(gameId); return GameManager.getInstance().getChatId(gameId);
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -584,8 +571,7 @@ public class MageServerImpl implements MageServer {
public UUID getTournamentChatId(UUID tournamentId) throws MageException { public UUID getTournamentChatId(UUID tournamentId) throws MageException {
try { try {
return TournamentManager.getInstance().getChatId(tournamentId); return TournamentManager.getInstance().getChatId(tournamentId);
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -675,8 +661,8 @@ public class MageServerImpl implements MageServer {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) { if (session != null) {
return DraftManager.getInstance().sendCardPick(draftId, session.getUserId(), cardPick, hiddenCards); return DraftManager.getInstance().sendCardPick(draftId, session.getUserId(), cardPick, hiddenCards);
} else{ } else {
logger.error("Session not found sessionId: "+ sessionId + " draftId:" + draftId); logger.error("Session not found sessionId: " + sessionId + " draftId:" + draftId);
} }
return null; return null;
} }
@ -691,8 +677,8 @@ public class MageServerImpl implements MageServer {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) { if (session != null) {
DraftManager.getInstance().sendCardMark(draftId, session.getUserId(), cardPick); DraftManager.getInstance().sendCardMark(draftId, session.getUserId(), cardPick);
} else{ } else {
logger.error("Session not found sessionId: "+ sessionId + " draftId:" + draftId); logger.error("Session not found sessionId: " + sessionId + " draftId:" + draftId);
} }
} }
}); });
@ -706,8 +692,8 @@ public class MageServerImpl implements MageServer {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) { if (session != null) {
GameManager.getInstance().quitMatch(gameId, session.getUserId()); GameManager.getInstance().quitMatch(gameId, session.getUserId());
} else{ } else {
logger.error("Session not found sessionId: "+ sessionId + " gameId:" +gameId); logger.error("Session not found sessionId: " + sessionId + " gameId:" + gameId);
} }
} }
}); });
@ -721,8 +707,8 @@ public class MageServerImpl implements MageServer {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) { if (session != null) {
TournamentManager.getInstance().quit(tournamentId, session.getUserId()); TournamentManager.getInstance().quit(tournamentId, session.getUserId());
}else{ } else {
logger.error("Session not found sessionId: "+ sessionId + " tournamentId:" + tournamentId); logger.error("Session not found sessionId: " + sessionId + " tournamentId:" + tournamentId);
} }
} }
}); });
@ -735,7 +721,7 @@ public class MageServerImpl implements MageServer {
public void execute() { public void execute() {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session == null) { if (session == null) {
logger.error("Session not found sessionId: "+ sessionId + " draftId:" + draftId); logger.error("Session not found sessionId: " + sessionId + " draftId:" + draftId);
return; return;
} }
UUID tableId = DraftManager.getInstance().getControllerByDraftId(draftId).getTableId(); UUID tableId = DraftManager.getInstance().getControllerByDraftId(draftId).getTableId();
@ -755,7 +741,7 @@ public class MageServerImpl implements MageServer {
public void execute() { public void execute() {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session == null) { if (session == null) {
logger.error("Session not found sessionId: "+ sessionId + " gameId:" + gameId); logger.error("Session not found sessionId: " + sessionId + " gameId:" + gameId);
return; return;
} }
GameManager.getInstance().sendPlayerAction(playerAction, gameId, session.getUserId(), data); GameManager.getInstance().sendPlayerAction(playerAction, gameId, session.getUserId(), data);
@ -893,8 +879,7 @@ public class MageServerImpl implements MageServer {
CardRepository.instance.getContentVersionConstant(), CardRepository.instance.getContentVersionConstant(),
ExpansionRepository.instance.getContentVersionConstant() ExpansionRepository.instance.getContentVersionConstant()
); );
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return null;
@ -925,7 +910,7 @@ public class MageServerImpl implements MageServer {
return false; return false;
} }
}); });
} }
public void handleException(Exception ex) throws MageException { public void handleException(Exception ex) throws MageException {
if (!ex.getMessage().equals("No message")) { if (!ex.getMessage().equals("No message")) {
@ -936,12 +921,12 @@ public class MageServerImpl implements MageServer {
@Override @Override
public GameView getGameView(final UUID gameId, final String sessionId, final UUID playerId) throws MageException { public GameView getGameView(final UUID gameId, final String sessionId, final UUID playerId) throws MageException {
return executeWithResult("getGameView", sessionId, new ActionWithNullNegativeResult<GameView>() { return executeWithResult("getGameView", sessionId, new ActionWithNullNegativeResult<GameView>() {
@Override @Override
public GameView execute() throws MageException { public GameView execute() throws MageException {
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
return GameManager.getInstance().getGameView(gameId, userId, playerId); return GameManager.getInstance().getGameView(gameId, userId, playerId);
} }
}); });
} }
@ -1009,9 +994,9 @@ public class MageServerImpl implements MageServer {
public Object getServerMessagesCompressed(String sessionId) throws MageException { public Object getServerMessagesCompressed(String sessionId) throws MageException {
return executeWithResult("getGameView", sessionId, new ActionWithNullNegativeResult<Object>() { return executeWithResult("getGameView", sessionId, new ActionWithNullNegativeResult<Object>() {
@Override @Override
public Object execute() throws MageException { public Object execute() throws MageException {
return CompressUtil.compress(ServerMessagesUtil.getInstance().getMessages()); return CompressUtil.compress(ServerMessagesUtil.getInstance().getMessages());
} }
}); });
} }
@ -1061,23 +1046,22 @@ public class MageServerImpl implements MageServer {
if (SessionManager.getInstance().isValidSession(sessionId)) { if (SessionManager.getInstance().isValidSession(sessionId)) {
try { try {
callExecutor.execute( callExecutor.execute(
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
if (SessionManager.getInstance().isValidSession(sessionId)) { if (SessionManager.getInstance().isValidSession(sessionId)) {
try { try {
action.execute(); action.execute();
} catch (MageException me) { } catch (MageException me) {
throw new RuntimeException(me); throw new RuntimeException(me);
}
} else {
LogServiceImpl.instance.log(LogKeys.KEY_NOT_VALID_SESSION_INTERNAL, actionName, sessionId);
} }
} else {
LogServiceImpl.instance.log(LogKeys.KEY_NOT_VALID_SESSION_INTERNAL, actionName, sessionId);
} }
} }
}
); );
} } catch (Exception ex) {
catch (Exception ex) {
handleException(ex); handleException(ex);
} }
} else { } else {

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server; package mage.server;
import java.util.Date; import java.util.Date;
@ -42,7 +41,6 @@ import mage.players.net.UserData;
import mage.players.net.UserGroup; import mage.players.net.UserGroup;
import mage.server.game.GamesRoomManager; import mage.server.game.GamesRoomManager;
import mage.server.util.ConfigSettings; import mage.server.util.ConfigSettings;
import mage.view.UserDataView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jboss.remoting.callback.AsynchInvokerCallbackHandler; import org.jboss.remoting.callback.AsynchInvokerCallbackHandler;
import org.jboss.remoting.callback.Callback; import org.jboss.remoting.callback.Callback;
@ -142,77 +140,49 @@ public class Session {
if (user == null) { if (user == null) {
user = UserManager.getInstance().findUser("Admin"); user = UserManager.getInstance().findUser("Admin");
} }
user.setUserData(new UserData(UserGroup.ADMIN, 0, false, false, false, null, "world.png", false)); UserData adminUserData = UserData.getDefaultUserDataView();
adminUserData.setGroupId(UserGroup.ADMIN.getGroupId());
user.setUserData(adminUserData);
if (!UserManager.getInstance().connectToSession(sessionId, user.getId())) { if (!UserManager.getInstance().connectToSession(sessionId, user.getId())) {
logger.info("Error connecting Admin!"); logger.info("Error connecting Admin!");
} }
this.userId = user.getId(); this.userId = user.getId();
} }
public boolean setUserData(String userName, UserDataView userDataView) { public boolean setUserData(String userName, UserData userData) {
User user = UserManager.getInstance().findUser(userName); User user = UserManager.getInstance().findUser(userName);
if (user != null) { if (user != null) {
UserData userData = user.getUserData(); if (user.getUserData() == null || user.getUserData().getGroupId() == UserGroup.DEFAULT.getGroupId()) {
if (userData == null) {
userData = new UserData(UserGroup.PLAYER, userDataView.getAvatarId(),
userDataView.isShowAbilityPickerForced(), userDataView.allowRequestShowHandCards(),
userDataView.confirmEmptyManaPool(), userDataView.getUserSkipPrioritySteps(),
userDataView.getFlagName(), userDataView.askMoveToGraveOrder());
user.setUserData(userData); user.setUserData(userData);
} else { } else {
if (userDataView.getAvatarId() == 51) { // Update special avatar if first avatar is selected user.getUserData().update(userData);
updateAvatar(userName, userData); }
} if (user.getUserData().getAvatarId() == 51) {
userData.setAvatarId(userDataView.getAvatarId()); user.getUserData().setAvatarId(updateAvatar(user.getName()));
userData.setShowAbilityPickerForced(userDataView.isShowAbilityPickerForced());
userData.setAllowRequestShowHandCards(userDataView.allowRequestShowHandCards());
userData.setUserSkipPrioritySteps(userDataView.getUserSkipPrioritySteps());
userData.setConfirmEmptyManaPool(userDataView.confirmEmptyManaPool());
userData.setAskMoveToGraveOrder(userDataView.askMoveToGraveOrder());
} }
return true; return true;
} }
return false; return false;
} }
private void updateAvatar(String userName, UserData userData) { private int updateAvatar(String userName) {
//TODO: move to separate class //TODO: move to separate class
//TODO: add for checking for private key //TODO: add for checking for private key
switch (userName) { switch (userName) {
case "nantuko": case "nantuko":
userData.setAvatarId(1000); return 1000;
break;
case "i_no_k":
userData.setAvatarId(1002);
break;
case "Askael":
userData.setAvatarId(1004);
break;
case "North": case "North":
userData.setAvatarId(1006); return 1006;
break;
case "BetaSteward": case "BetaSteward":
userData.setAvatarId(1008); return 1008;
break;
case "Arching":
userData.setAvatarId(1010);
break;
case "loki": case "loki":
userData.setAvatarId(1012); return 1012;
break;
case "Alive":
userData.setAvatarId(1014);
break;
case "Rahan":
userData.setAvatarId(1016);
break;
case "Ayrat": case "Ayrat":
userData.setAvatarId(1018); return 1018;
break;
case "Bandit": case "Bandit":
userData.setAvatarId(1020); return 1020;
break;
} }
return 51;
} }
public String getId() { public String getId() {
@ -220,10 +190,10 @@ public class Session {
} }
// because different threads can activate this // because different threads can activate this
public void userLostConnection() { public void userLostConnection() {
boolean lockSet = false; boolean lockSet = false;
try { try {
if(lock.tryLock(5000, TimeUnit.MILLISECONDS)) { if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {
lockSet = true; lockSet = true;
logger.debug("SESSION LOCK SET sessionId: " + sessionId); logger.debug("SESSION LOCK SET sessionId: " + sessionId);
} else { } else {
@ -243,9 +213,8 @@ public class Session {
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
logger.error("SESSION LOCK lost connection - userId: " + userId, ex); logger.error("SESSION LOCK lost connection - userId: " + userId, ex);
} } finally {
finally { if (lockSet) {
if (lockSet) {
lock.unlock(); lock.unlock();
logger.trace("SESSION LOCK UNLOCK sessionId: " + sessionId); logger.trace("SESSION LOCK UNLOCK sessionId: " + sessionId);
} }
@ -256,7 +225,7 @@ public class Session {
public void kill(DisconnectReason reason) { public void kill(DisconnectReason reason) {
boolean lockSet = false; boolean lockSet = false;
try { try {
if(lock.tryLock(5000, TimeUnit.MILLISECONDS)) { if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {
lockSet = true; lockSet = true;
logger.debug("SESSION LOCK SET sessionId: " + sessionId); logger.debug("SESSION LOCK SET sessionId: " + sessionId);
} else { } else {
@ -265,9 +234,8 @@ public class Session {
UserManager.getInstance().removeUser(userId, reason); UserManager.getInstance().removeUser(userId, reason);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
logger.error("SESSION LOCK - kill: userId " + userId, ex); logger.error("SESSION LOCK - kill: userId " + userId, ex);
} } finally {
finally { if (lockSet) {
if (lockSet) {
lock.unlock(); lock.unlock();
logger.debug("SESSION LOCK UNLOCK sessionId: " + sessionId); logger.debug("SESSION LOCK UNLOCK sessionId: " + sessionId);
@ -282,7 +250,7 @@ public class Session {
callbackHandler.handleCallbackOneway(new Callback(call)); callbackHandler.handleCallbackOneway(new Callback(call));
} catch (HandleCallbackException ex) { } catch (HandleCallbackException ex) {
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
logger.warn("SESSION CALLBACK EXCEPTION - " + (user != null ? user.getName():"") + " userId " + userId); logger.warn("SESSION CALLBACK EXCEPTION - " + (user != null ? user.getName() : "") + " userId " + userId);
logger.warn(" - method: " + call.getMethod()); logger.warn(" - method: " + call.getMethod());
logger.warn(" - cause: " + getBasicCause(ex).toString()); logger.warn(" - cause: " + getBasicCause(ex).toString());
logger.trace("Stack trace:", ex); logger.trace("Stack trace:", ex);

View file

@ -31,9 +31,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import mage.MageException; import mage.MageException;
import mage.players.net.UserData;
import mage.server.services.LogKeys; import mage.server.services.LogKeys;
import mage.server.services.impl.LogServiceImpl; import mage.server.services.impl.LogServiceImpl;
import mage.view.UserDataView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jboss.remoting.callback.InvokerCallbackHandler; import org.jboss.remoting.callback.InvokerCallbackHandler;
@ -73,7 +73,7 @@ public class SessionManager {
public boolean registerUser(String sessionId, String userName) throws MageException { public boolean registerUser(String sessionId, String userName) throws MageException {
Session session = sessions.get(sessionId); Session session = sessions.get(sessionId);
if (session != null) { if (session != null) {
String returnMessage = session.registerUser(userName); String returnMessage = session.registerUser(userName);
if (returnMessage == null) { if (returnMessage == null) {
LogServiceImpl.instance.log(LogKeys.KEY_USER_CONNECTED, userName, session.getHost(), sessionId); LogServiceImpl.instance.log(LogKeys.KEY_USER_CONNECTED, userName, session.getHost(), sessionId);
@ -102,10 +102,10 @@ public class SessionManager {
return false; return false;
} }
public boolean setUserData(String userName, String sessionId, UserDataView userDataView) throws MageException { public boolean setUserData(String userName, String sessionId, UserData userData) throws MageException {
Session session = sessions.get(sessionId); Session session = sessions.get(sessionId);
if (session != null) { if (session != null) {
session.setUserData(userName, userDataView); session.setUserData(userName, userData);
return true; return true;
} }
return false; return false;
@ -119,7 +119,7 @@ public class SessionManager {
// session was removed meanwhile by another thread so we can return // session was removed meanwhile by another thread so we can return
return; return;
} }
logger.debug("DISCONNECT " + reason.toString() + " - sessionId: "+ sessionId); logger.debug("DISCONNECT " + reason.toString() + " - sessionId: " + sessionId);
sessions.remove(sessionId); sessions.remove(sessionId);
switch (reason) { switch (reason) {
case Disconnected: case Disconnected:
@ -135,7 +135,7 @@ public class SessionManager {
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId); LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId);
break; break;
default: default:
logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: "+ sessionId); logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId);
} }
} else { } else {
sessions.remove(sessionId); sessions.remove(sessionId);
@ -155,6 +155,7 @@ public class SessionManager {
/** /**
* Admin requested the disconnect of a user * Admin requested the disconnect of a user
*
* @param sessionId * @param sessionId
* @param userSessionId * @param userSessionId
*/ */
@ -163,12 +164,12 @@ public class SessionManager {
User userAdmin, user; User userAdmin, user;
if ((userAdmin = getUserFromSession(sessionId)) != null) { if ((userAdmin = getUserFromSession(sessionId)) != null) {
if ((user = getUserFromSession(userSessionId)) != null) { if ((user = getUserFromSession(userSessionId)) != null) {
user.showUserMessage("Admin operation","Your session was disconnected by Admin."); user.showUserMessage("Admin operation", "Your session was disconnected by Admin.");
userAdmin.showUserMessage("Admin action", "User" + user.getName() + " was disconnected."); userAdmin.showUserMessage("Admin action", "User" + user.getName() + " was disconnected.");
disconnect(userSessionId, DisconnectReason.AdminDisconnect); disconnect(userSessionId, DisconnectReason.AdminDisconnect);
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED_BY_ADMIN, sessionId, userSessionId); LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED_BY_ADMIN, sessionId, userSessionId);
} else { } else {
userAdmin.showUserMessage("Admin operation","User with sessionId " + userSessionId + " could not be found!"); userAdmin.showUserMessage("Admin operation", "User with sessionId " + userSessionId + " could not be found!");
} }
} }
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server; package mage.server;
import java.util.Map; import java.util.Map;
@ -103,8 +102,7 @@ public class TableController {
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
// TODO: Handle if user == null // TODO: Handle if user == null
controllerName = user.getName(); controllerName = user.getName();
} } else {
else {
controllerName = "System"; controllerName = "System";
} }
table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes(), match); table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes(), match);
@ -123,8 +121,7 @@ public class TableController {
} else { } else {
controllerName = user.getName(); controllerName = user.getName();
} }
} } else {
else {
controllerName = "System"; controllerName = "System";
} }
table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), tournament); table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), tournament);
@ -133,20 +130,20 @@ public class TableController {
private void init() { private void init() {
match.addTableEventListener( match.addTableEventListener(
new Listener<TableEvent> () { new Listener<TableEvent>() {
@Override @Override
public void event(TableEvent event) { public void event(TableEvent event) {
try { try {
switch (event.getEventType()) { switch (event.getEventType()) {
case SIDEBOARD: case SIDEBOARD:
sideboard(event.getPlayerId(), event.getDeck()); sideboard(event.getPlayerId(), event.getDeck());
break; break;
}
} catch (MageException ex) {
logger.fatal("Table event listener error", ex);
} }
} catch (MageException ex) {
logger.fatal("Table event listener error", ex);
} }
} }
}
); );
} }
@ -171,13 +168,13 @@ public class TableController {
return false; return false;
} }
} }
if (userPlayerMap.containsKey(userId) && playerType.equals("Human")){ if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) {
user.showUserMessage("Join Table", new StringBuilder("You can join a table only one time.").toString()); user.showUserMessage("Join Table", new StringBuilder("You can join a table only one time.").toString());
return false; return false;
} }
Deck deck = null; Deck deck = null;
if (!table.getTournament().getTournamentType().isLimited()) { if (!table.getTournament().getTournamentType().isLimited()) {
if (deckList != null) { if (deckList != null) {
deck = Deck.load(deckList, false, false); deck = Deck.load(deckList, false, false);
} else { } else {
user.showUserMessage("Join Table", "No valid deck selected!"); user.showUserMessage("Join Table", "No valid deck selected!");
@ -210,7 +207,7 @@ public class TableController {
tournamentPlayer.submitDeck(deck); tournamentPlayer.submitDeck(deck);
} }
table.joinTable(player, seat); table.joinTable(player, seat);
logger.debug("Player " + player.getName() + " id: "+ player.getId() + " joined tableId: " + table.getId()); logger.debug("Player " + player.getName() + " id: " + player.getId() + " joined tableId: " + table.getId());
//only inform human players and add them to sessionPlayerMap //only inform human players and add them to sessionPlayerMap
if (seat.getPlayer().isHuman()) { if (seat.getPlayer().isHuman()) {
seat.getPlayer().setUserData(user.getUserData()); seat.getPlayer().setUserData(user.getUserData());
@ -250,7 +247,7 @@ public class TableController {
if (user == null) { if (user == null) {
return false; return false;
} }
if (userPlayerMap.containsKey(userId) && playerType.equals("Human")){ if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) {
user.showUserMessage("Join Table", new StringBuilder("You can join a table only one time.").toString()); user.showUserMessage("Join Table", new StringBuilder("You can join a table only one time.").toString());
return false; return false;
} }
@ -289,7 +286,7 @@ public class TableController {
if (player == null) { if (player == null) {
String message = new StringBuilder("Could not create player ").append(name).append(" of type ").append(seat.getPlayerType()).toString(); String message = new StringBuilder("Could not create player ").append(name).append(" of type ").append(seat.getPlayerType()).toString();
logger.warn(new StringBuilder("User: ").append(user.getName()).append(" => ").append(message).toString()); logger.warn(new StringBuilder("User: ").append(user.getName()).append(" => ").append(message).toString());
user.showUserMessage("Join Table",message); user.showUserMessage("Join Table", message);
return false; return false;
} }
logger.debug("DECK validated: " + table.getValidator().getName() + " " + player.getName() + " " + deck.getName()); logger.debug("DECK validated: " + table.getValidator().getName() + " " + player.getName() + " " + deck.getName());
@ -312,7 +309,7 @@ public class TableController {
return true; return true;
} }
public void addPlayer(UUID userId, Player player, String playerType, Deck deck) throws GameException { public void addPlayer(UUID userId, Player player, String playerType, Deck deck) throws GameException {
if (table.getState() != TableState.WAITING) { if (table.getState() != TableState.WAITING) {
return; return;
} }
@ -378,8 +375,7 @@ public class TableController {
if (table.getState() == TableState.SIDEBOARDING) { if (table.getState() == TableState.SIDEBOARDING) {
match.submitDeck(playerId, deck); match.submitDeck(playerId, deck);
UserManager.getInstance().getUser(userId).removeSideboarding(table.getId()); UserManager.getInstance().getUser(userId).removeSideboarding(table.getId());
} } else {
else {
TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck); TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck);
UserManager.getInstance().getUser(userId).removeConstructing(playerId); UserManager.getInstance().getUser(userId).removeConstructing(playerId);
} }
@ -390,7 +386,7 @@ public class TableController {
if (tournament != null) { if (tournament != null) {
TournamentManager.getInstance().updateDeck(tournament.getId(), playerId, deck); TournamentManager.getInstance().updateDeck(tournament.getId(), playerId, deck);
} else { } else {
logger.fatal("Tournament == null table: " + table.getId() +" userId: " + userId); logger.fatal("Tournament == null table: " + table.getId() + " userId: " + userId);
} }
} else { } else {
if (TableState.SIDEBOARDING.equals(table.getState())) { if (TableState.SIDEBOARDING.equals(table.getState())) {
@ -427,13 +423,11 @@ public class TableController {
// ReplayManager.getInstance().replayGame(table.getId(), userId); // ReplayManager.getInstance().replayGame(table.getId(), userId);
// return true; // return true;
// } // }
private Player createPlayer(String name, String playerType, int skill) { private Player createPlayer(String name, String playerType, int skill) {
Player player; Player player;
if (options == null) { if (options == null) {
player = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, skill); player = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, skill);
} } else {
else {
player = PlayerFactory.getInstance().createPlayer(playerType, name, options.getRange(), skill); player = PlayerFactory.getInstance().createPlayer(playerType, name, options.getRange(), skill);
} }
if (player != null) { if (player != null) {
@ -443,7 +437,7 @@ public class TableController {
} }
public void leaveTableAll() { public void leaveTableAll() {
for (UUID leavingUserId: userPlayerMap.keySet()) { for (UUID leavingUserId : userPlayerMap.keySet()) {
leaveTable(leavingUserId); leaveTable(leavingUserId);
} }
closeTable(); closeTable();
@ -488,13 +482,13 @@ public class TableController {
if (table.isTournament()) { if (table.isTournament()) {
logger.debug("Quit tournament sub tables for userId: " + userId); logger.debug("Quit tournament sub tables for userId: " + userId);
TableManager.getInstance().userQuitTournamentSubTables(tournament.getId(), userId); TableManager.getInstance().userQuitTournamentSubTables(tournament.getId(), userId);
logger.debug("Quit tournament Id: " + table.getTournament().getId() + "(" +table.getTournament().getTournamentState() + ")"); logger.debug("Quit tournament Id: " + table.getTournament().getId() + "(" + table.getTournament().getTournamentState() + ")");
TournamentManager.getInstance().quit(tournament.getId(), userId); TournamentManager.getInstance().quit(tournament.getId(), userId);
} else { } else {
MatchPlayer matchPlayer = match.getPlayer(playerId); MatchPlayer matchPlayer = match.getPlayer(playerId);
if (matchPlayer != null && !match.hasEnded() && !matchPlayer.hasQuit()) { if (matchPlayer != null && !match.hasEnded() && !matchPlayer.hasQuit()) {
Game game = match.getGame(); Game game = match.getGame();
if (game != null && !game.hasEnded()){ if (game != null && !game.hasEnded()) {
Player player = match.getPlayer(playerId).getPlayer(); Player player = match.getPlayer(playerId).getPlayer();
if (player != null && player.isInGame()) { if (player != null && player.isInGame()) {
GameManager.getInstance().quitMatch(game.getId(), userId); GameManager.getInstance().quitMatch(game.getId(), userId);
@ -536,7 +530,7 @@ public class TableController {
logger.info("Tourn. match started id:" + match.getId() + " tournId: " + table.getTournament().getId()); logger.info("Tourn. match started id:" + match.getId() + " tournId: " + table.getTournament().getId());
} else { } else {
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
logger.info("MATCH started [" + match.getName() + "] " + match.getId() + "(" + user.getName() +")"); logger.info("MATCH started [" + match.getName() + "] " + match.getId() + "(" + user.getName() + ")");
logger.debug("- " + match.getOptions().getGameType() + " - " + match.getOptions().getDeckType()); logger.debug("- " + match.getOptions().getGameType() + " - " + match.getOptions().getDeckType());
} }
match.startMatch(); match.startMatch();
@ -558,7 +552,7 @@ public class TableController {
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions); GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions);
String creator = null; String creator = null;
StringBuilder opponent = new StringBuilder(); StringBuilder opponent = new StringBuilder();
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { // no AI players for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { // no AI players
if (!match.getPlayer(entry.getValue()).hasQuit()) { if (!match.getPlayer(entry.getValue()).hasQuit()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
@ -582,7 +576,7 @@ public class TableController {
} }
} }
// Append AI opponents to the log file // Append AI opponents to the log file
for (MatchPlayer mPlayer :match.getPlayers()) { for (MatchPlayer mPlayer : match.getPlayers()) {
if (!mPlayer.getPlayer().isHuman()) { if (!mPlayer.getPlayer().isHuman()) {
if (opponent.length() > 0) { if (opponent.length() > 0) {
opponent.append(" - "); opponent.append(" - ");
@ -592,9 +586,8 @@ public class TableController {
} }
ServerMessagesUtil.getInstance().incGamesStarted(); ServerMessagesUtil.getInstance().incGamesStarted();
// log about game started // log about game started
logger.info("GAME started " + match.getGame().getId() + " [" + match.getName() +"] "+ creator + " - " + opponent.toString()); logger.info("GAME started " + match.getGame().getId() + " [" + match.getName() + "] " + creator + " - " + opponent.toString());
logger.debug("- matchId: " + match.getId() + " [" + match.getName() + "]"); logger.debug("- matchId: " + match.getId() + " [" + match.getName() + "]");
if (match.getGame() != null) { if (match.getGame() != null) {
logger.debug("- chatId: " + GameManager.getInstance().getChatId(match.getGame().getId())); logger.debug("- chatId: " + GameManager.getInstance().getChatId(match.getGame().getId()));
@ -602,8 +595,7 @@ public class TableController {
logger.debug("- no valid game object"); logger.debug("- no valid game object");
} }
LogServiceImpl.instance.log(LogKeys.KEY_GAME_STARTED, String.valueOf(userPlayerMap.size()), creator, opponent.toString()); LogServiceImpl.instance.log(LogKeys.KEY_GAME_STARTED, String.valueOf(userPlayerMap.size()), creator, opponent.toString());
} } catch (Exception ex) {
catch (Exception ex) {
logger.fatal("Error starting game", ex); logger.fatal("Error starting game", ex);
if (table != null) { if (table != null) {
TableManager.getInstance().removeTable(table.getId()); TableManager.getInstance().removeTable(table.getId());
@ -622,7 +614,7 @@ public class TableController {
if (userId.equals(this.userId) && table.getState().equals(TableState.STARTING)) { if (userId.equals(this.userId) && table.getState().equals(TableState.STARTING)) {
tournament.setStartTime(); tournament.setStartTime();
TournamentManager.getInstance().createTournamentSession(tournament, userPlayerMap, table.getId()); TournamentManager.getInstance().createTournamentSession(tournament, userPlayerMap, table.getId());
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
logger.info(new StringBuilder("User ").append(user.getName()).append(" tournament started: ").append(tournament.getId()).append(" userId: ").append(user.getId())); logger.info(new StringBuilder("User ").append(user.getName()).append(" tournament started: ").append(tournament.getId()).append(" userId: ").append(user.getId()));
@ -631,8 +623,7 @@ public class TableController {
} }
ServerMessagesUtil.getInstance().incTournamentsStarted(); ServerMessagesUtil.getInstance().incTournamentsStarted();
} }
} } catch (Exception ex) {
catch (Exception ex) {
logger.fatal("Error starting tournament", ex); logger.fatal("Error starting tournament", ex);
TableManager.getInstance().removeTable(table.getId()); TableManager.getInstance().removeTable(table.getId());
TournamentManager.getInstance().quit(tournament.getId(), userId); TournamentManager.getInstance().quit(tournament.getId(), userId);
@ -642,7 +633,7 @@ public class TableController {
public void startDraft(Draft draft) { public void startDraft(Draft draft) {
table.initDraft(); table.initDraft();
DraftManager.getInstance().createDraftSession(draft, userPlayerMap, table.getId()); DraftManager.getInstance().createDraftSession(draft, userPlayerMap, table.getId());
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
logger.info(new StringBuilder("User ").append(user.getName()).append(" draft started: ").append(draft.getId()).append(" userId: ").append(user.getId())); logger.info(new StringBuilder("User ").append(user.getName()).append(" draft started: ").append(draft.getId()).append(" userId: ").append(user.getId()));
@ -654,7 +645,7 @@ public class TableController {
} }
private void sideboard(UUID playerId, Deck deck) throws MageException { private void sideboard(UUID playerId, Deck deck) throws MageException {
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) { if (entry.getValue().equals(playerId)) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS); int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
@ -715,8 +706,7 @@ public class TableController {
} else { } else {
closeTable(); closeTable();
} }
} } else {
else {
closeTable(); closeTable();
} }
} catch (GameException ex) { } catch (GameException ex) {
@ -729,7 +719,7 @@ public class TableController {
table.sideboard(); table.sideboard();
setupTimeout(Match.SIDEBOARD_TIME); setupTimeout(Match.SIDEBOARD_TIME);
if (table.isTournamentSubTable()) { if (table.isTournamentSubTable()) {
for (MatchPlayer matchPlayer :match.getPlayers()) { for (MatchPlayer matchPlayer : match.getPlayers()) {
if (!matchPlayer.hasQuit()) { if (!matchPlayer.hasQuit()) {
TournamentPlayer tournamentPlayer = table.getTournament().getPlayer(matchPlayer.getPlayer().getId()); TournamentPlayer tournamentPlayer = table.getTournament().getPlayer(matchPlayer.getPlayer().getId());
if (tournamentPlayer != null) { if (tournamentPlayer != null) {
@ -741,7 +731,7 @@ public class TableController {
match.sideboard(); match.sideboard();
cancelTimeout(); cancelTimeout();
if (table.isTournamentSubTable()) { if (table.isTournamentSubTable()) {
for (MatchPlayer matchPlayer :match.getPlayers()) { for (MatchPlayer matchPlayer : match.getPlayers()) {
TournamentPlayer tournamentPlayer = table.getTournament().getPlayer(matchPlayer.getPlayer().getId()); TournamentPlayer tournamentPlayer = table.getTournament().getPlayer(matchPlayer.getPlayer().getId());
if (tournamentPlayer != null && tournamentPlayer.getStateInfo().equals("sideboarding")) { if (tournamentPlayer != null && tournamentPlayer.getStateInfo().equals("sideboarding")) {
tournamentPlayer.setStateInfo(""); tournamentPlayer.setStateInfo("");
@ -749,9 +739,10 @@ public class TableController {
} }
} }
} }
/** /**
* Tables of normal matches or tournament sub tables are no longer * Tables of normal matches or tournament sub tables are no longer needed,
* needed, if the match ends. * if the match ends.
* *
*/ */
private void closeTable() { private void closeTable() {
@ -761,11 +752,11 @@ public class TableController {
private void matchEnd() { private void matchEnd() {
if (match != null) { if (match != null) {
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
MatchPlayer matchPlayer = match.getPlayer(entry.getValue()); MatchPlayer matchPlayer = match.getPlayer(entry.getValue());
// opponent(s) left during sideboarding // opponent(s) left during sideboarding
if (matchPlayer != null) { if (matchPlayer != null) {
if(!matchPlayer.hasQuit()) { if (!matchPlayer.hasQuit()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
if (table.getState().equals(TableState.SIDEBOARDING)) { if (table.getState().equals(TableState.SIDEBOARDING)) {
@ -801,13 +792,13 @@ public class TableController {
cancelTimeout(); cancelTimeout();
if (seconds > 0) { if (seconds > 0) {
futureTimeout = timeoutExecutor.schedule( futureTimeout = timeoutExecutor.schedule(
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
autoSideboard(); autoSideboard();
} }
}, },
seconds, TimeUnit.SECONDS seconds, TimeUnit.SECONDS
); );
} }
} }
@ -819,7 +810,7 @@ public class TableController {
} }
private void autoSideboard() { private void autoSideboard() {
for (MatchPlayer player: match.getPlayers()) { for (MatchPlayer player : match.getPlayers()) {
if (!player.isDoneSideboarding()) { if (!player.isDoneSideboarding()) {
match.submitDeck(player.getPlayer().getId(), player.generateDeck()); match.submitDeck(player.getPlayer().getId(), player.generateDeck());
} }
@ -828,7 +819,7 @@ public class TableController {
public void endDraft(Draft draft) { public void endDraft(Draft draft) {
if (!draft.isAbort()) { if (!draft.isAbort()) {
for (DraftPlayer player: draft.getPlayers()) { for (DraftPlayer player : draft.getPlayers()) {
player.prepareDeck(); player.prepareDeck();
tournament.getPlayer(player.getPlayer().getId()).setDeck(player.getDeck()); tournament.getPlayer(player.getPlayer().getId()).setDeck(player.getDeck());
} }
@ -871,7 +862,7 @@ public class TableController {
public boolean isTournamentStillValid() { public boolean isTournamentStillValid() {
if (table.getTournament() != null) { if (table.getTournament() != null) {
if (!table.getState().equals(TableState.WAITING) && !table.getState().equals(TableState.READY_TO_START) && !table.getState().equals(TableState.STARTING) ) { if (!table.getState().equals(TableState.WAITING) && !table.getState().equals(TableState.READY_TO_START) && !table.getState().equals(TableState.STARTING)) {
TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(table.getTournament().getId()); TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(table.getTournament().getId());
if (tournamentController != null) { if (tournamentController != null) {
return tournamentController.isTournamentStillValid(table.getState()); return tournamentController.isTournamentStillValid(table.getState());
@ -888,7 +879,7 @@ public class TableController {
} }
public UUID getUserId(UUID playerId) { public UUID getUserId(UUID playerId) {
for (Map.Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Map.Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) { if (entry.getValue().equals(playerId)) {
return entry.getKey(); return entry.getKey();
} }
@ -900,7 +891,7 @@ public class TableController {
// check only normal match table with state != Finished // check only normal match table with state != Finished
if (!table.isTournament()) { if (!table.isTournament()) {
int humanPlayers = 0; int humanPlayers = 0;
int aiPlayers = 0 ; int aiPlayers = 0;
int validHumanPlayers = 0; int validHumanPlayers = 0;
if (!(table.getState().equals(TableState.WAITING) || table.getState().equals(TableState.STARTING) || table.getState().equals(TableState.READY_TO_START))) { if (!(table.getState().equals(TableState.WAITING) || table.getState().equals(TableState.STARTING) || table.getState().equals(TableState.READY_TO_START))) {
if (match == null) { if (match == null) {
@ -917,7 +908,7 @@ public class TableController {
} }
} }
// check for active players // check for active players
for(Map.Entry<UUID, UUID> userPlayerEntry: userPlayerMap.entrySet()) { for (Map.Entry<UUID, UUID> userPlayerEntry : userPlayerMap.entrySet()) {
MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue()); MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue());
if (matchPlayer == null) { if (matchPlayer == null) {
logger.debug("- Match player not found:"); logger.debug("- Match player not found:");
@ -928,11 +919,11 @@ public class TableController {
} }
if (matchPlayer.getPlayer().isHuman()) { if (matchPlayer.getPlayer().isHuman()) {
humanPlayers++; humanPlayers++;
if ((table.getState().equals(TableState.WAITING) || if ((table.getState().equals(TableState.WAITING)
table.getState().equals(TableState.STARTING) || || table.getState().equals(TableState.STARTING)
table.getState().equals(TableState.READY_TO_START)) || || table.getState().equals(TableState.READY_TO_START))
!match.isDoneSideboarding() || || !match.isDoneSideboarding()
(!matchPlayer.hasQuit() && match.getGame() != null && matchPlayer.getPlayer().isInGame())) { || (!matchPlayer.hasQuit() && match.getGame() != null && matchPlayer.getPlayer().isInGame())) {
User user = UserManager.getInstance().getUser(userPlayerEntry.getKey()); User user = UserManager.getInstance().getUser(userPlayerEntry.getKey());
if (user == null) { if (user == null) {
logger.debug("- Active user of match is missing: " + matchPlayer.getName()); logger.debug("- Active user of match is missing: " + matchPlayer.getName());
@ -956,7 +947,7 @@ public class TableController {
void cleanUp() { void cleanUp() {
if (!table.isTournamentSubTable()) { if (!table.isTournamentSubTable()) {
for(Map.Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Map.Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
User user = UserManager.getInstance().getUser(entry.getKey()); User user = UserManager.getInstance().getUser(entry.getKey());
if (user != null) { if (user != null) {
user.removeTable(entry.getValue()); user.removeTable(entry.getValue());
@ -973,7 +964,7 @@ public class TableController {
public synchronized boolean changeTableState(TableState newTableState) { public synchronized boolean changeTableState(TableState newTableState) {
switch (newTableState) { switch (newTableState) {
case WAITING: case WAITING:
if (getTable().getState().equals(TableState.STARTING)){ if (getTable().getState().equals(TableState.STARTING)) {
// tournament already started // tournament already started
return false; return false;
} }

View file

@ -53,7 +53,6 @@ import mage.server.util.SystemUtil;
import mage.view.TableClientMessage; import mage.view.TableClientMessage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -63,6 +62,7 @@ public class User {
private static final Logger logger = Logger.getLogger(User.class); private static final Logger logger = Logger.getLogger(User.class);
public enum UserState { public enum UserState {
Created, Connected, Disconnected, Reconnected, Expired; Created, Connected, Disconnected, Reconnected, Expired;
} }
@ -156,15 +156,15 @@ public class User {
long secondsLeft; long secondsLeft;
String sign = ""; String sign = "";
if (secondsDisconnected > (3 * 60)) { if (secondsDisconnected > (3 * 60)) {
sign="-"; sign = "-";
secondsLeft = secondsDisconnected - (3 *60); secondsLeft = secondsDisconnected - (3 * 60);
} else { } else {
secondsLeft = (3 * 60) - secondsDisconnected; secondsLeft = (3 * 60) - secondsDisconnected;
} }
int minutes = (int) secondsLeft / 60; int minutes = (int) secondsLeft / 60;
int seconds = (int) secondsLeft % 60; int seconds = (int) secondsLeft % 60;
return new StringBuilder(sign).append(Integer.toString(minutes)).append(":").append(seconds > 9 ? seconds: "0" + Integer.toString(seconds)).toString(); return new StringBuilder(sign).append(Integer.toString(minutes)).append(":").append(seconds > 9 ? seconds : "0" + Integer.toString(seconds)).toString();
} }
public long getSecondsDisconnected() { public long getSecondsDisconnected() {
@ -217,11 +217,11 @@ public class User {
fireCallback(new ClientCallback("showGameEndDialog", gameId)); fireCallback(new ClientCallback("showGameEndDialog", gameId));
} }
public void showUserMessage(final String titel, String message) { public void showUserMessage(final String titel, String message) {
List<String> messageData = new LinkedList<>(); List<String> messageData = new LinkedList<>();
messageData.add(titel); messageData.add(titel);
messageData.add(message); messageData.add(message);
fireCallback(new ClientCallback("showUserMessage", null, messageData )); fireCallback(new ClientCallback("showUserMessage", null, messageData));
} }
public boolean ccWatchGame(final UUID gameId) { public boolean ccWatchGame(final UUID gameId) {
@ -248,7 +248,7 @@ public class User {
GameManager.getInstance().sendPlayerManaType(gameId, playerId, userId, data); GameManager.getInstance().sendPlayerManaType(gameId, playerId, userId, data);
} }
public void sendPlayerBoolean(final UUID gameId, final Boolean data) { public void sendPlayerBoolean(final UUID gameId, final Boolean data) {
lastActivity = new Date(); lastActivity = new Date();
GameManager.getInstance().sendPlayerBoolean(gameId, userId, data); GameManager.getInstance().sendPlayerBoolean(gameId, userId, data);
} }
@ -276,13 +276,14 @@ public class User {
} }
logger.trace(new StringBuilder("isExpired: User ").append(userName).append(" lastActivity: ").append(lastActivity).append(" expired: ").append(expired).toString()); logger.trace(new StringBuilder("isExpired: User ").append(userName).append(" lastActivity: ").append(lastActivity).append(" expired: ").append(expired).toString());
return false; /*userState == UserState.Disconnected && */ return false; /*userState == UserState.Disconnected && */
} }
private void reconnect() { private void reconnect() {
for (Entry<UUID, Table> entry: tables.entrySet()) { for (Entry<UUID, Table> entry : tables.entrySet()) {
ccJoinedTable(entry.getValue().getRoomId(), entry.getValue().getId(), entry.getValue().isTournament()); ccJoinedTable(entry.getValue().getRoomId(), entry.getValue().getId(), entry.getValue().isTournament());
} }
for (Entry<UUID, UUID> entry: userTournaments.entrySet()) { for (Entry<UUID, UUID> entry : userTournaments.entrySet()) {
TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(entry.getValue()); TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(entry.getValue());
if (tournamentController != null) { if (tournamentController != null) {
ccTournamentStarted(entry.getValue(), entry.getKey()); ccTournamentStarted(entry.getValue(), entry.getKey());
@ -290,22 +291,22 @@ public class User {
} }
} }
for (Entry<UUID, GameSessionPlayer> entry: gameSessions.entrySet()) { for (Entry<UUID, GameSessionPlayer> entry : gameSessions.entrySet()) {
ccGameStarted(entry.getValue().getGameId(), entry.getKey()); ccGameStarted(entry.getValue().getGameId(), entry.getKey());
entry.getValue().init(); entry.getValue().init();
GameManager.getInstance().sendPlayerString(entry.getValue().getGameId(), userId, ""); GameManager.getInstance().sendPlayerString(entry.getValue().getGameId(), userId, "");
} }
for (Entry<UUID, DraftSession> entry: draftSessions.entrySet()) { for (Entry<UUID, DraftSession> entry : draftSessions.entrySet()) {
ccDraftStarted(entry.getValue().getDraftId(), entry.getKey()); ccDraftStarted(entry.getValue().getDraftId(), entry.getKey());
entry.getValue().init(); entry.getValue().init();
entry.getValue().update(); entry.getValue().update();
} }
for (Entry<UUID, TournamentSession> entry: constructing.entrySet()) { for (Entry<UUID, TournamentSession> entry : constructing.entrySet()) {
entry.getValue().construct(0); // TODO: Check if this is correct entry.getValue().construct(0); // TODO: Check if this is correct
} }
for (Entry<UUID, Deck> entry: sideboarding.entrySet()) { for (Entry<UUID, Deck> entry : sideboarding.entrySet()) {
TableController controller = TableManager.getInstance().getController(entry.getKey()); TableController controller = TableManager.getInstance().getController(entry.getKey());
ccSideboard(entry.getValue(), entry.getKey(), controller.getRemainingTime(), controller.getOptions().isLimited()); ccSideboard(entry.getValue(), entry.getKey(), controller.getRemainingTime(), controller.getOptions().isLimited());
} }
@ -357,30 +358,30 @@ public class User {
public void remove(DisconnectReason reason) { public void remove(DisconnectReason reason) {
logger.trace("REMOVE " + getName() + " Draft sessions " + draftSessions.size()); logger.trace("REMOVE " + getName() + " Draft sessions " + draftSessions.size());
for (DraftSession draftSession: draftSessions.values()) { for (DraftSession draftSession : draftSessions.values()) {
draftSession.setKilled(); draftSession.setKilled();
} }
draftSessions.clear(); draftSessions.clear();
logger.trace("REMOVE " + getName() + " Tournament sessions " + userTournaments.size()); logger.trace("REMOVE " + getName() + " Tournament sessions " + userTournaments.size());
for (UUID tournamentId: userTournaments.values()) { for (UUID tournamentId : userTournaments.values()) {
TournamentManager.getInstance().quit(tournamentId, getId()); TournamentManager.getInstance().quit(tournamentId, getId());
} }
userTournaments.clear(); userTournaments.clear();
logger.trace("REMOVE " + getName() + " Tables " + tables.size()); logger.trace("REMOVE " + getName() + " Tables " + tables.size());
for (Entry<UUID, Table> entry: tables.entrySet()) { for (Entry<UUID, Table> entry : tables.entrySet()) {
logger.debug("-- leave tableId: " + entry.getValue().getId()); logger.debug("-- leave tableId: " + entry.getValue().getId());
TableManager.getInstance().leaveTable(userId, entry.getValue().getId()); TableManager.getInstance().leaveTable(userId, entry.getValue().getId());
} }
tables.clear(); tables.clear();
logger.trace("REMOVE " + getName() + " Game sessions: " + gameSessions.size() ); logger.trace("REMOVE " + getName() + " Game sessions: " + gameSessions.size());
for (GameSessionPlayer gameSessionPlayer: gameSessions.values()) { for (GameSessionPlayer gameSessionPlayer : gameSessions.values()) {
logger.debug("-- kill game session of gameId: " + gameSessionPlayer.getGameId() ); logger.debug("-- kill game session of gameId: " + gameSessionPlayer.getGameId());
GameManager.getInstance().quitMatch(gameSessionPlayer.getGameId(), userId); GameManager.getInstance().quitMatch(gameSessionPlayer.getGameId(), userId);
gameSessionPlayer.quitGame(); gameSessionPlayer.quitGame();
} }
gameSessions.clear(); gameSessions.clear();
logger.trace("REMOVE " + getName() + " watched Games " + watchedGames.size()); logger.trace("REMOVE " + getName() + " watched Games " + watchedGames.size());
for (UUID gameId: watchedGames) { for (UUID gameId : watchedGames) {
GameManager.getInstance().stopWatching(gameId, userId); GameManager.getInstance().stopWatching(gameId, userId);
} }
watchedGames.clear(); watchedGames.clear();
@ -389,10 +390,17 @@ public class User {
} }
public void setUserData(UserData userData) { public void setUserData(UserData userData) {
this.userData = userData; if (this.userData != null) {
this.userData.update(userData);
} else {
this.userData = userData;
}
} }
public UserData getUserData() { public UserData getUserData() {
if (userData == null) {// default these to avaiod NPE -> will be updated from client short after
return UserData.getDefaultUserDataView();
}
return this.userData; return this.userData;
} }
@ -428,7 +436,7 @@ public class User {
} }
if (!isConnected()) { if (!isConnected()) {
tournamentPlayer.setDisconnectInfo(" (discon. "+ getDisconnectDuration() + ")"); tournamentPlayer.setDisconnectInfo(" (discon. " + getDisconnectDuration() + ")");
} else { } else {
tournamentPlayer.setDisconnectInfo(""); tournamentPlayer.setDisconnectInfo("");
} }
@ -460,7 +468,7 @@ public class User {
} }
} }
if (!tablesToDelete.isEmpty()) { if (!tablesToDelete.isEmpty()) {
for(UUID keyId: tablesToDelete) { for (UUID keyId : tablesToDelete) {
removeTable(keyId); removeTable(keyId);
} }
tablesToDelete.clear(); tablesToDelete.clear();
@ -513,7 +521,7 @@ public class User {
if (isConnected()) { if (isConnected()) {
return pingInfo; return pingInfo;
} else { } else {
return " (discon. "+ getDisconnectDuration() + ")"; return " (discon. " + getDisconnectDuration() + ")";
} }
} }

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server.game; package mage.server.game;
import java.io.Serializable; import java.io.Serializable;
@ -73,10 +72,10 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>(); private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>();
public GamesRoomImpl() { public GamesRoomImpl() {
updateExecutor.scheduleAtFixedRate(new Runnable() { updateExecutor.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run(){ public void run() {
try { try {
update(); update();
} catch (Exception ex) { } catch (Exception ex) {
@ -97,12 +96,11 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
ArrayList<MatchView> matchList = new ArrayList<>(); ArrayList<MatchView> matchList = new ArrayList<>();
List<Table> allTables = new ArrayList<>(tables.values()); List<Table> allTables = new ArrayList<>(tables.values());
Collections.sort(allTables, new TableListSorter()); Collections.sort(allTables, new TableListSorter());
for (Table table: allTables) { for (Table table : allTables) {
if (table.getState() != TableState.FINISHED) { if (table.getState() != TableState.FINISHED) {
tableList.add(new TableView(table)); tableList.add(new TableView(table));
} } else if (matchList.size() < 50) {
else if (matchList.size() < 50) { if (table.isTournament()) {
if (table.isTournament()) {
matchList.add(new MatchView(table)); matchList.add(new MatchView(table));
} else { } else {
matchList.add(new MatchView(table)); matchList.add(new MatchView(table));
@ -113,17 +111,22 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
TournamentManager.getInstance().removeTournament(table.getTournament().getId()); TournamentManager.getInstance().removeTournament(table.getTournament().getId());
} }
this.removeTable(table.getId()); this.removeTable(table.getId());
} }
} }
tableView = tableList; tableView = tableList;
matchView = matchList; matchView = matchList;
List<UsersView> users = new ArrayList<>(); List<UsersView> users = new ArrayList<>();
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
try { try {
users.add(new UsersView(user.getUserData().getFlagName(), user.getName(), user.getInfo(), user.getGameInfo(), user.getPingInfo())); users.add(new UsersView(user.getUserData().getFlagName(), user.getName(), user.getInfo(), user.getGameInfo(), user.getPingInfo()));
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex); logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
users.add(new UsersView(user.getUserData().getFlagName(), user.getName(), user.getInfo(), "[exception]", user.getPingInfo())); users.add(new UsersView(
(user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world",
user.getName() != null ? user.getName() : "<no name>",
user.getInfo() != null ? user.getInfo() : "<no info>",
"[exception]",
user.getPingInfo() != null ? user.getPingInfo() : "<no ping>"));
} }
} }
@ -222,14 +225,15 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
* @author LevelX2 * @author LevelX2
*/ */
class TableListSorter implements Comparator<Table> { class TableListSorter implements Comparator<Table> {
@Override @Override
public int compare(Table one, Table two) { public int compare(Table one, Table two) {
if (!one.getState().equals(TableState.SIDEBOARDING) && !one.getState().equals(TableState.DUELING)) { if (!one.getState().equals(TableState.SIDEBOARDING) && !one.getState().equals(TableState.DUELING)) {
if (one.getState().compareTo(two.getState()) != 0 ) { if (one.getState().compareTo(two.getState()) != 0) {
return one.getState().compareTo(two.getState()); return one.getState().compareTo(two.getState());
} }
} else if (!two.getState().equals(TableState.SIDEBOARDING) && !two.getState().equals(TableState.DUELING)) { } else if (!two.getState().equals(TableState.SIDEBOARDING) && !two.getState().equals(TableState.DUELING)) {
if (one.getState().compareTo(two.getState()) != 0 ) { if (one.getState().compareTo(two.getState()) != 0) {
return one.getState().compareTo(two.getState()); return one.getState().compareTo(two.getState());
} }
} }
@ -259,6 +263,7 @@ class TableListSorter implements Comparator<Table> {
} }
class UserNameSorter implements Comparator<UsersView> { class UserNameSorter implements Comparator<UsersView> {
@Override @Override
public int compare(UsersView one, UsersView two) { public int compare(UsersView one, UsersView two) {
return one.getUserName().compareToIgnoreCase(two.getUserName()); return one.getUserName().compareToIgnoreCase(two.getUserName());

View file

@ -1,31 +1,30 @@
/* /*
* Copyright 2011 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 * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server.tournament; package mage.server.tournament;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -63,7 +62,6 @@ import mage.view.ChatMessage.SoundToPlay;
import mage.view.TournamentView; import mage.view.TournamentView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -89,57 +87,57 @@ public class TournamentController {
private void init() { private void init() {
tournament.addTableEventListener( tournament.addTableEventListener(
new Listener<TableEvent> () { new Listener<TableEvent>() {
@Override @Override
public void event(TableEvent event) { public void event(TableEvent event) {
switch (event.getEventType()) { switch (event.getEventType()) {
case CHECK_STATE_PLAYERS: case CHECK_STATE_PLAYERS:
checkPlayersState(); checkPlayersState();
break; break;
case INFO: case INFO:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS); ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS);
logger.debug(tournament.getId() + " " + event.getMessage()); logger.debug(tournament.getId() + " " + event.getMessage());
break; break;
case START_DRAFT: case START_DRAFT:
startDraft(event.getDraft()); startDraft(event.getDraft());
break; break;
case CONSTRUCT:
if (!isAbort()) {
construct();
} else {
endTournament();
}
break;
case START_MATCH:
if (!isAbort()) {
initTournament(); // set state
startMatch(event.getPair(), event.getMatchOptions());
}
break;
case END:
endTournament();
break;
}
}
}
);
tournament.addPlayerQueryEventListener(
new Listener<PlayerQueryEvent> () {
@Override
public void event(PlayerQueryEvent event) {
try {
switch (event.getQueryType()) {
case CONSTRUCT: case CONSTRUCT:
construct(event.getPlayerId(), event.getMax()); if (!isAbort()) {
construct();
} else {
endTournament();
}
break;
case START_MATCH:
if (!isAbort()) {
initTournament(); // set state
startMatch(event.getPair(), event.getMatchOptions());
}
break;
case END:
endTournament();
break; break;
} }
} catch (MageException ex) {
logger.fatal("Player event listener error", ex);
} }
} }
}
); );
for (TournamentPlayer player: tournament.getPlayers()) { tournament.addPlayerQueryEventListener(
new Listener<PlayerQueryEvent>() {
@Override
public void event(PlayerQueryEvent event) {
try {
switch (event.getQueryType()) {
case CONSTRUCT:
construct(event.getPlayerId(), event.getMax());
break;
}
} catch (MageException ex) {
logger.fatal("Player event listener error", ex);
}
}
}
);
for (TournamentPlayer player : tournament.getPlayers()) {
if (!player.getPlayer().isHuman()) { if (!player.getPlayer().isHuman()) {
player.setJoined(); player.setJoined();
logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId()); logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId());
@ -172,22 +170,22 @@ public class TournamentController {
user.addTournament(playerId, tournament.getId()); user.addTournament(playerId, tournament.getId());
TournamentPlayer player = tournament.getPlayer(playerId); TournamentPlayer player = tournament.getPlayer(playerId);
player.setJoined(); player.setJoined();
logger.debug("player " +player.getPlayer().getName() + " - client has joined tournament " + tournament.getId()); logger.debug("player " + player.getPlayer().getName() + " - client has joined tournament " + tournament.getId());
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS); ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS);
checkStart(); checkStart();
} else { } else {
logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId()); logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId());
} }
} }
public void rejoin(UUID playerId) { public void rejoin(UUID playerId) {
TournamentSession tournamentSession = tournamentSessions.get(playerId); TournamentSession tournamentSession = tournamentSessions.get(playerId);
if (tournamentSession == null) { if (tournamentSession == null) {
logger.fatal("Tournament session not found - playerId:" + playerId + " tournamentId " + tournament.getId()); logger.fatal("Tournament session not found - playerId:" + playerId + " tournamentId " + tournament.getId());
return; return;
} }
if (!tournamentSession.init()) { if (!tournamentSession.init()) {
logger.fatal("Unable to initialize client userId: " + tournamentSession.userId + " tournamentId " + tournament.getId()); logger.fatal("Unable to initialize client userId: " + tournamentSession.userId + " tournamentId " + tournament.getId());
return; return;
} }
tournamentSession.update(); tournamentSession.update();
@ -196,12 +194,12 @@ public class TournamentController {
private void checkStart() { private void checkStart() {
if (!started && allJoined()) { if (!started && allJoined()) {
ThreadExecutor.getInstance().getCallExecutor().execute( ThreadExecutor.getInstance().getCallExecutor().execute(
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
startTournament(); startTournament();
} }
}); });
} }
} }
@ -209,7 +207,7 @@ public class TournamentController {
if (!tournament.allJoined()) { if (!tournament.allJoined()) {
return false; return false;
} }
for (TournamentPlayer player: tournament.getPlayers()) { for (TournamentPlayer player : tournament.getPlayers()) {
if (player.getPlayer().isHuman() && tournamentSessions.get(player.getPlayer().getId()) == null) { if (player.getPlayer().isHuman() && tournamentSessions.get(player.getPlayer().getId()) == null) {
return false; return false;
} }
@ -218,9 +216,9 @@ public class TournamentController {
} }
private synchronized void startTournament() { private synchronized void startTournament() {
for (final TournamentSession tournamentSession: tournamentSessions.values()) { for (final TournamentSession tournamentSession : tournamentSessions.values()) {
if (!tournamentSession.init()) { if (!tournamentSession.init()) {
logger.fatal("Unable to initialize client userId: " + tournamentSession.userId + " tournamentId " + tournament.getId()); logger.fatal("Unable to initialize client userId: " + tournamentSession.userId + " tournamentId " + tournament.getId());
//TODO: generate client error message //TODO: generate client error message
return; return;
} }
@ -231,10 +229,10 @@ public class TournamentController {
} }
private void endTournament() { private void endTournament() {
for (TournamentPlayer player: tournament.getPlayers()) { for (TournamentPlayer player : tournament.getPlayers()) {
player.setStateAtTournamentEnd(); player.setStateAtTournamentEnd();
} }
for (final TournamentSession tournamentSession: tournamentSessions.values()) { for (final TournamentSession tournamentSession : tournamentSessions.values()) {
tournamentSession.tournamentOver(); tournamentSession.tournamentOver();
} }
this.tournamentSessions.clear(); this.tournamentSessions.clear();
@ -296,7 +294,7 @@ public class TournamentController {
TournamentPlayer player = tournament.getPlayer(playerId); TournamentPlayer player = tournament.getPlayer(playerId);
if (player != null && !player.hasQuit()) { if (player != null && !player.hasQuit()) {
tournamentSessions.get(playerId).submitDeck(deck); tournamentSessions.get(playerId).submitDeck(deck);
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has submitted his tournament deck", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerSubmittedDeck); ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has submitted his tournament deck", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerSubmittedDeck);
} }
} }
} }
@ -387,7 +385,7 @@ public class TournamentController {
private boolean checkToReplaceDraftPlayerByAi(UUID userId, TournamentPlayer leavingPlayer) { private boolean checkToReplaceDraftPlayerByAi(UUID userId, TournamentPlayer leavingPlayer) {
int humans = 0; int humans = 0;
for (TournamentPlayer tPlayer :tournament.getPlayers()) { for (TournamentPlayer tPlayer : tournament.getPlayers()) {
if (tPlayer.getPlayer().isHuman()) { if (tPlayer.getPlayer().isHuman()) {
humans++; humans++;
} }
@ -415,7 +413,7 @@ public class TournamentController {
} }
private UUID getPlayerUserId(UUID playerId) { private UUID getPlayerUserId(UUID playerId) {
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) { if (entry.getValue().equals(playerId)) {
return entry.getKey(); return entry.getKey();
} }
@ -437,7 +435,7 @@ public class TournamentController {
} }
private void checkPlayersState() { private void checkPlayersState() {
for (TournamentPlayer tournamentPlayer: tournament.getPlayers()) { for (TournamentPlayer tournamentPlayer : tournament.getPlayers()) {
if (!tournamentPlayer.isEliminated() && tournamentPlayer.getPlayer().isHuman()) { if (!tournamentPlayer.isEliminated() && tournamentPlayer.getPlayer().isHuman()) {
if (tournamentSessions.containsKey(tournamentPlayer.getPlayer().getId())) { if (tournamentSessions.containsKey(tournamentPlayer.getPlayer().getId())) {
if (tournamentSessions.get(tournamentPlayer.getPlayer().getId()).isKilled()) { if (tournamentSessions.get(tournamentPlayer.getPlayer().getId()).isKilled()) {
@ -458,16 +456,16 @@ public class TournamentController {
} }
/** /**
* Check tournaments that are not already finished, if they are in a still valid state * Check tournaments that are not already finished, if they are in a still
* valid state
* *
* @param tableState state of the tournament table * @param tableState state of the tournament table
* @return true - if tournament is valid * @return true - if tournament is valid false - if tournament is not valid
* false - if tournament is not valid and should be removed * and should be removed
*/ */
public boolean isTournamentStillValid(TableState tableState) { public boolean isTournamentStillValid(TableState tableState) {
int activePlayers = 0; int activePlayers = 0;
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
TournamentPlayer tournamentPlayer = tournament.getPlayer(entry.getValue()); TournamentPlayer tournamentPlayer = tournament.getPlayer(entry.getValue());
if (tournamentPlayer != null) { if (tournamentPlayer != null) {
if (!tournamentPlayer.hasQuit()) { if (!tournamentPlayer.hasQuit()) {
@ -487,7 +485,7 @@ public class TournamentController {
logger.debug("Tournament player is missing - tournamentId: " + tournament.getId() + " state: " + tableState.toString()); logger.debug("Tournament player is missing - tournamentId: " + tournament.getId() + " state: " + tableState.toString());
} }
} }
for(TournamentPlayer tournamentPlayer: tournament.getPlayers()) { for (TournamentPlayer tournamentPlayer : tournament.getPlayers()) {
if (!tournamentPlayer.getPlayer().isHuman()) { if (!tournamentPlayer.getPlayer().isHuman()) {
if (!tournamentPlayer.hasQuit()) { if (!tournamentPlayer.hasQuit()) {
activePlayers++; activePlayers++;

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.1</version> <version>1.4.2</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>

View file

@ -99,7 +99,7 @@ class ArsenalThresherEffect extends OneShotEffect {
Permanent arsenalThresher = game.getPermanent(source.getSourceId()); Permanent arsenalThresher = game.getPermanent(source.getSourceId());
FilterArtifactCard filter = new FilterArtifactCard(); FilterArtifactCard filter = new FilterArtifactCard();
filter.add(new AnotherCardPredicate()); filter.add(new AnotherCardPredicate());
if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", game)) { if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", source, game)) {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);

View file

@ -111,7 +111,7 @@ class EtherwroughtPageEffect extends OneShotEffect {
CardsImpl cards = new CardsImpl(); CardsImpl cards = new CardsImpl();
cards.add(card); cards.add(card);
controller.lookAtCards("Etherwrought Page", cards, game); controller.lookAtCards("Etherwrought Page", cards, game);
if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) { if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", source, game)) {
return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
return true; return true;

View file

@ -139,7 +139,7 @@ class SovereignsOfLostAlaraEffect extends OneShotEffect {
FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature"); FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature");
filter.add(new SubtypePredicate("Aura")); filter.add(new SubtypePredicate("Aura"));
filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId())); filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId()));
if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", game)) { if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(filter); TargetCardInLibrary target = new TargetCardInLibrary(filter);
target.setNotTarget(true); target.setNotTarget(true);
if (you.searchLibrary(target, game)) { if (you.searchLibrary(target, game)) {

View file

@ -104,7 +104,7 @@ class VectisDominatorEffect extends OneShotEffect {
if (player != null) { if (player != null) {
cost.clearPaid(); cost.clearPaid();
final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(targetCreature.getName()).append(" will be tapped)"); final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(targetCreature.getName()).append(" will be tapped)");
if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) {
cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true); cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true);
} }
if (!cost.isPaid()) { if (!cost.isPaid()) {

View file

@ -39,9 +39,9 @@ import mage.constants.Rarity;
* *
* @author Sir-Speshkitty * @author Sir-Speshkitty
*/ */
public class AesthirGlider extends CardImpl { public class AesthirGlider1 extends CardImpl {
public AesthirGlider(UUID ownerId) { public AesthirGlider1(UUID ownerId) {
super(ownerId, 156, "Aesthir Glider", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); super(ownerId, 156, "Aesthir Glider", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
this.expansionSetCode = "ALL"; this.expansionSetCode = "ALL";
this.subtype.add("Bird"); this.subtype.add("Bird");
@ -54,12 +54,12 @@ public class AesthirGlider extends CardImpl {
this.addAbility(new CantBlockAbility()); this.addAbility(new CantBlockAbility());
} }
public AesthirGlider(final AesthirGlider card) { public AesthirGlider1(final AesthirGlider1 card) {
super(card); super(card);
} }
@Override @Override
public AesthirGlider copy() { public AesthirGlider1 copy() {
return new AesthirGlider(this); return new AesthirGlider1(this);
} }
} }

View file

@ -0,0 +1,52 @@
/*
* 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.sets.alliances;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class AesthirGlider2 extends mage.sets.alliances.AesthirGlider1 {
public AesthirGlider2(UUID ownerId) {
super(ownerId);
this.cardNumber = 157;
this.expansionSetCode = "ALL";
}
public AesthirGlider2(final AesthirGlider2 card) {
super(card);
}
@Override
public AesthirGlider2 copy() {
return new AesthirGlider2(this);
}
}

View file

@ -53,9 +53,9 @@ import mage.target.common.TargetControlledPermanent;
* *
* @author Quercitron * @author Quercitron
*/ */
public class SoldeviSage extends CardImpl { public class SoldeviSage1 extends CardImpl {
public SoldeviSage(UUID ownerId) { public SoldeviSage1(UUID ownerId) {
super(ownerId, 51, "Soldevi Sage", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); super(ownerId, 51, "Soldevi Sage", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.expansionSetCode = "ALL"; this.expansionSetCode = "ALL";
this.subtype.add("Human"); this.subtype.add("Human");
@ -70,13 +70,13 @@ public class SoldeviSage extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
} }
public SoldeviSage(final SoldeviSage card) { public SoldeviSage1(final SoldeviSage1 card) {
super(card); super(card);
} }
@Override @Override
public SoldeviSage copy() { public SoldeviSage1 copy() {
return new SoldeviSage(this); return new SoldeviSage1(this);
} }
} }

View file

@ -0,0 +1,52 @@
/*
* 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.sets.alliances;
import java.util.UUID;
/**
*
* @author LoneFox
*/
public class SoldeviSage2 extends mage.sets.alliances.SoldeviSage1 {
public SoldeviSage2(UUID ownerId) {
super(ownerId);
this.cardNumber = 52;
this.expansionSetCode = "ALL";
}
public SoldeviSage2(final SoldeviSage2 card) {
super(card);
}
@Override
public SoldeviSage2 copy() {
return new SoldeviSage2(this);
}
}

View file

@ -106,7 +106,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, game)) { if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) {
return false; return false;
} }

View file

@ -29,27 +29,18 @@ package mage.sets.apocalypse;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; import mage.abilities.common.DealsDamageToACreatureTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.RegenerateSourceEffect; import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; import mage.abilities.effects.common.continuous.BecomesColorSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.choices.ChoiceColor;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -70,7 +61,7 @@ public class Spiritmonger extends CardImpl {
// {B}: Regenerate Spiritmonger. // {B}: Regenerate Spiritmonger.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}")));
// {G}: Spiritmonger becomes the color of your choice until end of turn. // {G}: Spiritmonger becomes the color of your choice until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SpiritmongerChangeColorEffect(), new ManaCostsImpl("{G}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{G}")));
} }
public Spiritmonger(final Spiritmonger card) { public Spiritmonger(final Spiritmonger card) {
@ -82,37 +73,3 @@ public class Spiritmonger extends CardImpl {
return new Spiritmonger(this); return new Spiritmonger(this);
} }
} }
class SpiritmongerChangeColorEffect extends OneShotEffect {
public SpiritmongerChangeColorEffect() {
super(Outcome.Neutral);
staticText = "{this} becomes the color of your choice until end of turn";
}
public SpiritmongerChangeColorEffect(final SpiritmongerChangeColorEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent wildMongrel = game.getPermanent(source.getSourceId());
if (player != null && wildMongrel != null) {
ChoiceColor colorChoice = new ChoiceColor();
if (player.choose(Outcome.Neutral, colorChoice, game)) {
game.informPlayers(wildMongrel.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice());
ContinuousEffect effect = new BecomesColorTargetEffect(colorChoice.getColor(), Duration.EndOfTurn, "is " + colorChoice.getChoice());
effect.setTargetPointer(new FixedTarget(source.getSourceId()));
game.addEffect(effect, source);
return true;
}
}
return false;
}
@Override
public SpiritmongerChangeColorEffect copy() {
return new SpiritmongerChangeColorEffect(this);
}
}

View file

@ -122,7 +122,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
return false; return false;
} }
while (player.isInGame() && player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", game)) { while (player.isInGame() && player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", source, game)) {
Target targetAura = new TargetPermanent(filterAura); Target targetAura = new TargetPermanent(filterAura);
if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) { if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) {
Permanent aura = game.getPermanent(targetAura.getFirstTarget()); Permanent aura = game.getPermanent(targetAura.getFirstTarget());
@ -137,7 +137,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
int count = player.getHand().count(filterAuraCard, game); int count = player.getHand().count(filterAuraCard, game);
while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", game)) { while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());
@ -151,7 +151,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
count = player.getGraveyard().count(filterAuraCard, game); count = player.getGraveyard().count(filterAuraCard, game);
while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", game)) { while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", source, game)) {
TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());

View file

@ -110,7 +110,7 @@ class DescendantsPathEffect extends OneShotEffect {
} }
if (found) { if (found) {
game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card."); game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card.");
if (controller.chooseUse(Outcome.Benefit, "Cast the card?", game)) { if (controller.chooseUse(Outcome.Benefit, "Cast the card?", source, game)) {
controller.cast(card.getSpellAbility(), game, true); controller.cast(card.getSpellAbility(), game, true);
} else { } else {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card."); game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");

View file

@ -105,7 +105,7 @@ class FettergeistUnlessPaysEffect extends OneShotEffect {
if (count == 0) { if (count == 0) {
return true; return true;
} }
if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", game)) { if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", source, game)) {
GenericManaCost cost = new GenericManaCost(count); GenericManaCost cost = new GenericManaCost(count);
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {
return true; return true;

View file

@ -29,17 +29,17 @@ package mage.sets.avacynrestored;
import mage.constants.*; import mage.constants.*;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AttacksEachTurnStaticAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect;
/** /**
* @author noxx * @author noxx
@ -51,7 +51,6 @@ public class GuiseOfFire extends CardImpl {
this.expansionSetCode = "AVR"; this.expansionSetCode = "AVR";
this.subtype.add("Aura"); this.subtype.add("Aura");
// Enchant creature // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent(); TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
@ -60,8 +59,12 @@ public class GuiseOfFire extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Enchanted creature gets +1/-1 and attacks each turn if able. // Enchanted creature gets +1/-1 and attacks each turn if able.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, -1, Duration.WhileOnBattlefield))); ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, -1, Duration.WhileOnBattlefield));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new AttacksEachTurnStaticAbility(), AttachmentType.AURA))); Effect effect = new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA);
effect.setText("and attacks each turn if able");
ability.addEffect(effect);
this.addAbility(ability);
} }
public GuiseOfFire(final GuiseOfFire card) { public GuiseOfFire(final GuiseOfFire card) {

View file

@ -106,7 +106,7 @@ class KillingWaveEffect extends OneShotEffect {
int playerLife = player.getLife(); int playerLife = player.getLife();
for (Permanent creature : creatures) { for (Permanent creature : creatures) {
String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed."; String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed.";
if (playerLife - amount - lifePaid >= 0 && player != null && player.chooseUse(Outcome.Neutral, message, game)) { if (playerLife - amount - lifePaid >= 0 && player != null && player.chooseUse(Outcome.Neutral, message, source, game)) {
game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName()); game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName());
lifePaid += amount; lifePaid += amount;
} else { } else {

View file

@ -100,7 +100,7 @@ class PrimalSurgeEffect extends OneShotEffect {
if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE) if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE)
|| cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND) || cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND)
|| cardType.contains(CardType.PLANESWALKER)) || cardType.contains(CardType.PLANESWALKER))
&& player.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield?", game)) { && player.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield?", source, game)) {
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());

View file

@ -32,7 +32,7 @@ import mage.constants.Rarity;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.filter.common.FilterEnchantment; import mage.filter.common.FilterEnchantmentPermanent;
import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterLandPermanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetArtifactPermanent;
@ -59,7 +59,7 @@ public class RainOfThorns extends CardImpl {
Mode mode1 = new Mode(); Mode mode1 = new Mode();
mode1.getEffects().add(new DestroyTargetEffect()); mode1.getEffects().add(new DestroyTargetEffect());
mode1.getTargets().add(new TargetPermanent(new FilterEnchantment())); mode1.getTargets().add(new TargetPermanent(new FilterEnchantmentPermanent()));
this.getSpellAbility().addMode(mode1); this.getSpellAbility().addMode(mode1);
Mode mode2 = new Mode(); Mode mode2 = new Mode();

View file

@ -89,7 +89,7 @@ class VexingDevilEffect extends OneShotEffect {
if (controller != null && permanent != null) { if (controller != null && permanent != null) {
for (UUID opponentUuid : game.getOpponents(source.getControllerId())) { for (UUID opponentUuid : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentUuid); Player opponent = game.getPlayer(opponentUuid);
if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getLogName() + " deal 4 damage to you?", game)) { if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getLogName() + " deal 4 damage to you?", source, game)) {
game.informPlayers(opponent.getLogName() + " has chosen to receive 4 damage from " + permanent.getLogName()); game.informPlayers(opponent.getLogName() + " has chosen to receive 4 damage from " + permanent.getLogName());
opponent.damage(4, permanent.getId(), game, false, true); opponent.damage(4, permanent.getId(), game, false, true);
permanent.sacrifice(source.getSourceId(), game); permanent.sacrifice(source.getSourceId(), game);

View file

@ -113,7 +113,7 @@ class IwamoriOfTheOpenFistEffect extends OneShotEffect {
Player opponent = game.getPlayer(playerId); Player opponent = game.getPlayer(playerId);
Target target = new TargetCardInHand(filter); Target target = new TargetCardInHand(filter);
if (opponent != null && target.canChoose(source.getSourceId(), opponent.getId(), game)) { if (opponent != null && target.canChoose(source.getSourceId(), opponent.getId(), game)) {
if (opponent.chooseUse(Outcome.PutCreatureInPlay, "Put a legendary creature card from your hand onto the battlefield?", game)) { if (opponent.chooseUse(Outcome.PutCreatureInPlay, "Put a legendary creature card from your hand onto the battlefield?", source, game)) {
if (target.chooseTarget(Outcome.PutCreatureInPlay, opponent.getId(), source, game)) { if (target.chooseTarget(Outcome.PutCreatureInPlay, opponent.getId(), source, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -99,7 +99,7 @@ class OgreMarauderEffect extends OneShotEffect {
if (defender != null && sourceObject != null) { if (defender != null && sourceObject != null) {
Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent());
if (cost.canPay(source, source.getSourceId(), defendingPlayerId, game) && if (cost.canPay(source, source.getSourceId(), defendingPlayerId, game) &&
defender.chooseUse(Outcome.LoseAbility, "Sacrifice a creature to prevent that " + sourceObject.getLogName() + " can't be blocked?", game)) { defender.chooseUse(Outcome.LoseAbility, "Sacrifice a creature to prevent that " + sourceObject.getLogName() + " can't be blocked?", source, game)) {
if (!cost.pay(source, game, source.getSourceId(), defendingPlayerId, false)) { if (!cost.pay(source, game, source.getSourceId(), defendingPlayerId, false)) {
// cost was not payed - so source can't be blocked // cost was not payed - so source can't be blocked
ContinuousEffect effect = new CantBeBlockedSourceEffect(Duration.EndOfTurn); ContinuousEffect effect = new CantBeBlockedSourceEffect(Duration.EndOfTurn);

View file

@ -90,9 +90,9 @@ public class ToilsOfNightAndDay extends CardImpl {
for (UUID targetId : source.getTargets().get(0).getTargets()) { for (UUID targetId : source.getTargets().get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null) { if (permanent != null) {
if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), game)) { if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), source, game)) {
permanent.tap(game); permanent.tap(game);
} else if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), game)) { } else if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), source, game)) {
permanent.untap(game); permanent.untap(game);
} }
} }

View file

@ -122,7 +122,7 @@ class ArbiterOfTheIdealEffect extends OneShotEffect {
player.revealCards("Arbiter of the Ideal", cards, game); player.revealCards("Arbiter of the Ideal", cards, game);
if (card != null) { if (card != null) {
if (filter.match(card, game) && player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("onto battlefield?").toString(), game)) { if (filter.match(card, game) && player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("onto battlefield?").toString(), source, game)) {
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) { if (permanent != null) {

View file

@ -32,7 +32,9 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.ReturnToHandTargetPermanentCost; import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.combat.CantAttackBlockUnlessPaysSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
@ -53,6 +55,12 @@ import mage.target.common.TargetControlledPermanent;
*/ */
public class FloodtideSerpent extends CardImpl { public class FloodtideSerpent extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("an enchantment you control");
static {
filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
}
public FloodtideSerpent(UUID ownerId) { public FloodtideSerpent(UUID ownerId) {
super(ownerId, 41, "Floodtide Serpent", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{U}"); super(ownerId, 41, "Floodtide Serpent", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{U}");
this.expansionSetCode = "BNG"; this.expansionSetCode = "BNG";
@ -62,8 +70,8 @@ public class FloodtideSerpent extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Floodtide Serpent can't attack unless you return an enchantment you control to its owner's hand <i>(This cost is paid as attackers are declared.)</i> // Floodtide Serpent can't attack unless you return an enchantment you control to its owner's hand <i>(This cost is paid as attackers are declared.)</i>
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new FloodtideSerpentReplacementEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockUnlessPaysSourceEffect(
new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)), PayCostToAttackBlockEffectImpl.RestrictType.ATTACK)));
} }
@ -85,24 +93,23 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl {
filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
} }
FloodtideSerpentReplacementEffect ( ) { FloodtideSerpentReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral); super(Duration.WhileOnBattlefield, Outcome.Neutral);
staticText = "{this} can't attack unless you return an enchantment you control to its owner's hand <i>(This cost is paid as attackers are declared.)</i>"; staticText = "{this} can't attack unless you return an enchantment you control to its owner's hand <i>(This cost is paid as attackers are declared.)</i>";
} }
FloodtideSerpentReplacementEffect ( FloodtideSerpentReplacementEffect effect ) { FloodtideSerpentReplacementEffect(FloodtideSerpentReplacementEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(event.getPlayerId()); Player player = game.getPlayer(event.getPlayerId());
if ( player != null ) { if (player != null) {
ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)); ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter));
if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && if (attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game)
player.chooseUse(Outcome.Neutral, "Return an enchantment you control to hand to attack?", game) ) && player.chooseUse(Outcome.Neutral, "Return an enchantment you control to hand to attack?", source, game)) {
{ if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), true)) {
if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), true) ) {
return false; return false;
} }
} }
@ -116,7 +123,6 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl {
return event.getType() == EventType.DECLARE_ATTACKER; return event.getType() == EventType.DECLARE_ATTACKER;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
return event.getSourceId().equals(source.getSourceId()); return event.getSourceId().equals(source.getSourceId());

View file

@ -95,7 +95,7 @@ class HeroOfLeinaTowerEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
ManaCosts cost = new ManaCostsImpl("{X}"); ManaCosts cost = new ManaCostsImpl("{X}");
if (you != null && you.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", game)) { if (you != null && you.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", source, game)) {
int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
cost.add(new GenericManaCost(costX)); cost.add(new GenericManaCost(costX));
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {

View file

@ -171,7 +171,7 @@ class HeroesPodiumEffect extends OneShotEffect {
player.lookAtCards("Heroes' Podium", cards, game); player.lookAtCards("Heroes' Podium", cards, game);
// You may reveal a legendary creature card from among them and put it into your hand. // You may reveal a legendary creature card from among them and put it into your hand.
if (!cards.isEmpty() && legendaryIncluded && player.chooseUse(outcome, "Put a legendary creature card into your hand?", game)) { if (!cards.isEmpty() && legendaryIncluded && player.chooseUse(outcome, "Put a legendary creature card into your hand?", source, game)) {
if (cards.size() == 1) { if (cards.size() == 1) {
Card card = cards.getRandom(game); Card card = cards.getRandom(game);
cards.remove(card); cards.remove(card);

View file

@ -127,7 +127,7 @@ class DoUnlessTargetPaysCost extends OneShotEffect {
} }
message = CardUtil.replaceSourceName(message, mageObject.getLogName()); message = CardUtil.replaceSourceName(message, mageObject.getLogName());
cost.clearPaid(); cost.clearPaid();
if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffect.getOutcome(), message, game)) { if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffect.getOutcome(), message, source, game)) {
cost.pay(source, game, source.getSourceId(), player.getId(), false); cost.pay(source, game, source.getSourceId(), player.getId(), false);
} }
if (!cost.isPaid()) { if (!cost.isPaid()) {

View file

@ -108,7 +108,7 @@ class OracleOfBonesCastEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Target target = new TargetCardInHand(filter); Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && if (target.canChoose(source.getSourceId(), controller.getId(), game) &&
controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", game)) { controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null; Card cardToCast = null;
boolean cancel = false; boolean cancel = false;
while (controller.isInGame() && !cancel) { while (controller.isInGame() && !cancel) {

View file

@ -104,7 +104,7 @@ class SatyrWayfinderEffect extends OneShotEffect {
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand);
if (properCardFound && if (properCardFound &&
controller.chooseUse(outcome, "Put a land card into your hand?", game) && controller.chooseUse(outcome, "Put a land card into your hand?", source, game) &&
controller.choose(Outcome.DrawCard, cards, target, game)) { controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

Some files were not shown because too many files have changed in this diff Show more