diff --git a/Mage.Client/install_3d_party_libs.bat b/Mage.Client/install_3d_party_libs.bat
new file mode 100644
index 0000000000..9145c3c5c8
--- /dev/null
+++ b/Mage.Client/install_3d_party_libs.bat
@@ -0,0 +1,2 @@
+rem installs 3d party libs to local repository
+mvn install:install-file -Dfile=plugins/core/jspf.core-0.9.0.jar -DgroupId=org.plugins.jspf -DartifactId=jspf-core -Dversion=0.9.1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
\ No newline at end of file
diff --git a/Mage.Client/install_3d_party_libs.sh b/Mage.Client/install_3d_party_libs.sh
new file mode 100644
index 0000000000..5e0af555c2
--- /dev/null
+++ b/Mage.Client/install_3d_party_libs.sh
@@ -0,0 +1,2 @@
+# installs 3d party libs to local repository
+mvn install:install-file -Dfile=plugins/core/jspf.core-0.9.0.jar -DgroupId=org.plugins.jspf -DartifactId=jspf-core -Dversion=0.9.1 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
\ No newline at end of file
diff --git a/Mage.Client/plugins/Mage-Theme-Plugin-0.3-shaded.jar b/Mage.Client/plugins/Mage-Theme-Plugin-0.3-shaded.jar
new file mode 100644
index 0000000000..192fc6472c
Binary files /dev/null and b/Mage.Client/plugins/Mage-Theme-Plugin-0.3-shaded.jar differ
diff --git a/Mage.Client/plugins/core/jspf.core-0.9.0.jar b/Mage.Client/plugins/core/jspf.core-0.9.0.jar
new file mode 100644
index 0000000000..7617e9b59b
Binary files /dev/null and b/Mage.Client/plugins/core/jspf.core-0.9.0.jar differ
diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml
index a22964dd81..0b243a2e2b 100644
--- a/Mage.Client/pom.xml
+++ b/Mage.Client/pom.xml
@@ -32,6 +32,11 @@
Mage-Sets
${mage-version}
+
+ org.plugins.jspf
+ jspf-core
+ ${jspf-version}
+
@@ -44,32 +49,37 @@
1.6
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 2.3.1
+
maven-resources-plugin
UTF-8
-
- maven-jar-plugin
-
-
-
- true
- lib/
- mage.client.MageFrame
-
-
-
-
-
- maven-assembly-plugin
-
-
- src/main/assembly/distribution.xml
-
-
-
+
+ maven-jar-plugin
+
+
+
+ true
+ lib/
+ mage.client.MageFrame
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ src/main/assembly/distribution.xml
+
+
+
mage-client
@@ -77,5 +87,6 @@
0.3
+ 0.9.1
diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index 95dc10b8a0..67687103ba 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -37,23 +37,31 @@ package mage.client;
import java.awt.Cursor;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
+import java.io.File;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
+
import javax.swing.Box;
import javax.swing.JDesktopPane;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
+
import mage.client.dialog.AboutDialog;
import mage.client.dialog.CombatDialog;
import mage.client.dialog.ConnectDialog;
import mage.client.dialog.PickNumberDialog;
+import mage.client.plugins.impl.Plugins;
import mage.client.remote.Session;
import mage.client.util.EDTExceptionHandler;
+import mage.interfaces.plugin.ThemePlugin;
import mage.util.Logging;
+import net.xeoh.plugins.base.PluginManager;
+import net.xeoh.plugins.base.impl.PluginManagerFactory;
+import net.xeoh.plugins.base.util.PluginManagerUtil;
/**
*
@@ -103,6 +111,7 @@ public class MageFrame extends javax.swing.JFrame {
logger.log(Level.SEVERE, null, ex);
}
+ Plugins.getInstance().loadPlugins();
initComponents();
@@ -344,6 +353,7 @@ public class MageFrame extends javax.swing.JFrame {
private void exitApp() {
session.disconnect();
+ Plugins.getInstance().shutdown();
dispose();
System.exit(0);
}
diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java
index fe56d42820..fba8993833 100644
--- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java
@@ -38,13 +38,11 @@ import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
-import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
-import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
@@ -55,10 +53,10 @@ import mage.client.dialog.ExileZoneDialog;
import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.ShowCardsDialog;
import mage.client.game.FeedbackPanel.FeedbackMode;
+import mage.client.plugins.impl.Plugins;
import mage.client.remote.Session;
import mage.client.util.Config;
import mage.client.util.gui.ArrowBuilder;
-import mage.client.util.gui.ImagePanel;
import mage.util.Logging;
import mage.view.AbilityPickerView;
import mage.view.CardsView;
@@ -86,8 +84,8 @@ public class GamePanel extends javax.swing.JPanel {
//FIXME: remove from here
try {
- BufferedImage background = ImageIO.read(this.getClass().getResourceAsStream("/green.jpg"));
- ImagePanel bgPanel = new ImagePanel(background, ImagePanel.TILED);
+ /*BufferedImage background = ImageIO.read(this.getClass().getResourceAsStream("/green.jpg"));
+ ImagePanel bgPanel = new ImagePanel(background, ImagePanel.TILED);*/
// Override layout (I can't edit generated code)
this.setLayout(new BorderLayout());
@@ -95,16 +93,11 @@ public class GamePanel extends javax.swing.JPanel {
j.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.MODAL_LAYER);
j.setSize(1024,768);
//j.setBorder(BorderFactory.createLineBorder(Color.green));
- //this.add(j);
+ this.add(j);
j.add(jSplitPane1, JLayeredPane.DEFAULT_LAYER);
- jSplitPane1.setOpaque(false);
- pnlBattlefield.setOpaque(false);
- jPanel3.setOpaque(false);
- hand.setOpaque(false);
- chatPanel.setOpaque(false);
- bgPanel.add(j);
- this.add(bgPanel);
+ Map ui = getUIComponents(j);
+ Plugins.getInstance().updateGamePanel(ui);
// Enlarge jlayeredpane on resize
addComponentListener(new ComponentAdapter(){
@@ -125,6 +118,20 @@ public class GamePanel extends javax.swing.JPanel {
}
}
+ private Map getUIComponents(JLayeredPane jLayeredPane) {
+ Map components = new HashMap();
+
+ components.put("jSplitPane1", jSplitPane1);
+ components.put("pnlBattlefield", pnlBattlefield);
+ components.put("jPanel3", jPanel3);
+ components.put("hand", hand);
+ components.put("chatPanel", chatPanel);
+ components.put("jLayeredPane", jLayeredPane);
+ components.put("gamePanel", this);
+
+ return components;
+ }
+
public void cleanUp() {
MageFrame.getCombatDialog().hideDialog();
MageFrame.getPickNumberDialog().hide();
diff --git a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java
new file mode 100644
index 0000000000..84d14f2160
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java
@@ -0,0 +1,11 @@
+package mage.client.plugins;
+
+import java.util.Map;
+
+import javax.swing.JComponent;
+
+public interface MagePlugins {
+ void loadPlugins();
+ void shutdown();
+ void updateGamePanel(Map ui);
+}
diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java
new file mode 100644
index 0000000000..8ebccb0aa0
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java
@@ -0,0 +1,50 @@
+package mage.client.plugins.impl;
+
+import java.io.File;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JComponent;
+
+import mage.client.plugins.MagePlugins;
+import mage.client.util.Constants;
+import mage.interfaces.plugin.ThemePlugin;
+import mage.util.Logging;
+import net.xeoh.plugins.base.PluginManager;
+import net.xeoh.plugins.base.impl.PluginManagerFactory;
+import net.xeoh.plugins.base.util.PluginManagerUtil;
+
+
+public class Plugins implements MagePlugins {
+
+ private static final MagePlugins fINSTANCE = new Plugins();
+ private static PluginManager pm;
+ private final static Logger logger = Logging.getLogger(Plugins.class.getName());
+
+ public static MagePlugins getInstance() {
+ return fINSTANCE;
+ }
+
+ @Override
+ public void loadPlugins() {
+ logger.log(Level.INFO, "Loading plugins...");
+ pm = PluginManagerFactory.createPluginManager();
+ pm.addPluginsFrom(new File(Constants.PLUGINS_DIRECTORY).toURI());
+ logger.log(Level.INFO, "Done.");
+ }
+
+ @Override
+ public void shutdown() {
+ if (pm != null) pm.shutdown();
+ }
+
+ @Override
+ public void updateGamePanel(Map ui) {
+ PluginManagerUtil pmu = new PluginManagerUtil(pm);
+
+ for (ThemePlugin pl : pmu.getPlugins(ThemePlugin.class)) {
+ pl.apply(ui);
+ }
+ }
+}
diff --git a/Mage.Client/src/main/java/mage/client/util/Constants.java b/Mage.Client/src/main/java/mage/client/util/Constants.java
index 1daaeed73d..e3a77f2212 100644
--- a/Mage.Client/src/main/java/mage/client/util/Constants.java
+++ b/Mage.Client/src/main/java/mage/client/util/Constants.java
@@ -68,4 +68,6 @@ public final class Constants {
public static final int DAMAGE_MAX_LEFT = 180;
public static final double SCALE_FACTOR = 0.5;
+
+ public static final String PLUGINS_DIRECTORY = "plugins/";
}
diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml
index 5c8c547b90..35f5d037a1 100644
--- a/Mage.Common/pom.xml
+++ b/Mage.Common/pom.xml
@@ -22,6 +22,11 @@
Mage
${mage-version}
+
+ org.plugins.jspf
+ jspf-core
+ ${jspf-version}
+
@@ -50,5 +55,6 @@
0.3
+ 0.9.1
diff --git a/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java
new file mode 100644
index 0000000000..b840d8e1cf
--- /dev/null
+++ b/Mage.Common/src/mage/interfaces/plugin/CardPlugin.java
@@ -0,0 +1,13 @@
+package mage.interfaces.plugin;
+
+import net.xeoh.plugins.base.Plugin;
+
+/**
+ * Interface for card plugins
+ *
+ * @version 0.1 31.10.2010
+ * @author nantuko
+ */
+public interface CardPlugin extends Plugin {
+
+}
diff --git a/Mage.Common/src/mage/interfaces/plugin/ThemePlugin.java b/Mage.Common/src/mage/interfaces/plugin/ThemePlugin.java
new file mode 100644
index 0000000000..12c920c0e3
--- /dev/null
+++ b/Mage.Common/src/mage/interfaces/plugin/ThemePlugin.java
@@ -0,0 +1,17 @@
+package mage.interfaces.plugin;
+
+import java.util.Map;
+
+import javax.swing.JComponent;
+
+import net.xeoh.plugins.base.Plugin;
+
+/**
+ * Interface for theme plugins
+ *
+ * @version 0.1 31.10.2010
+ * @author nantuko
+ */
+public interface ThemePlugin extends Plugin {
+ void apply(Map ui);
+}
diff --git a/Mage.Player.AIMinimax/pom.xml b/Mage.Player.AIMinimax/pom.xml
index cde93ea5b5..2578ba11f2 100644
--- a/Mage.Player.AIMinimax/pom.xml
+++ b/Mage.Player.AIMinimax/pom.xml
@@ -10,7 +10,7 @@
org.mage
- mage-player-aiminimax
+ Mage-Player-AIMinimax
jar
0.3
Mage Player AI Minimax
diff --git a/Mage.Plugins/Mage.Card.Plugin/pom.xml b/Mage.Plugins/Mage.Card.Plugin/pom.xml
new file mode 100644
index 0000000000..cc8b0a9cbf
--- /dev/null
+++ b/Mage.Plugins/Mage.Card.Plugin/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+
+ org.mage
+ Mage-Plugins
+ ${mage-version}
+
+
+ org.mage
+ Mage-Card-Plugin
+ jar
+ ${plugin-version}
+ Mage Card Plugin
+ Plugin for drawing card
+
+
+
+ org.plugins.jspf
+ jspf-core
+ ${jspf-version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+ mage-card-plugin
+
+
+
+ 0.3
+ 0.9.1
+
+
diff --git a/Mage.Plugins/Mage.Theme.Plugin/pom.xml b/Mage.Plugins/Mage.Theme.Plugin/pom.xml
new file mode 100644
index 0000000000..cbd1f07928
--- /dev/null
+++ b/Mage.Plugins/Mage.Theme.Plugin/pom.xml
@@ -0,0 +1,81 @@
+
+
+ 4.0.0
+
+
+ org.mage
+ Mage-Plugins
+ ${mage-version}
+
+
+ org.mage
+ Mage-Theme-Plugin
+ jar
+ ${plugin-version}
+ Mage Theme Plugin
+ Contains resources for drawing background
+
+
+
+ org.mage
+ Mage-Common
+ ${mage-version}
+
+
+ org.plugins.jspf
+ jspf-core
+ ${jspf-version}
+
+
+ log4j
+ log4j
+ 1.2.9
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.6
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 1.4
+
+
+ package
+
+ shade
+
+
+ true
+
+
+ log4j:log4j:jar:
+
+
+
+
+
+
+
+
+
+ mage-theme-plugin
+
+
+
+ 0.3
+ 0.3
+ 0.9.1
+
+
diff --git a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/component/ImagePanel.java b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/component/ImagePanel.java
new file mode 100644
index 0000000000..d35796d127
--- /dev/null
+++ b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/component/ImagePanel.java
@@ -0,0 +1,105 @@
+package org.mage.plugins.component;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JViewport;
+
+@SuppressWarnings("serial")
+public class ImagePanel extends JPanel {
+ public static final int TILED = 0;
+ public static final int SCALED = 1;
+ public static final int ACTUAL = 2;
+
+ private BufferedImage image;
+ private int style;
+ private float alignmentX = 0.5f;
+ private float alignmentY = 0.5f;
+
+ public ImagePanel(BufferedImage image) {
+ this(image, TILED);
+ }
+
+ public ImagePanel(BufferedImage image, int style) {
+ this.image = image;
+ this.style = style;
+ setLayout(new BorderLayout());
+ }
+
+ public void setImageAlignmentX(float alignmentX) {
+ this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
+ }
+
+ public void setImageAlignmentY(float alignmentY) {
+ this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
+
+ }
+
+ public void add(JComponent component) {
+ add(component, null);
+ }
+
+ public void add(JComponent component, Object constraints) {
+ component.setOpaque(false);
+
+ if (component instanceof JScrollPane) {
+ JScrollPane scrollPane = (JScrollPane) component;
+ JViewport viewport = scrollPane.getViewport();
+ viewport.setOpaque(false);
+ Component c = viewport.getView();
+
+ if (c instanceof JComponent) {
+ ((JComponent) c).setOpaque(false);
+ }
+ }
+
+ super.add(component, constraints);
+ }
+
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ if (image == null)
+ return;
+
+ switch (style) {
+ case TILED:
+ drawTiled(g);
+ break;
+
+ case SCALED:
+ Dimension d = getSize();
+ g.drawImage(image, 0, 0, d.width, d.height, null);
+ break;
+
+ case ACTUAL:
+ drawActual(g);
+ break;
+ }
+ }
+
+ private void drawTiled(Graphics g) {
+ Dimension d = getSize();
+ int width = image.getWidth(null);
+ int height = image.getHeight(null);
+
+ for (int x = 0; x < d.width; x += width) {
+ for (int y = 0; y < d.height; y += height) {
+ g.drawImage(image, x, y, null, null);
+ }
+ }
+ }
+
+ private void drawActual(Graphics g) {
+ Dimension d = getSize();
+ float x = (d.width - image.getWidth()) * alignmentX;
+ float y = (d.height - image.getHeight()) * alignmentY;
+ g.drawImage(image, (int) x, (int) y, this);
+ }
+}
diff --git a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java
new file mode 100644
index 0000000000..236b231a3a
--- /dev/null
+++ b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java
@@ -0,0 +1,71 @@
+package org.mage.plugins.theme;
+import java.awt.image.BufferedImage;
+import java.io.FileNotFoundException;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.swing.JComponent;
+
+import mage.interfaces.plugin.ThemePlugin;
+import net.xeoh.plugins.base.annotations.PluginImplementation;
+import net.xeoh.plugins.base.annotations.events.Init;
+import net.xeoh.plugins.base.annotations.events.PluginLoaded;
+import net.xeoh.plugins.base.annotations.meta.Author;
+
+import org.apache.log4j.Logger;
+import org.mage.plugins.component.ImagePanel;
+
+@PluginImplementation
+@Author(name="nantuko")
+public class ThemePluginImpl implements ThemePlugin {
+
+ private final static Logger log = Logger.getLogger(ThemePluginImpl.class);
+
+ @Init
+ public void init() {
+ }
+
+ @PluginLoaded
+ public void newPlugin(ThemePlugin plugin) {
+ log.info(plugin.toString() + " has been loaded.");
+ }
+
+ public String toString() {
+ return "[Theme plugin by nantuko, version 0.1]";
+ }
+
+ public void apply(Map ui) {
+ log.info("Adding background...");
+ try {
+ BufferedImage background = ImageIO.read(this.getClass().getResourceAsStream("/green.jpg"));
+
+ if (background == null)
+ throw new FileNotFoundException("Couldn't find green.jpg in resources.");
+
+ if (ui.containsKey("gamePanel") && ui.containsKey("jLayeredPane")) {
+ ImagePanel bgPanel = new ImagePanel(background, ImagePanel.TILED);
+
+ unsetOpaque(ui.get("jSplitPane1"));
+ unsetOpaque(ui.get("pnlBattlefield"));
+ unsetOpaque(ui.get("jPanel3"));
+ unsetOpaque(ui.get("hand"));
+ unsetOpaque(ui.get("chatPanel"));
+
+ ui.get("gamePanel").remove(ui.get("jLayeredPane"));
+ bgPanel.add(ui.get("jLayeredPane"));
+ ui.get("gamePanel").add(bgPanel);
+ } else {
+ log.error("error: no components");
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return;
+ }
+
+ log.info("Done.");
+ }
+
+ private void unsetOpaque(JComponent c) {
+ if (c != null) c.setOpaque(false);
+ }
+}
diff --git a/Mage.Client/src/main/resources/green.jpg b/Mage.Plugins/Mage.Theme.Plugin/src/main/resources/green.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/green.jpg
rename to Mage.Plugins/Mage.Theme.Plugin/src/main/resources/green.jpg
diff --git a/Mage.Plugins/Mage.Theme.Plugin/src/main/resources/log4j.properties b/Mage.Plugins/Mage.Theme.Plugin/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..08d7f0e74f
--- /dev/null
+++ b/Mage.Plugins/Mage.Theme.Plugin/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+#default levels
+log4j.rootLogger=debug, console
+
+#console log
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-5p [%d{yyyy-MM-dd HH:mm [ss:SSS]}] %C{1}[%t]: %m%n
+log4j.appender.console.Threshold=DEBUG
\ No newline at end of file
diff --git a/Mage.Plugins/pom.xml b/Mage.Plugins/pom.xml
new file mode 100644
index 0000000000..8b70b2d3db
--- /dev/null
+++ b/Mage.Plugins/pom.xml
@@ -0,0 +1,25 @@
+
+
+
+ 4.0.0
+
+
+ org.mage
+ mage-root
+ ${mage-version}
+
+
+ org.mage
+ Mage-Plugins
+ ${mage-version}
+ pom
+ Mage Plugins
+ Mage Plugins POM
+
+
+ Mage.Theme.Plugin
+ Mage.Card.Plugin
+
+
+
diff --git a/pom.xml b/pom.xml
index 0bb0ba1e11..4e88e46e75 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,18 +1,19 @@
+
4.0.0
org.mage
mage-root
- 0.3
+ ${mage-version}
pom
Mage Root
Mage Root POM
-
- Mage
- Mage.Common
+
+ Mage
+ Mage.Common
Mage.Server
Mage.Sets
Mage.Client
@@ -22,20 +23,10 @@
Mage.Player.AI
Mage.Player.AIMinimax
Mage.Player.Human
-
+ Mage.Plugins
+
-
-
- normal-build
-
-
- true
-
-
-
-
0.3
-