mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
[card.plugin] first version (at the moment replaces only cards on battlefield) (should be installed manually)
This commit is contained in:
parent
d022c251f6
commit
5771691972
18 changed files with 1093 additions and 33 deletions
|
|
@ -47,6 +47,12 @@
|
||||||
<artifactId>java-image-scaling</artifactId>
|
<artifactId>java-image-scaling</artifactId>
|
||||||
<version>0.8.4</version>
|
<version>0.8.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.collections</groupId>
|
||||||
|
<artifactId>google-collections</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,24 @@ package mage.client;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.File;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JDesktopPane;
|
import javax.swing.JDesktopPane;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JToolBar.Separator;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.ExpansionSet;
|
||||||
import mage.client.dialog.AboutDialog;
|
import mage.client.dialog.AboutDialog;
|
||||||
import mage.client.dialog.CombatDialog;
|
import mage.client.dialog.CombatDialog;
|
||||||
import mage.client.dialog.ConnectDialog;
|
import mage.client.dialog.ConnectDialog;
|
||||||
|
|
@ -57,11 +62,8 @@ import mage.client.dialog.PickNumberDialog;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
import mage.client.remote.Session;
|
import mage.client.remote.Session;
|
||||||
import mage.client.util.EDTExceptionHandler;
|
import mage.client.util.EDTExceptionHandler;
|
||||||
import mage.interfaces.plugin.ThemePlugin;
|
import mage.sets.Sets;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import net.xeoh.plugins.base.PluginManager;
|
|
||||||
import net.xeoh.plugins.base.impl.PluginManagerFactory;
|
|
||||||
import net.xeoh.plugins.base.util.PluginManagerUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -127,8 +129,32 @@ public class MageFrame extends javax.swing.JFrame {
|
||||||
enableButtons();
|
enableButtons();
|
||||||
else
|
else
|
||||||
disableButtons();
|
disableButtons();
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
Separator separator = new javax.swing.JToolBar.Separator();
|
||||||
|
mageToolbar.add(separator);
|
||||||
|
|
||||||
|
JButton btnDownload = new JButton("Images");
|
||||||
|
btnDownload.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
|
||||||
|
btnDownload.setFocusable(false);
|
||||||
|
btnDownload.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
|
||||||
|
btnDownload.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
|
||||||
|
btnDownload.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
btnImagesActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mageToolbar.add(btnDownload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
Set<Card> allCards = new LinkedHashSet<Card>();
|
||||||
|
for (ExpansionSet set: Sets.getInstance().values()) {
|
||||||
|
allCards.addAll(set.createCards());
|
||||||
|
}
|
||||||
|
Plugins.getInstance().downloadImage(allCards);
|
||||||
|
}
|
||||||
|
|
||||||
public void showGame(UUID gameId, UUID playerId) {
|
public void showGame(UUID gameId, UUID playerId) {
|
||||||
this.tablesPane.hideTables();
|
this.tablesPane.hideTables();
|
||||||
this.tablesPane.setVisible(false);
|
this.tablesPane.setVisible(false);
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,6 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
|
||||||
ui.put("jScrollPane", jScrollPane);
|
ui.put("jScrollPane", jScrollPane);
|
||||||
ui.put("battlefieldPanel", this);
|
ui.put("battlefieldPanel", this);
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
addMouseListener(new MageMouseAdapter(this, gameId));
|
|
||||||
addMouseMotionListener(new MageMouseMotionAdapter(this, bigCard));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(UUID gameId, BigCard bigCard) {
|
public void init(UUID gameId, BigCard bigCard) {
|
||||||
|
|
@ -95,13 +92,13 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
|
||||||
if (Plugins.getInstance().isCardPluginLoaded()) {
|
if (Plugins.getInstance().isCardPluginLoaded()) {
|
||||||
bigCard.removeTextComponent();
|
bigCard.removeTextComponent();
|
||||||
}
|
}
|
||||||
|
addMouseListener(new MageMouseAdapter(this, gameId));
|
||||||
|
addMouseMotionListener(new MageMouseMotionAdapter(this, bigCard));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(Map<UUID, PermanentView> battlefield) {
|
public void update(Map<UUID, PermanentView> battlefield) {
|
||||||
for (PermanentView permanent: battlefield.values()) {
|
for (PermanentView permanent: battlefield.values()) {
|
||||||
if (!permanents.containsKey(permanent.getId())) {
|
if (!permanents.containsKey(permanent.getId())) {
|
||||||
//TODO: remove me
|
|
||||||
//System.out.println("Add permanent: " + permanent.getCardNumber());
|
|
||||||
addPermanent(permanent);
|
addPermanent(permanent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -133,8 +130,10 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
|
||||||
}
|
}
|
||||||
permanents.put(permanent.getId(), perm);
|
permanents.put(permanent.getId(), perm);
|
||||||
this.add(perm, 10);
|
this.add(perm, 10);
|
||||||
moveToFront(perm);
|
if (!Plugins.getInstance().isCardPluginLoaded()) {
|
||||||
perm.update(permanent);
|
moveToFront(perm);
|
||||||
|
perm.update(permanent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void groupAttachments(PermanentView permanent) {
|
private void groupAttachments(PermanentView permanent) {
|
||||||
|
|
@ -228,7 +227,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resizeBattlefield() {
|
private void resizeBattlefield() {
|
||||||
Dimension area = new Dimension(0, 0);
|
/*Dimension area = new Dimension(0, 0);
|
||||||
Dimension size = getPreferredSize();
|
Dimension size = getPreferredSize();
|
||||||
|
|
||||||
for (Component comp: getComponents()) {
|
for (Component comp: getComponents()) {
|
||||||
|
|
@ -244,7 +243,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
|
||||||
setPreferredSize(area);
|
setPreferredSize(area);
|
||||||
revalidate();
|
revalidate();
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@ package mage.client.plugins;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardDimensions;
|
import mage.cards.CardDimensions;
|
||||||
import mage.cards.MagePermanent;
|
import mage.cards.MagePermanent;
|
||||||
import mage.client.cards.BigCard;
|
import mage.client.cards.BigCard;
|
||||||
|
|
@ -18,4 +20,5 @@ public interface MagePlugins {
|
||||||
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId);
|
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, CardDimensions dimension, UUID gameId);
|
||||||
boolean isCardPluginLoaded();
|
boolean isCardPluginLoaded();
|
||||||
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents);
|
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents);
|
||||||
|
void downloadImage(Set<Card> allCards);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ public class MageMouseMotionAdapter extends MouseMotionAdapter {
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
if (!Plugins.getInstance().isCardPluginLoaded()) return;
|
if (!Plugins.getInstance().isCardPluginLoaded()) return;
|
||||||
|
if (bigCard == null) return;
|
||||||
Object o = parent.getComponentAt(e.getPoint());
|
Object o = parent.getComponentAt(e.getPoint());
|
||||||
if (o instanceof MagePermanent) {
|
if (o instanceof MagePermanent) {
|
||||||
MagePermanent card = (MagePermanent) o;
|
MagePermanent card = (MagePermanent) o;
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,18 @@ package mage.client.plugins.impl;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardDimensions;
|
import mage.cards.CardDimensions;
|
||||||
|
import mage.cards.ExpansionSet;
|
||||||
import mage.cards.MagePermanent;
|
import mage.cards.MagePermanent;
|
||||||
import mage.cards.action.impl.EmptyCallback;
|
import mage.cards.action.impl.EmptyCallback;
|
||||||
import mage.client.cards.BigCard;
|
import mage.client.cards.BigCard;
|
||||||
|
|
@ -20,6 +24,7 @@ import mage.client.util.DefaultActionCallback;
|
||||||
import mage.constants.Constants;
|
import mage.constants.Constants;
|
||||||
import mage.interfaces.plugin.CardPlugin;
|
import mage.interfaces.plugin.CardPlugin;
|
||||||
import mage.interfaces.plugin.ThemePlugin;
|
import mage.interfaces.plugin.ThemePlugin;
|
||||||
|
import mage.sets.Sets;
|
||||||
import mage.util.Logging;
|
import mage.util.Logging;
|
||||||
import mage.view.PermanentView;
|
import mage.view.PermanentView;
|
||||||
import net.xeoh.plugins.base.PluginManager;
|
import net.xeoh.plugins.base.PluginManager;
|
||||||
|
|
@ -81,4 +86,9 @@ public class Plugins implements MagePlugins {
|
||||||
public void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents) {
|
public void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> permanents) {
|
||||||
if (this.cardPlugin != null) this.cardPlugin.sortPermanents(ui, permanents);
|
if (this.cardPlugin != null) this.cardPlugin.sortPermanents(ui, permanents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadImage(Set<Card> allCards) {
|
||||||
|
if (this.cardPlugin != null) this.cardPlugin.downloadImages(allCards);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@ package mage.interfaces.plugin;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardDimensions;
|
import mage.cards.CardDimensions;
|
||||||
import mage.cards.MagePermanent;
|
import mage.cards.MagePermanent;
|
||||||
import mage.cards.action.ActionCallback;
|
import mage.cards.action.ActionCallback;
|
||||||
|
|
@ -21,4 +23,5 @@ import net.xeoh.plugins.base.Plugin;
|
||||||
public interface CardPlugin extends Plugin {
|
public interface CardPlugin extends Plugin {
|
||||||
MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback);
|
MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback);
|
||||||
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> cards);
|
void sortPermanents(Map<String, JComponent> ui, Collection<MagePermanent> cards);
|
||||||
|
void downloadImages(Set<Card> allCards);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mage</groupId>
|
<groupId>org.mage</groupId>
|
||||||
<artifactId>Mage-Common</artifactId>
|
<artifactId>Mage-Common</artifactId>
|
||||||
<version>${mage-version}</version>
|
<version>${mage-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
@ -33,6 +33,18 @@
|
||||||
<version>1.2.9</version>
|
<version>1.2.9</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.collections</groupId>
|
||||||
|
<artifactId>google-collections</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mortennobel</groupId>
|
||||||
|
<artifactId>java-image-scaling</artifactId>
|
||||||
|
<version>0.8.4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
@ -28,6 +27,8 @@ import mage.view.PermanentView;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
|
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
|
||||||
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
|
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
|
||||||
|
import org.mage.plugins.card.images.ImageCache;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked","rawtypes"})
|
@SuppressWarnings({"unchecked","rawtypes"})
|
||||||
public class CardPanel extends MagePermanent {
|
public class CardPanel extends MagePermanent {
|
||||||
|
|
@ -125,21 +126,15 @@ public class CardPanel extends MagePermanent {
|
||||||
|
|
||||||
Util.threadPool.submit(new Runnable() {
|
Util.threadPool.submit(new Runnable() {
|
||||||
public void run () {
|
public void run () {
|
||||||
//BufferedImage srcImage = null; //TODO: ImageCache.getImageOriginal(gameCard);
|
tappedAngle = gameCard.isTapped() ? CardPanel.TAPPED_ANGLE : 0;
|
||||||
tappedAngle = gameCard.isTapped() ? CardPanel.TAPPED_ANGLE : 0;
|
BufferedImage srcImage = ImageCache.getImageOriginal(gameCard);
|
||||||
|
|
||||||
try {
|
|
||||||
log.info(gameCard.getCardNumber() + " " + gameCard.getName() + " " + gameCard.getExpansionSetCode());
|
|
||||||
BufferedImage srcImage = ImageIO.read(CardPanel.class.getClassLoader().getResourceAsStream("Mountain.40.full.jpg"));
|
|
||||||
if (srcImage != null) {
|
if (srcImage != null) {
|
||||||
//setImage(srcImage, ImageUtil.getBlurredImage(srcImage, 3, 1.0f));
|
//setImage(srcImage, ImageUtil.getBlurredImage(srcImage, 3, 1.0f));
|
||||||
hasImage = true;
|
hasImage = true;
|
||||||
setText(gameCard);
|
setText(gameCard);
|
||||||
setImage(srcImage, srcImage);
|
setImage(srcImage, srcImage);
|
||||||
}
|
}
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -424,7 +419,7 @@ public class CardPanel extends MagePermanent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTapped() {
|
public boolean isTapped() {
|
||||||
return false;
|
return gameCard.isTapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package org.mage.plugins.card;
|
package org.mage.plugins.card;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
import mage.cards.CardDimensions;
|
import mage.cards.CardDimensions;
|
||||||
import mage.cards.MagePermanent;
|
import mage.cards.MagePermanent;
|
||||||
import mage.cards.action.ActionCallback;
|
import mage.cards.action.ActionCallback;
|
||||||
|
|
@ -27,7 +27,14 @@ import net.xeoh.plugins.base.annotations.meta.Author;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.mage.card.arcane.CardPanel;
|
import org.mage.card.arcane.CardPanel;
|
||||||
import org.mage.plugins.card.constants.Constants;
|
import org.mage.plugins.card.constants.Constants;
|
||||||
|
import org.mage.plugins.card.images.DownloadPictures;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CardPlugin} implementation.
|
||||||
|
*
|
||||||
|
* @version 0.1 01.11.2010
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
@PluginImplementation
|
@PluginImplementation
|
||||||
@Author(name = "nantuko")
|
@Author(name = "nantuko")
|
||||||
public class CardPluginImpl implements CardPlugin {
|
public class CardPluginImpl implements CardPlugin {
|
||||||
|
|
@ -62,7 +69,7 @@ public class CardPluginImpl implements CardPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[Card plugin, version 0.1]";
|
return "[Card plugin, version 0.2]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -216,7 +223,7 @@ public class CardPluginImpl implements CardPlugin {
|
||||||
int panelY = y + (stackPosition * stackSpacingY);
|
int panelY = y + (stackPosition * stackSpacingY);
|
||||||
//panel.setLocation(panelX, panelY);
|
//panel.setLocation(panelX, panelY);
|
||||||
battlefieldPanel.moveToBack(panel);
|
battlefieldPanel.moveToBack(panel);
|
||||||
panel.setCardBounds(panelX + 100, panelY+70, cardWidth, cardHeight);
|
panel.setCardBounds(panelX, panelY, cardWidth, cardHeight);
|
||||||
}
|
}
|
||||||
rowBottom = Math.max(rowBottom, y + stack.getHeight());
|
rowBottom = Math.max(rowBottom, y + stack.getHeight());
|
||||||
x += stack.getWidth();
|
x += stack.getWidth();
|
||||||
|
|
@ -370,5 +377,8 @@ public class CardPluginImpl implements CardPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadImages(Set<Card> allCards) {
|
||||||
|
DownloadPictures.startDownload(null, allCards);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.mage.plugins.card;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains card data and image url.
|
||||||
|
*
|
||||||
|
* @author nantuko
|
||||||
|
*/
|
||||||
|
public class CardUrl implements Serializable {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public String set;
|
||||||
|
public boolean token = false;
|
||||||
|
public Integer collector;
|
||||||
|
public String url = "";
|
||||||
|
public boolean existsInTheGame = false;
|
||||||
|
|
||||||
|
public CardUrl(String cardName, String cardSet, Integer collectorId, boolean isToken) {
|
||||||
|
name = cardName;
|
||||||
|
set = cardSet;
|
||||||
|
collector = collectorId;
|
||||||
|
token = isToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other == null) { return false; }
|
||||||
|
if (other instanceof CardUrl) {
|
||||||
|
return name.equals(((CardUrl) other).name) && set.equals(((CardUrl) other).set)
|
||||||
|
&& collector.equals(((CardUrl) other).collector) && token==((CardUrl)other).token;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash = name.hashCode();
|
||||||
|
hash = 31*hash + set.hashCode();
|
||||||
|
hash = 31*hash + collector.hashCode();
|
||||||
|
hash = 31*hash + (token ? 1 : 0);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExistsInTheGame() {
|
||||||
|
return existsInTheGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExistsInTheGame(boolean existsInTheGame) {
|
||||||
|
this.existsInTheGame = existsInTheGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2L;
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,20 @@
|
||||||
package org.mage.plugins.card.constants;
|
package org.mage.plugins.card.constants;
|
||||||
|
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
public static final String RESOURCE_PATH = "/images";
|
public static final String RESOURCE_PATH = "/images";
|
||||||
public static final String RESOURCE_PATH_MANA = resourcePath("mana");
|
public static final String RESOURCE_PATH_MANA = resourcePath("mana");
|
||||||
|
|
||||||
public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149);
|
public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149);
|
||||||
|
|
||||||
|
public interface IO {
|
||||||
|
public static final String imageBaseDir = "." + File.separator + "plugins" + File.separator + "images" + File.separator;
|
||||||
|
public static final String IMAGE_PROPERTIES_FILE = "image.url.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String CARD_IMAGE_PATH_TEMPLATE = "." + File.separator + "plugins" + File.separator + "images/{set}/{name}.{collector}.full.jpg";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build resource path.
|
* Build resource path.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.mage.plugins.card.images;
|
||||||
|
|
||||||
|
public class CardInfo {
|
||||||
|
public String name;
|
||||||
|
public String set;
|
||||||
|
public Integer collectorId;
|
||||||
|
public boolean isToken = false;
|
||||||
|
public CardInfo(String name, String set, Integer collectorId) {
|
||||||
|
this.name = name;
|
||||||
|
this.set = set;
|
||||||
|
this.collectorId = collectorId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,409 @@
|
||||||
|
package org.mage.plugins.card.images;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.ComboBoxModel;
|
||||||
|
import javax.swing.DefaultBoundedRangeModel;
|
||||||
|
import javax.swing.DefaultComboBoxModel;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.JRadioButton;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.mage.plugins.card.CardUrl;
|
||||||
|
import org.mage.plugins.card.constants.Constants;
|
||||||
|
import org.mage.plugins.card.properties.SettingsManager;
|
||||||
|
import org.mage.plugins.card.utils.CardImageUtils;
|
||||||
|
|
||||||
|
public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable {
|
||||||
|
|
||||||
|
private int type;
|
||||||
|
private JTextField addr, port;
|
||||||
|
private JProgressBar bar;
|
||||||
|
private JOptionPane dlg;
|
||||||
|
private boolean cancel;
|
||||||
|
private JButton close;
|
||||||
|
private int cardIndex;
|
||||||
|
private ArrayList<CardUrl> cards;
|
||||||
|
private ArrayList<CardUrl> cardsInGame;
|
||||||
|
private JComboBox jComboBox1;
|
||||||
|
private JLabel jLabel1;
|
||||||
|
private static boolean offlineMode = false;
|
||||||
|
private JCheckBox checkBox;
|
||||||
|
|
||||||
|
public static final Proxy.Type[] types = Proxy.Type.values();
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
startDownload(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startDownload(JFrame frame, Set<Card> allCards) {
|
||||||
|
ArrayList<CardUrl> cards = getNeededCards(allCards);
|
||||||
|
|
||||||
|
if (cards == null || cards.size() == 0) {
|
||||||
|
JOptionPane.showMessageDialog(null, "All card pictures have been downloaded.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadPictures download = new DownloadPictures(cards);
|
||||||
|
JDialog dlg = download.getDlg(frame);
|
||||||
|
dlg.setVisible(true);
|
||||||
|
dlg.dispose();
|
||||||
|
download.setCancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JDialog getDlg(JFrame frame) {
|
||||||
|
String title = "Downloading";
|
||||||
|
if (offlineMode) {
|
||||||
|
title += " (using local card db)";
|
||||||
|
}
|
||||||
|
final JDialog dlg = this.dlg.createDialog(frame, title);
|
||||||
|
close.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
dlg.setVisible(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dlg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCancel(boolean cancel) {
|
||||||
|
this.cancel = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadPictures(ArrayList<CardUrl> cards) {
|
||||||
|
this.cards = cards;
|
||||||
|
|
||||||
|
this.cardsInGame = new ArrayList<CardUrl>();
|
||||||
|
for (CardUrl url : cards) {
|
||||||
|
if (url.isExistsInTheGame())
|
||||||
|
cardsInGame.add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = new JTextField("Proxy Address");
|
||||||
|
port = new JTextField("Proxy Port");
|
||||||
|
bar = new JProgressBar(this);
|
||||||
|
|
||||||
|
JPanel p0 = new JPanel();
|
||||||
|
p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
// Proxy Choice
|
||||||
|
ButtonGroup bg = new ButtonGroup();
|
||||||
|
String[] labels = { "No Proxy", "HTTP Proxy", "SOCKS Proxy" };
|
||||||
|
for (int i = 0; i < types.length; i++) {
|
||||||
|
JRadioButton rb = new JRadioButton(labels[i]);
|
||||||
|
rb.addChangeListener(new ProxyHandler(i));
|
||||||
|
bg.add(rb);
|
||||||
|
p0.add(rb);
|
||||||
|
if (i == 0)
|
||||||
|
rb.setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proxy config
|
||||||
|
p0.add(addr);
|
||||||
|
p0.add(port);
|
||||||
|
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
jLabel1 = new JLabel();
|
||||||
|
jLabel1.setText("Please select server:");
|
||||||
|
|
||||||
|
jLabel1.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
p0.add(jLabel1);
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "magiccards.info" });
|
||||||
|
jComboBox1 = new JComboBox();
|
||||||
|
|
||||||
|
jComboBox1.setModel(jComboBox1Model);
|
||||||
|
jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
p0.add(jComboBox1);
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
|
||||||
|
// Start
|
||||||
|
final JButton b = new JButton("Start download");
|
||||||
|
b.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
new Thread(DownloadPictures.this).start();
|
||||||
|
b.setEnabled(false);
|
||||||
|
checkBox.setEnabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
|
||||||
|
// Progress
|
||||||
|
p0.add(bar);
|
||||||
|
bar.setStringPainted(true);
|
||||||
|
int count = cards.size();
|
||||||
|
float mb = (count * 70.0f) / 1024;
|
||||||
|
bar.setString(String.format(cardIndex == cards.size() ? "%d of %d cards finished! Please close!"
|
||||||
|
: "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cards.size(), mb));
|
||||||
|
Dimension d = bar.getPreferredSize();
|
||||||
|
d.width = 300;
|
||||||
|
bar.setPreferredSize(d);
|
||||||
|
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
checkBox = new JCheckBox("Download for current game only.");
|
||||||
|
p0.add(checkBox);
|
||||||
|
p0.add(Box.createVerticalStrut(5));
|
||||||
|
checkBox.setEnabled(!offlineMode);
|
||||||
|
|
||||||
|
checkBox.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (checkBox.isSelected()) {
|
||||||
|
int count = DownloadPictures.this.cardsInGame.size();
|
||||||
|
float mb = (count * 70.0f) / 1024;
|
||||||
|
bar.setString(String.format(count == 0 ? "No images to download!" : "%d of %d cards finished! Please wait! [%.1f Mb]",
|
||||||
|
0, DownloadPictures.this.cardsInGame.size(), mb));
|
||||||
|
} else {
|
||||||
|
int count = DownloadPictures.this.cards.size();
|
||||||
|
float mb = (count * 70.0f) / 1024;
|
||||||
|
bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
|
||||||
|
: "%d of %d cards finished! Please wait! [%.1f Mb]", 0, count, mb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// JOptionPane
|
||||||
|
Object[] options = { b, close = new JButton("Cancel") };
|
||||||
|
dlg = new JOptionPane(p0, JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArrayList<CardUrl> getNeededCards(Set<Card> allCards) {
|
||||||
|
|
||||||
|
ArrayList<CardUrl> cardsToDownload = new ArrayList<CardUrl>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read all card names and urls
|
||||||
|
*/
|
||||||
|
ArrayList<CardUrl> allcards = new ArrayList<CardUrl>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
offlineMode = true;
|
||||||
|
|
||||||
|
for (Card card : allCards) {
|
||||||
|
if (card.getCardNumber() > 0 && !card.getExpansionSetCode().isEmpty()) {
|
||||||
|
CardUrl url = new CardUrl(card.getName(), card.getExpansionSetCode(), card.getCardNumber(), false);
|
||||||
|
allcards.add(url);
|
||||||
|
} else {
|
||||||
|
if (card.getCardNumber() < 1) {
|
||||||
|
System.err.println("There was a critical error!");
|
||||||
|
log.error("Card has no collector ID and won't be sent to client: " + card);
|
||||||
|
} else if (card.getExpansionSetCode().isEmpty()) {
|
||||||
|
System.err.println("There was a critical error!");
|
||||||
|
log.error("Card has no set name and won't be sent to client:" + card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
File file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check to see which cards we already have
|
||||||
|
*/
|
||||||
|
for (CardUrl card : allcards) {
|
||||||
|
boolean withCollectorId = false;
|
||||||
|
if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp") || card.name.equals("Island")
|
||||||
|
|| card.name.equals("Plains")) {
|
||||||
|
withCollectorId = true;
|
||||||
|
}
|
||||||
|
file = new File(CardImageUtils.getImagePath(card, withCollectorId));
|
||||||
|
if (!file.exists()) {
|
||||||
|
cardsToDownload.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CardUrl card : cardsToDownload) {
|
||||||
|
if (card.token) {
|
||||||
|
log.info("Card to download: " + card.name + " (Token) " + card.url);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
log.info("Card to download: " + card.name + " (" + card.set + ") "
|
||||||
|
+ CardImageUtils.generateURL(card.collector, card.set));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cardsToDownload;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProxyHandler implements ChangeListener {
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
public ProxyHandler(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
if (((AbstractButton) e.getSource()).isSelected()) {
|
||||||
|
DownloadPictures.this.type = type;
|
||||||
|
addr.setEnabled(type != 0);
|
||||||
|
port.setEnabled(type != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
BufferedInputStream in;
|
||||||
|
BufferedOutputStream out;
|
||||||
|
|
||||||
|
File base = new File(Constants.IO.imageBaseDir);
|
||||||
|
if (!base.exists()) {
|
||||||
|
base.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
Proxy p = null;
|
||||||
|
if (type == 0)
|
||||||
|
p = Proxy.NO_PROXY;
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
p = new Proxy(types[type], new InetSocketAddress(addr.getText(), Integer.parseInt(port.getText())));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != null) {
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
|
||||||
|
|
||||||
|
for (update(0); (checkBox.isSelected() ? cardIndex < cardsInGame.size() : cardIndex < cards.size()) && !cancel; update(cardIndex + 1)) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
CardUrl card = checkBox.isSelected() ? cardsInGame.get(cardIndex) : cards.get(cardIndex);
|
||||||
|
|
||||||
|
log.info("Downloading card: " + card.name + " (" + card.set + ")");
|
||||||
|
|
||||||
|
URL url = new URL(CardImageUtils.generateURL(card.collector, card.set));
|
||||||
|
if (ignoreUrls.contains(card.set) || card.token) {
|
||||||
|
// we have card in scripts, but we should ignore
|
||||||
|
// downloading image for it
|
||||||
|
// (e.g. for cards from custom or not released yet sets
|
||||||
|
// such urls should come from card-pictures files
|
||||||
|
// instead
|
||||||
|
if (card.collector != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
url = new URL(card.url);
|
||||||
|
}
|
||||||
|
in = new BufferedInputStream(url.openConnection(p).getInputStream());
|
||||||
|
|
||||||
|
createDirForCard(card);
|
||||||
|
|
||||||
|
boolean withCollectorId = false;
|
||||||
|
if (card.name.equals("Forest") || card.name.equals("Mountain") || card.name.equals("Swamp")
|
||||||
|
|| card.name.equals("Island") || card.name.equals("Plains")) {
|
||||||
|
withCollectorId = true;
|
||||||
|
}
|
||||||
|
File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId));
|
||||||
|
|
||||||
|
out = new BufferedOutputStream(new FileOutputStream(fileOut));
|
||||||
|
|
||||||
|
while ((len = in.read(buf)) != -1) {
|
||||||
|
// user cancelled
|
||||||
|
if (cancel) {
|
||||||
|
in.close();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
// delete what was written so far
|
||||||
|
fileOut.delete();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error(ex, ex);
|
||||||
|
/*
|
||||||
|
* int more = JOptionPane.showConfirmDialog(null,
|
||||||
|
* "Some error occured. Continue downloading pictures?",
|
||||||
|
* "Error", JOptionPane.YES_NO_OPTION); if (more ==
|
||||||
|
* JOptionPane.NO_OPTION) { break; }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close.setText("Close");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File createDirForCard(CardUrl card) throws Exception {
|
||||||
|
File setDir = new File(CardImageUtils.getImageDir(card));
|
||||||
|
if (!setDir.exists()) {
|
||||||
|
setDir.mkdirs();
|
||||||
|
}
|
||||||
|
return setDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update(int card) {
|
||||||
|
this.cardIndex = card;
|
||||||
|
final class Worker implements Runnable {
|
||||||
|
private int card;
|
||||||
|
|
||||||
|
Worker(int card) {
|
||||||
|
this.card = card;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
fireStateChanged();
|
||||||
|
if (checkBox.isSelected()) {
|
||||||
|
int count = DownloadPictures.this.cardsInGame.size();
|
||||||
|
int countLeft = count - card;
|
||||||
|
float mb = (countLeft * 70.0f) / 1024;
|
||||||
|
bar.setString(String.format(this.card == count ? "%d of %d cards finished! Please close!"
|
||||||
|
: "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb));
|
||||||
|
} else {
|
||||||
|
int count = DownloadPictures.this.cards.size();
|
||||||
|
int countLeft = count - card;
|
||||||
|
float mb = (countLeft * 70.0f) / 1024;
|
||||||
|
bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
|
||||||
|
: "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EventQueue.invokeLater(new Worker(card));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(DownloadPictures.class);
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
package org.mage.plugins.card.images;
|
||||||
|
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import mage.view.CardView;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.mage.plugins.card.utils.CardImageUtils;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ComputationException;
|
||||||
|
import com.google.common.collect.MapMaker;
|
||||||
|
import com.mortennobel.imagescaling.ResampleOp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class stores ALL card images in a cache with soft values. this means
|
||||||
|
* that the images may be collected when they are not needed any more, but will
|
||||||
|
* be kept as long as possible.
|
||||||
|
*
|
||||||
|
* Key format: "<cardname>#<setname>#<collectorID>#<param>"
|
||||||
|
*
|
||||||
|
* where param is:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>#Normal: request for unrotated image</li>
|
||||||
|
* <li>#Tapped: request for rotated image</li>
|
||||||
|
* <li>#Cropped: request for cropped image that is used for Shandalar like card
|
||||||
|
* look</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class ImageCache {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(ImageCache.class);
|
||||||
|
|
||||||
|
private static final Map<String, BufferedImage> imageCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common pattern for keys.
|
||||||
|
* Format: "<cardname>#<setname>#<collectorID>"
|
||||||
|
*/
|
||||||
|
private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)");
|
||||||
|
|
||||||
|
static {
|
||||||
|
imageCache = new MapMaker().softValues().makeComputingMap(new Function<String, BufferedImage>() {
|
||||||
|
public BufferedImage apply(String key) {
|
||||||
|
try {
|
||||||
|
Matcher m = KEY_PATTERN.matcher(key);
|
||||||
|
|
||||||
|
if (m.matches()) {
|
||||||
|
String name = m.group(1);
|
||||||
|
String set = m.group(2);
|
||||||
|
Integer collectorId = Integer.parseInt(m.group(3));
|
||||||
|
|
||||||
|
CardInfo info = new CardInfo(name, set, collectorId);
|
||||||
|
|
||||||
|
if (collectorId == 0) info.isToken = true;
|
||||||
|
String path = CardImageUtils.getImagePath(info);
|
||||||
|
if (path == null) return null;
|
||||||
|
File file = new File(path);
|
||||||
|
|
||||||
|
BufferedImage image = loadImage(file);
|
||||||
|
return image;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Requested image doesn't fit the requirement for key (<cardname>#<setname>#<collectorID>): " + key);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
if (ex instanceof ComputationException)
|
||||||
|
throw (ComputationException) ex;
|
||||||
|
else
|
||||||
|
throw new ComputationException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage getImageOriginal(CardView card) {
|
||||||
|
String key = getKey(card);
|
||||||
|
log.debug("#key: " + key);
|
||||||
|
return getImage(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Image corresponding to the key
|
||||||
|
*/
|
||||||
|
private static BufferedImage getImage(String key) {
|
||||||
|
try {
|
||||||
|
BufferedImage image = imageCache.get(key);
|
||||||
|
return image;
|
||||||
|
} catch (NullPointerException ex) {
|
||||||
|
// unfortunately NullOutputException, thrown when apply() returns
|
||||||
|
// null, is not public
|
||||||
|
// NullOutputException is a subclass of NullPointerException
|
||||||
|
// legitimate, happens when a card has no image
|
||||||
|
return null;
|
||||||
|
} catch (ComputationException ex) {
|
||||||
|
if (ex.getCause() instanceof NullPointerException)
|
||||||
|
return null;
|
||||||
|
log.error(ex,ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map key for a card, without any suffixes for the image size.
|
||||||
|
*/
|
||||||
|
private static String getKey(CardView card) {
|
||||||
|
String set = card.getExpansionSetCode();
|
||||||
|
String key = card.getName() + "#" + set + "#" + String.valueOf(card.getCardNumber());
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load image from file
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* file to load image from
|
||||||
|
* @return {@link BufferedImage}
|
||||||
|
*/
|
||||||
|
public static BufferedImage loadImage(File file) {
|
||||||
|
BufferedImage image = null;
|
||||||
|
if (!file.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
image = ImageIO.read(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an image scaled to the size given
|
||||||
|
*/
|
||||||
|
/*private static BufferedImage getNormalSizeImage(BufferedImage original) {
|
||||||
|
int srcWidth = original.getWidth();
|
||||||
|
int srcHeight = original.getHeight();
|
||||||
|
|
||||||
|
int tgtWidth = SettingsManager.getManager().getCardSize().width;
|
||||||
|
int tgtHeight = SettingsManager.getManager().getCardSize().height;
|
||||||
|
|
||||||
|
if (srcWidth == tgtWidth && srcHeight == tgtHeight)
|
||||||
|
return original;
|
||||||
|
|
||||||
|
ResampleOp resampleOp = new ResampleOp(tgtWidth, tgtHeight);
|
||||||
|
BufferedImage image = resampleOp.filter(original, null);
|
||||||
|
return image;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an image scaled to the size appropriate for the card picture
|
||||||
|
* panel For future use.
|
||||||
|
*/
|
||||||
|
private static BufferedImage getFullSizeImage(BufferedImage original, double scale) {
|
||||||
|
if (scale == 1)
|
||||||
|
return original;
|
||||||
|
ResampleOp resampleOp = new ResampleOp((int) (original.getWidth() * scale), (int) (original.getHeight() * scale));
|
||||||
|
BufferedImage image = resampleOp.filter(original, null);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an image scaled to the size appropriate for the card picture
|
||||||
|
* panel
|
||||||
|
*/
|
||||||
|
private static BufferedImage getResizedImage(BufferedImage original, Rectangle sizeNeed) {
|
||||||
|
ResampleOp resampleOp = new ResampleOp(sizeNeed.width, sizeNeed.height);
|
||||||
|
BufferedImage image = resampleOp.filter(original, null);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the image appropriate to display the card in the picture panel
|
||||||
|
*/
|
||||||
|
public static BufferedImage getImage(CardView card, int width, int height) {
|
||||||
|
String key = getKey(card);
|
||||||
|
BufferedImage original = getImage(key);
|
||||||
|
if (original == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight());
|
||||||
|
if (scale > 1)
|
||||||
|
scale = 1;
|
||||||
|
|
||||||
|
return getFullSizeImage(original, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package org.mage.plugins.card.properties;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.mage.plugins.card.constants.Constants;
|
||||||
|
|
||||||
|
public class SettingsManager {
|
||||||
|
|
||||||
|
private static SettingsManager settingsManager = null;
|
||||||
|
|
||||||
|
public static SettingsManager getIntance() {
|
||||||
|
if (settingsManager == null) {
|
||||||
|
synchronized (SettingsManager.class) {
|
||||||
|
if (settingsManager == null) settingsManager = new SettingsManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return settingsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SettingsManager() {
|
||||||
|
loadImageProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadImageProperties() {
|
||||||
|
loadImageProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadImageProperties() {
|
||||||
|
imageUrlProperties = new Properties();
|
||||||
|
try {
|
||||||
|
InputStream is = SettingsManager.class.getClassLoader().getResourceAsStream(Constants.IO.IMAGE_PROPERTIES_FILE);
|
||||||
|
if (is == null)
|
||||||
|
throw new RuntimeException("Couldn't load " + Constants.IO.IMAGE_PROPERTIES_FILE);
|
||||||
|
imageUrlProperties.load(is);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
ioe.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSetNameReplacement(String setName) {
|
||||||
|
String result = setName;
|
||||||
|
if (imageUrlProperties != null) {
|
||||||
|
result = imageUrlProperties.getProperty(setName, setName);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet<String> getIgnoreUrls() {
|
||||||
|
HashSet<String> ignoreUrls = new HashSet<String>();
|
||||||
|
if (imageUrlProperties != null) {
|
||||||
|
String result = imageUrlProperties.getProperty("ignore.urls");
|
||||||
|
if (result != null) {
|
||||||
|
String[] ignore = result.split(",");
|
||||||
|
for (String i : ignore) {
|
||||||
|
ignoreUrls.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ignoreUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getTokenLookupOrder() {
|
||||||
|
ArrayList<String> order = new ArrayList<String>();
|
||||||
|
if (imageUrlProperties != null) {
|
||||||
|
String result = imageUrlProperties.getProperty("token.lookup.order");
|
||||||
|
if (result != null) {
|
||||||
|
String[] sets = result.split(",");
|
||||||
|
for (String s : sets) {
|
||||||
|
order.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties imageUrlProperties;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
package org.mage.plugins.card.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.game.permanent.PermanentToken;
|
||||||
|
|
||||||
|
import org.mage.plugins.card.CardUrl;
|
||||||
|
import org.mage.plugins.card.constants.Constants;
|
||||||
|
import org.mage.plugins.card.images.CardInfo;
|
||||||
|
import org.mage.plugins.card.properties.SettingsManager;
|
||||||
|
|
||||||
|
public class CardImageUtils {
|
||||||
|
|
||||||
|
private static HashMap<CardUrl, String> pathCache = new HashMap<CardUrl, String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path to image for specific card.
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
* card to get path for
|
||||||
|
* @return String if image exists, else null
|
||||||
|
*/
|
||||||
|
public static String getImagePath(CardInfo c) {
|
||||||
|
String filePath;
|
||||||
|
String suffix = ".jpg";
|
||||||
|
String cardname = c.name;
|
||||||
|
String set = c.set;
|
||||||
|
|
||||||
|
CardUrl card = new CardUrl(cardname, set, c.collectorId, c.isToken);
|
||||||
|
|
||||||
|
File file = null;
|
||||||
|
if (c.isToken) {
|
||||||
|
if (pathCache.containsKey(card)) {
|
||||||
|
return pathCache.get(card);
|
||||||
|
}
|
||||||
|
filePath = getTokenImagePath(card);
|
||||||
|
file = new File(filePath);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
filePath = searchForCardImage(card);
|
||||||
|
file = new File(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
pathCache.put(card, filePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filePath = getImagePath(card, false);
|
||||||
|
file = new File(filePath);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
filePath = getImagePath(card, true);
|
||||||
|
file = new File(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try current directory
|
||||||
|
*/
|
||||||
|
if (file == null || !file.exists()) {
|
||||||
|
filePath = cleanString(c.name) + suffix;
|
||||||
|
file = new File(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
return filePath;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isToken(Card c) {
|
||||||
|
return c != null && c instanceof PermanentToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTokenImagePath(CardUrl card) {
|
||||||
|
String filename = getImagePath(card, false);
|
||||||
|
CardUrl c = new CardUrl(card.name, card.set, 0, card.token);
|
||||||
|
|
||||||
|
File file = new File(filename);
|
||||||
|
if (!file.exists()) {
|
||||||
|
c.name = card.name + " 1";
|
||||||
|
filename = getImagePath(c, false);
|
||||||
|
file = new File(filename);
|
||||||
|
if (!file.exists()) {
|
||||||
|
c.name = card.name + " 2";
|
||||||
|
filename = getImagePath(c, false);
|
||||||
|
file = new File(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String searchForCardImage(CardUrl card) {
|
||||||
|
File file = null;
|
||||||
|
String path = "";
|
||||||
|
CardUrl c = new CardUrl(card.name, card.set, 0, card.token);
|
||||||
|
boolean found = false; // search only in older sets
|
||||||
|
for (String set : SettingsManager.getIntance().getTokenLookupOrder()) {
|
||||||
|
if (found) { // start looking for image only if we have found card.set in the list (as this list is ordered)
|
||||||
|
c.set = set;
|
||||||
|
path = getTokenImagePath(c);
|
||||||
|
file = new File(path);
|
||||||
|
if (file.exists()) {
|
||||||
|
pathCache.put(card, path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (set.equals(card.set)) found = true;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String cleanString(String in) {
|
||||||
|
in = in.trim();
|
||||||
|
StringBuffer out = new StringBuffer();
|
||||||
|
char c;
|
||||||
|
for (int i = 0; i < in.length(); i++) {
|
||||||
|
c = in.charAt(i);
|
||||||
|
if (c == ' ' || c == '-')
|
||||||
|
out.append('_');
|
||||||
|
else if (Character.isLetterOrDigit(c)) {
|
||||||
|
out.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.toString().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateURL(Integer collectorId, String cardSet) throws Exception {
|
||||||
|
if (collectorId == null || cardSet == null) {
|
||||||
|
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
|
||||||
|
}
|
||||||
|
String set = updateSet(cardSet,true);
|
||||||
|
String url = "http://magiccards.info/scans/en/";
|
||||||
|
url += set.toLowerCase() + "/" + collectorId + ".jpg";
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String updateSet(String cardSet, boolean forUrl) {
|
||||||
|
String set = cardSet.toLowerCase();
|
||||||
|
if (set.equals("con")) {
|
||||||
|
set = "cfx";
|
||||||
|
}
|
||||||
|
if (forUrl) {
|
||||||
|
set = SettingsManager.getIntance().getSetNameReplacement(set);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getImageDir(CardUrl card) {
|
||||||
|
if (card.set == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String set = updateSet(card.set,false).toUpperCase();
|
||||||
|
if (card.token) {
|
||||||
|
return Constants.IO.imageBaseDir + File.separator + "TOK" + File.separator + set;
|
||||||
|
} else {
|
||||||
|
return Constants.IO.imageBaseDir + set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getImagePath(CardUrl card, boolean withCollector) {
|
||||||
|
if (withCollector) {
|
||||||
|
return getImageDir(card) + File.separator + card.name + "." + card.collector + ".full.jpg";
|
||||||
|
} else {
|
||||||
|
return getImageDir(card) + File.separator + card.name + ".full.jpg";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
tsp=ts
|
||||||
|
tor=tr
|
||||||
|
mor=mt
|
||||||
|
ody=od
|
||||||
|
lrw=lw
|
||||||
|
plc=pc
|
||||||
|
gpt=gp
|
||||||
|
inv=in
|
||||||
|
ons=on
|
||||||
|
scg=sc
|
||||||
|
jud=ju
|
||||||
|
mmq=mm
|
||||||
|
pls=ps
|
||||||
|
mrd=mi
|
||||||
|
mir=mr
|
||||||
|
tst=ts
|
||||||
|
usg=us
|
||||||
|
apc=ap
|
||||||
|
nms=ne
|
||||||
|
dis=di
|
||||||
|
vis=vi
|
||||||
|
9ed=9e
|
||||||
|
8ed=8e
|
||||||
|
7ed=7e
|
||||||
|
4ed=4e
|
||||||
|
tsb=tsts
|
||||||
|
ulg=ul
|
||||||
|
5ed=5e
|
||||||
|
6ed=6e
|
||||||
|
btd=bd
|
||||||
|
sth=sh
|
||||||
|
nem=ne
|
||||||
|
por=po
|
||||||
|
s99=st
|
||||||
|
lgn=le
|
||||||
|
ice=ia
|
||||||
|
csp=cs
|
||||||
|
tmp=tp
|
||||||
|
s00=st2k
|
||||||
|
dst=ds
|
||||||
|
pcy=pr
|
||||||
|
uds=ud
|
||||||
|
exo=ex
|
||||||
|
lea=al
|
||||||
|
hop=pch
|
||||||
|
chr=ch
|
||||||
|
arn=an
|
||||||
|
wth=wl
|
||||||
|
leb=be
|
||||||
|
2ed=un
|
||||||
|
3ed=rv
|
||||||
|
brb=br
|
||||||
|
atq=aq
|
||||||
|
fem=fe
|
||||||
|
leg=lg
|
||||||
|
ptk=p3k
|
||||||
|
ignore.urls=TOK
|
||||||
|
# sets ordered by release time (newest goes first)
|
||||||
|
token.lookup.order=ROE,PVC,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS
|
||||||
Loading…
Add table
Add a link
Reference in a new issue