Merge pull request #83 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
L_J 2018-12-23 13:34:57 +01:00 committed by GitHub
commit a2a8df8059
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
351 changed files with 15655 additions and 7702 deletions

View file

@ -1,3 +0,0 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
SplashScreen-Image: splash.jpg

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.31</version> <version>1.4.32</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
@ -194,11 +194,13 @@
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<configuration> <configuration>
<archive> <archive>
<manifestFile>${manifest.file}</manifestFile>
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
<mainClass>mage.client.MageFrame</mainClass> <mainClass>mage.client.MageFrame</mainClass>
</manifest> </manifest>
<manifestEntries>
<SplashScreen-Image>splash.jpg</SplashScreen-Image>
</manifestEntries>
</archive> </archive>
</configuration> </configuration>
</plugin> </plugin>

View file

@ -1,21 +1,5 @@
package mage.client; package mage.client;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
@ -63,10 +47,26 @@ import net.java.truevfs.access.TConfig;
import net.java.truevfs.kernel.spec.FsAccessOption; import net.java.truevfs.kernel.spec.FsAccessOption;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.ManaSymbols;
import org.mage.plugins.card.images.DownloadPictures; import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.info.CardInfoPaneImpl; import org.mage.plugins.card.info.CardInfoPaneImpl;
import org.mage.plugins.card.utils.impl.ImageManagerImpl; import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -93,7 +93,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class); private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class);
private JLabel title; private JLabel title;
private Rectangle titleRectangle; private Rectangle titleRectangle;
private static final MageVersion VERSION = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); private static final MageVersion VERSION = new MageVersion(MageFrame.class);
private Connection currentConnection; private Connection currentConnection;
private static MagePane activeFrame; private static MagePane activeFrame;
private static boolean liteMode = false; private static boolean liteMode = false;
@ -760,7 +760,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
prepareAndShowTablesPane(); prepareAndShowTablesPane();
return true; return true;
} else { } else {
showMessage("Unable to connect to server"); showMessage("Unable connect to server");
} }
} finally { } finally {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
@ -1010,7 +1010,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}//GEN-LAST:event_btnImagesActionPerformed }//GEN-LAST:event_btnImagesActionPerformed
public void downloadImages() { public void downloadImages() {
DownloadPictures.startDownload(); DownloadPicturesService.startDownload();
} }
public void exitApp() { public void exitApp() {
@ -1380,7 +1380,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
Plugins.instance.downloadSymbols(); Plugins.instance.downloadSymbols();
break; break;
case CLIENT_DOWNLOAD_CARD_IMAGES: case CLIENT_DOWNLOAD_CARD_IMAGES:
DownloadPictures.startDownload(); DownloadPicturesService.startDownload();
break; break;
case CLIENT_DISCONNECT: case CLIENT_DISCONNECT:
if (SessionHandler.isConnected()) { if (SessionHandler.isConnected()) {

View file

@ -1,9 +1,8 @@
package mage.client.components.ability; package mage.client.components.ability;
import mage.client.SessionHandler; import mage.client.SessionHandler;
import mage.client.dialog.MageDialog;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil;
import mage.remote.Session; import mage.remote.Session;
import mage.view.AbilityPickerView; import mage.view.AbilityPickerView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -17,8 +16,8 @@ import org.mage.card.arcane.UI;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.util.*;
import java.util.List; import java.util.List;
import java.util.*;
/** /**
* Dialog for choosing abilities. * Dialog for choosing abilities.
@ -112,10 +111,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
this.selected = false; // back to false - waiting for selection this.selected = false; // back to false - waiting for selection
setVisible(true); setVisible(true);
Point centered = SettingsManager.instance.getComponentPosition(DIALOG_WIDTH, DIALOG_HEIGHT); MageDialog.makeWindowCentered(this, DIALOG_WIDTH, DIALOG_HEIGHT);
this.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
//startModal(); //startModal();
} }

View file

@ -41,7 +41,7 @@ import mage.view.PlaneView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.ManaSymbols;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import static org.mage.plugins.card.images.DownloadPictures.getTokenCardUrls; import static org.mage.plugins.card.images.DownloadPicturesService.getTokenCardUrls;
/** /**
* Mage book with cards and page flipping. * Mage book with cards and page flipping.

View file

@ -34,6 +34,8 @@ import javax.swing.DefaultComboBoxModel;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import mage.cards.repository.CardRepository;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.client.MageFrame; import mage.client.MageFrame;
@ -454,7 +456,8 @@ public class ConnectDialog extends MageDialog {
connection.setPort(Integer.valueOf(this.txtPort.getText().trim())); connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim()); connection.setUsername(this.txtUserName.getText().trim());
connection.setPassword(this.txtPassword.getText().trim()); connection.setPassword(this.txtPassword.getText().trim());
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected()); boolean redownloadDatabase = CardRepository.instance.findCard("Island") == null;
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected() || redownloadDatabase);
String allMAC = ""; String allMAC = "";
try { try {
allMAC = connection.getMAC(); allMAC = connection.getMAC();

View file

@ -0,0 +1,560 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.8" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="title" type="java.lang.String" value="Downloading images"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 400]"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</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"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,73,0,0,2,65"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="panelGlobal">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="North"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/>
</Layout>
<SubComponents>
<Component class="javax.swing.Box$Filler" name="fillerGlobal1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 5]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelGlobal">
<Properties>
<Property name="text" type="java.lang.String" value="Initializing image download..."/>
<Property name="alignmentX" type="float" value="0.5"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="buttonStop">
<Properties>
<Property name="text" type="java.lang.String" value="Cancel"/>
<Property name="alignmentX" type="float" value="0.5"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[65, 30]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonStopActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.Box$Filler" name="fillerglobal2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 5]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JTabbedPane" name="tabsList">
<Properties>
<Property name="tabLayoutPolicy" type="int" value="1"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="tabMain">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Standard download">
<Property name="tabTitle" type="java.lang.String" value="Standard download"/>
<Property name="tabIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/buttons/card_panel.png"/>
</Property>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="panelInfo">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/>
</Layout>
<SubComponents>
<Component class="javax.swing.Box$Filler" name="fillerInfo1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 5]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelInfo">
<Properties>
<Property name="text" type="java.lang.String" value="Missing stats: 12345 card images / 789 token images"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
<EmptyBorder bottom="0" left="7" right="0" top="0"/>
</Border>
</Property>
</Properties>
</Component>
<Component class="javax.swing.Box$Filler" name="fillerInfo2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 5]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelSource">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[65536, 55]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[352, 55]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[593, 55]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="0"/>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="panelSourceLeft">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[430, 30]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout">
<Property name="alignment" type="int" value="3"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelSource">
<Properties>
<Property name="text" type="java.lang.String" value="Images source to download:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboSource">
<Properties>
<Property name="maximumRowCount" type="int" value="15"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 20]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[400, 25]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelSourceRight">
<Properties>
<Property name="alignmentX" type="float" value="0.0"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 30]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 100]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout">
<Property name="alignment" type="int" value="3"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelLanguage">
<Properties>
<Property name="text" type="java.lang.String" value="Language:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboLanguage">
<Properties>
<Property name="maximumRowCount" type="int" value="15"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[90, 25]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelMode">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32869, 55]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[322, 55]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 55]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="panelModeInner">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[430, 43]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout">
<Property name="alignment" type="int" value="0"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelMode">
<Properties>
<Property name="text" type="java.lang.String" value="Sets to download:"/>
<Property name="alignmentY" type="float" value="0.0"/>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="panelModeSelect">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="0"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JComboBox" name="comboSets">
<Properties>
<Property name="maximumRowCount" type="int" value="15"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[373, 25]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.Box$Filler" name="fillerMode1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="buttonSearchSet">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/buttons/search_24.png"/>
</Property>
<Property name="toolTipText" type="java.lang.String" value="Fast search your flag"/>
<Property name="alignmentX" type="float" value="1.0"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[25, 25]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonSearchSetActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelRedownload">
<Properties>
<Property name="alignmentX" type="float" value="0.0"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 30]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[130, 100]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="checkboxRedownload">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;html&gt;Re-download selected images"/>
<Property name="verticalAlignment" type="int" value="3"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.Box$Filler" name="filler1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 5]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 5]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 3]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Last"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.Box$Filler" name="fillerMain1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 10]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 10]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 10]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalStrut"/>
</AuxValues>
</Component>
<Container class="javax.swing.JPanel" name="panelProgress">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32777, 30]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[20, 30]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[564, 30]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="0"/>
</Layout>
<SubComponents>
<Component class="javax.swing.Box$Filler" name="fillerProgress1">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/>
</AuxValues>
</Component>
<Component class="javax.swing.JProgressBar" name="progress">
<Properties>
<Property name="value" type="int" value="75"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 25]"/>
</Property>
<Property name="string" type="java.lang.String" value="123 of 12313 (120 cards/546 tokens) image downloads finished! Please wait! [123 Mb]"/>
<Property name="stringPainted" type="boolean" value="true"/>
</Properties>
</Component>
<Component class="javax.swing.Box$Filler" name="fillerProgress2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 32767]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[5, 0]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalStrut"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.Box$Filler" name="fillerMain2">
<Properties>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.Glue"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="tabCustom">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Custom download">
<Property name="tabTitle" type="java.lang.String" value="Custom download"/>
<Property name="tabIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/buttons/list_panel.png"/>
</Property>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
<Property name="axis" type="int" value="1"/>
</Layout>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="panelCommands">
<Properties>
<Property name="alignmentX" type="float" value="0.0"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="South"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout">
<Property name="alignment" type="int" value="4"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="buttonOK">
<Properties>
<Property name="text" type="java.lang.String" value="Start download"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[120, 30]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_AddingCodePost" type="java.lang.String" value="getRootPane().setDefaultButton(buttonOK);"/>
<AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="DownloadImagesDialog_buttonOK"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="buttonCancel">
<Properties>
<Property name="text" type="java.lang.String" value="Cancel"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[80, 30]"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View file

@ -0,0 +1,470 @@
package mage.client.dialog;
import mage.client.MageFrame;
import mage.client.util.gui.FastSearchUtil;
import mage.client.util.gui.MageDialogState;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
/**
* @author JayDi85
*/
public class DownloadImagesDialog extends MageDialog {
public static final int RET_CANCEL = 0;
public static final int RET_OK = 1;
private Dimension sizeModeMessageOnly;
private Dimension sizeModeMessageAndControls;
private Map<Component, Boolean> actionsControlStates = new HashMap<>();
/**
* Creates new form DownloadImagesDialog
*/
public DownloadImagesDialog() {
initComponents();
this.setModal(true);
// fix for panelInfo (it's resets aligmentX after netbeans designer opened)
panelInfo.setAlignmentX(CENTER_ALIGNMENT);
// save default sizes
//
this.sizeModeMessageAndControls = new Dimension(580, 330); // dialog -> properties -> designer size
//
this.sizeModeMessageOnly = new Dimension(this.sizeModeMessageAndControls.getSize());
sizeModeMessageOnly.height = 25 * 4;
sizeModeMessageOnly.width = sizeModeMessageOnly.width / 2;
// Close the dialog when Esc is pressed
String cancelName = "cancel";
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), cancelName);
ActionMap actionMap = getRootPane().getActionMap();
actionMap.put(cancelName, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
doClose(RET_CANCEL);
}
});
}
public void setWindowSize(int width, int heigth) {
this.setSize(new Dimension(width, heigth));
}
public void showDialog() {
showDialog(null);
}
public void showDialog(MageDialogState mageDialogState) {
showDownloadControls(false); // call to change window size
// window settings
if (this.isModal()) {
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
} else {
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
}
if (mageDialogState != null) {
mageDialogState.setStateToDialog(this);
} else {
this.makeWindowCentered();
}
this.setVisible(true);
}
public void setGlobalInfo(String info) {
this.labelGlobal.setText(info);
}
public void setCurrentInfo(String info) {
this.labelInfo.setText(info);
}
public JComboBox getSourcesCombo() {
return this.comboSource;
}
public JComboBox getLaunguagesCombo() {
return this.comboLanguage;
}
public JComboBox getSetsCombo() {
return this.comboSets;
}
public JButton getStartButton() {
return this.buttonOK;
}
public JButton getCancelButton() {
return this.buttonCancel;
}
public JButton getStopButton() {
return this.buttonStop;
}
public JProgressBar getProgressBar() {
return this.progress;
}
public JCheckBox getRedownloadCheckbox() {
return this.checkboxRedownload;
}
public void showLanguagesSupport(boolean haveSupport) {
labelLanguage.setEnabled(haveSupport);
comboLanguage.setEnabled(haveSupport);
}
private void enableActionControl(boolean enable, Component comp) {
if (enable) {
// restore last enable state
comp.setEnabled(actionsControlStates.getOrDefault(comp, true));
} else {
// save enable state and disable it
actionsControlStates.putIfAbsent(comp, comp.isEnabled());
comp.setEnabled(false);
}
}
public void enableActionControls(boolean enable) {
// restrict user actions while downloading/processing (all buttons, comboboxes and edits)
enableActionControl(enable, tabsList);
enableActionControl(enable, comboSource);
enableActionControl(enable, comboSets);
enableActionControl(enable, buttonSearchSet);
enableActionControl(enable, comboLanguage);
enableActionControl(enable, checkboxRedownload);
}
private void setTabTitle(int tabIndex, String title, String iconResourceName) {
// tab caption with left sided icon
// https://stackoverflow.com/questions/1782224/jtabbedpane-icon-on-left-side-of-tabs
JLabel lbl = new JLabel(title);
Icon icon = new ImageIcon(getClass().getResource(iconResourceName));
lbl.setIcon(icon);
lbl.setIconTextGap(5);
lbl.setHorizontalTextPosition(SwingConstants.RIGHT);
tabsList.setTabComponentAt(tabIndex, lbl);
}
public void showDownloadControls(boolean needToShow) {
// 2 modes:
// - only message;
// - message + download controls and buttons
this.panelGlobal.setVisible(true);
this.buttonStop.setVisible(!needToShow); // stop button only for loading mode
this.tabsList.setVisible(needToShow);
this.panelCommands.setVisible(needToShow);
// auto-size form
if (needToShow) {
this.setWindowSize(this.sizeModeMessageAndControls.width, this.sizeModeMessageAndControls.height);
} else {
this.setWindowSize(this.sizeModeMessageOnly.width, this.sizeModeMessageOnly.height);
}
this.makeWindowCentered();
//this.setLocationRelativeTo(null); // center screen //FIX
// icons on tabs left side
setTabTitle(0, "Standard download", "/buttons/card_panel.png");
setTabTitle(1, "Custom download", "/buttons/list_panel.png");
// TODO: add manual mode as tab
this.tabsList.getTabComponentAt(1).setEnabled(false);
this.tabsList.setEnabledAt(1, false);
}
/**
* @return the return status of this dialog - one of RET_OK or RET_CANCEL
*/
public int getReturnStatus() {
return returnStatus;
}
/**
* 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() {
panelGlobal = new javax.swing.JPanel();
fillerGlobal1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5));
labelGlobal = new javax.swing.JLabel();
buttonStop = new javax.swing.JButton();
fillerglobal2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5));
tabsList = new javax.swing.JTabbedPane();
tabMain = new javax.swing.JPanel();
panelInfo = new javax.swing.JPanel();
fillerInfo1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5));
labelInfo = new javax.swing.JLabel();
fillerInfo2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 5), new java.awt.Dimension(32767, 5));
panelSource = new javax.swing.JPanel();
panelSourceLeft = new javax.swing.JPanel();
labelSource = new javax.swing.JLabel();
comboSource = new javax.swing.JComboBox<>();
panelSourceRight = new javax.swing.JPanel();
labelLanguage = new javax.swing.JLabel();
comboLanguage = new javax.swing.JComboBox<>();
panelMode = new javax.swing.JPanel();
panelModeInner = new javax.swing.JPanel();
labelMode = new javax.swing.JLabel();
panelModeSelect = new javax.swing.JPanel();
comboSets = new javax.swing.JComboBox<>();
fillerMode1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
buttonSearchSet = new javax.swing.JButton();
panelRedownload = new javax.swing.JPanel();
checkboxRedownload = new javax.swing.JCheckBox();
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 5), new java.awt.Dimension(0, 3), new java.awt.Dimension(32767, 5));
fillerMain1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 10));
panelProgress = new javax.swing.JPanel();
fillerProgress1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
progress = new javax.swing.JProgressBar();
fillerProgress2 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 0), new java.awt.Dimension(5, 32767));
fillerMain2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767));
tabCustom = new javax.swing.JPanel();
panelCommands = new javax.swing.JPanel();
buttonOK = new javax.swing.JButton();
buttonCancel = new javax.swing.JButton();
setTitle("Downloading images");
setPreferredSize(new java.awt.Dimension(600, 400));
getContentPane().setLayout(new java.awt.BorderLayout());
panelGlobal.setLayout(new javax.swing.BoxLayout(panelGlobal, javax.swing.BoxLayout.Y_AXIS));
panelGlobal.add(fillerGlobal1);
labelGlobal.setText("Initializing image download...");
labelGlobal.setAlignmentX(0.5F);
panelGlobal.add(labelGlobal);
buttonStop.setText("Cancel");
buttonStop.setAlignmentX(0.5F);
buttonStop.setPreferredSize(new java.awt.Dimension(65, 30));
buttonStop.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonStopActionPerformed(evt);
}
});
panelGlobal.add(buttonStop);
panelGlobal.add(fillerglobal2);
getContentPane().add(panelGlobal, java.awt.BorderLayout.NORTH);
tabsList.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
tabMain.setLayout(new javax.swing.BoxLayout(tabMain, javax.swing.BoxLayout.Y_AXIS));
panelInfo.setLayout(new javax.swing.BoxLayout(panelInfo, javax.swing.BoxLayout.Y_AXIS));
panelInfo.add(fillerInfo1);
labelInfo.setText("Missing stats: 12345 card images / 789 token images");
labelInfo.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 7, 0, 0));
panelInfo.add(labelInfo);
panelInfo.add(fillerInfo2);
tabMain.add(panelInfo);
panelSource.setMaximumSize(new java.awt.Dimension(65536, 55));
panelSource.setMinimumSize(new java.awt.Dimension(352, 55));
panelSource.setPreferredSize(new java.awt.Dimension(593, 55));
panelSource.setLayout(new javax.swing.BoxLayout(panelSource, javax.swing.BoxLayout.X_AXIS));
panelSourceLeft.setMinimumSize(new java.awt.Dimension(430, 30));
panelSourceLeft.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING));
labelSource.setText("Images source to download:");
panelSourceLeft.add(labelSource);
comboSource.setMaximumRowCount(15);
comboSource.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
comboSource.setMinimumSize(new java.awt.Dimension(300, 20));
comboSource.setPreferredSize(new java.awt.Dimension(400, 25));
panelSourceLeft.add(comboSource);
panelSource.add(panelSourceLeft);
panelSourceRight.setAlignmentX(0.0F);
panelSourceRight.setMaximumSize(new java.awt.Dimension(130, 32767));
panelSourceRight.setMinimumSize(new java.awt.Dimension(130, 30));
panelSourceRight.setPreferredSize(new java.awt.Dimension(130, 100));
panelSourceRight.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING));
labelLanguage.setText("Language:");
panelSourceRight.add(labelLanguage);
comboLanguage.setMaximumRowCount(15);
comboLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
comboLanguage.setPreferredSize(new java.awt.Dimension(90, 25));
panelSourceRight.add(comboLanguage);
panelSource.add(panelSourceRight);
tabMain.add(panelSource);
panelMode.setMaximumSize(new java.awt.Dimension(32869, 55));
panelMode.setMinimumSize(new java.awt.Dimension(322, 55));
panelMode.setPreferredSize(new java.awt.Dimension(100, 55));
panelMode.setLayout(new javax.swing.BoxLayout(panelMode, javax.swing.BoxLayout.LINE_AXIS));
panelModeInner.setMinimumSize(new java.awt.Dimension(430, 43));
panelModeInner.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
labelMode.setText("Sets to download:");
labelMode.setAlignmentY(0.0F);
panelModeInner.add(labelMode);
panelModeSelect.setLayout(new javax.swing.BoxLayout(panelModeSelect, javax.swing.BoxLayout.X_AXIS));
comboSets.setMaximumRowCount(15);
comboSets.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
comboSets.setPreferredSize(new java.awt.Dimension(373, 25));
panelModeSelect.add(comboSets);
panelModeSelect.add(fillerMode1);
buttonSearchSet.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/search_24.png"))); // NOI18N
buttonSearchSet.setToolTipText("Fast search your flag");
buttonSearchSet.setAlignmentX(1.0F);
buttonSearchSet.setPreferredSize(new java.awt.Dimension(25, 25));
buttonSearchSet.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonSearchSetActionPerformed(evt);
}
});
panelModeSelect.add(buttonSearchSet);
panelModeInner.add(panelModeSelect);
panelMode.add(panelModeInner);
panelRedownload.setAlignmentX(0.0F);
panelRedownload.setMaximumSize(new java.awt.Dimension(130, 32767));
panelRedownload.setMinimumSize(new java.awt.Dimension(130, 30));
panelRedownload.setPreferredSize(new java.awt.Dimension(130, 100));
panelRedownload.setLayout(new java.awt.BorderLayout());
checkboxRedownload.setText("<html>Re-download selected images");
checkboxRedownload.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
panelRedownload.add(checkboxRedownload, java.awt.BorderLayout.CENTER);
panelRedownload.add(filler1, java.awt.BorderLayout.PAGE_END);
panelMode.add(panelRedownload);
tabMain.add(panelMode);
tabMain.add(fillerMain1);
panelProgress.setMaximumSize(new java.awt.Dimension(32777, 30));
panelProgress.setMinimumSize(new java.awt.Dimension(20, 30));
panelProgress.setPreferredSize(new java.awt.Dimension(564, 30));
panelProgress.setLayout(new javax.swing.BoxLayout(panelProgress, javax.swing.BoxLayout.X_AXIS));
panelProgress.add(fillerProgress1);
progress.setValue(75);
progress.setMaximumSize(new java.awt.Dimension(32767, 25));
progress.setString("123 of 12313 (120 cards/546 tokens) image downloads finished! Please wait! [123 Mb]");
progress.setStringPainted(true);
panelProgress.add(progress);
panelProgress.add(fillerProgress2);
tabMain.add(panelProgress);
tabMain.add(fillerMain2);
tabsList.addTab("Standard download", new javax.swing.ImageIcon(getClass().getResource("/buttons/card_panel.png")), tabMain); // NOI18N
tabCustom.setLayout(new javax.swing.BoxLayout(tabCustom, javax.swing.BoxLayout.Y_AXIS));
tabsList.addTab("Custom download", new javax.swing.ImageIcon(getClass().getResource("/buttons/list_panel.png")), tabCustom); // NOI18N
getContentPane().add(tabsList, java.awt.BorderLayout.CENTER);
panelCommands.setAlignmentX(0.0F);
panelCommands.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.TRAILING));
buttonOK.setText("Start download");
buttonOK.setPreferredSize(new java.awt.Dimension(120, 30));
panelCommands.add(buttonOK);
getRootPane().setDefaultButton(buttonOK);
buttonCancel.setText("Cancel");
buttonCancel.setPreferredSize(new java.awt.Dimension(80, 30));
panelCommands.add(buttonCancel);
getContentPane().add(panelCommands, java.awt.BorderLayout.SOUTH);
pack();
}// </editor-fold>//GEN-END:initComponents
/**
* Closes the dialog
*/
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
doClose(RET_CANCEL);
}//GEN-LAST:event_closeDialog
private void buttonSearchSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSearchSetActionPerformed
FastSearchUtil.showFastSearchForStringComboBox(comboSets, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE, 400, 500);
}//GEN-LAST:event_buttonSearchSetActionPerformed
private void buttonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStopActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_buttonStopActionPerformed
private void doClose(int retStatus) {
returnStatus = retStatus;
setVisible(false);
dispose();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonCancel;
private javax.swing.JButton buttonOK;
private javax.swing.JButton buttonSearchSet;
private javax.swing.JButton buttonStop;
private javax.swing.JCheckBox checkboxRedownload;
private javax.swing.JComboBox<String> comboLanguage;
private javax.swing.JComboBox<String> comboSets;
private javax.swing.JComboBox<String> comboSource;
private javax.swing.Box.Filler filler1;
private javax.swing.Box.Filler fillerGlobal1;
private javax.swing.Box.Filler fillerInfo1;
private javax.swing.Box.Filler fillerInfo2;
private javax.swing.Box.Filler fillerMain1;
private javax.swing.Box.Filler fillerMain2;
private javax.swing.Box.Filler fillerMode1;
private javax.swing.Box.Filler fillerProgress1;
private javax.swing.Box.Filler fillerProgress2;
private javax.swing.Box.Filler fillerglobal2;
private javax.swing.JLabel labelGlobal;
private javax.swing.JLabel labelInfo;
private javax.swing.JLabel labelLanguage;
private javax.swing.JLabel labelMode;
private javax.swing.JLabel labelSource;
private javax.swing.JPanel panelCommands;
private javax.swing.JPanel panelGlobal;
private javax.swing.JPanel panelInfo;
private javax.swing.JPanel panelMode;
private javax.swing.JPanel panelModeInner;
private javax.swing.JPanel panelModeSelect;
private javax.swing.JPanel panelProgress;
private javax.swing.JPanel panelRedownload;
private javax.swing.JPanel panelSource;
private javax.swing.JPanel panelSourceLeft;
private javax.swing.JPanel panelSourceRight;
private javax.swing.JProgressBar progress;
private javax.swing.JPanel tabCustom;
private javax.swing.JPanel tabMain;
private javax.swing.JTabbedPane tabsList;
// End of variables declaration//GEN-END:variables
private int returnStatus = RET_CANCEL;
}

View file

@ -1,31 +1,19 @@
/*
* MageDialog.java
*
* Created on 15-Dec-2009, 10:28:27 PM
*/
package mage.client.dialog; package mage.client.dialog;
import java.awt.AWTEvent; import mage.client.MageFrame;
import java.awt.ActiveEvent; import mage.client.util.SettingsManager;
import java.awt.Component; import mage.client.util.gui.GuiDisplayUtil;
import java.awt.EventQueue; import org.apache.log4j.Logger;
import java.awt.KeyboardFocusManager;
import java.awt.MenuComponent; import javax.swing.*;
import java.awt.TrayIcon; import java.awt.*;
import java.awt.event.InvocationEvent; 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;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.*;
import mage.client.MageFrame;
import org.apache.log4j.Logger;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class MageDialog extends javax.swing.JInternalFrame { public class MageDialog extends javax.swing.JInternalFrame {
@ -105,6 +93,7 @@ public class MageDialog extends javax.swing.JInternalFrame {
} }
private synchronized void startModal() { private synchronized void startModal() {
// modal loop -- all mouse events must be ignored by other windows
try { try {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
EventQueue theQueue = getToolkit().getSystemEventQueue(); EventQueue theQueue = getToolkit().getSystemEventQueue();
@ -115,18 +104,46 @@ public class MageDialog extends javax.swing.JInternalFrame {
// https://github.com/magefree/mage/issues/584 - Let's hope this will fix the Linux window problem // 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)) { if (event.getSource() != null && event.getSource() instanceof TrayIcon && !(event instanceof InvocationEvent)) {
return; dispatch = false;
//return; // JayDi85: users can move mouse over try icon to disable modal mode (it's a bug but can be used in the future)
} }
// ignore mouse events outside from panel, only drag and move allowed -- as example:
// combobox's popup will be selectable outside
// cards and button hints will be works
Component popupComponent = null;
MouseEvent popupEvent = null;
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);
if (!this.contains(m.getPoint()) && e.getID() != MouseEvent.MOUSE_DRAGGED) {
dispatch = false; // disable all outer events (except some actions)
if (!this.contains(m.getPoint())) {
boolean allowedEvent = false;
// need any mouse move (for hints)
if (e.getID() == MouseEvent.MOUSE_DRAGGED || e.getID() == MouseEvent.MOUSE_MOVED) {
allowedEvent = true;
}
// need popup clicks and mouse wheel (for out of bound actions)
if (!allowedEvent) {
popupComponent = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY()); // show root component (popups creates at root)
if (popupComponent != null && popupComponent.getClass().getName().contains("BasicComboPopup")) {
popupEvent = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, popupComponent);
allowedEvent = true;
}
}
dispatch = allowedEvent;
} }
} }
if (dispatch) { if (dispatch) {
if (event instanceof ActiveEvent) { if (popupEvent != null) {
// process outer popup events, it's must be FIRST check
popupComponent.dispatchEvent(popupEvent);
} else if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch(); ((ActiveEvent) event).dispatch();
} else if (source instanceof Component) { } else if (source instanceof Component) {
((Component) source).dispatchEvent(event); ((Component) source).dispatchEvent(event);
@ -174,14 +191,21 @@ public class MageDialog extends javax.swing.JInternalFrame {
java.util.logging.Logger.getLogger(MageDialog.class.getName()).log(Level.SEVERE, "setClosed(false) failed", ex); java.util.logging.Logger.getLogger(MageDialog.class.getName()).log(Level.SEVERE, "setClosed(false) failed", ex);
} }
MageFrame.getDesktop().remove(this); MageFrame.getDesktop().remove(this);
}
public void makeWindowCentered() {
makeWindowCentered(this, getWidth(), getHeight());
}
public static void makeWindowCentered(Component component, int width, int height) {
Point centered = SettingsManager.instance.getComponentPosition(width, height);
component.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, component);
} }
/** /**
* Used to set a tooltip text on icon and titel bar * Used to set a tooltip text on icon and titel bar
* *
* used in {@link ExileZoneDialog} and {@link ShowCardsDialog}
*
* @param text * @param text
*/ */
public void setTitelBarToolTip(final String text) { public void setTitelBarToolTip(final String text) {

View file

@ -51,6 +51,7 @@ public class NewTableDialog extends MageDialog {
this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1)); this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1));
this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1)); this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1));
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5)); this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10));
this.spnEdhPowerLevel.setModel(new SpinnerNumberModel(100, 0, 100, 5)); this.spnEdhPowerLevel.setModel(new SpinnerNumberModel(100, 0, 100, 5));
MageFrame.getUI().addButton(MageComponents.NEW_TABLE_OK_BUTTON, btnOK); MageFrame.getUI().addButton(MageComponents.NEW_TABLE_OK_BUTTON, btnOK);
} }
@ -102,8 +103,10 @@ public class NewTableDialog extends MageDialog {
btnPreviousConfiguration2 = new javax.swing.JButton(); btnPreviousConfiguration2 = new javax.swing.JButton();
btnCancel = new javax.swing.JButton(); btnCancel = new javax.swing.JButton();
lblQuitRatio = new javax.swing.JLabel(); lblQuitRatio = new javax.swing.JLabel();
lblMinimumRating = new javax.swing.JLabel();
lblEdhPowerLevel = new javax.swing.JLabel(); lblEdhPowerLevel = new javax.swing.JLabel();
spnQuitRatio = new javax.swing.JSpinner(); spnQuitRatio = new javax.swing.JSpinner();
spnMinimumRating = new javax.swing.JSpinner();
spnEdhPowerLevel = new javax.swing.JSpinner(); spnEdhPowerLevel = new javax.swing.JSpinner();
setTitle("New Table"); setTitle("New Table");
@ -186,9 +189,11 @@ public class NewTableDialog extends MageDialog {
btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt)); btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt));
lblQuitRatio.setText("Allowed quit %"); lblQuitRatio.setText("Allowed quit %");
lblMinimumRating.setText("Minimum rating");
lblEdhPowerLevel.setText("EDH power level"); lblEdhPowerLevel.setText("EDH power level");
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table"); spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table");
spnEdhPowerLevel.setToolTipText("Players with decks with a higher power level can't join this table"); spnEdhPowerLevel.setToolTipText("Players with decks with a higher power level can't join this table");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
@ -239,9 +244,10 @@ public class NewTableDialog extends MageDialog {
.addComponent(lblQuitRatio) .addComponent(lblQuitRatio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblEdhPowerLevel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblMinimumRating)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
@ -270,7 +276,11 @@ public class NewTableDialog extends MageDialog {
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblNumWins) .addComponent(lblNumWins)
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblEdhPowerLevel)
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addComponent(jSeparator2) .addComponent(jSeparator2)
.addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
@ -297,14 +307,13 @@ public class NewTableDialog extends MageDialog {
.addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbDeckType) .addComponent(lbDeckType)
.addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(chkRated)
.addComponent(lblQuitRatio) .addComponent(lblQuitRatio)
.addComponent(chkRated)
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblEdhPowerLevel) .addComponent(lblMinimumRating)
.addComponent(chkRated) .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
@ -326,6 +335,7 @@ public class NewTableDialog extends MageDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblSkillLevel) .addComponent(lblSkillLevel)
.addComponent(lblNumWins) .addComponent(lblNumWins)
.addComponent(lblEdhPowerLevel)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblRange) .addComponent(lblRange)
.addComponent(lblAttack))) .addComponent(lblAttack)))
@ -334,7 +344,8 @@ public class NewTableDialog extends MageDialog {
.addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -394,6 +405,7 @@ public class NewTableDialog extends MageDialog {
options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue()); options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue());
options.setPassword(this.txtPassword.getText()); options.setPassword(this.txtPassword.getText());
options.setQuitRatio((Integer) this.spnQuitRatio.getValue()); options.setQuitRatio((Integer) this.spnQuitRatio.getValue());
options.setMinimumRating((Integer) this.spnMinimumRating.getValue());
options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue()); options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue());
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
@ -695,6 +707,7 @@ public class NewTableDialog extends MageDialog {
} }
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO, "100"))); this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO, "100")));
this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, "0")));
this.spnEdhPowerLevel.setValue(0); this.spnEdhPowerLevel.setValue(0);
} }
@ -729,6 +742,7 @@ public class NewTableDialog extends MageDialog {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, options.isSpectatorsAllowed() ? "Yes" : "No"); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, options.isSpectatorsAllowed() ? "Yes" : "No");
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No"); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No");
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO + versionStr, Integer.toString(options.getQuitRatio())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO + versionStr, Integer.toString(options.getQuitRatio()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, Integer.toString(options.getMinimumRating()));
StringBuilder playerTypesString = new StringBuilder(); StringBuilder playerTypesString = new StringBuilder();
for (Object player : players) { for (Object player : players) {
if (playerTypesString.length() > 0) { if (playerTypesString.length() > 0) {
@ -770,6 +784,7 @@ public class NewTableDialog extends MageDialog {
private javax.swing.JLabel lblNumWins; private javax.swing.JLabel lblNumWins;
private javax.swing.JLabel lblPassword; private javax.swing.JLabel lblPassword;
private javax.swing.JLabel lblQuitRatio; private javax.swing.JLabel lblQuitRatio;
private javax.swing.JLabel lblMinimumRating;
private javax.swing.JLabel lblEdhPowerLevel; private javax.swing.JLabel lblEdhPowerLevel;
private javax.swing.JLabel lblRange; private javax.swing.JLabel lblRange;
private javax.swing.JLabel lblSkillLevel; private javax.swing.JLabel lblSkillLevel;
@ -779,6 +794,7 @@ public class NewTableDialog extends MageDialog {
private javax.swing.JSpinner spnNumPlayers; private javax.swing.JSpinner spnNumPlayers;
private javax.swing.JSpinner spnNumWins; private javax.swing.JSpinner spnNumWins;
private javax.swing.JSpinner spnQuitRatio; private javax.swing.JSpinner spnQuitRatio;
private javax.swing.JSpinner spnMinimumRating;
private javax.swing.JSpinner spnEdhPowerLevel; private javax.swing.JSpinner spnEdhPowerLevel;
private javax.swing.JTextField txtName; private javax.swing.JTextField txtName;
private javax.swing.JTextField txtPassword; private javax.swing.JTextField txtPassword;

View file

@ -75,6 +75,7 @@ public class NewTournamentDialog extends MageDialog {
this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2)); this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2));
this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1)); this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1));
this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5)); this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5));
this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10));
} }
public void showDialog(UUID roomId) { public void showDialog(UUID roomId) {
@ -165,6 +166,8 @@ public class NewTournamentDialog extends MageDialog {
pnlRandomPacks = new javax.swing.JPanel(); pnlRandomPacks = new javax.swing.JPanel();
lblQuitRatio = new javax.swing.JLabel(); lblQuitRatio = new javax.swing.JLabel();
spnQuitRatio = new javax.swing.JSpinner(); spnQuitRatio = new javax.swing.JSpinner();
lblMinimumRating = new javax.swing.JLabel();
spnMinimumRating = new javax.swing.JSpinner();
setTitle("New Tournament"); setTitle("New Tournament");
@ -315,8 +318,10 @@ public class NewTournamentDialog extends MageDialog {
pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS)); pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS));
lblQuitRatio.setText("Allowed quit %:"); lblQuitRatio.setText("Allowed quit %:");
lblMinimumRating.setText("Minimum rating:");
spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table"); spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table");
spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table");
spnNumSeats.setToolTipText("The number of seats for each duel. If more than 2, will set number of wins to 1"); spnNumSeats.setToolTipText("The number of seats for each duel. If more than 2, will set number of wins to 1");
spnNumPlayers.setToolTipText("The total number of players who will draft"); spnNumPlayers.setToolTipText("The total number of players who will draft");
@ -386,11 +391,15 @@ public class NewTournamentDialog extends MageDialog {
.addComponent(lblNumWins) .addComponent(lblNumWins)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblQuitRatio) .addComponent(lblQuitRatio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblMinimumRating)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(chkRated)) .addComponent(chkRated))
.addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
@ -444,6 +453,8 @@ public class NewTournamentDialog extends MageDialog {
.addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblQuitRatio) .addComponent(lblQuitRatio)
.addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblMinimumRating)
.addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(chkRated)) .addComponent(chkRated))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
@ -522,6 +533,7 @@ public class NewTournamentDialog extends MageDialog {
tOptions.setWatchingAllowed(cbAllowSpectators.isSelected()); tOptions.setWatchingAllowed(cbAllowSpectators.isSelected());
tOptions.setPlaneChase(cbPlaneChase.isSelected()); tOptions.setPlaneChase(cbPlaneChase.isSelected());
tOptions.setQuitRatio((Integer) spnQuitRatio.getValue()); tOptions.setQuitRatio((Integer) spnQuitRatio.getValue());
tOptions.setMinimumRating((Integer) spnMinimumRating.getValue());
for (TournamentPlayerPanel player : players) { for (TournamentPlayerPanel player : players) {
tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem()); tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem());
} }
@ -1065,6 +1077,7 @@ public class NewTournamentDialog extends MageDialog {
this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, "0"))); this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, "0")));
this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2"))); this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2")));
this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100"))); this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100")));
this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, "0")));
TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem();
activatePanelElements(tournamentType); activatePanelElements(tournamentType);
@ -1150,6 +1163,7 @@ public class NewTournamentDialog extends MageDialog {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(tOptions.getMatchOptions().getFreeMulligans())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(tOptions.getMatchOptions().getFreeMulligans()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, Integer.toString(tOptions.getMatchOptions().getWinsNeeded())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, Integer.toString(tOptions.getMatchOptions().getWinsNeeded()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, Integer.toString(tOptions.getQuitRatio())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, Integer.toString(tOptions.getQuitRatio()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, Integer.toString(tOptions.getMinimumRating()));
if (tOptions.getTournamentType().startsWith("Sealed")) { if (tOptions.getTournamentType().startsWith("Sealed")) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, tOptions.getLimitedOptions().getSetCodes().toString()); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, tOptions.getLimitedOptions().getSetCodes().toString());
@ -1221,6 +1235,7 @@ public class NewTournamentDialog extends MageDialog {
private javax.swing.JLabel lblPassword; private javax.swing.JLabel lblPassword;
private javax.swing.JLabel lblPlayer1; private javax.swing.JLabel lblPlayer1;
private javax.swing.JLabel lblQuitRatio; private javax.swing.JLabel lblQuitRatio;
private javax.swing.JLabel lblMinimumRating;
private javax.swing.JLabel lblTournamentType; private javax.swing.JLabel lblTournamentType;
private mage.client.table.NewPlayerPanel player1Panel; private mage.client.table.NewPlayerPanel player1Panel;
private javax.swing.JPanel pnlDraftOptions; private javax.swing.JPanel pnlDraftOptions;
@ -1235,6 +1250,7 @@ public class NewTournamentDialog extends MageDialog {
private javax.swing.JSpinner spnNumRounds; private javax.swing.JSpinner spnNumRounds;
private javax.swing.JSpinner spnNumWins; private javax.swing.JSpinner spnNumWins;
private javax.swing.JSpinner spnQuitRatio; private javax.swing.JSpinner spnQuitRatio;
private javax.swing.JSpinner spnMinimumRating;
private javax.swing.JTextField txtName; private javax.swing.JTextField txtName;
private javax.swing.JTextField txtPassword; private javax.swing.JTextField txtPassword;
private org.jdesktop.beansbinding.BindingGroup bindingGroup; private org.jdesktop.beansbinding.BindingGroup bindingGroup;

View file

@ -1,37 +1,17 @@
/*
* 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; package mage.client.dialog;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.DefaultListModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import mage.choices.Choice; import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil;
import mage.client.util.gui.MageDialogState; import mage.client.util.gui.MageDialogState;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/** /**
*
* @author JayDi85 * @author JayDi85
* @author Salco * @author Salco
*/ */
@ -54,6 +34,7 @@ public class PickCheckBoxDialog extends MageDialog {
} }
this.scrollList.setViewportView((java.awt.Component) obj); this.scrollList.setViewportView((java.awt.Component) obj);
} }
private javax.swing.JList get_a_Jlist_from_ScrollListView() { private javax.swing.JList get_a_Jlist_from_ScrollListView() {
return ((javax.swing.JList) this.scrollList.getViewport().getView()); return ((javax.swing.JList) this.scrollList.getViewport().getView());
} }
@ -95,8 +76,7 @@ public class PickCheckBoxDialog extends MageDialog {
if (tList != null) { if (tList != null) {
indexInTList = m_dataModel.indexOf(entry.getKey()); indexInTList = m_dataModel.indexOf(entry.getKey());
tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue(), (CheckBoxList.CheckBoxListItem) this.tList.getModel().getElementAt(indexInTList)); tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue(), (CheckBoxList.CheckBoxListItem) this.tList.getModel().getElementAt(indexInTList));
} } else {
else{
tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue()); tempKeyValue = new KeyValueItem(entry.getKey(), entry.getValue());
} }
this.allItems.add(tempKeyValue); this.allItems.add(tempKeyValue);
@ -106,8 +86,7 @@ public class PickCheckBoxDialog extends MageDialog {
if (tList != null) { if (tList != null) {
indexInTList = m_dataModel.indexOf(value); indexInTList = m_dataModel.indexOf(value);
tempKeyValue = new KeyValueItem(value, value, (CheckBoxList.CheckBoxListItem) tList.getModel().getElementAt(indexInTList)); tempKeyValue = new KeyValueItem(value, value, (CheckBoxList.CheckBoxListItem) tList.getModel().getElementAt(indexInTList));
} } else {
else{
tempKeyValue = new KeyValueItem(value, value); tempKeyValue = new KeyValueItem(value, value);
} }
this.allItems.add(tempKeyValue); this.allItems.add(tempKeyValue);
@ -127,8 +106,7 @@ public class PickCheckBoxDialog extends MageDialog {
} }
// search // search
if(choice.isSearchEnabled()) if (choice.isSearchEnabled()) {
{
panelSearch.setVisible(true); panelSearch.setVisible(true);
this.editSearch.setText(choice.getSearchText()); this.editSearch.setText(choice.getSearchText());
} else { } else {
@ -210,11 +188,8 @@ public class PickCheckBoxDialog extends MageDialog {
} }
if (mageDialogState != null) { if (mageDialogState != null) {
mageDialogState.setStateToDialog(this); mageDialogState.setStateToDialog(this);
} else { } else {
Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); this.makeWindowCentered();
this.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
} }
// final load // final load
@ -253,7 +228,9 @@ public class PickCheckBoxDialog extends MageDialog {
private void loadData() { private void loadData() {
// load data to datamodel after filter or on startup // load data to datamodel after filter or on startup
String filter = choice.getSearchText(); String filter = choice.getSearchText();
if (filter == null){ filter = ""; } if (filter == null) {
filter = "";
}
filter = filter.toLowerCase(); filter = filter.toLowerCase();
this.dataModel.clear(); this.dataModel.clear();
@ -309,6 +286,7 @@ public class PickCheckBoxDialog extends MageDialog {
/** /**
* Creates new form PickChoiceDialog * Creates new form PickChoiceDialog
*
* @param list * @param list
*/ */
public PickCheckBoxDialog(CheckBoxList list) { public PickCheckBoxDialog(CheckBoxList list) {
@ -318,8 +296,7 @@ public class PickCheckBoxDialog extends MageDialog {
this.listChoices.setModel(dataModel); this.listChoices.setModel(dataModel);
this.setModal(true); this.setModal(true);
if(tList != null) if (tList != null) {
{
this.listChoices.setVisible(false); this.listChoices.setVisible(false);
m_dataModel = (CheckBoxList.CheckBoxListModel) tList.getModel(); m_dataModel = (CheckBoxList.CheckBoxListModel) tList.getModel();
@ -331,6 +308,7 @@ public class PickCheckBoxDialog extends MageDialog {
} }
} }
/** /**
* Creates new form PickChoiceDialog * Creates new form PickChoiceDialog
*/ */
@ -360,8 +338,7 @@ public class PickCheckBoxDialog extends MageDialog {
} }
} }
class KeyValueItem class KeyValueItem {
{
private final String Key; private final String Key;
private final String Value; private final String Value;
private final CheckBoxList.CheckBoxListItem objectValue; private final CheckBoxList.CheckBoxListItem objectValue;
@ -369,9 +346,11 @@ public class PickCheckBoxDialog extends MageDialog {
public KeyValueItem(String value) { public KeyValueItem(String value) {
this(value, null, null); this(value, null, null);
} }
public KeyValueItem(String value, String label) { public KeyValueItem(String value, String label) {
this(value, label, null); this(value, label, null);
} }
public KeyValueItem(String value, String label, CheckBoxList.CheckBoxListItem object) { public KeyValueItem(String value, String label, CheckBoxList.CheckBoxListItem object) {
this.Key = value; this.Key = value;
this.Value = label; this.Value = label;
@ -471,8 +450,14 @@ public class PickCheckBoxDialog extends MageDialog {
listChoices.setModel(new javax.swing.AbstractListModel() { listChoices.setModel(new javax.swing.AbstractListModel() {
String[] strings = {"item1", "item2", "item3"}; String[] strings = {"item1", "item2", "item3"};
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; } public int getSize() {
return strings.length;
}
public Object getElementAt(int i) {
return strings[i];
}
}); });
scrollList.setViewportView(listChoices); scrollList.setViewportView(listChoices);

View file

@ -1,36 +1,17 @@
/*
* 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; package mage.client.dialog;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.DefaultListModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import mage.choices.Choice; import mage.choices.Choice;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil;
import mage.client.util.gui.MageDialogState; import mage.client.util.gui.MageDialogState;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/** /**
*
* @author JayDi85 * @author JayDi85
*/ */
@ -89,8 +70,7 @@ public class PickChoiceDialog extends MageDialog {
} }
// search // search
if(choice.isSearchEnabled()) if (choice.isSearchEnabled()) {
{
panelSearch.setVisible(true); panelSearch.setVisible(true);
this.editSearch.setText(choice.getSearchText()); this.editSearch.setText(choice.getSearchText());
} else { } else {
@ -174,9 +154,7 @@ public class PickChoiceDialog extends MageDialog {
mageDialogState.setStateToDialog(this); mageDialogState.setStateToDialog(this);
} else { } else {
Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); this.makeWindowCentered();
this.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
} }
// final load // final load
@ -202,14 +180,16 @@ public class PickChoiceDialog extends MageDialog {
this.setVisible(true); this.setVisible(true);
} }
public void setWindowSize(int width, int heigth){ public void setWindowSize(int width, int height) {
this.setSize(new Dimension(width, heigth)); this.setSize(new Dimension(width, height));
} }
private void loadData() { private void loadData() {
// load data to datamodel after filter or on startup // load data to datamodel after filter or on startup
String filter = choice.getSearchText(); String filter = choice.getSearchText();
if (filter == null){ filter = ""; } if (filter == null) {
filter = "";
}
filter = filter.toLowerCase(Locale.ENGLISH); filter = filter.toLowerCase(Locale.ENGLISH);
this.dataModel.clear(); this.dataModel.clear();
@ -290,8 +270,7 @@ public class PickChoiceDialog extends MageDialog {
} }
} }
class KeyValueItem class KeyValueItem {
{
private final String Key; private final String Key;
private final String Value; private final String Value;
@ -388,8 +367,14 @@ public class PickChoiceDialog extends MageDialog {
listChoices.setModel(new javax.swing.AbstractListModel() { listChoices.setModel(new javax.swing.AbstractListModel() {
String[] strings = {"item1", "item2", "item3"}; String[] strings = {"item1", "item2", "item3"};
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; } public int getSize() {
return strings.length;
}
public Object getElementAt(int i) {
return strings[i];
}
}); });
scrollList.setViewportView(listChoices); scrollList.setViewportView(listChoices);

View file

@ -1,31 +1,21 @@
/*
* PickNumberDialog.java
*
* Created on Feb 25, 2010, 12:03:39 PM
*/
package mage.client.dialog; package mage.client.dialog;
import java.awt.Point; import mage.client.MageFrame;
import javax.swing.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.event.KeyListener;
import javax.swing.*;
import mage.client.MageFrame;
import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class PickNumberDialog extends MageDialog { public class PickNumberDialog extends MageDialog {
private boolean cancel; private boolean cancel;
/** Creates new form PickNumberDialog */ /**
* Creates new form PickNumberDialog
*/
public PickNumberDialog() { public PickNumberDialog() {
initComponents(); initComponents();
this.setModal(true); this.setModal(true);
@ -68,9 +58,7 @@ public class PickNumberDialog extends MageDialog {
}); });
Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); this.makeWindowCentered();
this.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
// TODO: need to fix focus restore on second popup (it's not focues, test on Manamorphose) // TODO: need to fix focus restore on second popup (it's not focues, test on Manamorphose)
this.setVisible(true); this.setVisible(true);
@ -84,7 +72,8 @@ public class PickNumberDialog extends MageDialog {
return cancel; return cancel;
} }
/** This method is called from within the constructor to /**
* This method is called from within the constructor to
* initialize the form. * 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 regenerated by the Form Editor. * always regenerated by the Form Editor.

View file

@ -1,23 +1,16 @@
package mage.client.dialog; package mage.client.dialog;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import java.util.UUID;
import javax.swing.JButton;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.cards.CardArea; import mage.client.cards.CardArea;
import mage.client.util.SettingsManager;
import mage.client.util.gui.GuiDisplayUtil;
import mage.view.CardsView; import mage.view.CardsView;
import org.mage.card.arcane.CardPanel; import org.mage.card.arcane.CardPanel;
import javax.swing.*;
import java.awt.*;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class PickPileDialog extends MageDialog { public class PickPileDialog extends MageDialog {
@ -81,9 +74,7 @@ public class PickPileDialog extends MageDialog {
} }
pack(); pack();
Point centered = SettingsManager.instance.getComponentPosition(getWidth(), getHeight()); this.makeWindowCentered();
this.setLocation(centered.x, centered.y);
GuiDisplayUtil.keepComponentInsideScreen(centered.x, centered.y, this);
this.revalidate(); this.revalidate();
this.repaint(); this.repaint();

View file

@ -236,7 +236,7 @@
<Property name="toolTipText" type="java.lang.String" value="Write the card&apos;s name on the card to make the card name more recognizable."/> <Property name="toolTipText" type="java.lang.String" value="Write the card&apos;s name on the card to make the card name more recognizable."/>
<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">
<Color id="Standardcursor"/> <Color id="Default Cursor"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
@ -267,7 +267,7 @@
<Property name="selected" type="boolean" value="true"/> <Property name="selected" type="boolean" value="true"/>
<Property name="toolTipText" type="java.lang.String" value="Show the path Xmage is expecting for this card&apos;s image (only displays if missing)"/> <Property name="toolTipText" type="java.lang.String" value="Show the path Xmage is expecting for this card&apos;s image (only displays if missing)"/>
<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">
<Color id="Standardcursor"/> <Color id="Default Cursor"/>
</Property> </Property>
<Property name="label" type="java.lang.String" value="Display image path for missing images"/> <Property name="label" type="java.lang.String" value="Display image path for missing images"/>
</Properties> </Properties>
@ -4425,6 +4425,7 @@
</Component> </Component>
<Component class="javax.swing.JComboBox" name="cbPreferedImageLanguage"> <Component class="javax.swing.JComboBox" name="cbPreferedImageLanguage">
<Properties> <Properties>
<Property name="maximumRowCount" type="int" value="20"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4"> <StringArray count="4">
<StringItem index="0" value="Item 1"/> <StringItem index="0" value="Item 1"/>
@ -4451,6 +4452,7 @@
</Component> </Component>
<Component class="javax.swing.JComboBox" name="cbNumberOfDownloadThreads"> <Component class="javax.swing.JComboBox" name="cbNumberOfDownloadThreads">
<Properties> <Properties>
<Property name="maximumRowCount" type="int" value="20"/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4"> <StringArray count="4">
<StringItem index="0" value="Item 1"/> <StringItem index="0" value="Item 1"/>

View file

@ -41,6 +41,8 @@ import mage.client.MageFrame;
import mage.client.SessionHandler; import mage.client.SessionHandler;
import mage.client.components.KeyBindButton; import mage.client.components.KeyBindButton;
import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR; import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
import mage.client.util.CardLanguage;
import mage.client.util.Config; import mage.client.util.Config;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.client.util.ImageHelper; import mage.client.util.ImageHelper;
@ -222,6 +224,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers"; public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers";
public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes"; public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes";
public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio"; public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio";
public static final String KEY_NEW_TABLE_MINIMUM_RATING = "newTableMinimumRating";
public static final String KEY_NEW_TABLE_RATED = "newTableRated"; public static final String KEY_NEW_TABLE_RATED = "newTableRated";
// pref setting for new tournament dialog // pref setting for new tournament dialog
@ -243,6 +246,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_NEW_TOURNAMENT_ALLOW_ROLLBACKS = "newTournamentAllowRollbacks"; public static final String KEY_NEW_TOURNAMENT_ALLOW_ROLLBACKS = "newTournamentAllowRollbacks";
public static final String KEY_NEW_TOURNAMENT_DECK_FILE = "newTournamentDeckFile"; public static final String KEY_NEW_TOURNAMENT_DECK_FILE = "newTournamentDeckFile";
public static final String KEY_NEW_TOURNAMENT_QUIT_RATIO = "newTournamentQuitRatio"; public static final String KEY_NEW_TOURNAMENT_QUIT_RATIO = "newTournamentQuitRatio";
public static final String KEY_NEW_TOURNAMENT_MINIMUM_RATING = "newTournamentMinimumRating";
public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated"; public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated";
// pref setting for deck generator // pref setting for deck generator
@ -336,6 +340,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
fc_i.addChoosableFileFilter(new ImageFileFilter()); fc_i.addChoosableFileFilter(new ImageFileFilter());
} }
public static CardLanguage getPrefImagesLanguage() {
return CardLanguage.valueByCode(getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode()));
}
private static class ImageFileFilter extends FileFilter { private static class ImageFileFilter extends FileFilter {
@Override @Override
@ -372,7 +380,7 @@ 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<>(CardLanguage.toList()));
cbNumberOfDownloadThreads.setModel(new DefaultComboBoxModel<>(new String[]{"10", "9", "8", "7", "6", "5", "4", "3", "2", "1"})); cbNumberOfDownloadThreads.setModel(new DefaultComboBoxModel<>(new String[]{"10", "9", "8", "7", "6", "5", "4", "3", "2", "1"}));
} }
@ -1556,6 +1564,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
} }
}); });
cbPreferedImageLanguage.setMaximumRowCount(20);
cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); cbPreferedImageLanguage.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
labelPreferedImageLanguage.setText("Prefered image language:"); labelPreferedImageLanguage.setText("Prefered image language:");
@ -1563,6 +1572,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
labelNumberOfDownloadThreads.setText("Number of download threads:"); labelNumberOfDownloadThreads.setText("Number of download threads:");
cbNumberOfDownloadThreads.setMaximumRowCount(20);
cbNumberOfDownloadThreads.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); cbNumberOfDownloadThreads.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
org.jdesktop.layout.GroupLayout panelCardImagesLayout = new org.jdesktop.layout.GroupLayout(panelCardImages); org.jdesktop.layout.GroupLayout panelCardImagesLayout = new org.jdesktop.layout.GroupLayout(panelCardImages);
@ -3409,7 +3419,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.cbCheckForNewImages, KEY_CARD_IMAGES_CHECK, "true"); load(prefs, dialog.cbCheckForNewImages, KEY_CARD_IMAGES_CHECK, "true");
load(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true"); load(prefs, dialog.cbSaveToZipFiles, KEY_CARD_IMAGES_SAVE_TO_ZIP, "true");
dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10")); dialog.cbNumberOfDownloadThreads.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_THREADS, "10"));
dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, "en")); dialog.cbPreferedImageLanguage.setSelectedItem(MageFrame.getPreferences().get(KEY_CARD_IMAGES_PREF_LANGUAGE, CardLanguage.ENGLISH.getCode()));
// rendering settings // rendering settings
load(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true"); load(prefs, dialog.cbCardRenderImageFallback, KEY_CARD_RENDERING_FALLBACK, "true");

View file

@ -21,7 +21,6 @@ import mage.client.util.audio.AudioManager;
import mage.client.util.gui.BufferedImageBuilder; import mage.client.util.gui.BufferedImageBuilder;
import mage.constants.PlayerAction; import mage.constants.PlayerAction;
import mage.view.*; import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.*; import javax.swing.*;
import javax.swing.Timer; import javax.swing.Timer;
@ -31,12 +30,9 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.List;
/** /**
* *
@ -44,8 +40,6 @@ import java.util.*;
*/ */
public class DraftPanel extends javax.swing.JPanel { public class DraftPanel extends javax.swing.JPanel {
private static final Logger LOGGER = Logger.getLogger(DraftPanel.class);
private UUID draftId; private UUID draftId;
private Timer countdown; private Timer countdown;
private int timeout; private int timeout;
@ -63,8 +57,11 @@ public class DraftPanel extends javax.swing.JPanel {
// id of card with popup menu // id of card with popup menu
protected UUID cardIdPopupMenu; protected UUID cardIdPopupMenu;
// Filename for the draft log (only updated if writing the log). // Helper for writing the draft log.
private String logFilename; private DraftPickLogger draftLogger;
// List of set codes (for draft log writing).
private List<String> setCodes;
// Number of the current booster (for draft log writing). // Number of the current booster (for draft log writing).
private int packNo; private int packNo;
@ -73,7 +70,6 @@ public class DraftPanel extends javax.swing.JPanel {
private int pickNo; private int pickNo;
// Cached booster data to be written into the log (see logLastPick). // Cached booster data to be written into the log (see logLastPick).
private String currentBoosterHeader;
private String[] currentBooster; private String[] currentBooster;
private static final CardsView EMPTY_VIEW = new CardsView(); private static final CardsView EMPTY_VIEW = new CardsView();
@ -139,17 +135,11 @@ public class DraftPanel extends javax.swing.JPanel {
} }
if (isLogging()) { if (isLogging()) {
// If we are logging the draft create a file that will contain
// the log.
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".txt"; String logFilename = "Draft_" + sdf.format(new Date()) + '_' + draftId + ".txt";
try { draftLogger = new DraftPickLogger(new File("gamelogs"), logFilename);
Files.write(pathToDraftLog(), "".getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException ex) {
LOGGER.error(null, ex);
}
} else { } else {
logFilename = null; draftLogger = new DraftPickLogger();
} }
} }
@ -171,6 +161,8 @@ public class DraftPanel extends javax.swing.JPanel {
packNo = draftView.getBoosterNum(); packNo = draftView.getBoosterNum();
pickNo = draftView.getCardNum(); pickNo = draftView.getCardNum();
setCodes = draftView.getSetCodes();
draftLogger.updateDraft(draftId, draftView);
int right = draftView.getPlayers().size() / 2; int right = draftView.getPlayers().size() / 2;
int left = draftView.getPlayers().size() - right; int left = draftView.getPlayers().size() - right;
@ -416,13 +408,21 @@ public class DraftPanel extends javax.swing.JPanel {
if (currentBooster != null) { if (currentBooster != null) {
String lastPick = getCardName(getLastPick(pickView.getPicks().values())); String lastPick = getCardName(getLastPick(pickView.getPicks().values()));
if (lastPick != null && currentBooster.length > 1) { if (lastPick != null && currentBooster.length > 1) {
logPick(lastPick); draftLogger.logPick(getCurrentSetCode(), packNo, pickNo-1, lastPick, currentBooster);
} }
currentBooster = null; currentBooster = null;
} }
setCurrentBoosterForLog(pickView.getBooster()); setCurrentBoosterForLog(pickView.getBooster());
if (currentBooster.length == 1) { if (currentBooster.length == 1) {
logPick(currentBooster[0]); draftLogger.logPick(getCurrentSetCode(), packNo, pickNo, currentBooster[0], currentBooster);
}
}
private String getCurrentSetCode() {
if (!setCodes.isEmpty()) {
return setCodes.get(packNo-1);
} else {
return "";
} }
} }
@ -440,38 +440,9 @@ public class DraftPanel extends javax.swing.JPanel {
} }
} }
currentBoosterHeader = "Pack " + packNo + " pick " + pickNo + ":\n";
currentBooster = cards.toArray(new String[cards.size()]); currentBooster = cards.toArray(new String[cards.size()]);
} }
private void logPick(String pick) {
StringBuilder b = new StringBuilder();
b.append(currentBoosterHeader);
for (String name : currentBooster) {
b.append(pick.equals(name) ? "--> " : " ");
b.append(name);
b.append('\n');
}
b.append('\n');
appendToDraftLog(b.toString());
}
private Path pathToDraftLog() {
File saveDir = new File("gamelogs");
if (!saveDir.exists()) {
saveDir.mkdirs();
}
return new File(saveDir, logFilename).toPath();
}
private void appendToDraftLog(String data) {
try {
Files.write(pathToDraftLog(), data.getBytes(), StandardOpenOption.APPEND);
} catch (IOException ex) {
LOGGER.error(null, ex);
}
}
private static SimpleCardView getLastPick(Collection<SimpleCardView> picks) { private static SimpleCardView getLastPick(Collection<SimpleCardView> picks) {
SimpleCardView last = null; SimpleCardView last = null;
for (SimpleCardView pick : picks) { for (SimpleCardView pick : picks) {

View file

@ -0,0 +1,85 @@
package mage.client.draft;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import org.apache.log4j.Logger;
import mage.view.DraftView;
public class DraftPickLogger {
private static final Logger LOGGER = Logger.getLogger(DraftPickLogger.class);
private final Path logPath;
private final boolean logging;
private boolean headerWritten = false;
public DraftPickLogger(File directory, String logFilename) {
this.logging = true;
if (!directory.exists()) {
directory.mkdirs();
}
this.logPath = new File(directory, logFilename).toPath();
try {
Files.write(logPath, new byte[0], StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException ex) {
LOGGER.error(null, ex);
}
}
public DraftPickLogger() {
this.logging = false;
this.logPath = null;
}
public void updateDraft(UUID draftId, DraftView draftView) {
if (headerWritten) {
return;
}
headerWritten = true;
Date now = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("M/d/yyyy h:mm:ss a");
StringBuilder buffer = new StringBuilder()
.append("Event #: ").append(draftId).append("\n")
.append("Time: ").append(formatter.format(now)).append('\n');
buffer.append("Players:\n");
for (String player : draftView.getPlayers()) {
buffer.append(" ").append(player).append('\n');
}
buffer.append('\n');
appendToDraftLog(buffer.toString());
}
public void logPick(String setCode, int packNo, int pickNo, String pick, String[] currentBooster) {
StringBuilder b = new StringBuilder();
if (pickNo == 1) {
b.append("------ ").append(setCode).append(" ------\n\n");
}
b.append("Pack ").append(packNo).append(" pick ").append(pickNo).append(":\n");
for (String name : currentBooster) {
b.append(pick.equals(name) ? "--> " : " ");
b.append(name);
b.append('\n');
}
b.append('\n');
appendToDraftLog(b.toString());
}
private void appendToDraftLog(String data) {
if (logging) {
try {
Files.write(logPath, data.getBytes(), StandardOpenOption.APPEND);
} catch (IOException ex) {
LOGGER.error(null, ex);
}
}
}
}

View file

@ -353,8 +353,9 @@ public class CallbackClientImpl implements CallbackClient {
} }
case DRAFT_UPDATE: { case DRAFT_UPDATE: {
DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); DraftPanel panel = MageFrame.getDraft(callback.getObjectId());
DraftClientMessage message = (DraftClientMessage) callback.getData();
if (panel != null) { if (panel != null) {
panel.updateDraft((DraftView) callback.getData()); panel.updateDraft(message.getDraftView());
} }
break; break;
} }

View file

@ -0,0 +1,145 @@
package mage.client.table;
import mage.remote.MageRemoteException;
import mage.view.MatchView;
import javax.swing.table.AbstractTableModel;
import java.util.Collection;
import java.util.Date;
import java.util.UUID;
public class MatchesTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Rating", "Result", "Duration", "Start Time", "End Time", "Action"};
public static final int COLUMN_DURATION = 5;
public static final int COLUMN_START = 6;
public static final int COLUMN_END = 7;
public static final int COLUMN_ACTION = 8; // column the action is located (starting with 0)
private MatchView[] matches = new MatchView[0];
public void loadData(Collection<MatchView> matches) throws MageRemoteException {
this.matches = matches.toArray(new MatchView[0]);
this.fireTableDataChanged();
}
MatchesTableModel() {
}
public String getTableAndGameInfo(int row) {
return this.matches[row].getTableId().toString() + ";" + (!matches[row].getGames().isEmpty() ? matches[row].getGames().get(0).toString() : "null");
}
public String findTableAndGameInfoByRow(int row) {
if (row >= 0 && row < this.matches.length) {
return getTableAndGameInfo(row);
} else {
return null;
}
}
public int findRowByTableAndGameInfo(String tableAndGame) {
for (int i = 0; i < this.matches.length; i++) {
String rowID = this.matches[i].getTableId().toString() + ";" + (!this.matches[i].getGames().isEmpty() ? this.matches[i].getGames().get(0).toString() : "null");
if (tableAndGame.equals(rowID)) {
return i;
}
}
return -1;
}
@Override
public int getRowCount() {
return matches.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return matches[arg0].getDeckType();
case 1:
return matches[arg0].getPlayers();
case 2:
return matches[arg0].getGameType();
case 3:
return matches[arg0].isRated() ? TablesTableModel.RATED_VALUE_YES : TablesTableModel.RATED_VALUE_NO;
case 4:
return matches[arg0].getResult();
case 5:
if (matches[arg0].getEndTime() != null) {
return matches[arg0].getEndTime().getTime() - matches[arg0].getStartTime().getTime() + new Date().getTime();
} else {
return 0L;
}
case 6:
return matches[arg0].getStartTime();
case 7:
return matches[arg0].getEndTime();
case 8:
if (matches[arg0].isTournament()) {
return "Show";
} else if (matches[arg0].isReplayAvailable()) {
return "Replay";
} else {
return "None";
}
case 9:
return matches[arg0].getGames();
}
return "";
}
public java.util.List<UUID> getListofGames(int row) {
return matches[row].getGames();
}
public boolean isTournament(int row) {
return matches[row].isTournament();
}
public UUID getMatchId(int row) {
return matches[row].getMatchId();
}
public UUID getTableId(int row) {
return matches[row].getTableId();
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_DURATION:
return Long.class;
case COLUMN_START:
return Date.class;
case COLUMN_END:
return Date.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == COLUMN_ACTION;
}
}

View file

@ -1,25 +1,21 @@
package mage.client.table;
package mage.client.util; import mage.client.util.GUISizeHelper;
import java.awt.Component; import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class ButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener { public class TablesButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener {
private final JTable table; private final JTable table;
private final Action action; private final Action action;
@ -28,7 +24,7 @@ public class ButtonColumn extends AbstractCellEditor implements TableCellRendere
private String text; private String text;
private boolean isButtonColumnEditor; private boolean isButtonColumnEditor;
public ButtonColumn(JTable table, Action action, int column) { public TablesButtonColumn(JTable table, Action action, int column) {
super(); super();
this.table = table; this.table = table;
this.action = action; this.action = action;
@ -88,7 +84,7 @@ public class ButtonColumn extends AbstractCellEditor implements TableCellRendere
if (table.getRowCount() > 0 && table.getRowCount() >= table.getEditingRow() && table.getEditingRow() >= 0) { if (table.getRowCount() > 0 && table.getRowCount() >= table.getEditingRow() && table.getEditingRow() >= 0) {
int row = table.convertRowIndexToModel(table.getEditingRow()); int row = table.convertRowIndexToModel(table.getEditingRow());
fireEditingStopped(); fireEditingStopped();
ActionEvent event = new ActionEvent(table, ActionEvent.ACTION_PERFORMED, String.valueOf(row)); ActionEvent event = new ActionEvent(table, ActionEvent.ACTION_PERFORMED, TablesUtil.getSearchIdFromTable(table, row));
action.actionPerformed(event); action.actionPerformed(event);
} }
} }

View file

@ -1,8 +1,3 @@
/*
* TablesPanel.java
*
* Created on 15-Dec-2009, 10:54:01 PM
*/
package mage.client.table; package mage.client.table;
import mage.cards.decks.importer.DeckImporterUtil; import mage.cards.decks.importer.DeckImporterUtil;
@ -11,7 +6,10 @@
import mage.client.chat.ChatPanelBasic; import mage.client.chat.ChatPanelBasic;
import mage.client.components.MageComponents; import mage.client.components.MageComponents;
import mage.client.dialog.*; import mage.client.dialog.*;
import mage.client.util.*; import mage.client.util.GUISizeHelper;
import mage.client.util.IgnoreList;
import mage.client.util.MageTableRowSorter;
import mage.client.util.URLHandler;
import mage.client.util.gui.GuiDisplayUtil; import mage.client.util.gui.GuiDisplayUtil;
import mage.client.util.gui.TableUtil; import mage.client.util.gui.TableUtil;
import mage.constants.*; import mage.constants.*;
@ -30,7 +28,6 @@
import javax.swing.*; import javax.swing.*;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellRenderer;
import java.awt.*; import java.awt.*;
@ -57,7 +54,7 @@
private static final Logger LOGGER = Logger.getLogger(TablesPanel.class); private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60}; private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60};
private final TableTableModel tableModel; private final TablesTableModel tableModel;
private final MatchesTableModel matchesModel; private final MatchesTableModel matchesModel;
private UUID roomId; private UUID roomId;
private UpdateTablesTask updateTablesTask; private UpdateTablesTask updateTablesTask;
@ -72,8 +69,8 @@
private final MageTableRowSorter activeTablesSorter; private final MageTableRowSorter activeTablesSorter;
private final MageTableRowSorter completedTablesSorter; private final MageTableRowSorter completedTablesSorter;
private final ButtonColumn actionButton1; private final TablesButtonColumn actionButton1;
private final ButtonColumn actionButton2; private final TablesButtonColumn actionButton2;
final JToggleButton[] filterButtons; final JToggleButton[] filterButtons;
@ -166,7 +163,7 @@
*/ */
public TablesPanel() { public TablesPanel() {
tableModel = new TableTableModel(); tableModel = new TablesTableModel();
matchesModel = new MatchesTableModel(); matchesModel = new MatchesTableModel();
gameChooser = new GameChooser(); gameChooser = new GameChooser();
@ -184,21 +181,22 @@
tableTables.setRowSorter(activeTablesSorter); tableTables.setRowSorter(activeTablesSorter);
// time ago // time ago
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer); tableTables.getColumnModel().getColumn(TablesTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer);
// skill level // skill level
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_SKILL).setCellRenderer(skillCellRenderer); tableTables.getColumnModel().getColumn(TablesTableModel.COLUMN_SKILL).setCellRenderer(skillCellRenderer);
/* date sorter (not need, default is good - see getColumnClass) /* date sorter (not need, default is good - see getColumnClass)
activeTablesSorter.setComparator(TableTableModel.COLUMN_CREATED, new Comparator<Date>() { activeTablesSorter.setComparator(TablesTableModel.COLUMN_CREATED, new Comparator<Date>() {
@Override @Override
public int compare(Date v1, Date v2) { public int compare(Date v1, Date v2) {
return v1.compareTo(v2); return v1.compareTo(v2);
} }
});*/ });*/
// default sort by created date (last games from above) // default sort by created date (last games from above)
ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING)); list.add(new RowSorter.SortKey(TablesTableModel.COLUMN_CREATED, SortOrder.DESCENDING));
activeTablesSorter.setSortKeys(list); activeTablesSorter.setSortKeys(list);
TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER);
@ -243,14 +241,18 @@
openTableAction = new AbstractAction() { openTableAction = new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int modelRow = Integer.valueOf(e.getActionCommand()); String searchID = e.getActionCommand();
UUID tableId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 3); int modelRow = TablesUtil.findTableRowFromSearchId(tableModel, searchID);
UUID gameId = (UUID) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2); if (modelRow == -1) {
String action = (String) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN); return;
String deckType = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE); }
boolean isTournament = (Boolean) tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1); UUID tableId = (UUID) tableModel.getValueAt(modelRow, TablesTableModel.ACTION_COLUMN + 3);
String owner = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER); UUID gameId = (UUID) tableModel.getValueAt(modelRow, TablesTableModel.ACTION_COLUMN + 2);
String pwdColumn = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_PASSWORD); String action = (String) tableModel.getValueAt(modelRow, TablesTableModel.ACTION_COLUMN);
String deckType = (String) tableModel.getValueAt(modelRow, TablesTableModel.COLUMN_DECK_TYPE);
boolean isTournament = (Boolean) tableModel.getValueAt(modelRow, TablesTableModel.ACTION_COLUMN + 1);
String owner = (String) tableModel.getValueAt(modelRow, TablesTableModel.COLUMN_OWNER);
String pwdColumn = (String) tableModel.getValueAt(modelRow, TablesTableModel.COLUMN_PASSWORD);
switch (action) { switch (action) {
case "Join": case "Join":
if (owner.equals(SessionHandler.getUserName()) || owner.startsWith(SessionHandler.getUserName() + ',')) { if (owner.equals(SessionHandler.getUserName()) || owner.startsWith(SessionHandler.getUserName() + ',')) {
@ -277,7 +279,7 @@
if (isTournament) { if (isTournament) {
LOGGER.info("Joining tournament " + tableId); LOGGER.info("Joining tournament " + tableId);
if (deckType.startsWith("Limited")) { if (deckType.startsWith("Limited")) {
if (TableTableModel.PASSWORD_VALUE_YES.equals(pwdColumn)) { if (TablesTableModel.PASSWORD_VALUE_YES.equals(pwdColumn)) {
joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited"));
} else { } else {
SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), PlayerType.HUMAN, 1, null, ""); SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), PlayerType.HUMAN, 1, null, "");
@ -320,7 +322,11 @@
closedTableAction = new AbstractAction() { closedTableAction = new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int modelRow = Integer.valueOf(e.getActionCommand()); String searchID = e.getActionCommand();
int modelRow = TablesUtil.findTableRowFromSearchId(matchesModel, searchID);
if (modelRow == -1) {
return;
}
String action = (String) matchesModel.getValueAt(modelRow, MatchesTableModel.COLUMN_ACTION); String action = (String) matchesModel.getValueAt(modelRow, MatchesTableModel.COLUMN_ACTION);
switch (action) { switch (action) {
case "Replay": case "Replay":
@ -345,8 +351,8 @@
}; };
// !!!! adds action buttons to the table panel (don't delete this) // !!!! adds action buttons to the table panel (don't delete this)
actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN)); actionButton1 = new TablesButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TablesTableModel.ACTION_COLUMN));
actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION)); actionButton2 = new TablesButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION));
// !!!! // !!!!
addTableDoubleClickListener(tableTables, openTableAction); addTableDoubleClickListener(tableTables, openTableAction);
addTableDoubleClickListener(tableCompleted, closedTableAction); addTableDoubleClickListener(tableCompleted, closedTableAction);
@ -356,14 +362,9 @@
table.addMouseListener(new MouseAdapter() { table.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) { int row = table.getSelectedRow();
int selRow = table.getSelectedRow(); if (e.getClickCount() == 2 && row != -1) {
if (selRow != -1) { action.actionPerformed(new ActionEvent(table, ActionEvent.ACTION_PERFORMED, TablesUtil.getSearchIdFromTable(table, row)));
int dataRow = table.convertRowIndexToModel(selRow);
if (dataRow != -1) {
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + dataRow));
}
}
} }
} }
}); });
@ -607,87 +608,87 @@
// state // state
java.util.List<RowFilter<Object, Object>> stateFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> stateFilterList = new ArrayList<>();
if (btnStateWaiting.isSelected()) { if (btnStateWaiting.isSelected()) {
stateFilterList.add(RowFilter.regexFilter("Waiting", TableTableModel.COLUMN_STATUS)); stateFilterList.add(RowFilter.regexFilter("Waiting", TablesTableModel.COLUMN_STATUS));
} }
if (btnStateActive.isSelected()) { if (btnStateActive.isSelected()) {
stateFilterList.add(RowFilter.regexFilter("Dueling|Constructing|Drafting|Sideboard", TableTableModel.COLUMN_STATUS)); stateFilterList.add(RowFilter.regexFilter("Dueling|Constructing|Drafting|Sideboard", TablesTableModel.COLUMN_STATUS));
} }
// type // type
java.util.List<RowFilter<Object, Object>> typeFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> typeFilterList = new ArrayList<>();
if (btnTypeMatch.isSelected()) { if (btnTypeMatch.isSelected()) {
typeFilterList.add(RowFilter.regexFilter("Two|Commander|Free|Tiny|Momir", TableTableModel.COLUMN_GAME_TYPE)); typeFilterList.add(RowFilter.regexFilter("Two|Commander|Free|Tiny|Momir", TablesTableModel.COLUMN_GAME_TYPE));
} }
if (btnTypeTourneyConstructed.isSelected()) { if (btnTypeTourneyConstructed.isSelected()) {
typeFilterList.add(RowFilter.regexFilter("Constructed", TableTableModel.COLUMN_GAME_TYPE)); typeFilterList.add(RowFilter.regexFilter("Constructed", TablesTableModel.COLUMN_GAME_TYPE));
} }
if (btnTypeTourneyLimited.isSelected()) { if (btnTypeTourneyLimited.isSelected()) {
typeFilterList.add(RowFilter.regexFilter("Booster|Sealed", TableTableModel.COLUMN_GAME_TYPE)); typeFilterList.add(RowFilter.regexFilter("Booster|Sealed", TablesTableModel.COLUMN_GAME_TYPE));
} }
// format // format
java.util.List<RowFilter<Object, Object>> formatFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> formatFilterList = new ArrayList<>();
if (btnFormatBlock.isSelected()) { if (btnFormatBlock.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Constructed.*Block", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Constructed.*Block", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatStandard.isSelected()) { if (btnFormatStandard.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Standard", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Constructed - Standard", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatModern.isSelected()) { if (btnFormatModern.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Modern", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Constructed - Modern", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatLegacy.isSelected()) { if (btnFormatLegacy.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Legacy", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Constructed - Legacy", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatVintage.isSelected()) { if (btnFormatVintage.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatCommander.isSelected()) { if (btnFormatCommander.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander|^Duel Brawl|^Brawl", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatTinyLeader.isSelected()) { if (btnFormatTinyLeader.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Tiny", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Tiny", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatLimited.isSelected()) { if (btnFormatLimited.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Limited", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Limited", TablesTableModel.COLUMN_DECK_TYPE));
} }
if (btnFormatOther.isSelected()) { if (btnFormatOther.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE)); formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TablesTableModel.COLUMN_DECK_TYPE));
} }
// skill // skill
java.util.List<RowFilter<Object, Object>> skillFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> skillFilterList = new ArrayList<>();
if (btnSkillBeginner.isSelected()) { if (btnSkillBeginner.isSelected()) {
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.BEGINNER, true), TableTableModel.COLUMN_SKILL)); skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.BEGINNER, true), TablesTableModel.COLUMN_SKILL));
} }
if (btnSkillCasual.isSelected()) { if (btnSkillCasual.isSelected()) {
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.CASUAL, true), TableTableModel.COLUMN_SKILL)); skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.CASUAL, true), TablesTableModel.COLUMN_SKILL));
} }
if (btnSkillSerious.isSelected()) { if (btnSkillSerious.isSelected()) {
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.SERIOUS, true), TableTableModel.COLUMN_SKILL)); skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.SERIOUS, true), TablesTableModel.COLUMN_SKILL));
} }
String ratedMark = TableTableModel.RATED_VALUE_YES; String ratedMark = TablesTableModel.RATED_VALUE_YES;
java.util.List<RowFilter<Object, Object>> ratingFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> ratingFilterList = new ArrayList<>();
if (btnRated.isSelected()) { if (btnRated.isSelected()) {
// yes word // yes word
ratingFilterList.add(RowFilter.regexFilter("^" + ratedMark, TableTableModel.COLUMN_RATING)); ratingFilterList.add(RowFilter.regexFilter("^" + ratedMark, TablesTableModel.COLUMN_RATING));
} }
if (btnUnrated.isSelected()) { if (btnUnrated.isSelected()) {
// not yes word, see https://stackoverflow.com/a/406408/1276632 // not yes word, see https://stackoverflow.com/a/406408/1276632
ratingFilterList.add(RowFilter.regexFilter("^((?!" + ratedMark + ").)*$", TableTableModel.COLUMN_RATING)); ratingFilterList.add(RowFilter.regexFilter("^((?!" + ratedMark + ").)*$", TablesTableModel.COLUMN_RATING));
} }
// Password // Password
String passwordMark = TableTableModel.PASSWORD_VALUE_YES; String passwordMark = TablesTableModel.PASSWORD_VALUE_YES;
java.util.List<RowFilter<Object, Object>> passwordFilterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> passwordFilterList = new ArrayList<>();
if (btnPassword.isSelected()) { if (btnPassword.isSelected()) {
// yes // yes
passwordFilterList.add(RowFilter.regexFilter("^" + passwordMark, TableTableModel.COLUMN_PASSWORD)); passwordFilterList.add(RowFilter.regexFilter("^" + passwordMark, TablesTableModel.COLUMN_PASSWORD));
} }
if (btnOpen.isSelected()) { if (btnOpen.isSelected()) {
// no // no
passwordFilterList.add(RowFilter.regexFilter("^((?!" + passwordMark + ").)*$", TableTableModel.COLUMN_PASSWORD)); passwordFilterList.add(RowFilter.regexFilter("^((?!" + passwordMark + ").)*$", TablesTableModel.COLUMN_PASSWORD));
} }
// Hide games of ignored players // Hide games of ignored players
@ -698,7 +699,7 @@
ignoreListFilterList.add(new RowFilter<Object, Object>() { ignoreListFilterList.add(new RowFilter<Object, Object>() {
@Override @Override
public boolean include(Entry<? extends Object, ? extends Object> entry) { public boolean include(Entry<? extends Object, ? extends Object> entry) {
final String owner = entry.getStringValue(TableTableModel.COLUMN_OWNER); final String owner = entry.getStringValue(TablesTableModel.COLUMN_OWNER);
return !ignoreListCopy.contains(owner); return !ignoreListCopy.contains(owner);
} }
}); });
@ -707,7 +708,7 @@
if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty() if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty()
|| skillFilterList.isEmpty() || ratingFilterList.isEmpty() || skillFilterList.isEmpty() || ratingFilterList.isEmpty()
|| passwordFilterList.isEmpty()) { // no selection || passwordFilterList.isEmpty()) { // no selection
activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TableTableModel.COLUMN_SKILL)); activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TablesTableModel.COLUMN_SKILL));
} else { } else {
java.util.List<RowFilter<Object, Object>> filterList = new ArrayList<>(); java.util.List<RowFilter<Object, Object>> filterList = new ArrayList<>();
@ -1257,6 +1258,7 @@
options.setSkillLevel(SkillLevel.CASUAL); options.setSkillLevel(SkillLevel.CASUAL);
options.setRollbackTurnsAllowed(true); options.setRollbackTurnsAllowed(true);
options.setQuitRatio(100); options.setQuitRatio(100);
options.setMinimumRating(0);
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); options.setBannedUsers(IgnoreList.ignoreList(serverAddress));
table = SessionHandler.createTable(roomId, options); table = SessionHandler.createTable(roomId, options);
@ -1355,176 +1357,6 @@
} }
class TableTableModel extends AbstractTableModel {
final ImageIcon tourneyIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/tourney_icon.png"));
final ImageIcon matchIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/match_icon.png"));
public static final int COLUMN_ICON = 0;
public static final int COLUMN_DECK_TYPE = 1; // column the deck type is located (starting with 0) Start string is used to check for Limited
public static final int COLUMN_OWNER = 2;
public static final int COLUMN_GAME_TYPE = 3;
public static final int COLUMN_INFO = 4;
public static final int COLUMN_STATUS = 5;
public static final int COLUMN_PASSWORD = 6;
public static final int COLUMN_CREATED = 7;
public static final int COLUMN_SKILL = 8;
public static final int COLUMN_RATING = 9;
public static final int COLUMN_QUIT_RATIO = 10;
public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0)
public static final String RATED_VALUE_YES = "YES";
public static final String RATED_VALUE_NO = "";
public static final String PASSWORD_VALUE_YES = "YES";
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"};
private TableView[] tables = new TableView[0];
TableTableModel() {
}
public void loadData(Collection<TableView> tables) throws MageRemoteException {
this.tables = tables.toArray(new TableView[0]);
this.fireTableDataChanged();
}
public String getSkillLevelAsCode(SkillLevel skill, boolean asRegExp) {
String res;
switch (skill) {
case BEGINNER:
res = "*";
break;
case CASUAL:
res = "**";
break;
case SERIOUS:
res = "***";
break;
default:
res = "";
break;
}
// regexp format for search table rows
if (asRegExp) {
res = String.format("^%s$", res.replace("*", "\\*"));
}
return res;
}
@Override
public int getRowCount() {
return tables.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return tables[arg0].isTournament() ? tourneyIcon : matchIcon;
case 1:
return tables[arg0].getDeckType();
case 2:
return tables[arg0].getControllerName();
case 3:
return tables[arg0].getGameType();
case 4:
return tables[arg0].getAdditionalInfo();
case 5:
return tables[arg0].getTableStateText();
case 6:
return tables[arg0].isPassworded() ? PASSWORD_VALUE_YES : "";
case 7:
return tables[arg0].getCreateTime(); // use cell render, not format here
case 8:
return this.getSkillLevelAsCode(tables[arg0].getSkillLevel(), false);
case 9:
return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO;
case 10:
return tables[arg0].getQuitRatio();
case 11:
switch (tables[arg0].getTableState()) {
case WAITING:
String owner = tables[arg0].getControllerName();
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
return "";
}
return "Join";
case CONSTRUCTING:
case DRAFTING:
if (tables[arg0].isTournament()) {
return "Show";
}
case DUELING:
if (tables[arg0].isTournament()) {
return "Show";
} else {
owner = tables[arg0].getControllerName();
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
return "";
}
if (tables[arg0].getSpectatorsAllowed()) {
return "Watch";
}
return "";
}
default:
return "";
}
case 12:
return tables[arg0].isTournament();
case 13:
if (!tables[arg0].getGames().isEmpty()) {
return tables[arg0].getGames().get(0);
}
return null;
case 14:
return tables[arg0].getTableId();
}
return "";
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_ICON:
return Icon.class;
case COLUMN_SKILL:
return SkillLevel.class;
case COLUMN_CREATED:
return Date.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == ACTION_COLUMN;
}
}
class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> { class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
private final UUID roomId; private final UUID roomId;
@ -1613,119 +1445,6 @@
} }
class MatchesTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Rating", "Result", "Duration", "Start Time", "End Time", "Action"};
public static final int COLUMN_DURATION = 5;
public static final int COLUMN_START = 6;
public static final int COLUMN_END = 7;
public static final int COLUMN_ACTION = 8; // column the action is located (starting with 0)
private MatchView[] matches = new MatchView[0];
public void loadData(Collection<MatchView> matches) throws MageRemoteException {
this.matches = matches.toArray(new MatchView[0]);
this.fireTableDataChanged();
}
MatchesTableModel() {
}
@Override
public int getRowCount() {
return matches.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return matches[arg0].getDeckType();
case 1:
return matches[arg0].getPlayers();
case 2:
return matches[arg0].getGameType();
case 3:
return matches[arg0].isRated() ? TableTableModel.RATED_VALUE_YES : TableTableModel.RATED_VALUE_NO;
case 4:
return matches[arg0].getResult();
case 5:
if (matches[arg0].getEndTime() != null) {
return matches[arg0].getEndTime().getTime() - matches[arg0].getStartTime().getTime() + new Date().getTime();
} else {
return 0L;
}
case 6:
return matches[arg0].getStartTime();
case 7:
return matches[arg0].getEndTime();
case 8:
if (matches[arg0].isTournament()) {
return "Show";
} else if (matches[arg0].isReplayAvailable()) {
return "Replay";
} else {
return "None";
}
case 9:
return matches[arg0].getGames();
}
return "";
}
public java.util.List<UUID> getListofGames(int row) {
return matches[row].getGames();
}
public boolean isTournament(int row) {
return matches[row].isTournament();
}
public UUID getMatchId(int row) {
return matches[row].getMatchId();
}
public UUID getTableId(int row) {
return matches[row].getTableId();
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_DURATION:
return Long.class;
case COLUMN_START:
return Date.class;
case COLUMN_END:
return Date.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == COLUMN_ACTION;
}
}
class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> { class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
private final UUID roomId; private final UUID roomId;

View file

@ -0,0 +1,206 @@
package mage.client.table;
import mage.client.SessionHandler;
import mage.constants.SkillLevel;
import mage.remote.MageRemoteException;
import mage.view.TableView;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.util.Collection;
import java.util.Date;
public class TablesTableModel extends AbstractTableModel {
final ImageIcon tourneyIcon = new ImageIcon(getClass().getResource("/tables/tourney_icon.png"));
final ImageIcon matchIcon = new ImageIcon(getClass().getResource("/tables/match_icon.png"));
public static final int COLUMN_ICON = 0;
public static final int COLUMN_DECK_TYPE = 1; // column the deck type is located (starting with 0) Start string is used to check for Limited
public static final int COLUMN_OWNER = 2;
public static final int COLUMN_GAME_TYPE = 3;
public static final int COLUMN_INFO = 4;
public static final int COLUMN_STATUS = 5;
public static final int COLUMN_PASSWORD = 6;
public static final int COLUMN_CREATED = 7;
public static final int COLUMN_SKILL = 8;
public static final int COLUMN_RATING = 9;
public static final int COLUMN_QUIT_RATIO = 10;
public static final int COLUMN_MINIMUM_RATING = 11;
public static final int ACTION_COLUMN = 12; // column the action is located (starting with 0)
public static final String RATED_VALUE_YES = "YES";
public static final String RATED_VALUE_NO = "";
public static final String PASSWORD_VALUE_YES = "YES";
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rated", "Quit %", "Min Rating", "Action"};
private TableView[] tables = new TableView[0];
TablesTableModel() {
}
public void loadData(Collection<TableView> tables) throws MageRemoteException {
this.tables = tables.toArray(new TableView[0]);
this.fireTableDataChanged();
}
public String getTableAndGameInfo(int row) {
return this.tables[row].getTableId().toString() + ";" + (!tables[row].getGames().isEmpty() ? tables[row].getGames().get(0).toString() : "null");
}
public String findTableAndGameInfoByRow(int row) {
if (row >= 0 && row < this.tables.length) {
return getTableAndGameInfo(row);
} else {
return null;
}
}
public int findRowByTableAndGameInfo(String tableAndGame) {
for (int i = 0; i < this.tables.length; i++) {
String rowID = this.tables[i].getTableId().toString() + ";" + (!this.tables[i].getGames().isEmpty() ? this.tables[i].getGames().get(0).toString() : "null");
if (tableAndGame.equals(rowID)) {
return i;
}
}
return -1;
}
public String getSkillLevelAsCode(SkillLevel skill, boolean asRegExp) {
String res;
switch (skill) {
case BEGINNER:
res = "*";
break;
case CASUAL:
res = "**";
break;
case SERIOUS:
res = "***";
break;
default:
res = "";
break;
}
// regexp format for search table rows
if (asRegExp) {
res = String.format("^%s$", res.replace("*", "\\*"));
}
return res;
}
@Override
public int getRowCount() {
return tables.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return tables[arg0].isTournament() ? tourneyIcon : matchIcon;
case 1:
return tables[arg0].getDeckType();
case 2:
return tables[arg0].getControllerName();
case 3:
return tables[arg0].getGameType();
case 4:
return tables[arg0].getAdditionalInfo();
case 5:
return tables[arg0].getTableStateText();
case 6:
return tables[arg0].isPassworded() ? PASSWORD_VALUE_YES : "";
case 7:
return tables[arg0].getCreateTime(); // use cell render, not format here
case 8:
return this.getSkillLevelAsCode(tables[arg0].getSkillLevel(), false);
case 9:
return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO;
case 10:
return tables[arg0].getQuitRatio();
case 11:
return tables[arg0].getMinimumRating();
case 12:
switch (tables[arg0].getTableState()) {
case WAITING:
String owner = tables[arg0].getControllerName();
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
return "";
}
return "Join";
case CONSTRUCTING:
case DRAFTING:
if (tables[arg0].isTournament()) {
return "Show";
}
case DUELING:
if (tables[arg0].isTournament()) {
return "Show";
} else {
owner = tables[arg0].getControllerName();
if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
return "";
}
if (tables[arg0].getSpectatorsAllowed()) {
return "Watch";
}
return "";
}
default:
return "";
}
case 13:
return tables[arg0].isTournament();
case 14:
if (!tables[arg0].getGames().isEmpty()) {
return tables[arg0].getGames().get(0);
}
return null;
case 15:
return tables[arg0].getTableId();
}
return "";
}
@Override
public String getColumnName(int columnIndex) {
String colName = "";
if (columnIndex <= getColumnCount()) {
colName = columnNames[columnIndex];
}
return colName;
}
@Override
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case COLUMN_ICON:
return Icon.class;
case COLUMN_SKILL:
return SkillLevel.class;
case COLUMN_CREATED:
return Date.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == ACTION_COLUMN;
}
}

View file

@ -0,0 +1,40 @@
package mage.client.table;
import org.apache.log4j.Logger;
import javax.swing.*;
/**
* @author JayDi85
*/
public class TablesUtil {
private static final Logger logger = Logger.getLogger(TablesUtil.class);
public static String getSearchIdFromTable(JTable table, int row) {
// tableUUID;gameUUID
String searchId = null;
if (table.getModel() instanceof TablesTableModel) {
searchId = ((TablesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else if (table.getModel() instanceof MatchesTableModel) {
searchId = ((MatchesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else {
logger.error("Not supported tables model " + table.getModel().getClass().toString());
}
return searchId;
}
public static int findTableRowFromSearchId(Object tableModel, String searchId) {
// tableUUID;gameUUID
int row = -1;
if (tableModel instanceof TablesTableModel) {
row = ((TablesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else if (tableModel instanceof MatchesTableModel) {
row = ((MatchesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else {
logger.error("Not supported tables model " + tableModel.getClass().toString());
}
return row;
}
}

View file

@ -1,15 +1,21 @@
/*
* TournamentPanel.java
*
* Created on 20-Jan-2011, 9:18:30 PM
*/
package mage.client.tournament; package mage.client.tournament;
import java.awt.Component; import mage.client.MageFrame;
import java.awt.Dimension; import mage.client.SessionHandler;
import java.awt.Rectangle; import mage.client.chat.ChatPanelBasic;
import mage.client.dialog.PreferencesDialog;
import mage.client.table.TablesButtonColumn;
import mage.client.util.Format;
import mage.client.util.GUISizeHelper;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.constants.PlayerAction;
import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -19,34 +25,10 @@ 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 java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.swing.AbstractAction;
import javax.swing.Action; import static mage.client.dialog.PreferencesDialog.*;
import javax.swing.Icon;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
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.Format;
import mage.client.util.GUISizeHelper;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.constants.PlayerAction;
import mage.view.RoundView;
import mage.view.TournamentGameView;
import mage.view.TournamentPlayerView;
import mage.view.TournamentView;
import mage.view.UserRequestMessage;
import org.apache.log4j.Logger;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TournamentPanel extends javax.swing.JPanel { public class TournamentPanel extends javax.swing.JPanel {
@ -64,7 +46,7 @@ public class TournamentPanel extends javax.swing.JPanel {
private UpdateTournamentTask updateTask; private UpdateTournamentTask updateTask;
private final DateFormat df; private final DateFormat df;
private final ButtonColumn actionButtonColumn1; private final TablesButtonColumn actionButtonColumn1;
/** /**
* Creates new form TournamentPanel * Creates new form TournamentPanel
@ -111,7 +93,7 @@ public class TournamentPanel extends javax.swing.JPanel {
}; };
// action button, don't delete this // action button, don't delete this
actionButtonColumn1 = new ButtonColumn(tableMatches, action, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN)); actionButtonColumn1 = new TablesButtonColumn(tableMatches, action, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN));
setGUISize(); setGUISize();
} }

View file

@ -0,0 +1,68 @@
package mage.client.util;
import java.util.ArrayList;
/**
* @author JayDi85
*/
public enum CardLanguage {
ENGLISH("en", "English"),
SPANISH("es", "Spanish"),
FRENCH("fr", "French"),
GERMAN("de", "German"),
ITALIAN("it", "Italian"),
PORTUGUESE("pt", "Portuguese"),
JAPANESE("jp", "Japanese"),
KOREAN("ko", "Korean"),
RUSSIAN("ru", "Russian"),
CHINES_SIMPLE("cns", "Chinese Simplified"),
CHINES_TRADITION("cnt", "Chinese Traditional");
private final String code;
private final String text;
CardLanguage(String code, String text) {
this.code = code;
this.text = text;
}
@Override
public String toString() {
return code;
}
public String getCode() {
return code;
}
public String getText() {
return text;
}
public static String[] toList() {
ArrayList<String> res = new ArrayList<>();
for (CardLanguage l : values()) {
res.add(l.toString());
}
return res.toArray(new String[0]);
}
public static CardLanguage valueByText(String text) {
for (CardLanguage type : values()) {
if (type.text.equals(text)) {
return type;
}
}
return CardLanguage.ENGLISH;
}
public static CardLanguage valueByCode(String code) {
for (CardLanguage type : values()) {
if (type.code.equals(code)) {
return type;
}
}
return CardLanguage.ENGLISH;
}
}

View file

@ -57,7 +57,7 @@ public class AudioManager {
try { try {
linePool = new LinePool(); linePool = new LinePool();
} catch (Exception e) { } catch (Exception e) {
log.warn("Failed to initialize AudioManager. No sounds will be played.", e); log.warn("Failed to initialize AudioManager (can't find compatible sound device). No sounds will be played.");
} }
} }

View file

@ -19,12 +19,16 @@ public class FastSearchUtil {
public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion"; public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion";
public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion"; public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion";
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage){
showFastSearchForStringComboBox(combo, chooseMessage, 300, 500);
}
/** /**
* Show fast choice modal dialog with incremental searching for any string combobox components * Show fast choice modal dialog with incremental searching for any string combobox components
* @param combo combobox control with default data model * @param combo combobox control with default data model
* @param chooseMessage caption message for dialog * @param chooseMessage caption message for dialog
*/ */
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage){ public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage, int windowWidth, int windowHeight){
// fast search/choice dialog for string combobox // fast search/choice dialog for string combobox
mage.choices.Choice choice = new ChoiceImpl(false); mage.choices.Choice choice = new ChoiceImpl(false);
@ -51,7 +55,7 @@ public class FastSearchUtil {
// ask for new value // ask for new value
PickChoiceDialog dlg = new PickChoiceDialog(); PickChoiceDialog dlg = new PickChoiceDialog();
dlg.setWindowSize(300, 500); dlg.setWindowSize(windowWidth, windowHeight);
dlg.showDialog(choice, needSelectValue); dlg.showDialog(choice, needSelectValue);
if(choice.isChosen()){ if(choice.isChosen()){
item = choice.getChoiceKey(); item = choice.getChoiceKey();

View file

@ -1,10 +1,11 @@
package org.mage.plugins.card.dl.sources; package org.mage.plugins.card.dl.sources;
import java.util.ArrayList; import mage.client.util.CardLanguage;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import java.util.ArrayList;
/** /**
*
* @author North * @author North
*/ */
public interface CardImageSource { public interface CardImageSource {
@ -31,10 +32,21 @@ public interface CardImageSource {
return false; return false;
} }
default boolean isLanguagesSupport() {
return false;
}
default void setCurrentLanguage(CardLanguage cardLanguage) {
}
default CardLanguage getCurrentLanguage() {
return CardLanguage.ENGLISH;
}
void doPause(String httpImageUrl); void doPause(String httpImageUrl);
default ArrayList<String> getSupportedSets() { default ArrayList<String> getSupportedSets() {
return null; return new ArrayList<>();
} }
default boolean isSetSupportedComplete(String setCode) { default boolean isSetSupportedComplete(String setCode) {

View file

@ -1,439 +0,0 @@
package org.mage.plugins.card.dl.sources;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import mage.client.dialog.PreferencesDialog;
import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.utils.CardImageUtils;
/**
* @author North
*/
public enum MagicCardsImageSource implements CardImageSource {
instance;
private static final Set<String> supportedSets = new LinkedHashSet<String>() {
{
// add("PTC"); // Prerelease Events
add("LEA");
add("LEB");
add("2ED");
add("ARN");
add("ATQ");
add("3ED");
add("LEG");
add("DRK");
add("FEM");
add("4ED");
add("ICE");
add("CHR");
add("HML");
add("ALL");
add("MIR");
add("VIS");
add("5ED");
add("POR");
add("WTH");
add("TMP");
add("STH");
add("EXO");
add("P02");
add("UGL");
add("USG");
add("DD3DVD");
add("DD3EVG");
add("DD3GVL");
add("DD3JVC");
add("ULG");
add("6ED");
add("UDS");
add("PTK");
add("S99");
add("MMQ");
// add("BRB");Battle Royale Box Set
add("NEM");
add("S00");
add("PCY");
add("INV");
// add("BTD"); // Beatdown Boxset
add("PLS");
add("7ED");
add("APC");
add("ODY");
// add("DKM"); // Deckmasters 2001
add("TOR");
add("JUD");
add("ONS");
add("LGN");
add("SCG");
add("8ED");
add("MRD");
add("DST");
add("5DN");
add("CHK");
add("UNH");
add("BOK");
add("SOK");
add("9ED");
add("RAV");
add("GPT");
add("DIS");
add("CSP");
add("TSP");
add("TSB");
add("PLC");
add("FUT");
add("10E");
add("MED");
add("LRW");
add("EVG");
add("MOR");
add("SHM");
add("EVE");
add("DRB");
add("ME2");
add("ALA");
add("DD2");
add("CON");
add("DDC");
add("ARB");
add("M10");
// add("TD0"); // Magic Online Deck Series
add("V09");
add("HOP");
add("ME3");
add("ZEN");
add("DDD");
add("H09");
add("WWK");
add("DDE");
add("ROE");
add("DPA");
add("ARC");
add("M11");
add("V10");
add("DDF");
add("SOM");
// add("TD0"); // Commander Theme Decks
add("PD2");
add("ME4");
add("MBS");
add("DDG");
add("NPH");
add("CMD");
add("M12");
add("V11");
add("DDH");
add("ISD");
add("PD3");
add("DKA");
add("DDI");
add("AVR");
add("PC2");
add("M13");
add("V12");
add("DDJ");
add("RTR");
add("CM1");
// add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia
add("GTC");
add("DDK");
add("DGM");
add("MMA");
add("M14");
add("V13");
add("DDL");
add("THS");
add("C13");
add("BNG");
add("DDM");
add("JOU");
// add("MD1"); // Modern Event Deck
add("CNS");
add("VMA");
add("M15");
add("V14");
add("DDN");
add("KTK");
add("C14");
// add("DD3"); // Duel Decks Anthology
add("FRF");
add("DDO");
add("DTK");
add("TPR");
add("MM2");
add("ORI");
add("V15");
add("DDP");
add("BFZ");
add("EXP");
add("C15");
// add("PZ1"); // Legendary Cube
add("OGW");
add("DDQ");
add("W16");
add("SOI");
add("EMA");
add("EMN");
add("V16");
add("CN2");
add("DDR");
add("KLD");
add("MPS");
// add("PZ2"); // Treasure Chests
add("C16");
add("PCA");
add("AER");
add("MM3");
add("DDS");
add("W17");
add("AKH");
add("MPS");
add("CMA");
add("E01");
add("HOU");
add("C17");
add("XLN");
add("DDT");
add("DDU");
add("IMA");
add("E02");
add("V17");
add("UST");
add("RIX");
add("A25");
add("DOM");
// add("CM2");
// add("M19");
}
};
private static final Map<String, String> setNameTokenReplacement = new HashMap<String, String>() {
{
put("10E", "tenth-edition");
put("AER", "aether-revolt");
put("AKH", "amonkhet");
put("ALA", "shards-of-alara");
put("ANB", "archenemy-nicol-bolas");
put("APAC", "asia-pacific-land-program");
put("APC", "player-rewards-2001");
put("ARB", "alara-reborn");
put("ARC", "archenemy");
put("ARENA", "arena-league");
put("AVR", "avacyn-restored");
put("BFZ", "battle-for-zendikar");
put("BNG", "born-of-the-gods");
put("C13", "commander-2013-edition");
put("C14", "commander-2014");
put("C15", "commander-2015");
put("C16", "commander-2016");
put("CLASH", "clash-pack");
put("CMA", "commander-anthology");
put("CMA", "commanders-arsenal");
put("CMD", "commander");
put("CN2", "conspiracy-take-the-crown");
put("CNS", "conspiracy");
put("CON", "conflux");
put("CP", "champs");
put("CSP", "coldsnap");
put("DD2", "duel-decks-jace-vs-chandra");
put("DD3DVD", "duel-decks-anthology-divine-vs-demonic");
put("DD3EVG", "duel-decks-anthology-elves-vs-goblins");
put("DD3GVL", "duel-decks-anthology-garruk-vs-liliana");
put("DD3JVC", "duel-decks-anthology-jace-vs-chandra");
put("DDC", "duel-decks-divine-vs-demonic");
put("DDD", "duel-decks-garruk-vs-liliana");
put("DDE", "duel-decks-phyrexia-vs-the-coalition");
put("DDF", "duel-decks-elspeth-vs-tezzeret");
put("DDG", "duel-decks-knights-vs-dragons");
put("DDH", "duel-decks-ajani-vs-nicol-bolas");
put("DDI", "duel-decks-venser-vs-koth");
put("DDJ", "duel-decks-izzet-vs-golgari");
put("DDK", "duel-decks-sorin-vs-tibalt");
put("DDL", "duel-decks-heroes-vs-monsters");
put("DDM", "duel-decks-jace-vs-vraska");
put("DDN", "duel-decks-speed-vs-cunning");
put("DDO", "duel-decks-elspeth-vs-kiora");
put("DDP", "duel-decks-zendikar-vs-eldrazi");
put("DDQ", "duel-decks-blessed-vs-cursed");
put("DDR", "duel-decks-nissa-vs-ob-nixilis");
put("DDS", "duel-decks-mind-vs-might");
put("DDT", "duel-decks-merfolk-vs-goblin");
put("DDU", "duel-decks-elves-vs-inventors");
put("DGM", "dragons-maze");
put("DKA", "dark-ascension");
put("DRB", "from-the-vault-dragons");
put("DTK", "dragons-of-tarkir");
put("EMA", "eternal-masters");
put("EMN", "eldritch-moon");
put("EURO", "european-land-program");
put("EVE", "eventide");
put("EVG", "duel-decks-elves-vs-goblins");
put("EXP", "zendikar-expeditions");
put("FNMP", "friday-night-magic");
put("FRF", "fate-reforged");
put("GPX", "grand-prix");
put("GRC", "wpngateway");
put("GTC", "gatecrash");
put("HOP", "planechase");
put("HOU", "hour-of-devastation");
put("INV", "player-rewards-2001");
put("ISD", "innistrad");
put("JOU", "journey-into-nyx");
put("JR", "judge-gift-program");
put("KLD", "kaladesh");
put("KTK", "khans-of-tarkir");
put("LRW", "lorwyn");
put("M10", "magic-2010");
put("M11", "magic-2011");
put("M12", "magic-2012");
put("M13", "magic-2013");
put("M14", "magic-2014");
put("M15", "magic-2015");
put("MBP", "media-inserts");
put("MBS", "mirrodin-besieged");
put("MGDC", "magic-game-day-cards");
put("MLP", "launch-party");
put("MM2", "modern-masters-2015");
put("MM3", "modern-masters-2017");
put("MMA", "modern-masters");
put("MOR", "morningtide");
put("MPRP", "magic-player-rewards");
put("MPS", "masterpiece-series");
put("NPH", "new-phyrexia");
put("ODY", "player-rewards-2002");
put("OGW", "oath-of-the-gatewatch");
put("ORG", "oath-of-the-gatewatch");
put("ORI", "magic-origins");
put("PC2", "planechase-2012-edition");
put("PO2", "portal-second-age");
put("PLS", "player-rewards-2001");
put("POR", "portal");
put("PTC", "prerelease-events");
put("PTK", "portal-three-kingdoms");
put("ROE", "rise-of-the-eldrazi");
put("RTR", "return-to-ravnica");
put("SHM", "shadowmoor");
put("SOI", "shadows-over-innistrad");
put("SOM", "scars-of-mirrodin");
put("SUS", "super-series");
put("THS", "theros");
put("TPR", "tempest-remastered");
put("UGIN", "ugins-fate");
put("V09", "from-the-vault-exiled");
put("V10", "from-the-vault-relics");
put("V11", "from-the-vault-legends");
put("V12", "from-the-vault-realms");
put("V13", "from-the-vault-twenty");
put("V14", "from-the-vault-annihilation");
put("V15", "from-the-vault-angels");
put("V16", "from-the-vault-lore");
put("VMA", "vintage-masters");
put("W16", "welcome-deck-2016");
put("W17", "welcome-deck-2017");
put("WMCQ", "world-magic-cup-qualifier");
put("WWK", "worldwake");
put("ZEN", "zendikar");
}
private static final long serialVersionUID = 1L;
};
@Override
public String getSourceName() {
return "magiccards.info";
}
@Override
public String getNextHttpImageUrl() {
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
return null;
}
@Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
}
String set = CardImageUtils.updateSet(cardSet, true);
String preferedLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
StringBuilder url = new StringBuilder("http://magiccards.info/scans/").append(preferedLanguage).append('/');
url.append(set.toLowerCase(Locale.ENGLISH)).append('/').append(collectorId);
if (card.isTwoFacedCard()) {
url.append(card.isSecondSide() ? "b" : "a");
}
if (card.isSplitCard()) {
url.append('a');
}
if (card.isFlipCard()) {
if (card.isFlippedSide()) { // download rotated by 180 degree image
url.append('b');
} else {
url.append('a');
}
}
url.append(".jpg");
return new CardImageUrls(url.toString());
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) {
String name = card.getName();
// add type to name if it's not 0
if (card.getType() > 0) {
name = name + ' ' + card.getType();
}
name = name.replaceAll(" ", "-").replace(",", "").toLowerCase(Locale.ENGLISH);
String set = "not-supported-set";
if (setNameTokenReplacement.containsKey(card.getSet())) {
set = setNameTokenReplacement.get(card.getSet());
} else {
set += '-' + card.getSet();
}
return new CardImageUrls("http://magiccards.info/extras/token/" + set + '/' + name + ".jpg");
}
@Override
public float getAverageSize() {
return 70.0f;
}
@Override
public int getTotalImages() {
return -1;
}
@Override
public boolean isTokenSource() {
return true;
}
@Override
public ArrayList<String> getSupportedSets() {
ArrayList<String> supportedSetsCopy = new ArrayList<>();
supportedSetsCopy.addAll(supportedSets);
return supportedSetsCopy;
}
@Override
public void doPause(String httpImageUrl) {
}
}

View file

@ -1,6 +1,6 @@
package org.mage.plugins.card.dl.sources; package org.mage.plugins.card.dl.sources;
import mage.client.dialog.PreferencesDialog; import mage.client.util.CardLanguage;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import java.util.*; import java.util.*;
@ -13,21 +13,23 @@ public enum ScryfallImageSource implements CardImageSource {
instance; instance;
private final Set<String> supportedSets; private final Set<String> supportedSets;
private final Map<String, String> languageAliases; private final Map<CardLanguage, String> languageAliases;
private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language
ScryfallImageSource() { ScryfallImageSource() {
// https://scryfall.com/docs/api/languages // https://scryfall.com/docs/api/languages
languageAliases = new HashMap<>(); languageAliases = new HashMap<>();
languageAliases.put("en", "en"); languageAliases.put(CardLanguage.ENGLISH, "en");
languageAliases.put("es", "es"); languageAliases.put(CardLanguage.SPANISH, "es");
languageAliases.put("jp", "ja"); languageAliases.put(CardLanguage.FRENCH, "fr");
languageAliases.put("it", "it"); languageAliases.put(CardLanguage.GERMAN, "de");
languageAliases.put("fr", "fr"); languageAliases.put(CardLanguage.ITALIAN, "it");
languageAliases.put("cn", "zhs"); // Simplified Chinese languageAliases.put(CardLanguage.PORTUGUESE, "pt");
languageAliases.put("de", "de"); languageAliases.put(CardLanguage.JAPANESE, "ja");
languageAliases.put("ko", "ko"); languageAliases.put(CardLanguage.KOREAN, "ko");
languageAliases.put("pt", "pt"); languageAliases.put(CardLanguage.RUSSIAN, "ru");
languageAliases.put("ru", "ru"); languageAliases.put(CardLanguage.CHINES_SIMPLE, "zhs");
languageAliases.put(CardLanguage.CHINES_TRADITION, "zht");
supportedSets = new LinkedHashSet<>(); supportedSets = new LinkedHashSet<>();
// supportedSets.add("PTC"); // // supportedSets.add("PTC"); //
@ -234,6 +236,7 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("GNT"); supportedSets.add("GNT");
supportedSets.add("UMA"); supportedSets.add("UMA");
supportedSets.add("PUMA"); supportedSets.add("PUMA");
supportedSets.add("RNA");
// //
supportedSets.add("EURO"); supportedSets.add("EURO");
supportedSets.add("GPX"); supportedSets.add("GPX");
@ -245,9 +248,9 @@ public enum ScryfallImageSource implements CardImageSource {
@Override @Override
public CardImageUrls generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); String preferredCode = this.getCurrentLanguage().getCode();
String defaultCode = "en"; String defaultCode = CardLanguage.ENGLISH.getCode();
String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode); String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode);
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image // loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
// WARNING, some cards haven't direct images and uses random GUID: // WARNING, some cards haven't direct images and uses random GUID:
@ -345,6 +348,21 @@ public enum ScryfallImageSource implements CardImageSource {
return false; return false;
} }
@Override
public boolean isLanguagesSupport() {
return true;
}
@Override
public void setCurrentLanguage(CardLanguage cardLanguage) {
this.currentLanguage = cardLanguage;
}
@Override
public CardLanguage getCurrentLanguage() {
return currentLanguage;
}
@Override @Override
public void doPause(String httpImageUrl) { public void doPause(String httpImageUrl) {
@ -368,6 +386,7 @@ public enum ScryfallImageSource implements CardImageSource {
put("WMCQ", "pwcq"); put("WMCQ", "pwcq");
put("EURO", "pelp"); put("EURO", "pelp");
put("GPX", "pgpx"); put("GPX", "pgpx");
put("MED", "me1");
} }
}; };

View file

@ -20,7 +20,7 @@ import java.util.logging.Level;
import mage.constants.SubType; import mage.constants.SubType;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.DownloadPictures; import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
/** /**
@ -182,7 +182,7 @@ public enum TokensMtgImageSource implements CardImageSource {
private HashMap<String, ArrayList<TokenData>> getTokensData() throws IOException { private HashMap<String, ArrayList<TokenData>> getTokensData() throws IOException {
synchronized (tokensDataSync) { synchronized (tokensDataSync) {
if (tokensData == null) { if (tokensData == null) {
DownloadPictures.getInstance().updateAndViewMessage("Creating token data..."); DownloadPicturesService.getInstance().updateAndViewMessage("Find tokens data...");
tokensData = new HashMap<>(); tokensData = new HashMap<>();
// get tokens data from resource file // get tokens data from resource file
@ -233,10 +233,10 @@ public enum TokensMtgImageSource implements CardImageSource {
} }
} }
} }
DownloadPictures.getInstance().updateAndViewMessage(""); DownloadPicturesService.getInstance().updateAndViewMessage("");
} catch (Exception ex) { } catch (Exception ex) {
logger.warn("Failed to get tokens description from tokens.mtg.onl", ex); logger.warn("Failed to get tokens description from tokens.mtg.onl", ex);
DownloadPictures.getInstance().updateAndViewMessage(ex.getMessage()); DownloadPicturesService.getInstance().updateAndViewMessage(ex.getMessage());
} }
} }
} }

View file

@ -1,22 +1,10 @@
package org.mage.plugins.card.dl.sources; package org.mage.plugins.card.dl.sources;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.client.dialog.PreferencesDialog; import mage.client.util.CardLanguage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
@ -24,6 +12,12 @@ import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/** /**
* @author North * @author North
*/ */
@ -34,9 +28,10 @@ public enum WizardCardsImageSource implements CardImageSource {
private static final Logger logger = Logger.getLogger(WizardCardsImageSource.class); private static final Logger logger = Logger.getLogger(WizardCardsImageSource.class);
private final Map<String, String> setsAliases; private final Map<String, String> setsAliases;
private final Map<String, String> languageAliases; private final Map<CardLanguage, String> languageAliases;
private final Map<String, Map<String, String>> sets; private final Map<String, Map<String, String>> sets;
private final Set<String> supportedSets; private final Set<String> supportedSets;
private CardLanguage currentLanguage = CardLanguage.ENGLISH; // working language
@Override @Override
public String getSourceName() { public String getSourceName() {
@ -44,6 +39,20 @@ public enum WizardCardsImageSource implements CardImageSource {
} }
WizardCardsImageSource() { WizardCardsImageSource() {
languageAliases = new HashMap<>();
languageAliases.put(CardLanguage.ENGLISH, "English");
languageAliases.put(CardLanguage.SPANISH, "Spanish");
languageAliases.put(CardLanguage.FRENCH, "French");
languageAliases.put(CardLanguage.GERMAN, "German");
languageAliases.put(CardLanguage.ITALIAN, "Italian");
languageAliases.put(CardLanguage.PORTUGUESE, "Portuguese (Brazil)");
languageAliases.put(CardLanguage.JAPANESE, "Japanese");
languageAliases.put(CardLanguage.KOREAN, "Korean");
languageAliases.put(CardLanguage.RUSSIAN, "Russian");
languageAliases.put(CardLanguage.CHINES_SIMPLE, "Chinese Simplified");
languageAliases.put(CardLanguage.CHINES_TRADITION, "Chinese Traditional ");
supportedSets = new LinkedHashSet<>(); supportedSets = new LinkedHashSet<>();
// supportedSets.add("PTC"); // Prerelease Events // supportedSets.add("PTC"); // Prerelease Events
supportedSets.add("LEA"); supportedSets.add("LEA");
@ -430,18 +439,6 @@ public enum WizardCardsImageSource implements CardImageSource {
setsAliases.put("WTH", "Weatherlight"); setsAliases.put("WTH", "Weatherlight");
setsAliases.put("WWK", "Worldwake"); setsAliases.put("WWK", "Worldwake");
setsAliases.put("ZEN", "Zendikar"); setsAliases.put("ZEN", "Zendikar");
languageAliases = new HashMap<>();
languageAliases.put("en", "English");
languageAliases.put("es", "Spanish");
languageAliases.put("jp", "Japanese");
languageAliases.put("it", "Italian");
languageAliases.put("fr", "French");
languageAliases.put("cn", "Chinese Simplified");
languageAliases.put("de", "German");
languageAliases.put("ko", "Korean");
languageAliases.put("pt", "Portuguese (Brazil)");
languageAliases.put("ru", "Russian");
} }
@Override @Override
@ -517,7 +514,7 @@ public enum WizardCardsImageSource implements CardImageSource {
if (setNames == null) { if (setNames == null) {
setNames = Sets.getInstance().get(cardSet).getName(); setNames = Sets.getInstance().get(cardSet).getName();
} }
String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
for (String setName : setNames.split("\\^")) { for (String setName : setNames.split("\\^")) {
// String URLSetName = URLEncoder.encode(setName, "UTF-8"); // String URLSetName = URLEncoder.encode(setName, "UTF-8");
String URLSetName = setName.replaceAll(" ", "%20"); String URLSetName = setName.replaceAll(" ", "%20");
@ -555,7 +552,7 @@ public enum WizardCardsImageSource implements CardImageSource {
cardName = cardName.substring(0, pos1); cardName = cardName.substring(0, pos1);
} }
} }
Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId); Integer preferredMultiverseId = getLocalizedMultiverseId(getCurrentLanguage(), multiverseId);
setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferredMultiverseId)); setLinks.put(cardName.toLowerCase(Locale.ENGLISH) + numberChar, generateLink(preferredMultiverseId));
} }
} }
@ -617,8 +614,8 @@ public enum WizardCardsImageSource implements CardImageSource {
return "/Handlers/Image.ashx?multiverseid=" + landMultiverseId + "&type=card"; return "/Handlers/Image.ashx?multiverseid=" + landMultiverseId + "&type=card";
} }
private int getLocalizedMultiverseId(String preferredLanguage, Integer multiverseId) throws IOException { private int getLocalizedMultiverseId(CardLanguage preferredLanguage, Integer multiverseId) throws IOException {
if (preferredLanguage.equals("en")) { if (preferredLanguage.equals(CardLanguage.ENGLISH)) {
return multiverseId; return multiverseId;
} }
@ -682,43 +679,6 @@ public enum WizardCardsImageSource implements CardImageSource {
return 60.0f; return 60.0f;
} }
// private final class GetImageLinkTask implements Runnable {
//
// private int multiverseId;
// private String cardName;
// private String preferredLanguage;
// private LinkedHashMap setLinks;
//
// public GetImageLinkTask(int multiverseId, String cardName, String preferredLanguage, LinkedHashMap setLinks) {
// try {
// this.multiverseId = multiverseId;
// this.cardName = cardName;
// this.preferredLanguage = preferredLanguage;
// this.setLinks = setLinks;
// } catch (Exception ex) {
// logger.error(ex.getMessage());
// logger.error("multiverseId: " + multiverseId);
// logger.error("cardName: " + cardName);
// logger.error("preferredLanguage: " + preferredLanguage);
// logger.error("setLinks: " + setLinks.toString());
// }
// }
//
// @Override
// public void run() {
// try {
// if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
// setLinks.putAll(getLandVariations(multiverseId, cardName));
// } else {
// Integer preferredMultiverseId = getLocalizedMultiverseId(preferredLanguage, multiverseId);
// setLinks.put(cardName.toLowerCase(Locale.ENGLISH), generateLink(preferredMultiverseId));
// }
// } catch (IOException | NumberFormatException ex) {
// logger.error("Exception when parsing the wizards page: " + ex.getMessage());
// }
// }
//
// }
@Override @Override
public int getTotalImages() { public int getTotalImages() {
return -1; return -1;
@ -729,6 +689,21 @@ public enum WizardCardsImageSource implements CardImageSource {
return false; return false;
} }
@Override
public boolean isLanguagesSupport() {
return true;
}
@Override
public void setCurrentLanguage(CardLanguage cardLanguage) {
this.currentLanguage = cardLanguage;
}
@Override
public CardLanguage getCurrentLanguage() {
return currentLanguage;
}
@Override @Override
public void doPause(String httpImageUrl) { public void doPause(String httpImageUrl) {
} }

View file

@ -1,28 +1,14 @@
package org.mage.plugins.card.images; package org.mage.plugins.card.images;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.io.*;
import java.net.*;
import java.nio.file.AccessDeniedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.dialog.DownloadImagesDialog;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.util.CardLanguage;
import mage.client.util.sets.ConstructedFormats; import mage.client.util.sets.ConstructedFormats;
import mage.remote.Connection; import mage.remote.Connection;
import mage.util.StreamUtils; import mage.util.StreamUtils;
@ -35,46 +21,49 @@ import org.mage.plugins.card.dl.sources.*;
import org.mage.plugins.card.properties.SettingsManager; import org.mage.plugins.card.properties.SettingsManager;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.io.*;
import java.net.*;
import java.nio.file.AccessDeniedException;
import java.util.List;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable { /**
* @author JayDi85
*/
public class DownloadPicturesService extends DefaultBoundedRangeModel implements Runnable {
// don't forget to remove new sets from ignore.urls to download (propeties file in resources) // don't forget to remove new sets from ignore.urls to download (properties file in resources)
private static DownloadPictures instance; private static DownloadPicturesService instance;
private static final Logger logger = Logger.getLogger(DownloadPicturesService.class);
private static final Logger logger = Logger.getLogger(DownloadPictures.class); public static final String ALL_IMAGES = "- ALL images from selected source (can be slow)";
public static final String ALL_MODERN_IMAGES = "- MODERN images (can be slow)";
public static final String ALL_STANDARD_IMAGES = "- STANDARD images";
public static final String ALL_TOKENS = "- TOKEN images";
public static final String ALL_IMAGES = "- ALL images from selected source (CAN BE VERY SLOW)"; private DownloadImagesDialog uiDialog;
public static final String ALL_STANDARD_IMAGES = "- Only images from STANDARD sets"; private boolean needCancel;
public static final String ALL_TOKENS = "- Only token images from selected source";
private JDialog dialog;
private final JProgressBar bar;
private final JOptionPane dlg;
private boolean cancel;
private final JButton closeButton;
private final JButton startDownloadButton;
private int cardIndex; private int cardIndex;
private List<CardDownloadData> allCardsMissingImage;
private List<CardDownloadData> cardsToDownload;
private int missingCards = 0; private List<CardInfo> cardsAll;
private int missingTokens = 0; private List<CardDownloadData> cardsMissing;
private List<CardDownloadData> cardsDownloadQueue;
private int missingCardsCount = 0;
private int missingTokensCount = 0;
List<String> selectedSetCodes = new ArrayList<>(); List<String> selectedSets = new ArrayList<>();
private static CardImageSource selectedSource;
private final JComboBox jComboBoxServer;
private final JLabel jLabelMessage;
private final JLabel jLabelAllMissing;
private final JLabel jLabelServer;
private final JComboBox jComboBoxSet;
private final JLabel jLabelSet;
private final Object sync = new Object(); private final Object sync = new Object();
private static CardImageSource cardImageSource;
private Proxy p = Proxy.NO_PROXY; private Proxy p = Proxy.NO_PROXY;
enum DownloadSources { enum DownloadSources {
@ -87,7 +76,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance),
COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance); COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance);
// MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet
// MAGICCARDS("magiccards.info", MagicCardsImageSource.instance)
private final String text; private final String text;
private final CardImageSource source; private final CardImageSource source;
@ -108,7 +96,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
public static DownloadPictures getInstance() { public static DownloadPicturesService getInstance() {
return instance; return instance;
} }
@ -117,245 +105,245 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
public static void startDownload() { public static void startDownload() {
// load images info in background task
instance = new DownloadPicturesService(MageFrame.getInstance());
new Thread(new LoadMissingCardDataNew(instance)).start();
/* // show dialog
* if (cards == null || cards.isEmpty()) { instance.setNeedCancel(false);
* JOptionPane.showMessageDialog(null, instance.uiDialog.showDialog();
* "All card pictures have been downloaded."); return; } instance.uiDialog.dispose();
*/ instance.setNeedCancel(true);
instance = new DownloadPictures(MageFrame.getInstance());
Thread t1 = new Thread(new LoadMissingCardData(instance));
t1.start();
instance.getDlg().setVisible(true);
instance.getDlg().dispose();
instance.cancel = true;
} }
public JDialog getDlg() { public boolean getNeedCancel() {
return dialog; return this.needCancel;
} }
public void setCancel(boolean cancel) { public void setNeedCancel(boolean needCancel) {
this.cancel = cancel; this.needCancel = needCancel;
} }
static int WIDTH = 400; public DownloadPicturesService(JFrame frame) {
// init service and dialog
cardsAll = Collections.synchronizedList(new ArrayList<>());
cardsMissing = Collections.synchronizedList(new ArrayList<>());
cardsDownloadQueue = Collections.synchronizedList(new ArrayList<>());
uiDialog = new DownloadImagesDialog();
public DownloadPictures(JFrame frame) { // MESSAGE
uiDialog.setGlobalInfo("Initializing image download...");
cardsToDownload = new ArrayList<>(); // SOURCES - scryfall is default source
uiDialog.getSourcesCombo().setModel(new DefaultComboBoxModel(DownloadSources.values()));
JPanel p0 = new JPanel(); uiDialog.getSourcesCombo().setSelectedItem(DownloadSources.SCRYFALL);
p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); selectedSource = ScryfallImageSource.instance;
uiDialog.getSourcesCombo().addItemListener((ItemEvent event) -> {
p0.add(Box.createVerticalStrut(5));
jLabelMessage = new JLabel();
jLabelMessage.setAlignmentX(Component.CENTER_ALIGNMENT);
jLabelMessage.setText("Initializing image download...");
p0.add(jLabelMessage);
p0.add(Box.createVerticalStrut(5));
jLabelAllMissing = new JLabel();
jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT);
// jLabelAllMissing.setText("Computing number of missing images...");
p0.add(jLabelAllMissing);
p0.add(Box.createVerticalStrut(5));
jLabelServer = new JLabel();
jLabelServer.setText("Please select image source:");
jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT);
jLabelServer.setVisible(false);
p0.add(jLabelServer);
p0.add(Box.createVerticalStrut(5));
jComboBoxServer = new JComboBox();
jComboBoxServer.setModel(new DefaultComboBoxModel(DownloadSources.values()));
jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT);
jComboBoxServer.setAlignmentY(Component.LEFT_ALIGNMENT);
jComboBoxServer.addItemListener((ItemEvent event) -> {
if (event.getStateChange() == ItemEvent.SELECTED) { if (event.getStateChange() == ItemEvent.SELECTED) {
comboBoxServerItemSelected(event); comboboxSourceSelected(event);
} }
}); });
Dimension d = jComboBoxServer.getPreferredSize();
d.width = WIDTH;
jComboBoxServer.setPreferredSize(d);
p0.add(jComboBoxServer);
jComboBoxServer.setVisible(false);
// set the first source as default // LANGUAGES
cardImageSource = WizardCardsImageSource.instance; uiDialog.getLaunguagesCombo().setModel(new DefaultComboBoxModel(CardLanguage.values()));
uiDialog.getLaunguagesCombo().setSelectedItem(PreferencesDialog.getPrefImagesLanguage());
reloadLanguagesForSelectedSource();
p0.add(Box.createVerticalStrut(5)); // REDOWNLOAD
uiDialog.getRedownloadCheckbox().setSelected(false);
uiDialog.getRedownloadCheckbox().addItemListener(this::checkboxRedowloadChanged);
// Set selection ---------------------------------
jLabelSet = new JLabel();
jLabelSet.setText("Please select sets to download the images for:");
jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT);
jLabelSet.setVisible(false);
p0.add(jLabelSet);
jComboBoxSet = new JComboBox(); // SETS (fills after source and language select)
// jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); //uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel(DownloadSources.values()));
jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); uiDialog.getSetsCombo().addItemListener((ItemEvent event) -> {
jComboBoxSet.addItemListener((ItemEvent event) -> {
if (event.getStateChange() == ItemEvent.SELECTED) { if (event.getStateChange() == ItemEvent.SELECTED) {
comboBoxSetItemSelected(event); comboboxSetSelected(event);
} }
}); });
p0.add(jComboBoxSet); // BUTTON START
jComboBoxSet.setVisible(false); uiDialog.getStartButton().addActionListener(e -> {
// selected language setup
p0.add(Box.createVerticalStrut(5)); if (selectedSource != null) {
if (selectedSource.isLanguagesSupport()) {
// Start selectedSource.setCurrentLanguage((CardLanguage) uiDialog.getLaunguagesCombo().getSelectedItem());
startDownloadButton = new JButton("Start download"); }
startDownloadButton.addActionListener(e -> {
new Thread(DownloadPictures.this).start();
startDownloadButton.setEnabled(false);
});
p0.add(Box.createVerticalStrut(5));
// Progress
bar = new JProgressBar(this);
p0.add(bar);
bar.setStringPainted(true);
d = bar.getPreferredSize();
d.width = WIDTH;
bar.setPreferredSize(d);
bar.setVisible(false);
// JOptionPane
Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")};
startDownloadButton.setVisible(false);
closeButton.addActionListener(e -> dialog.setVisible(false));
closeButton.setVisible(false);
dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]);
dialog = this.dlg.createDialog(frame, "Downloading images");
} }
public void setAllMissingCards() { // run
updateAndViewMessage("Get all available cards from the repository..."); uiDialog.enableActionControls(false);
List<CardInfo> cards = CardRepository.instance.findCards(new CardCriteria()); uiDialog.getStartButton().setEnabled(false);
updateAndViewMessage("Check which images are missing ..."); new Thread(DownloadPicturesService.this).start();
this.allCardsMissingImage = getNeededCards(cards); });
updateAndViewMessage("Check which images the current source is providing ...");
jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource()));
updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); // BUTTON CANCEL (dialog and loading)
uiDialog.getCancelButton().addActionListener(e -> uiDialog.setVisible(false));
uiDialog.getStopButton().addActionListener(e -> uiDialog.setVisible(false));
jComboBoxServer.setVisible(true); // PROGRESS BAR
jLabelServer.setVisible(true); uiDialog.getProgressBar().setValue(0);
jComboBoxSet.setVisible(true);
jLabelSet.setVisible(true);
bar.setVisible(true);
startDownloadButton.setVisible(true);
closeButton.setVisible(true);
uiDialog.showDownloadControls(false);
}
public void findMissingCards() {
updateAndViewMessage("Loading...");
this.cardsAll.clear();
this.cardsMissing.clear();
this.cardsDownloadQueue.clear();
updateAndViewMessage("Loading cards list...");
this.cardsAll = Collections.synchronizedList(CardRepository.instance.findCards(new CardCriteria()));
updateAndViewMessage("Finding missing images...");
this.cardsMissing = prepareMissingCards(this.cardsAll, uiDialog.getRedownloadCheckbox().isSelected());
updateAndViewMessage("Finding available sets from selected source...");
this.uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource()));
reloadCardsToDownload(this.uiDialog.getSetsCombo().getSelectedItem().toString());
this.uiDialog.showDownloadControls(true);
updateAndViewMessage(""); updateAndViewMessage("");
} }
private void comboBoxServerItemSelected(ItemEvent evt) { private void reloadLanguagesForSelectedSource() {
if (jComboBoxServer.isEnabled()) { this.uiDialog.showLanguagesSupport(selectedSource != null && selectedSource.isLanguagesSupport());
cardImageSource = ((DownloadSources) evt.getItem()).getSource(); }
// update the available sets / token comboBox
jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); private void reloadSetsForSelectedSource() {
updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); // update the available sets / token combobox
Object oldSelection = this.uiDialog.getSetsCombo().getSelectedItem();
this.uiDialog.getSetsCombo().setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource()));
if (oldSelection != null) {
this.uiDialog.getSetsCombo().setSelectedItem(oldSelection);
}
reloadCardsToDownload(this.uiDialog.getSetsCombo().getSelectedItem().toString());
}
private void comboboxSourceSelected(ItemEvent evt) {
if (this.uiDialog.getSourcesCombo().isEnabled()) {
selectedSource = ((DownloadSources) evt.getItem()).getSource();
reloadSetsForSelectedSource();
reloadLanguagesForSelectedSource();
} }
} }
public void updateAndViewMessage(String text) { public void updateAndViewMessage(String text) {
jLabelMessage.setText(text); this.uiDialog.setGlobalInfo(text);
if (dialog != null) {
dialog.pack(); // auto-size on empty message (on complete)
dialog.validate(); if (text.isEmpty()) {
dialog.repaint(); this.uiDialog.showDownloadControls(true);
} }
} }
private String getSetNameWithYear(ExpansionSet exp) {
Calendar cal = Calendar.getInstance();
cal.setTime(exp.getReleaseDate());
String year = String.valueOf(cal.get(Calendar.YEAR));
return exp.getName() + " (" + exp.getCode() + ", " + year + ")";
/*
if (!exp.getName().contains(year)) {
return exp.getName() + " (" + year + ")";
} else {
return exp.getName();
}
*/
}
private ExpansionSet findSetByNameWithYear(String name) {
return Sets.getInstance().values().stream()
.filter(exp -> getSetNameWithYear(exp).equals(name))
.findFirst()
.orElse(null);
}
private Object[] getSetsForCurrentImageSource() { private Object[] getSetsForCurrentImageSource() {
// Set the available sets to the combo box // Set the available sets to the combo box
ArrayList<String> supportedSets = cardImageSource.getSupportedSets(); ArrayList<String> supportedSets = selectedSource.getSupportedSets();
List<String> setNames = new ArrayList<>(); List<String> setNames = new ArrayList<>();
if (supportedSets != null) {
// multiple sets selection
setNames.add(ALL_IMAGES); setNames.add(ALL_IMAGES);
setNames.add(ALL_MODERN_IMAGES);
setNames.add(ALL_STANDARD_IMAGES); setNames.add(ALL_STANDARD_IMAGES);
} if (selectedSource.isTokenSource()) {
if (cardImageSource.isTokenSource()) {
setNames.add(ALL_TOKENS); setNames.add(ALL_TOKENS);
} }
if (supportedSets != null) {
for (String setCode : supportedSets) {
ExpansionSet expansionSet = Sets.findSet(setCode);
if (expansionSet != null) {
setNames.add(expansionSet.getName());
} else {
logger.warn("Source: " + cardImageSource.getSourceName() + ": Expansion set for code " + setCode + " not found in xmage sets!");
}
}
} // single set selection
Collection<ExpansionSet> dbSets = Sets.getInstance().values();
Collection<String> comboSets = dbSets.stream()
.filter(exp -> supportedSets.contains(exp.getCode()))
.sorted(Comparator.comparing(ExpansionSet::getReleaseDate).reversed())
.map(this::getSetNameWithYear)
.collect(Collectors.toList());
setNames.addAll(comboSets);
if (setNames.isEmpty()) { if (setNames.isEmpty()) {
logger.error("Source " + cardImageSource.getSourceName() + " creates no selectable items."); logger.error("Source " + selectedSource.getSourceName() + " creates no selectable items.");
setNames.add("not avalable"); setNames.add("not available");
} }
return setNames.toArray(new String[0]); return setNames.toArray(new String[0]);
} }
private void updateCardsToDownload(String itemText) { private void reloadCardsToDownload(String selectedItem) {
selectedSetCodes.clear(); // find selected sets
switch (itemText) { selectedSets.clear();
List<String> formatSets;
List<String> sourceSets = selectedSource.getSupportedSets();
switch (selectedItem) {
case ALL_IMAGES: case ALL_IMAGES:
if (cardImageSource.getSupportedSets() == null) { selectedSets.addAll(selectedSource.getSupportedSets());
selectedSetCodes = cardImageSource.getSupportedSets();
} else {
selectedSetCodes.addAll(cardImageSource.getSupportedSets());
}
break; break;
case ALL_STANDARD_IMAGES: case ALL_STANDARD_IMAGES:
List<String> standardSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); formatSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD);
for (String setCode : cardImageSource.getSupportedSets()) { formatSets.stream()
if (standardSets.contains(setCode)) { .filter(sourceSets::contains)
selectedSetCodes.add(setCode); .forEachOrdered(selectedSets::add);
} else {
logger.debug("Set code " + setCode + " from download source " + cardImageSource.getSourceName());
}
}
break; break;
case ALL_MODERN_IMAGES:
formatSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.MODERN);
formatSets.stream()
.filter(sourceSets::contains)
.forEachOrdered(selectedSets::add);
break;
case ALL_TOKENS: case ALL_TOKENS:
break; break;
default: default:
int nonSetEntries = 0; // selects one set
if (cardImageSource.getSupportedSets() != null) { ExpansionSet selectedExp = findSetByNameWithYear(selectedItem);
nonSetEntries = 2; if (selectedExp != null) {
selectedSets.add(selectedExp.getCode());
} }
if (cardImageSource.isTokenSource()) { break;
nonSetEntries++;
} }
selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries));
} // find missing cards to download
cardsToDownload.clear(); cardsDownloadQueue.clear();
int numberTokenImagesAvailable = 0; int numberTokenImagesAvailable = 0;
int numberCardImagesAvailable = 0; int numberCardImagesAvailable = 0;
for (CardDownloadData data : allCardsMissingImage) { for (CardDownloadData data : cardsMissing) {
if (data.isToken()) { if (data.isToken()) {
if (cardImageSource.isTokenSource() && cardImageSource.isImageProvided(data.getSet(), data.getName())) { if (selectedSource.isTokenSource() && selectedSource.isImageProvided(data.getSet(), data.getName())) {
numberTokenImagesAvailable++; numberTokenImagesAvailable++;
cardsToDownload.add(data); cardsDownloadQueue.add(data);
} else { } else {
//logger.warn("Source do not support token (set " + data.getSet() + ", token " + data.getName() + ")"); //logger.warn("Source do not support token (set " + data.getSet() + ", token " + data.getName() + ")");
} }
} else { } else {
if (selectedSetCodes != null && selectedSetCodes.contains(data.getSet())) { if (selectedSets != null && selectedSets.contains(data.getSet())) {
if (cardImageSource.isSetSupportedComplete(data.getSet()) || cardImageSource.isImageProvided(data.getSet(), data.getName())) { if (selectedSource.isSetSupportedComplete(data.getSet()) || selectedSource.isImageProvided(data.getSet(), data.getName())) {
numberCardImagesAvailable++; numberCardImagesAvailable++;
cardsToDownload.add(data); cardsDownloadQueue.add(data);
} }
} }
} }
@ -363,24 +351,40 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
updateProgressText(numberCardImagesAvailable, numberTokenImagesAvailable); updateProgressText(numberCardImagesAvailable, numberTokenImagesAvailable);
} }
private void comboBoxSetItemSelected(ItemEvent event) { private void comboboxSetSelected(ItemEvent event) {
// Update the cards to download related to the selected set // Update the cards to download related to the selected set
updateCardsToDownload(event.getItem().toString()); reloadCardsToDownload(event.getItem().toString());
}
private void checkboxRedowloadChanged(ItemEvent event) {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
this.cardsMissing.clear();
this.cardsMissing = prepareMissingCards(this.cardsAll, uiDialog.getRedownloadCheckbox().isSelected());
reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString());
} finally {
MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
} }
private void updateProgressText(int cardCount, int tokenCount) { private void updateProgressText(int cardCount, int tokenCount) {
missingTokens = 0; missingTokensCount = 0;
for (CardDownloadData card : allCardsMissingImage) { for (CardDownloadData card : cardsMissing) {
if (card.isToken()) { if (card.isToken()) {
missingTokens++; missingTokensCount++;
} }
} }
missingCards = allCardsMissingImage.size() - missingTokens; missingCardsCount = cardsMissing.size() - missingTokensCount;
jLabelAllMissing.setText("Missing: " + missingCards + " card images / " + missingTokens + " token images");
uiDialog.setCurrentInfo("Missing: " + missingCardsCount + " card images / " + missingTokensCount + " token images");
int imageSum = cardCount + tokenCount; int imageSum = cardCount + tokenCount;
float mb = (imageSum * cardImageSource.getAverageSize()) / 1024; float mb = (imageSum * selectedSource.getAverageSize()) / 1024;
bar.setString(String.format(cardIndex == imageSum ? "%d of %d (%d cards/%d tokens) image downloads finished! Please close!" uiDialog.getProgressBar().setString(String.format(
: "%d of %d (%d cards/%d tokens) image downloads finished! Please wait! [%.1f Mb]", 0, imageSum, cardCount, tokenCount, mb)); cardIndex == imageSum
? "%d of %d (%d cards/%d tokens) image downloads finished! Please close!"
: "%d of %d (%d cards/%d tokens) image downloads finished! Please wait! [%.1f Mb]",
0, imageSum, cardCount, tokenCount, mb
));
} }
private static String createDownloadName(CardInfo card) { private static String createDownloadName(CardInfo card) {
@ -388,16 +392,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
return className.substring(className.lastIndexOf('.') + 1); return className.substring(className.lastIndexOf('.') + 1);
} }
private static List<CardDownloadData> getNeededCards(List<CardInfo> allCards) { private static List<CardDownloadData> prepareMissingCards(List<CardInfo> allCards, boolean redownloadMode) {
/**
* read all card names and urls
*/
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
/** // get filter for Standard Type 2 cards
* get filter for Standard Type 2 cards
*/
Set<String> type2SetsFilter = new HashSet<>(); Set<String> type2SetsFilter = new HashSet<>();
List<String> constructedFormats = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); List<String> constructedFormats = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD);
if (constructedFormats != null && !constructedFormats.isEmpty()) { if (constructedFormats != null && !constructedFormats.isEmpty()) {
@ -406,6 +404,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
logger.warn("No formats defined. Try connecting to a server first!"); logger.warn("No formats defined. Try connecting to a server first!");
} }
// prepare checking list
List<CardDownloadData> allCardsUrls = Collections.synchronizedList(new ArrayList<>()); List<CardDownloadData> allCardsUrls = Collections.synchronizedList(new ArrayList<>());
try { try {
allCards.parallelStream().forEach(card -> { allCards.parallelStream().forEach(card -> {
@ -455,32 +454,33 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
logger.info("Card was not selected: " + card.getName()); logger.info("Card was not selected: " + card.getName());
} }
}); });
allCardsUrls.addAll(getTokenCardUrls()); allCardsUrls.addAll(getTokenCardUrls());
} catch (Exception e) { } catch (Exception e) {
logger.error(e); logger.error(e);
} }
/** // find missing files
* check to see which cards we already have
*/
List<CardDownloadData> cardsToDownload = Collections.synchronizedList(new ArrayList<>()); List<CardDownloadData> cardsToDownload = Collections.synchronizedList(new ArrayList<>());
allCardsUrls.parallelStream().forEach(card -> { allCardsUrls.parallelStream().forEach(card -> {
File file = new TFile(CardImageUtils.buildImagePathToCard(card)); if (redownloadMode) {
logger.debug(card.getName() + " (is_token=" + card.isToken() + "). Image is here:" + file.getAbsolutePath() + " (exists=" + file.exists() + ')'); // need all cards
if (!file.exists()) {
logger.debug("Missing: " + file.getAbsolutePath());
// logger.info("Missing image: " + (card.isToken() ? "TOKEN " : "CARD ") + card.getSet() + "/" + card.getName() + " type: " + card.getType());
cardsToDownload.add(card); cardsToDownload.add(card);
} else {
// need missing cards
File file = new TFile(CardImageUtils.buildImagePathToCard(card));
if (!file.exists()) {
cardsToDownload.add(card);
}
} }
}); });
return new ArrayList<>(cardsToDownload); return Collections.synchronizedList(new ArrayList<>(cardsToDownload));
} }
public static ArrayList<CardDownloadData> getTokenCardUrls() throws RuntimeException { public static ArrayList<CardDownloadData> getTokenCardUrls() throws RuntimeException {
ArrayList<CardDownloadData> list = new ArrayList<>(); ArrayList<CardDownloadData> list = new ArrayList<>();
InputStream in = DownloadPictures.class InputStream in = DownloadPicturesService.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt");
.getClassLoader().getResourceAsStream("card-pictures-tok.txt");
if (in == null) { if (in == null) {
logger.error("resources input stream is null"); logger.error("resources input stream is null");
@ -545,7 +545,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} catch (Exception ex) { } catch (Exception ex) {
logger.error(ex); logger.error(ex);
throw new RuntimeException("DownloadPictures : readFile() error"); throw new RuntimeException("DownloadPicturesService : readFile() error");
} }
return list; return list;
} }
@ -581,62 +581,62 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80")); Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80"));
p = new Proxy(type, new InetSocketAddress(address, port)); p = new Proxy(type, new InetSocketAddress(address, port));
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex); throw new RuntimeException("Gui_DownloadPicturesService : error 1 - " + ex);
} }
} }
if (p != null) { if (p != null) {
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
update(0, cardsToDownload.size()); update(0, cardsDownloadQueue.size());
logger.info("Started download of " + cardsToDownload.size() + " images from source: " + cardImageSource.getSourceName()); logger.info("Started download of " + cardsDownloadQueue.size() + " images"
+ " from source: " + selectedSource.getSourceName()
+ ", language: " + selectedSource.getCurrentLanguage().getCode());
int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10"));
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
for (int i = 0; i < cardsToDownload.size() && !cancel; i++) { for (int i = 0; i < cardsDownloadQueue.size() && !this.getNeedCancel(); i++) {
try { try {
CardDownloadData card = cardsDownloadQueue.get(i);
CardDownloadData card = cardsToDownload.get(i);
logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')'); logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')');
CardImageUrls urls; CardImageUrls urls;
if (ignoreUrls.contains(card.getSet()) || card.isToken()) { if (ignoreUrls.contains(card.getSet()) || card.isToken()) {
if (!"0".equals(card.getCollectorId())) { if (!"0".equals(card.getCollectorId())) {
continue; continue;
} }
urls = cardImageSource.generateTokenUrl(card); urls = selectedSource.generateTokenUrl(card);
} else { } else {
urls = cardImageSource.generateURL(card); urls = selectedSource.generateURL(card);
} }
if (urls == null) { if (urls == null) {
String imageRef = cardImageSource.getNextHttpImageUrl(); String imageRef = selectedSource.getNextHttpImageUrl();
String fileName = cardImageSource.getFileForHttpImage(imageRef); String fileName = selectedSource.getFileForHttpImage(imageRef);
if (imageRef != null && fileName != null) { if (imageRef != null && fileName != null) {
imageRef = cardImageSource.getSourceName() + imageRef; imageRef = selectedSource.getSourceName() + imageRef;
try { try {
card.setToken(cardImageSource.isTokenSource()); card.setToken(selectedSource.isTokenSource());
Runnable task = new DownloadTask(card, imageRef, fileName, cardImageSource.getTotalImages()); Runnable task = new DownloadTask(card, imageRef, fileName, selectedSource.getTotalImages());
executor.execute(task); executor.execute(task);
} catch (Exception ex) { } catch (Exception ex) {
} }
} else if (cardImageSource.getTotalImages() == -1) { } else if (selectedSource.getTotalImages() == -1) {
logger.info("Image not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); logger.info("Image not available on " + selectedSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')');
synchronized (sync) { synchronized (sync) {
update(cardIndex + 1, cardsToDownload.size()); update(cardIndex + 1, cardsDownloadQueue.size());
} }
} }
} else { } else {
Runnable task = new DownloadTask(card, urls, cardsToDownload.size()); Runnable task = new DownloadTask(card, urls, cardsDownloadQueue.size());
executor.execute(task); executor.execute(task);
} }
} catch (Exception ex) { } catch (Exception ex) {
logger.error(ex, ex); logger.error(ex, ex);
} }
} }
executor.shutdown(); executor.shutdown();
while (!executor.isTerminated()) { while (!executor.isTerminated()) {
try { try {
@ -645,6 +645,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
} }
} }
try { try {
TVFS.umount(); TVFS.umount();
} catch (FsSyncException e) { } catch (FsSyncException e) {
@ -653,11 +654,15 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} finally { } finally {
// //
} }
closeButton.setText("Close");
updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); // stop
reloadCardsToDownload(uiDialog.getSetsCombo().getSelectedItem().toString());
// reset images cache
ImageCache.clearCache();
} }
static String convertStreamToString(java.io.InputStream is) { static String convertStreamToString(InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : ""; return s.hasNext() ? s.next() : "";
} }
@ -670,10 +675,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
private final String actualFilename; private final String actualFilename;
private final boolean useSpecifiedPaths; private final boolean useSpecifiedPaths;
DownloadTask(CardDownloadData card, String baseUrl, int count) {
this(card, new CardImageUrls(baseUrl, null), count);
}
DownloadTask(CardDownloadData card, CardImageUrls urls, int count) { DownloadTask(CardDownloadData card, CardImageUrls urls, int count) {
this.card = card; this.card = card;
this.urls = urls; this.urls = urls;
@ -692,7 +693,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
@Override @Override
public void run() { public void run() {
if (cancel) { if (DownloadPicturesService.getInstance().getNeedCancel()) {
synchronized (sync) { synchronized (sync) {
update(cardIndex + 1, count); update(cardIndex + 1, count);
} }
@ -736,20 +737,23 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
// FILE already exists (in zip or in dir) // FILE already exists (in zip or in dir)
// don't use, images can be re-downloaded
/*
if (destFile.exists()) { if (destFile.exists()) {
synchronized (sync) { synchronized (sync) {
update(cardIndex + 1, count); update(cardIndex + 1, count);
} }
return; return;
} }
*/
// zip can't be read // check zip access
TFile testArchive = destFile.getTopLevelArchive(); TFile testArchive = destFile.getTopLevelArchive();
if (testArchive != null && testArchive.exists()) { if (testArchive != null && testArchive.exists()) {
try { try {
testArchive.list(); testArchive.list();
} catch (Exception e) { } catch (Exception e) {
logger.error("Error reading archive, may be it was corrapted. Try to delete it: " + testArchive.toString()); logger.error("Error reading archive, it's can be corrupted. Try to delete it: " + testArchive.toString());
synchronized (sync) { synchronized (sync) {
update(cardIndex + 1, count); update(cardIndex + 1, count);
@ -773,12 +777,12 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
URL url = new URL(currentUrl); URL url = new URL(currentUrl);
// on download cancel need to stop // on download cancel need to stop
if (cancel) { if (DownloadPicturesService.getInstance().getNeedCancel()) {
return; return;
} }
// download // download
cardImageSource.doPause(url.getPath()); selectedSource.doPause(url.getPath());
httpConn = url.openConnection(p); httpConn = url.openConnection(p);
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"); httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
httpConn.connect(); httpConn.connect();
@ -819,7 +823,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
int len; int len;
while ((len = in.read(buf)) != -1) { while ((len = in.read(buf)) != -1) {
// user cancelled // user cancelled
if (cancel) { if (DownloadPicturesService.getInstance().getNeedCancel()) {
// stop download, save current state and exit // stop download, save current state and exit
TFile archive = destFile.getTopLevelArchive(); TFile archive = destFile.getTopLevelArchive();
///* not need to unmout/close - it's auto action ///* not need to unmout/close - it's auto action
@ -881,34 +885,38 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
} }
private void update(int card, int count) { private void update(int lastCardIndex, int needDownloadCount) {
this.cardIndex = card; this.cardIndex = lastCardIndex;
if (cardIndex < count) { if (cardIndex < needDownloadCount) {
float mb = ((count - card) * cardImageSource.getAverageSize()) / 1024; // downloading
bar.setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", float mb = ((needDownloadCount - lastCardIndex) * selectedSource.getAverageSize()) / 1024;
card, count, mb)); uiDialog.getProgressBar().setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]",
lastCardIndex, needDownloadCount, mb));
} else { } else {
List<CardDownloadData> remainingCards = Collections.synchronizedList(new ArrayList<>()); // finished
DownloadPictures.this.allCardsMissingImage.parallelStream().forEach(cardDownloadData -> { List<CardDownloadData> downloadedCards = Collections.synchronizedList(new ArrayList<>());
DownloadPicturesService.this.cardsMissing.parallelStream().forEach(cardDownloadData -> {
TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData)); TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData));
if (!file.exists()) { if (file.exists()) {
remainingCards.add(cardDownloadData); downloadedCards.add(cardDownloadData);
} }
}); });
// remove the cards not downloaded to get the siccessfull downloaded cards // remove all downloaded cards, missing must be remains
DownloadPictures.this.cardsToDownload.removeAll(remainingCards); this.cardsDownloadQueue.removeAll(downloadedCards);
DownloadPictures.this.allCardsMissingImage.removeAll(DownloadPictures.this.cardsToDownload); this.cardsMissing.removeAll(downloadedCards);
count = remainingCards.size(); if (this.cardsDownloadQueue.size() == 0) {
// stop download
if (count == 0) { uiDialog.getProgressBar().setString("0 images remaining. Please close.");
bar.setString("0 images remaining! Please close!");
} else { } else {
// bar.setString(String.format("%d cards remaining! Please choose another source!", count)); // try download again
startDownloadButton.setEnabled(true);
} }
this.uiDialog.getRedownloadCheckbox().setSelected(false);
uiDialog.enableActionControls(true);
uiDialog.getStartButton().setEnabled(true);
} }
} }
@ -916,22 +924,21 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
class LoadMissingCardData implements Runnable { class LoadMissingCardDataNew implements Runnable {
private static DownloadPictures downloadPictures; private static DownloadPicturesService downloadPicturesService;
public LoadMissingCardData(DownloadPictures downloadPictures) { public LoadMissingCardDataNew(DownloadPicturesService downloadPicturesService) {
LoadMissingCardData.downloadPictures = downloadPictures; this.downloadPicturesService = downloadPicturesService;
} }
@Override @Override
public void run() { public void run() {
downloadPictures.setAllMissingCards(); downloadPicturesService.findMissingCards();
} }
public static void main() { public static void main() {
(new Thread(new LoadMissingCardDataNew(downloadPicturesService))).start();
(new Thread(new LoadMissingCardData(downloadPictures))).start();
} }
} }

View file

@ -3,15 +3,6 @@ package org.mage.plugins.card.images;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ComputationException; import com.google.common.collect.ComputationException;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import mage.client.constants.Constants; import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.util.TransformedImageCache; import mage.client.util.TransformedImageCache;
@ -23,13 +14,23 @@ import org.apache.log4j.Logger;
import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* This class stores ALL card images in a cache with soft values. this means * This class stores ALL card images in a cache with soft values. this means
* that the images may be garbage collected when they are not needed any more, * that the images may be garbage collected when they are not needed any more,
* but will be kept as long as possible. * but will be kept as long as possible.
* * <p>
* Key format: "[cardname]#[setname]#[type]#[collectorID]#[param]" * Key format: "[cardname]#[setname]#[type]#[collectorID]#[param]"
* * <p>
* where param is: * where param is:
* <ul> * <ul>
* <li>size of image</li> * <li>size of image</li>
@ -228,6 +229,10 @@ public final class ImageCache {
}); });
} }
public static void clearCache() {
IMAGE_CACHE.clear();
}
public static String getFilePath(CardView card, int width) { public static String getFilePath(CardView card, int width) {
String key = getKey(card, card.getName(), Integer.toString(width)); String key = getKey(card, card.getName(), Integer.toString(width));
boolean usesVariousArt = false; boolean usesVariousArt = false;
@ -472,6 +477,7 @@ public final class ImageCache {
// return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#" // return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#"
// + (card.getTokenSetCode() == null ? "":card.getTokenSetCode()); // + (card.getTokenSetCode() == null ? "":card.getTokenSetCode());
// } // }
/** /**
* Load image from file * Load image from file
* *

View file

@ -1,3 +0,0 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
SplashScreen-Image: splash.jpg

View file

@ -187,6 +187,7 @@
|Generate|TOK:ALL|Graveborn|||SekKuarDeathkeeperGravebornToken| |Generate|TOK:ALL|Graveborn|||SekKuarDeathkeeperGravebornToken|
|Generate|TOK:ALL|Hippo|||HippoToken| |Generate|TOK:ALL|Hippo|||HippoToken|
|Generate|TOK:ALL|Soldier|||SoldierToken| |Generate|TOK:ALL|Soldier|||SoldierToken|
|Generate|TOK:ALL|Starfish|||StarfishToken|
|Generate|TOK:ALL|Zombie|||ZombieToken| |Generate|TOK:ALL|Zombie|||ZombieToken|
|Generate|TOK:APC|Angel|||HauntedAngelToken| |Generate|TOK:APC|Angel|||HauntedAngelToken|
|Generate|TOK:APC|Cat|||PenumbraBobcatToken| |Generate|TOK:APC|Cat|||PenumbraBobcatToken|

View file

@ -1,8 +1,5 @@
package mage.client.game; package mage.client.game;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import mage.client.components.MageUI; import mage.client.components.MageUI;
import mage.interfaces.MageClient; import mage.interfaces.MageClient;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
@ -13,6 +10,10 @@ import mage.utils.MageVersion;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.junit.Ignore; import org.junit.Ignore;
import javax.swing.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/** /**
* Test for emulating the connection from multi mage clients. * Test for emulating the connection from multi mage clients.
* *
@ -30,7 +31,7 @@ public class MultiConnectTest {
private static final CountDownLatch latch = new CountDownLatch(USER_CONNECT_COUNT); private static final CountDownLatch latch = new CountDownLatch(USER_CONNECT_COUNT);
private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); private static final MageVersion version = new MageVersion(MultiConnectTest.class);
private static volatile int connected; private static volatile int connected;

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-common</artifactId> <artifactId>mage-common</artifactId>

View file

@ -1,15 +1,5 @@
package mage.remote; package mage.remote;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import mage.MageException; import mage.MageException;
import mage.cards.decks.DeckCardLists; import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
@ -38,6 +28,12 @@ import org.jboss.remoting.transport.bisocket.Bisocket;
import org.jboss.remoting.transport.socket.SocketWrapper; import org.jboss.remoting.transport.socket.SocketWrapper;
import org.jboss.remoting.transporter.TransporterClient; import org.jboss.remoting.transporter.TransporterClient;
import java.io.*;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -94,37 +90,38 @@ public class SessionImpl implements Session {
return remoting.run(); return remoting.run();
} catch (MalformedURLException ex) { } catch (MalformedURLException ex) {
logger.fatal("", ex); logger.fatal("", ex);
client.showMessage("Unable to connect to server. " + ex.getMessage()); client.showMessage("Unable connect to server. " + ex.getMessage());
} catch (UndeclaredThrowableException ex) { } catch (UndeclaredThrowableException ex) {
String addMessage = ""; String addMessage = "";
Throwable cause = ex.getCause(); Throwable cause = ex.getCause();
if (cause instanceof InvocationFailureException) { if (cause instanceof InvocationFailureException) {
InvocationFailureException exep = (InvocationFailureException) cause; InvocationFailureException exep = (InvocationFailureException) cause;
if (exep.getCause() instanceof IOException) { if (exep.getCause() instanceof IOException) {
if (exep.getCause().getMessage().startsWith("Field hash null is not available on current")) { if (exep.getCause().getMessage().startsWith("Field hash null is not available on current")
addMessage = "Probabaly the server version is not compatible to the client. "; || exep.getCause().getMessage().endsWith("end of file")) {
addMessage = "Probably the server version is not compatible with the client. ";
} }
} }
} else if (cause instanceof NoSuchMethodException) { } else if (cause instanceof NoSuchMethodException) {
// NoSuchMethodException is thrown on an invocation of an unknow JBoss remoting // NoSuchMethodException is thrown on an invocation of an unknow JBoss remoting
// method, so it's likely to be because of a version incompatibility. // method, so it's likely to be because of a version incompatibility.
addMessage = "The following method is not available in the server, probably the " addMessage = "The following method is not available in the server, probably the "
+ "server version is not compatible to the client: " + cause.getMessage(); + "server version is not compatible with the client: " + cause.getMessage();
} }
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 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 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 connect to server. " + ex.getMessage());
} }
disconnect(false); disconnect(false);
} catch (CannotConnectException ex) { } catch (CannotConnectException ex) {
@ -132,11 +129,11 @@ public class SessionImpl implements Session {
handleCannotConnectException(ex); handleCannotConnectException(ex);
} }
} catch (Throwable t) { } catch (Throwable t) {
logger.fatal("Unable to connect to server - ", t); logger.fatal("Unable connect to server - ", t);
if (!canceled) { if (!canceled) {
disconnect(false); disconnect(false);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Unable to connect to server.\n"); sb.append("Unable 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');
} }
@ -442,7 +439,7 @@ public class SessionImpl implements Session {
t = t.getCause(); t = t.getCause();
} }
client.showMessage("Unable to connect to server. " + message); client.showMessage("Unable connect to server. " + message);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("StackTrace", t); logger.trace("StackTrace", t);
} }

View file

@ -1,9 +1,10 @@
package mage.utils; package mage.utils;
import mage.util.JarVersion;
import java.io.Serializable; import java.io.Serializable;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class MageVersion implements Serializable, Comparable<MageVersion> { public class MageVersion implements Serializable, Comparable<MageVersion> {
@ -13,23 +14,31 @@ 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 = 31; public final static int MAGE_VERSION_PATCH = 32;
public final static String MAGE_VERSION_MINOR_PATCH = "V4"; public final static String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0
public final static String MAGE_VERSION_INFO = ""; public final static String MAGE_VERSION_MINOR_PATCH = "V0";
private final int major; private final int major;
private final int minor; private final int minor;
private final int patch; private final int patch;
private final String minorPatch; // doesn't matter for compatibility private final String minorPatch; // doesn't matter for compatibility
private final String buildTime;
private String editionInfo;
private final boolean showBuildTime = true;
private String info = ""; public MageVersion(Class sourceClass) {
this(MAGE_VERSION_MAJOR, MAGE_VERSION_MINOR, MAGE_VERSION_PATCH, MAGE_VERSION_MINOR_PATCH, MAGE_EDITION_INFO, sourceClass);
}
public MageVersion(int major, int minor, int patch, String minorPatch, String info) { public MageVersion(int major, int minor, int patch, String minorPatch, String editionInfo, Class sourceClass) {
this.major = major; this.major = major;
this.minor = minor; this.minor = minor;
this.patch = patch; this.patch = patch;
this.minorPatch = minorPatch; this.minorPatch = minorPatch;
this.info = info; this.editionInfo = editionInfo;
// build time
this.buildTime = showBuildTime ? JarVersion.getBuildTime(sourceClass) : "";
} }
public int getMajor() { public int getMajor() {
@ -50,7 +59,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
@Override @Override
public String toString() { public String toString() {
return major + "." + minor + '.' + patch + info + minorPatch; // 1.4.32-betaV0 (build: time)
return major + "." + minor + '.' + patch + editionInfo + minorPatch + (!this.buildTime.isEmpty() ? " (build: " + this.buildTime + ")" : "");
} }
@Override @Override
@ -64,7 +74,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
if (patch != o.patch) { if (patch != o.patch) {
return patch - o.patch; return patch - o.patch;
} }
return info.compareTo(o.info); return editionInfo.compareTo(o.editionInfo);
} }
} }

View file

@ -13,21 +13,12 @@ public class DraftClientMessage implements Serializable {
private DraftView draftView; private DraftView draftView;
private DraftPickView draftPickView; private DraftPickView draftPickView;
private String message;
public DraftClientMessage(DraftView draftView) { public DraftClientMessage(DraftView draftView, DraftPickView draftPickView) {
this.draftView = draftView; this.draftView = draftView;
}
public DraftClientMessage(DraftPickView draftPickView) {
this.draftPickView = draftPickView; this.draftPickView = draftPickView;
} }
public DraftClientMessage(DraftView draftView, String message) {
this.message = message;
this.draftView = draftView;
}
public DraftPickView getDraftPickView() { public DraftPickView getDraftPickView() {
return draftPickView; return draftPickView;
} }

View file

@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.game.draft.Draft; import mage.game.draft.Draft;
import mage.game.draft.DraftCube;
import mage.game.draft.DraftPlayer; import mage.game.draft.DraftPlayer;
/** /**
@ -17,6 +18,7 @@ public class DraftView implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final List<String> sets = new ArrayList<>(); private final List<String> sets = new ArrayList<>();
private final List<String> setCodes = new ArrayList<>();
private final int boosterNum; private final int boosterNum;
private final int cardNum; private final int cardNum;
private final List<String> players = new ArrayList<>(); private final List<String> players = new ArrayList<>();
@ -24,11 +26,14 @@ public class DraftView implements Serializable {
public DraftView(Draft draft) { public DraftView(Draft draft) {
if (draft.getDraftCube() != null) { if (draft.getDraftCube() != null) {
for (int i = 0; i < draft.getNumberBoosters(); i++) { for (int i = 0; i < draft.getNumberBoosters(); i++) {
sets.add(draft.getDraftCube().getName()); DraftCube cube = draft.getDraftCube();
sets.add(cube.getName());
setCodes.add(cube.getCode());
} }
} else { } else {
for (ExpansionSet set: draft.getSets()) { for (ExpansionSet set: draft.getSets()) {
sets.add(set.getName()); sets.add(set.getName());
setCodes.add(set.getCode());
} }
} }
this.boosterNum = draft.getBoosterNum(); this.boosterNum = draft.getBoosterNum();
@ -42,6 +47,10 @@ public class DraftView implements Serializable {
return sets; return sets;
} }
public List<String> getSetCodes() {
return setCodes;
}
public List<String> getPlayers() { public List<String> getPlayers() {
return players; return players;
} }

View file

@ -36,6 +36,7 @@ public class TableView implements Serializable {
private List<SeatView> seats = new ArrayList<>(); private List<SeatView> seats = new ArrayList<>();
private List<UUID> games = new ArrayList<>(); private List<UUID> games = new ArrayList<>();
private final String quitRatio; private final String quitRatio;
private final String minimumRating;
private final boolean limited; private final boolean limited;
private final boolean rated; private final boolean rated;
private final boolean passworded; private final boolean passworded;
@ -111,6 +112,7 @@ public class TableView implements Serializable {
this.additionalInfo = addInfo.toString(); this.additionalInfo = addInfo.toString();
this.skillLevel = table.getMatch().getOptions().getSkillLevel(); this.skillLevel = table.getMatch().getOptions().getSkillLevel();
this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio()); this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio());
this.minimumRating = Integer.toString(table.getMatch().getOptions().getMinimumRating());
this.limited = table.getMatch().getOptions().isLimited(); this.limited = table.getMatch().getOptions().isLimited();
this.rated = table.getMatch().getOptions().isRated(); this.rated = table.getMatch().getOptions().isRated();
this.passworded = !table.getMatch().getOptions().getPassword().isEmpty(); this.passworded = !table.getMatch().getOptions().getPassword().isEmpty();
@ -159,6 +161,7 @@ public class TableView implements Serializable {
this.deckType = table.getDeckType() + ' ' + table.getTournament().getBoosterInfo() + (tableNameInfo != null ? tableNameInfo : ""); this.deckType = table.getDeckType() + ' ' + table.getTournament().getBoosterInfo() + (tableNameInfo != null ? tableNameInfo : "");
this.skillLevel = table.getTournament().getOptions().getMatchOptions().getSkillLevel(); this.skillLevel = table.getTournament().getOptions().getMatchOptions().getSkillLevel();
this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio()); this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio());
this.minimumRating = Integer.toString(table.getTournament().getOptions().getMinimumRating());
this.limited = table.getTournament().getOptions().getMatchOptions().isLimited(); this.limited = table.getTournament().getOptions().getMatchOptions().isLimited();
this.rated = table.getTournament().getOptions().getMatchOptions().isRated(); this.rated = table.getTournament().getOptions().getMatchOptions().isRated();
this.passworded = !table.getTournament().getOptions().getPassword().isEmpty(); this.passworded = !table.getTournament().getOptions().getPassword().isEmpty();
@ -223,9 +226,9 @@ public class TableView implements Serializable {
return skillLevel; return skillLevel;
} }
public String getQuitRatio() { public String getQuitRatio() { return quitRatio; }
return quitRatio;
} public String getMinimumRating() { return minimumRating; }
public boolean isLimited() { public boolean isLimited() {
return limited; return limited;

View file

@ -43,7 +43,7 @@ public class TournamentGameView implements Serializable {
String duelingTime = ""; String duelingTime = "";
if (game.hasEnded()) { if (game.hasEnded()) {
if (game.getEndTime() != null) { if (game.getEndTime() != null && game.getStartTime() != null) {
duelingTime = " (" + DateFormat.getDuration((game.getEndTime().getTime() - game.getStartTime().getTime())/1000) + ')'; duelingTime = " (" + DateFormat.getDuration((game.getEndTime().getTime() - game.getStartTime().getTime())/1000) + ')';
} }
this.state = "Finished" + duelingTime; this.state = "Finished" + duelingTime;

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-counter-plugin</artifactId> <artifactId>mage-counter-plugin</artifactId>

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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
@ -53,7 +53,6 @@
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<configuration> <configuration>
<archive> <archive>
<manifestFile>${manifest.file}</manifestFile>
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
<mainClass>mage.server.console.ConsoleFrame</mainClass> <mainClass>mage.server.console.ConsoleFrame</mainClass>

View file

@ -1,11 +1,3 @@
/*
* ConsoleFrame.java
*
* Created on May 13, 2011, 2:39:10 PM
*/
package mage.server.console; package mage.server.console;
import mage.interfaces.MageClient; import mage.interfaces.MageClient;
@ -25,7 +17,6 @@ import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class ConsoleFrame extends javax.swing.JFrame implements MageClient { public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
@ -35,9 +26,10 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
private static Session session; private static Session session;
private ConnectDialog connectDialog; private ConnectDialog connectDialog;
private static final Preferences prefs = Preferences.userNodeForPackage(ConsoleFrame.class); private static final Preferences prefs = Preferences.userNodeForPackage(ConsoleFrame.class);
private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); private static final MageVersion version = new MageVersion(ConsoleFrame.class);
private static final ScheduledExecutorService pingTaskExecutor = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService pingTaskExecutor = Executors.newSingleThreadScheduledExecutor();
/** /**
* @return the session * @return the session
*/ */
@ -54,7 +46,9 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
return version; return version;
} }
/** Creates new form ConsoleFrame */ /**
* Creates new form ConsoleFrame
*/
public ConsoleFrame() { public ConsoleFrame() {
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@ -100,7 +94,8 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
btnSendMessage.setEnabled(false); btnSendMessage.setEnabled(false);
} }
/** This method is called from within the constructor to /**
* This method is called from within the constructor to
* initialize the form. * 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 regenerated by the Form Editor. * always regenerated by the Form Editor.
@ -206,8 +201,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
setStatusText(message); setStatusText(message);
enableButtons(); enableButtons();
} } else {
else {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
setStatusText(message); setStatusText(message);
enableButtons(); enableButtons();
@ -221,8 +215,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
consolePanel1.stop(); consolePanel1.stop();
setStatusText("Not connected"); setStatusText("Not connected");
disableButtons(); disableButtons();
} } else {
else {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
consolePanel1.stop(); consolePanel1.stop();
setStatusText("Not connected"); setStatusText("Not connected");
@ -235,8 +228,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
public void showMessage(final String message) { public void showMessage(final String message) {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
JOptionPane.showMessageDialog(this, message); JOptionPane.showMessageDialog(this, message);
} } else {
else {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getFrame(), message)); SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getFrame(), message));
} }
} }
@ -245,8 +237,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
public void showError(final String message) { public void showError(final String message) {
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
} } else {
else {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE)); SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getFrame(), message, "Error", JOptionPane.ERROR_MESSAGE));
} }
} }

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-deck-constructed</artifactId> <artifactId>mage-deck-constructed</artifactId>

View file

@ -4,7 +4,6 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.SetType;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -82,7 +81,7 @@ public class AusHighlander extends Constructed {
public AusHighlander() { public AusHighlander() {
this("Australian Highlander"); this("Australian Highlander");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -4,7 +4,6 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.SetType;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -64,7 +63,7 @@ public class CanadianHighlander extends Constructed {
public CanadianHighlander() { public CanadianHighlander() {
this("Canadian Highlander"); this("Canadian Highlander");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -1,6 +1,5 @@
package mage.deck; package mage.deck;
import java.util.*;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.CanBeYourCommanderAbility;
@ -12,11 +11,11 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.SetType;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import java.util.*;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public class Commander extends Constructed { public class Commander extends Constructed {
@ -27,7 +26,7 @@ public class Commander extends Constructed {
public Commander() { public Commander() {
this("Commander"); this("Commander");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -4,7 +4,6 @@ package mage.deck;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.constants.SetType;
/** /**
* This class implements the new casual format "Eternal", which is legacy with * This class implements the new casual format "Eternal", which is legacy with
@ -18,7 +17,7 @@ public class Eternal extends Constructed {
public Eternal() { public Eternal() {
super("Constructed - Eternal"); super("Constructed - Eternal");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -14,7 +14,7 @@ public class Legacy extends Constructed {
public Legacy() { public Legacy() {
super("Constructed - Legacy"); super("Constructed - Legacy");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -9,10 +9,8 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.SetType;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class Pauper extends Constructed { public class Pauper extends Constructed {
@ -22,7 +20,7 @@ public class Pauper extends Constructed {
//TODO: Add only Magic Online sets for pauper //TODO: Add only Magic Online sets for pauper
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -1,8 +1,6 @@
package mage.deck; package mage.deck;
import java.util.*;
import java.util.Map.Entry;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.keyword.PartnerAbility; import mage.abilities.keyword.PartnerAbility;
@ -12,11 +10,12 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.SetType;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import java.util.*;
import java.util.Map.Entry;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public class PennyDreadfulCommander extends Constructed { public class PennyDreadfulCommander extends Constructed {
@ -28,7 +27,7 @@ public class PennyDreadfulCommander extends Constructed {
public PennyDreadfulCommander() { public PennyDreadfulCommander() {
this("Penny Dreadful Commander"); this("Penny Dreadful Commander");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

View file

@ -1,10 +1,6 @@
package mage.deck; package mage.deck;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.CanBeYourCommanderAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
@ -12,12 +8,15 @@ import mage.cards.Sets;
import mage.cards.SplitCard; import mage.cards.SplitCard;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.SetType;
import mage.filter.FilterMana; import mage.filter.FilterMana;
import mage.game.GameTinyLeadersImpl; import mage.game.GameTinyLeadersImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
*
* @author JRHerlehy * @author JRHerlehy
*/ */
public class TinyLeaders extends Constructed { public class TinyLeaders extends Constructed {
@ -27,7 +26,7 @@ public class TinyLeaders extends Constructed {
public TinyLeaders() { public TinyLeaders() {
this("Tiny Leaders"); this("Tiny Leaders");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }
@ -85,7 +84,6 @@ public class TinyLeaders extends Constructed {
} }
/** /**
*
* @param deck * @param deck
* @return - True if deck is valid * @return - True if deck is valid
*/ */
@ -212,7 +210,6 @@ public class TinyLeaders extends Constructed {
} }
/** /**
*
* @param commander FilterMana object with Color Identity of Commander set * @param commander FilterMana object with Color Identity of Commander set
* @param card Card to validate * @param card Card to validate
* @return True if card has a valid color identity * @return True if card has a valid color identity

View file

@ -4,10 +4,8 @@ package mage.deck;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.decks.Constructed; import mage.cards.decks.Constructed;
import mage.constants.SetType;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class Vintage extends Constructed { public class Vintage extends Constructed {
@ -15,7 +13,7 @@ public class Vintage extends Constructed {
public Vintage() { public Vintage() {
super("Constructed - Vintage"); super("Constructed - Vintage");
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
if (set.getSetType() != SetType.CUSTOM_SET) { if (set.isEternalLegal()) {
setCodes.add(set.getCode()); setCodes.add(set.getCode());
} }
} }

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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-brawlduel</artifactId> <artifactId>mage-game-brawlduel</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-brawlfreeforall</artifactId> <artifactId>mage-game-brawlfreeforall</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId> <artifactId>mage-game-canadianhighlanderduel</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-freeforall</artifactId> <artifactId>mage-game-freeforall</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId> <artifactId>mage-game-freeformcommanderfreeforall</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-momirduel</artifactId> <artifactId>mage-game-momirduel</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-momirfreeforall</artifactId> <artifactId>mage-game-momirfreeforall</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId> <artifactId>mage-game-pennydreadfulcommanderfreeforall</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-player-ai-ma</artifactId> <artifactId>mage-player-ai-ma</artifactId>

View file

@ -111,9 +111,8 @@ public class ComputerPlayer7 extends ComputerPlayer6 {
Game sim = createSimulation(game); Game sim = createSimulation(game);
SimulationNode2.resetCount(); SimulationNode2.resetCount();
root = new SimulationNode2(null, sim, maxDepth, playerId); root = new SimulationNode2(null, sim, maxDepth, playerId);
addActionsTimed(); addActionsTimed(); // TODO: root can be null again after addActionsTimed O_o need to research (it's a CPU AI problem?)
if (root.children != null if (root != null && root.children != null && !root.children.isEmpty()) {
&& !root.children.isEmpty()) {
logger.trace("After add actions timed: root.children.size = " + root.children.size()); logger.trace("After add actions timed: root.children.size = " + root.children.size());
root = root.children.get(0); root = root.children.get(0);
// prevent repeating always the same action with no cost // prevent repeating always the same action with no cost

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-player-ai</artifactId> <artifactId>mage-player-ai</artifactId>

View file

@ -0,0 +1,254 @@
Bitterblossom:1000
Mana Vault:986
Liliana of the Veil:974
Karn Liberated:964
Mikaeus, the Unhallowed:954
Sublime Archangel:945
Sigarda, Host of Herons:937
Noble Hierarch:929
Shriekmaw:922
Snapcaster Mage:915
Glen Elendra Archmage:908
Balefire Dragon:902
Vengevine:896
Demonic Tutor:891
Maelstrom Pulse:885
Celestial Colonnade:880
Tasigur, the Golden Fang:875
Reveillark:870
Lord of Extinction:865
Eternal Witness:861
Tarmogoyf:856
Woodfall Primus:852
Eldrazi Conscription:848
Kitchen Finks:843
Temporal Manipulation:839
Fiend Hunter:836
Dig Through Time:832
Talrand, Sky Summoner:828
Chainer's Edict:824
Faith's Fetters:821
Creeping Tar Pit:817
Fire // Ice:814
Raging Ravine:810
Reanimate:807
Platinum Emperion:804
Moan of the Unhallowed:801
Fauna Shaman:797
Sovereigns of Lost Alara:794
Ancient Tomb:791
Spider Spawning:788
Kozilek, Butcher of Truth:785
Urban Evolution:782
Young Pyromancer:779
Angel of Despair:776
Last Gasp:774
Rolling Temblor:771
All Is Dust:768
Devoted Druid:765
Fiery Temper:763
Murderous Redcap:760
Leovold, Emissary of Trest:757
Wall of Reverence:755
Golgari Grave-Troll:752
Unburial Rites:749
Mahamoti Djinn:747
Ulamog, the Infinite Gyre:744
Stirring Wildwood:742
Swift Reckoning:739
Pattern of Rebirth:737
Dimir Guildmage:735
Warleader's Helix:732
Thermo-Alchemist:730
Penumbra Wurm:727
Unholy Hunger:725
Through the Breach:723
Gurmag Angler:720
Emancipation Angel:718
Sleight of Hand:716
Wild Mongrel:713
Boar Umbra:711
Reckless Wurm:709
Kodama's Reach:707
Magmaw:705
Phalanx Leader:702
Vengeful Rebirth:700
Emrakul, the Aeons Torn:698
Daybreak Coronet:696
Treasure Cruise:694
Rise from the Tides:691
Firewing Phoenix:689
Travel Preparations:687
Satyr Wayfinder:685
Engineered Explosives:683
Entomb:681
Hero of Iroas:679
Reya Dawnbringer:677
Soul's Fire:675
Become Immense:673
Containment Priest:670
Archaeomancer:668
Slum Reaper:666
Forbidden Alchemy:664
Stingerfling Spider:662
Anger:660
Artisan of Kozilek:658
Garna, the Bloodflame:656
Lavaclaw Reaches:654
Think Twice:652
Vexing Devil:650
Shirei, Shizo's Caretaker:648
Magus of the Bazaar:646
Snake Umbra:644
Ulamog's Crusher:642
Aethersnipe:640
Iridescent Drake:638
Hero of Leina Tower:636
Mad Prophet:634
Blast of Genius:633
Brazen Scourge:631
Stitched Drake:629
Faithless Looting:627
Squee, Goblin Nabob:625
Ghoulsteed:623
Resurrection:621
Life from the Loam:619
Safehold Elite:617
Canker Abomination:615
Flight of Fancy:613
Frantic Search:611
Rune Snag:609
Sigil of the New Dawn:607
Circular Logic:605
Hooting Mandrills:603
Just the Wind:602
Gaddock Teeg:600
Wickerbough Elder:598
Seismic Assault:596
Deranged Assistant:594
Marang River Prowler:592
Rally the Peasants:590
Wingsteed Rider:588
Walker of the Grove:586
Gods Willing:584
Basking Rootwalla:582
Scuzzback Marauders:580
Slippery Bogle:578
Spider Umbra:576
Boneyard Wurm:574
Skywing Aven:572
Death Denied:571
Sparkspitter:569
Staunch-Hearted Warrior:567
Goryo's Vengeance:565
Icatian Crier:563
Golgari Thug:561
Lotus-Eye Mystics:559
Conflagrate:557
Seize the Day:555
Miraculous Recovery:553
Molten Birth:551
Fulminator Mage:549
Prismatic Lens:547
Karakas:545
Dreamscape Artist:543
Eel Umbra:541
Skyspear Cavalry:539
Cathodion:537
Prey Upon:535
Grave Scrabbler:533
Brawn:531
Wild Hunger:529
Apprentice Necromancer:527
Heliod's Pilgrim:525
Olivia's Dragoon:522
Phyrexian Tower:520
Generator Servant:518
Cavern of Souls:516
Ghoulcaller's Accomplice:514
Plumeveil:512
Pulse of Murasa:510
Foil:508
Dark Depths:506
Hissing Iguanar:503
Visions of Beyond:501
Mystic Retrieval:499
Golgari Charm:497
Desolate Lighthouse:495
Disrupting Shoal:492
Mammoth Umbra:490
Double Cleave:488
Verdant Eidolon:486
Living Lore:483
Reviving Vapors:481
Whirlwind Adept:479
Hyena Umbra:477
Tethmos High Priest:474
Countersquall:472
Terramorphic Expanse:469
Crow of Dark Tidings:467
Miming Slime:465
Ancestor's Chosen:462
Spirit Cairn:460
Unstable Mutation:457
Urborg, Tomb of Yawgmoth:455
Twins of Maurer Estate:452
Malevolent Whispers:450
Shed Weakness:447
Shielding Plax:445
Golgari Brownscale:442
Buried Alive:439
Arena Athlete:437
Dawn Charm:434
Ronom Unicorn:431
Fecundity:428
Gamble:426
Akroan Crusader:423
Bloodflow Connoisseur:420
Myr Servitor:417
Fume Spitter:414
Sultai Skullkeeper:411
Rakdos Shred-Freak:408
Undying Rage:405
Raid Bombardment:402
Turn to Mist:399
Lava Spike:396
Wandering Champion:392
Desperate Ritual:389
Martyr of Sands:386
Spoils of the Vault:382
Phyrexian Altar:379
Conviction:375
Thespian's Stage:371
Angelic Renewal:368
Furnace Celebration:364
Laboratory Maniac:360
Reckless Charge:356
Stitcher's Apprentice:352
Grave Strength:348
Runed Halo:343
Dark Dabbling:339
Crushing Canopy:334
Flagstones of Trokair:329
Rogue's Passage:325
Mark of the Vampire:320
Vessel of Endless Rest:314
Beckon Apparition:309
Offalsnout:303
Songs of the Damned:297
Appetite for Brains:291
Mage-Ring Network:285
Nightbird's Clutches:278
Bridge from Below:271
Patchwork Gnomes:263
Ingot Chewer:255
Sanitarium Skeleton:246
Mistveil Plains:236
Repel the Darkness:226
Back to Basics:214
Dakmor Salvage:201
Groundskeeper:186
Defy Gravity:168
Nourishing Shoal:145
Stream of Consciousness:115
Heap Doll:66
1 Bitterblossom:1000
2 Mana Vault:986
3 Liliana of the Veil:974
4 Karn Liberated:964
5 Mikaeus, the Unhallowed:954
6 Sublime Archangel:945
7 Sigarda, Host of Herons:937
8 Noble Hierarch:929
9 Shriekmaw:922
10 Snapcaster Mage:915
11 Glen Elendra Archmage:908
12 Balefire Dragon:902
13 Vengevine:896
14 Demonic Tutor:891
15 Maelstrom Pulse:885
16 Celestial Colonnade:880
17 Tasigur, the Golden Fang:875
18 Reveillark:870
19 Lord of Extinction:865
20 Eternal Witness:861
21 Tarmogoyf:856
22 Woodfall Primus:852
23 Eldrazi Conscription:848
24 Kitchen Finks:843
25 Temporal Manipulation:839
26 Fiend Hunter:836
27 Dig Through Time:832
28 Talrand, Sky Summoner:828
29 Chainer's Edict:824
30 Faith's Fetters:821
31 Creeping Tar Pit:817
32 Fire // Ice:814
33 Raging Ravine:810
34 Reanimate:807
35 Platinum Emperion:804
36 Moan of the Unhallowed:801
37 Fauna Shaman:797
38 Sovereigns of Lost Alara:794
39 Ancient Tomb:791
40 Spider Spawning:788
41 Kozilek, Butcher of Truth:785
42 Urban Evolution:782
43 Young Pyromancer:779
44 Angel of Despair:776
45 Last Gasp:774
46 Rolling Temblor:771
47 All Is Dust:768
48 Devoted Druid:765
49 Fiery Temper:763
50 Murderous Redcap:760
51 Leovold, Emissary of Trest:757
52 Wall of Reverence:755
53 Golgari Grave-Troll:752
54 Unburial Rites:749
55 Mahamoti Djinn:747
56 Ulamog, the Infinite Gyre:744
57 Stirring Wildwood:742
58 Swift Reckoning:739
59 Pattern of Rebirth:737
60 Dimir Guildmage:735
61 Warleader's Helix:732
62 Thermo-Alchemist:730
63 Penumbra Wurm:727
64 Unholy Hunger:725
65 Through the Breach:723
66 Gurmag Angler:720
67 Emancipation Angel:718
68 Sleight of Hand:716
69 Wild Mongrel:713
70 Boar Umbra:711
71 Reckless Wurm:709
72 Kodama's Reach:707
73 Magmaw:705
74 Phalanx Leader:702
75 Vengeful Rebirth:700
76 Emrakul, the Aeons Torn:698
77 Daybreak Coronet:696
78 Treasure Cruise:694
79 Rise from the Tides:691
80 Firewing Phoenix:689
81 Travel Preparations:687
82 Satyr Wayfinder:685
83 Engineered Explosives:683
84 Entomb:681
85 Hero of Iroas:679
86 Reya Dawnbringer:677
87 Soul's Fire:675
88 Become Immense:673
89 Containment Priest:670
90 Archaeomancer:668
91 Slum Reaper:666
92 Forbidden Alchemy:664
93 Stingerfling Spider:662
94 Anger:660
95 Artisan of Kozilek:658
96 Garna, the Bloodflame:656
97 Lavaclaw Reaches:654
98 Think Twice:652
99 Vexing Devil:650
100 Shirei, Shizo's Caretaker:648
101 Magus of the Bazaar:646
102 Snake Umbra:644
103 Ulamog's Crusher:642
104 Aethersnipe:640
105 Iridescent Drake:638
106 Hero of Leina Tower:636
107 Mad Prophet:634
108 Blast of Genius:633
109 Brazen Scourge:631
110 Stitched Drake:629
111 Faithless Looting:627
112 Squee, Goblin Nabob:625
113 Ghoulsteed:623
114 Resurrection:621
115 Life from the Loam:619
116 Safehold Elite:617
117 Canker Abomination:615
118 Flight of Fancy:613
119 Frantic Search:611
120 Rune Snag:609
121 Sigil of the New Dawn:607
122 Circular Logic:605
123 Hooting Mandrills:603
124 Just the Wind:602
125 Gaddock Teeg:600
126 Wickerbough Elder:598
127 Seismic Assault:596
128 Deranged Assistant:594
129 Marang River Prowler:592
130 Rally the Peasants:590
131 Wingsteed Rider:588
132 Walker of the Grove:586
133 Gods Willing:584
134 Basking Rootwalla:582
135 Scuzzback Marauders:580
136 Slippery Bogle:578
137 Spider Umbra:576
138 Boneyard Wurm:574
139 Skywing Aven:572
140 Death Denied:571
141 Sparkspitter:569
142 Staunch-Hearted Warrior:567
143 Goryo's Vengeance:565
144 Icatian Crier:563
145 Golgari Thug:561
146 Lotus-Eye Mystics:559
147 Conflagrate:557
148 Seize the Day:555
149 Miraculous Recovery:553
150 Molten Birth:551
151 Fulminator Mage:549
152 Prismatic Lens:547
153 Karakas:545
154 Dreamscape Artist:543
155 Eel Umbra:541
156 Skyspear Cavalry:539
157 Cathodion:537
158 Prey Upon:535
159 Grave Scrabbler:533
160 Brawn:531
161 Wild Hunger:529
162 Apprentice Necromancer:527
163 Heliod's Pilgrim:525
164 Olivia's Dragoon:522
165 Phyrexian Tower:520
166 Generator Servant:518
167 Cavern of Souls:516
168 Ghoulcaller's Accomplice:514
169 Plumeveil:512
170 Pulse of Murasa:510
171 Foil:508
172 Dark Depths:506
173 Hissing Iguanar:503
174 Visions of Beyond:501
175 Mystic Retrieval:499
176 Golgari Charm:497
177 Desolate Lighthouse:495
178 Disrupting Shoal:492
179 Mammoth Umbra:490
180 Double Cleave:488
181 Verdant Eidolon:486
182 Living Lore:483
183 Reviving Vapors:481
184 Whirlwind Adept:479
185 Hyena Umbra:477
186 Tethmos High Priest:474
187 Countersquall:472
188 Terramorphic Expanse:469
189 Crow of Dark Tidings:467
190 Miming Slime:465
191 Ancestor's Chosen:462
192 Spirit Cairn:460
193 Unstable Mutation:457
194 Urborg, Tomb of Yawgmoth:455
195 Twins of Maurer Estate:452
196 Malevolent Whispers:450
197 Shed Weakness:447
198 Shielding Plax:445
199 Golgari Brownscale:442
200 Buried Alive:439
201 Arena Athlete:437
202 Dawn Charm:434
203 Ronom Unicorn:431
204 Fecundity:428
205 Gamble:426
206 Akroan Crusader:423
207 Bloodflow Connoisseur:420
208 Myr Servitor:417
209 Fume Spitter:414
210 Sultai Skullkeeper:411
211 Rakdos Shred-Freak:408
212 Undying Rage:405
213 Raid Bombardment:402
214 Turn to Mist:399
215 Lava Spike:396
216 Wandering Champion:392
217 Desperate Ritual:389
218 Martyr of Sands:386
219 Spoils of the Vault:382
220 Phyrexian Altar:379
221 Conviction:375
222 Thespian's Stage:371
223 Angelic Renewal:368
224 Furnace Celebration:364
225 Laboratory Maniac:360
226 Reckless Charge:356
227 Stitcher's Apprentice:352
228 Grave Strength:348
229 Runed Halo:343
230 Dark Dabbling:339
231 Crushing Canopy:334
232 Flagstones of Trokair:329
233 Rogue's Passage:325
234 Mark of the Vampire:320
235 Vessel of Endless Rest:314
236 Beckon Apparition:309
237 Offalsnout:303
238 Songs of the Damned:297
239 Appetite for Brains:291
240 Mage-Ring Network:285
241 Nightbird's Clutches:278
242 Bridge from Below:271
243 Patchwork Gnomes:263
244 Ingot Chewer:255
245 Sanitarium Skeleton:246
246 Mistveil Plains:236
247 Repel the Darkness:226
248 Back to Basics:214
249 Dakmor Salvage:201
250 Groundskeeper:186
251 Defy Gravity:168
252 Nourishing Shoal:145
253 Stream of Consciousness:115
254 Heap Doll:66

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-player-ai-mcts</artifactId> <artifactId>mage-player-ai-mcts</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-player-human</artifactId> <artifactId>mage-player-human</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>

View file

@ -1,3 +0,0 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

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.31</version> <version>1.4.32</version>
</parent> </parent>
<artifactId>mage-server</artifactId> <artifactId>mage-server</artifactId>
@ -258,7 +258,6 @@
<configuration> <configuration>
<generatePackage>mage.server.util.config</generatePackage> <generatePackage>mage.server.util.config</generatePackage>
<schemaDirectory>./src/main/xml-resources/jaxb/Config/</schemaDirectory> <schemaDirectory>./src/main/xml-resources/jaxb/Config/</schemaDirectory>
<arguments>-Xcommons-lang</arguments>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View file

@ -1,10 +1,5 @@
package mage.server; package mage.server;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.ExecutorService;
import javax.management.timer.Timer;
import mage.MageException; import mage.MageException;
import mage.cards.decks.DeckCardLists; import mage.cards.decks.DeckCardLists;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
@ -43,6 +38,11 @@ import mage.view.ChatMessage.MessageColor;
import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import javax.management.timer.Timer;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.ExecutorService;
/** /**
* @author BetaSteward_at_googlemail.com, noxx * @author BetaSteward_at_googlemail.com, noxx
*/ */
@ -227,6 +227,20 @@ public class MageServerImpl implements MageServer {
user.showUserMessage("Create tournament", message); user.showUserMessage("Create tournament", message);
throw new MageException("No message"); throw new MageException("No message");
} }
// check if the user satisfies the minimumRating requirement.
int minimumRating = options.getMinimumRating();
int userRating;
if (options.getMatchOptions().isLimited()) {
userRating = user.getUserData().getLimitedRating();
} else {
userRating = user.getUserData().getConstructedRating();
}
if (userRating < minimumRating) {
String message = new StringBuilder("Your rating ").append(userRating)
.append(" is lower than the table requirement ").append(minimumRating).toString();
user.showUserMessage("Create tournament", message);
throw new MageException("No message");
}
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId); Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
if (!room.isPresent()) { if (!room.isPresent()) {
@ -1293,8 +1307,8 @@ public class MageServerImpl implements MageServer {
logger.error("Session not found : " + sessionId); logger.error("Session not found : " + sessionId);
return null; return null;
} else { } else {
UUID userId = session.get().getUserId(); //UUID userId = session.get().getUserId();
return GameManager.instance.getGameView(gameId, userId, playerId); return GameManager.instance.getGameView(gameId, playerId);
} }
} }
} }
@ -1386,7 +1400,19 @@ public class MageServerImpl implements MageServer {
user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + '%'); user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + '%');
throw new MageException("No message"); throw new MageException("No message");
} }
// check if the user satisfies the minimumRating requirement.
int minimumRating = options.getMinimumRating();
int userRating;
if (options.isLimited()) {
userRating = user.getUserData().getLimitedRating();
} else {
userRating = user.getUserData().getConstructedRating();
}
if (userRating < minimumRating) {
String message = new StringBuilder("Your rating ").append(userRating).append(" is lower than the table requirement ").append(minimumRating).toString();
user.showUserMessage("Create table", message);
throw new MageException("No message");
}
Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId); Optional<GamesRoom> room = GamesRoomManager.instance.getRoom(roomId);
if (room.isPresent()) { if (room.isPresent()) {
TableView table = room.get().createTable(userId, options); TableView table = room.get().createTable(userId, options);

View file

@ -1,12 +1,5 @@
package mage.server; package mage.server;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.*;
import javax.management.MBeanServer;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardScanner; import mage.cards.repository.CardScanner;
@ -39,13 +32,20 @@ import org.jboss.remoting.transporter.TransporterClient;
import org.jboss.remoting.transporter.TransporterServer; import org.jboss.remoting.transporter.TransporterServer;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import javax.management.MBeanServer;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.*;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class Main { public final class Main {
private static final Logger logger = Logger.getLogger(Main.class); private static final Logger logger = Logger.getLogger(Main.class);
private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); private static final MageVersion version = new MageVersion(Main.class);
private static final String testModeArg = "-testMode="; private static final String testModeArg = "-testMode=";
private static final String fastDBModeArg = "-fastDbMode="; private static final String fastDBModeArg = "-fastDbMode=";

View file

@ -1,4 +1,3 @@
package mage.server; package mage.server;
import java.util.Locale; import java.util.Locale;
@ -172,6 +171,21 @@ public class TableController {
return false; return false;
} }
// Check minimum rating.
int minimumRating = table.getTournament().getOptions().getMinimumRating();
int userRating;
if (table.getTournament().getOptions().getMatchOptions().isLimited()) {
userRating = user.getUserData().getLimitedRating();
} else {
userRating = user.getUserData().getConstructedRating();
}
if (userRating < minimumRating) {
String message = new StringBuilder("Your rating ").append(userRating)
.append(" is lower than the table requirement ").append(minimumRating).toString();
user.showUserMessage("Join Table", message);
return false;
}
Optional<Player> playerOptional = createPlayer(name, seat.getPlayerType(), skill); Optional<Player> playerOptional = createPlayer(name, seat.getPlayerType(), skill);
if (playerOptional.isPresent()) { if (playerOptional.isPresent()) {
Player player = playerOptional.get(); Player player = playerOptional.get();
@ -225,6 +239,7 @@ public class TableController {
public synchronized boolean joinTable(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException { public synchronized boolean joinTable(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException {
Optional<User> _user = UserManager.instance.getUser(userId); Optional<User> _user = UserManager.instance.getUser(userId);
if (!_user.isPresent()) { if (!_user.isPresent()) {
logger.error("Join Table: can't find user to join " + name + " Id = " + userId);
return false; return false;
} }
User user = _user.get(); User user = _user.get();
@ -272,6 +287,21 @@ public class TableController {
return false; return false;
} }
// Check minimum rating.
int minimumRating = table.getMatch().getOptions().getMinimumRating();
int userRating;
if (table.getMatch().getOptions().isLimited()) {
userRating = user.getUserData().getLimitedRating();
} else {
userRating = user.getUserData().getConstructedRating();
}
if (userRating < minimumRating) {
String message = new StringBuilder("Your rating ").append(userRating)
.append(" is lower than the table requirement ").append(minimumRating).toString();
user.showUserMessage("Join Table", message);
return false;
}
// Check power level for table (currently only used for EDH/Commander table) // Check power level for table (currently only used for EDH/Commander table)
int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel(); int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel();
if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase(Locale.ENGLISH).equals("commander")) { if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase(Locale.ENGLISH).equals("commander")) {

View file

@ -48,7 +48,8 @@ public class DraftSession {
if (user.isPresent()) { if (user.isPresent()) {
if (futureTimeout != null && !futureTimeout.isDone()) { if (futureTimeout != null && !futureTimeout.isDone()) {
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS); int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
user.get().fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_INIT, draft.getId(), new DraftClientMessage(getDraftPickView(remaining)))); user.get().fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_INIT, draft.getId(),
new DraftClientMessage(getDraftView(), getDraftPickView(remaining))));
} }
return true; return true;
} }
@ -60,8 +61,8 @@ public class DraftSession {
if (!killed) { if (!killed) {
UserManager.instance UserManager.instance
.getUser(userId). .getUser(userId).
ifPresent(user -> user.fireCallback( ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_UPDATE, draft.getId(),
new ClientCallback(ClientCallbackMethod.DRAFT_UPDATE, draft.getId(), getDraftView()))); new DraftClientMessage(getDraftView(), null))));
} }
} }
@ -70,7 +71,6 @@ public class DraftSession {
UserManager.instance UserManager.instance
.getUser(userId) .getUser(userId)
.ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_OVER, draft.getId()))); .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_OVER, draft.getId())));
} }
} }
@ -79,7 +79,8 @@ public class DraftSession {
setupTimeout(timeout); setupTimeout(timeout);
UserManager.instance UserManager.instance
.getUser(userId) .getUser(userId)
.ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_PICK, draft.getId(), new DraftClientMessage(getDraftPickView(timeout))))); .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_PICK, draft.getId(),
new DraftClientMessage(getDraftView(), getDraftPickView(timeout)))));
} }
} }

View file

@ -1,6 +1,12 @@
package mage.server.game; package mage.server.game;
import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.constants.PlayerAction;
import mage.game.Game;
import mage.game.GameOptions;
import mage.view.GameView;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -9,15 +15,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.constants.PlayerAction;
import mage.game.Game;
import mage.game.GameOptions;
import mage.view.GameView;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public enum GameManager { public enum GameManager {
@ -38,15 +37,25 @@ public enum GameManager {
return gameController.getSessionId(); return gameController.getSessionId();
} }
private GameController getGameControllerSafe(UUID gameId) {
final Lock r = gameControllersLock.readLock();
r.lock();
try {
return gameControllers.get(gameId);
} finally {
r.unlock();
}
}
public void joinGame(UUID gameId, UUID userId) { public void joinGame(UUID gameId, UUID userId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.join(userId); gameController.join(userId);
} }
} }
public Optional<UUID> getChatId(UUID gameId) { public Optional<UUID> getChatId(UUID gameId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
return Optional.of(gameController.getChatId()); return Optional.of(gameController.getChatId());
} }
@ -54,56 +63,56 @@ public enum GameManager {
} }
public void sendPlayerUUID(UUID gameId, UUID userId, UUID data) { public void sendPlayerUUID(UUID gameId, UUID userId, UUID data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerUUID(userId, data); gameController.sendPlayerUUID(userId, data);
} }
} }
public void sendPlayerString(UUID gameId, UUID userId, String data) { public void sendPlayerString(UUID gameId, UUID userId, String data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerString(userId, data); gameController.sendPlayerString(userId, data);
} }
} }
public void sendPlayerManaType(UUID gameId, UUID playerId, UUID userId, ManaType data) { public void sendPlayerManaType(UUID gameId, UUID playerId, UUID userId, ManaType data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerManaType(userId, playerId, data); gameController.sendPlayerManaType(userId, playerId, data);
} }
} }
public void sendPlayerBoolean(UUID gameId, UUID userId, Boolean data) { public void sendPlayerBoolean(UUID gameId, UUID userId, Boolean data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerBoolean(userId, data); gameController.sendPlayerBoolean(userId, data);
} }
} }
public void sendPlayerInteger(UUID gameId, UUID userId, Integer data) { public void sendPlayerInteger(UUID gameId, UUID userId, Integer data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerInteger(userId, data); gameController.sendPlayerInteger(userId, data);
} }
} }
public void quitMatch(UUID gameId, UUID userId) { public void quitMatch(UUID gameId, UUID userId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.quitMatch(userId); gameController.quitMatch(userId);
} }
} }
public void sendPlayerAction(PlayerAction playerAction, UUID gameId, UUID userId, Object data) { public void sendPlayerAction(PlayerAction playerAction, UUID gameId, UUID userId, Object data) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.sendPlayerAction(playerAction, userId, data); gameController.sendPlayerAction(playerAction, userId, data);
} }
} }
public boolean watchGame(UUID gameId, UUID userId) { public boolean watchGame(UUID gameId, UUID userId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
return gameController.watch(userId); return gameController.watch(userId);
} }
@ -111,21 +120,21 @@ public enum GameManager {
} }
public void stopWatching(UUID gameId, UUID userId) { public void stopWatching(UUID gameId, UUID userId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.stopWatching(userId); gameController.stopWatching(userId);
} }
} }
public void cheat(UUID gameId, UUID userId, UUID playerId, DeckCardLists deckList) { public void cheat(UUID gameId, UUID userId, UUID playerId, DeckCardLists deckList) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.cheat(userId, playerId, deckList); gameController.cheat(userId, playerId, deckList);
} }
} }
public boolean cheat(UUID gameId, UUID userId, UUID playerId, String cardName) { public boolean cheat(UUID gameId, UUID userId, UUID playerId, String cardName) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
return gameController.cheat(userId, playerId, cardName); return gameController.cheat(userId, playerId, cardName);
} }
@ -133,7 +142,7 @@ public enum GameManager {
} }
public void removeGame(UUID gameId) { public void removeGame(UUID gameId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
gameController.cleanUp(); gameController.cleanUp();
final Lock w = gameControllersLock.writeLock(); final Lock w = gameControllersLock.writeLock();
@ -147,15 +156,15 @@ public enum GameManager {
} }
public boolean saveGame(UUID gameId) { public boolean saveGame(UUID gameId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
return gameController.saveGame(); return gameController.saveGame();
} }
return false; return false;
} }
public GameView getGameView(UUID gameId, UUID userId, UUID playerId) { public GameView getGameView(UUID gameId, UUID playerId) {
GameController gameController = gameControllers.get(gameId); GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) { if (gameController != null) {
return gameController.getGameView(playerId); return gameController.getGameView(playerId);
} }
@ -163,7 +172,7 @@ public enum GameManager {
} }
public int getNumberActiveGames() { public int getNumberActiveGames() {
return gameControllers.size(); return getGameController().size();
} }
public Map<UUID, GameController> getGameController() { public Map<UUID, GameController> getGameController() {

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.31</version> <version>1.4.32</version>
</parent> </parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>

View file

@ -0,0 +1,45 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.keyword.AdaptEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Aeromunculus extends CardImpl {
public Aeromunculus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}");
this.subtype.add(SubType.HOMUNCULUS);
this.subtype.add(SubType.MUTANT);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// {2}{G}{U}: Adapt 1.
this.addAbility(new SimpleActivatedAbility(
new AdaptEffect(1), new ManaCostsImpl("{2}{G}{U}")
));
}
public Aeromunculus(final Aeromunculus card) {
super(card);
}
@Override
public Aeromunculus copy() {
return new Aeromunculus(this);
}
}

View file

@ -0,0 +1,144 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
/**
*
* @author jeffwadsworth
*/
public final class AetherTide extends CardImpl {
public AetherTide(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
// As an additional cost to cast Aether Tide, discard X creature cards.
this.getSpellAbility().addCost(new AetherTideCost());
// Return X target creatures to their owners' hands.
this.getSpellAbility().addEffect(new ReturnToHandTargetPermanentEffect());
}
public AetherTide(final AetherTide card) {
super(card);
}
@Override
public AetherTide copy() {
return new AetherTide(this);
}
}
class AetherTideCost extends VariableCostImpl {
public AetherTideCost() {
super("discard X creature cards");
text = "As an additional cost to cast {this}, discard X creature cards";
}
public AetherTideCost(AetherTideCost cost) {
super(cost);
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
return (game.getPlayer(controllerId).getHand().count(new FilterCreatureCard(), game) > 0);
}
@Override
public int getMaxValue(Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
return controller.getHand().count(new FilterCreatureCard(), game);
}
return 0;
}
@Override
public int getMinValue(Ability source, Game game) {
return 0;
}
@Override
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
TargetCardInHand target = new TargetCardInHand(xValue, new FilterCreatureCard());
return new DiscardTargetCost(target);
}
@Override
public int announceXValue(Ability source, Game game) {
int xValue = 0;
Player controller = game.getPlayer(source.getControllerId());
StackObject stackObject = game.getStack().getStackObject(source.getId());
if (controller != null
&& stackObject != null) {
xValue = controller.announceXCost(getMinValue(source, game), getMaxValue(source, game),
"Announce the number of creature cards to discard", game, source, this);
}
return xValue;
}
@Override
public AetherTideCost copy() {
return new AetherTideCost(this);
}
}
class ReturnToHandTargetPermanentEffect extends OneShotEffect {
public ReturnToHandTargetPermanentEffect() {
super(Outcome.ReturnToHand);
setText("Return X target creatures to their owners' hands");
}
public ReturnToHandTargetPermanentEffect(final ReturnToHandTargetPermanentEffect effect) {
super(effect);
}
@Override
public ReturnToHandTargetPermanentEffect copy() {
return new ReturnToHandTargetPermanentEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
int xPaid = source.getCosts().getVariableCosts().get(0).getAmount();
if (controller != null
&& xPaid > 0) {
int available = game.getBattlefield().count(new FilterCreaturePermanent(),
source.getSourceId(),
source.getControllerId(), game);
if (available > 0) {
TargetPermanent target = new TargetPermanent(Math.min(xPaid, available),
xPaid,
new FilterCreaturePermanent("creatures to return to their owner's hands"),
true);
if (controller.chooseTarget(outcome.Detriment, target, source, game)) {
controller.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
}
return true;
}
}
return false;
}
}

View file

@ -1,6 +1,5 @@
package mage.cards.a; package mage.cards.a;
import java.util.*;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
@ -16,6 +15,10 @@ import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/** /**
* @author stravant * @author stravant
*/ */
@ -64,7 +67,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
ApproachOfTheSecondSunWatcher watcher ApproachOfTheSecondSunWatcher watcher
= (ApproachOfTheSecondSunWatcher) game.getState().getWatchers().get(ApproachOfTheSecondSunWatcher.class.getSimpleName()); = (ApproachOfTheSecondSunWatcher) game.getState().getWatchers().get(ApproachOfTheSecondSunWatcher.class.getSimpleName());
if (watcher != null if (watcher != null
&& !spell.isCopiedSpell() && !spell.isCopy()
&& watcher.getApproachesCast(controller.getId()) > 1 && watcher.getApproachesCast(controller.getId()) > 1
&& spell.getFromZone() == Zone.HAND) { && spell.getFromZone() == Zone.HAND) {
// Win the game // Win the game
@ -74,7 +77,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
controller.gainLife(7, game, source); controller.gainLife(7, game, source);
// Put this into the library as the 7th from the top // Put this into the library as the 7th from the top
if (spell.isCopiedSpell()) { if (spell.isCopy()) {
return true; return true;
} }
Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard();

View file

@ -6,7 +6,7 @@ import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.game.permanent.token.BeckonApparitionToken; import mage.game.permanent.token.WhiteBlackSpiritToken;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import java.util.UUID; import java.util.UUID;
@ -22,7 +22,7 @@ public final class BeckonApparition extends CardImpl {
// Exile target card from a graveyard. Create a 1/1 white and black Spirit creature token with flying. // Exile target card from a graveyard. Create a 1/1 white and black Spirit creature token with flying.
this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInGraveyard()); this.getSpellAbility().addTarget(new TargetCardInGraveyard());
this.getSpellAbility().addEffect(new CreateTokenEffect(new BeckonApparitionToken(), 1)); this.getSpellAbility().addEffect(new CreateTokenEffect(new WhiteBlackSpiritToken(), 1));
} }
public BeckonApparition(final BeckonApparition card) { public BeckonApparition(final BeckonApparition card) {

View file

@ -0,0 +1,45 @@
package mage.cards.b;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Bedevil extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact, creature, or planeswalker");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.PLANESWALKER)
));
}
public Bedevil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}{R}");
// Destroy target artifact, creature, or planeswalker.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
}
public Bedevil(final Bedevil card) {
super(card);
}
@Override
public Bedevil copy() {
return new Bedevil(this);
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.effects.common.continuous.BoostAllEffect;
@ -12,9 +10,11 @@ import mage.constants.Duration;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author Quercitron * @author Quercitron
*/ */
public final class BileBlight extends CardImpl { public final class BileBlight extends CardImpl {
@ -56,12 +56,12 @@ class BileBlightEffect extends BoostAllEffect {
if (this.affectedObjectsSet) { if (this.affectedObjectsSet) {
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
if (target != null) { if (target != null) {
if (target.getName().isEmpty()) { // face down creature if (CardUtil.haveEmptyName(target)) { // face down creature
affectedObjectList.add(new MageObjectReference(target, game)); affectedObjectList.add(new MageObjectReference(target, game));
} else { } else {
String name = target.getName(); String name = target.getName();
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
if (perm.getName().equals(name)) { if (CardUtil.haveSameNames(perm.getName(), name)) {
affectedObjectList.add(new MageObjectReference(perm, game)); affectedObjectList.add(new MageObjectReference(perm, game));
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -14,9 +12,11 @@ import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author Styxo * @author Styxo
*/ */
public final class BrainPry extends CardImpl { public final class BrainPry extends CardImpl {
@ -60,7 +60,7 @@ class BrainPryEffect extends OneShotEffect {
if (targetPlayer != null && controller != null && sourceObject != null && cardName != null) { if (targetPlayer != null && controller != null && sourceObject != null && cardName != null) {
boolean hasDiscarded = false; boolean hasDiscarded = false;
for (Card card : targetPlayer.getHand().getCards(game)) { for (Card card : targetPlayer.getHand().getCards(game)) {
if (card.getName().equals(cardName)) { if (CardUtil.haveSameNames(card.getName(), cardName)) {
targetPlayer.discard(card, source, game); targetPlayer.discard(card, source, game);
hasDiscarded = true; hasDiscarded = true;
break; break;

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