diff --git a/.hgignore b/.hgignore index f7ef203151..02cf303401 100644 --- a/.hgignore +++ b/.hgignore @@ -24,9 +24,10 @@ Mage/target syntax: regexp .class .jar -.iml -.ipr -.iws +.iml +.ipr +.iws nbactions.xml glob:Mage.Client/cheat.dck glob:Mage.Client/test.dck +glob:Mage.Server.Console/target/ diff --git a/Mage.Client/plugins/mage-counter-plugin.jar b/Mage.Client/plugins/mage-counter-plugin.jar index 7114efce24..4cd8c3e86e 100644 Binary files a/Mage.Client/plugins/mage-counter-plugin.jar and b/Mage.Client/plugins/mage-counter-plugin.jar differ diff --git a/Mage.Client/plugins/mage-theme-plugin.jar b/Mage.Client/plugins/mage-theme-plugin.jar index 54a15502b1..575c757aa6 100644 Binary files a/Mage.Client/plugins/mage-theme-plugin.jar and b/Mage.Client/plugins/mage-theme-plugin.jar differ diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index e9b4b4bfad..72b75d7104 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -97,6 +97,11 @@ 0.1 runtime + + ${project.groupId} + Mage-Common + ${project.version} + diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form index 5354625cd3..9e18483966 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form @@ -72,13 +72,11 @@ - + - - - - + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index aa6f1623ba..bcf680160b 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -261,12 +261,11 @@ public class NewTournamentDialog extends MageDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE) + .addComponent(pnlPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE) .addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(spnNumPlayers) - .addComponent(jLabel2)) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE) + .addComponent(jLabel2) .addComponent(pnlDraftOptions, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) diff --git a/Mage.Client/src/main/java/mage/client/remote/Session.java b/Mage.Client/src/main/java/mage/client/remote/Session.java index b99bceeb7c..95ad65df90 100644 --- a/Mage.Client/src/main/java/mage/client/remote/Session.java +++ b/Mage.Client/src/main/java/mage/client/remote/Session.java @@ -37,8 +37,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import javax.swing.JOptionPane; import mage.cards.decks.DeckCardLists; import mage.client.MageFrame; @@ -61,6 +63,7 @@ import mage.view.GameTypeView; import mage.view.TableView; import mage.view.TournamentTypeView; import mage.view.TournamentView; +import org.apache.log4j.Logger; /** * @@ -68,7 +71,8 @@ import mage.view.TournamentView; */ public class Session { - private final static Logger logger = Logging.getLogger(Session.class.getName()); + private final static Logger logger = Logger.getLogger(Session.class); + private static ScheduledExecutorService sessionExecutor = Executors.newScheduledThreadPool(1); private UUID sessionId; private Server server; @@ -81,6 +85,7 @@ public class Session { private Map drafts = new HashMap(); private Map tournaments = new HashMap(); private CallbackClientDaemon callbackDaemon; + private ScheduledFuture future; private MageUI ui = new MageUI(); public Session(MageFrame frame) { @@ -112,20 +117,21 @@ public class Session { sessionId = server.registerClient(userName, client.getId(), frame.getVersion()); callbackDaemon = new CallbackClientDaemon(sessionId, client, server); serverState = server.getServerState(); + future = sessionExecutor.scheduleWithFixedDelay(new ServerPinger(), 5, 5, TimeUnit.SECONDS); logger.info("Connected to RMI server at " + serverName + ":" + port); frame.setStatusText("Connected to " + serverName + ":" + port + " "); frame.enableButtons(); return true; } catch (MageException ex) { - logger.log(Level.SEVERE, null, ex); + logger.fatal("", ex); disconnect(); JOptionPane.showMessageDialog(frame, "Unable to connect to server. " + ex.getMessage()); } catch (RemoteException ex) { - logger.log(Level.SEVERE, "Unable to connect to server - ", ex); + logger.fatal("Unable to connect to server - ", ex); disconnect(); JOptionPane.showMessageDialog(frame, "Unable to connect to server. " + ex.getMessage()); } catch (NotBoundException ex) { - logger.log(Level.SEVERE, "Unable to connect to server - ", ex); + logger.fatal("Unable to connect to server - ", ex); } return false; } @@ -134,7 +140,6 @@ public class Session { if (isConnected()) { try { - frame.hideTables(); for (UUID chatId: chats.keySet()) { server.leaveChat(chatId, sessionId); } @@ -145,18 +150,26 @@ public class Session { try { //TODO: stop daemon server.deregisterClient(sessionId); - server = null; - logger.info("Disconnected ... "); } catch (RemoteException ex) { - logger.log(Level.SEVERE, "Error disconnecting ...", ex); + logger.fatal("Error disconnecting ...", ex); } catch (MageException ex) { - logger.log(Level.SEVERE, "Error disconnecting ...", ex); + logger.fatal("Error disconnecting ...", ex); } - frame.setStatusText("Not connected "); - frame.disableButtons(); + removeServer(); } } + private void removeServer() { + if (future != null && !future.isDone()) + future.cancel(true); + server = null; + frame.hideTables(); + frame.setStatusText("Not connected"); + frame.disableButtons(); + logger.info("Disconnected ... "); + JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Disconnected.", "Disconnected", JOptionPane.INFORMATION_MESSAGE); + } + public void ack(String message) { try { server.ack(message, sessionId); @@ -167,6 +180,17 @@ public class Session { } } + public boolean ping() { + try { + return server.ping(sessionId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + public boolean isConnected() { return server != null; } @@ -717,26 +741,19 @@ public class Session { } private void handleRemoteException(RemoteException ex) { - logger.log(Level.SEVERE, "Communication error", ex); - if (ex instanceof java.rmi.ConnectException) { - server = null; - frame.setStatusText("Not connected"); - frame.disableButtons(); - JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Communication error - disconnecting.", "Error", JOptionPane.ERROR_MESSAGE); - } - else - JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Communication error.", "Error", JOptionPane.ERROR_MESSAGE); + logger.fatal("Communication error", ex); + removeServer(); } private void handleMageException(MageException ex) { - logger.log(Level.SEVERE, "Server error", ex); + logger.fatal("Server error", ex); JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Critical server error. Disconnecting", "Error", JOptionPane.ERROR_MESSAGE); disconnect(); frame.disableButtons(); } private void handleGameException(GameException ex) { - logger.log(Level.WARNING, "Game error", ex.getMessage()); + logger.warn(ex.getMessage()); JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } @@ -752,5 +769,24 @@ public class Session { public Server getServerRef() { return server; } + + class ServerPinger implements Runnable { + private int missed = 0; + + @Override + public void run() { + if (!ping()) { + missed++; + if (missed > 10) { + logger.info("Connection to server timed out"); + removeServer(); + } + } + else { + missed = 0; + } + } + + } } \ No newline at end of file diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 4dac2f9091..bb2f03ca67 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -190,10 +190,11 @@ public class TablesPanel extends javax.swing.JPanel { } public void hideTables() { - if (tableWaitingDialog.isVisible()) { + if (tableWaitingDialog != null && tableWaitingDialog.isVisible()) { tableWaitingDialog.closeDialog(); } - updateTask.cancel(true); + if (updateTask != null) + updateTask.cancel(true); this.chatPanel.disconnect(); Component c = this.getParent(); diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form index a7a2cba1d1..cf0e9c838d 100644 --- a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form +++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.form @@ -21,7 +21,7 @@ - + @@ -78,11 +78,11 @@ - + - + diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java index ecf9485760..42fdffe889 100644 --- a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java @@ -116,11 +116,11 @@ public class TournamentPlayerPanel extends javax.swing.JPanel { .addGroup(pnlPlayerNameLayout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cbLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)) + .addComponent(txtPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE)) ); pnlPlayerNameLayout.setVerticalGroup( pnlPlayerNameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -140,7 +140,7 @@ public class TournamentPlayerPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cbPlayerType, javax.swing.GroupLayout.PREFERRED_SIZE, 138, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbPlayerType, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(pnlPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); diff --git a/Mage.Common/src/mage/interfaces/Server.java b/Mage.Common/src/mage/interfaces/Server.java index e19e092301..852b9f0ded 100644 --- a/Mage.Common/src/mage/interfaces/Server.java +++ b/Mage.Common/src/mage/interfaces/Server.java @@ -42,6 +42,7 @@ import mage.view.DraftPickView; import mage.view.TableView; import mage.view.GameView; import mage.view.TournamentView; +import mage.view.UserView; /** * @@ -50,8 +51,10 @@ import mage.view.TournamentView; public interface Server extends Remote, CallbackServer { public UUID registerClient(String userName, UUID clientId, MageVersion version) throws RemoteException, MageException; + public UUID registerAdmin(String password, MageVersion version) throws RemoteException, MageException; public void deregisterClient(UUID sessionId) throws RemoteException, MageException; public void ack(String message, UUID sessionId) throws RemoteException, MageException; + public boolean ping(UUID sessionId) throws RemoteException, MageException; public ServerState getServerState() throws RemoteException, MageException; @@ -116,4 +119,8 @@ public interface Server extends Remote, CallbackServer { public void cheat(UUID gameId, UUID sessionId, UUID playerId, DeckCardLists deckList) throws RemoteException, MageException; public boolean cheat(UUID gameId, UUID sessionId, UUID playerId, String cardName) throws RemoteException, MageException; public GameView getGameView(UUID gameId, UUID sessionId, UUID playerId) throws RemoteException, MageException; + + //admin methods + public List getUsers(UUID sessionId) throws RemoteException, MageException; + } diff --git a/Mage.Common/src/mage/view/UserView.java b/Mage.Common/src/mage/view/UserView.java new file mode 100644 index 0000000000..ef91e22892 --- /dev/null +++ b/Mage.Common/src/mage/view/UserView.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.view; + +import java.io.Serializable; +import java.util.Date; +import java.util.UUID; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class UserView implements Serializable { + + private String userName; + private String host; + private UUID sessionId; + private Date timeConnected; + + public UserView(String userName, String host, UUID sessionId, Date timeConnected) { + this.userName = userName; + this.host = host; + this.sessionId = sessionId; + } + + public String getUserName() { + return userName; + } + + public String getHost() { + return host; + } + + public UUID getSessionId() { + return sessionId; + } + + public Date getConnectionTime() { + return timeConnected; + } + +} diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml new file mode 100644 index 0000000000..2fe1efb053 --- /dev/null +++ b/Mage.Server.Console/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + mage-root + org.mage + 0.7.2 + + org.mage + Mage.Server.Console + 0.8 + Mage Server Console + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + ${project.groupId} + Mage-Common + 0.7.2 + + + org.swinglabs + swingx + 1.6.1 + + + diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.form b/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.form new file mode 100644 index 0000000000..1ee8b0374f --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.form @@ -0,0 +1,240 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.java b/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.java new file mode 100644 index 0000000000..58a83b84fd --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.java @@ -0,0 +1,410 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +/* + * ConnectDialog.java + * + * Created on 20-Jan-2010, 9:37:07 PM + */ + +package mage.server.console; + +import java.awt.Cursor; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import org.apache.log4j.Logger; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ConnectDialog extends JDialog { + + private final static Logger logger = Logger.getLogger(ConnectDialog.class); + + private ConsoleFrame console; + + /** Creates new form ConnectDialog */ + public ConnectDialog() { + initComponents(); + } + + public void showDialog(ConsoleFrame console) { + this.console = console; + this.txtServer.setText(ConsoleFrame.getPreferences().get("serverAddress", "")); + this.txtPort.setText(ConsoleFrame.getPreferences().get("serverPort", "")); + this.chkAutoConnect.setSelected(Boolean.parseBoolean(ConsoleFrame.getPreferences().get("autoConnect", "false"))); + this.txtProxyServer.setText(ConsoleFrame.getPreferences().get("proxyAddress", "")); + this.txtProxyPort.setText(ConsoleFrame.getPreferences().get("proxyPort", "")); + this.chkUseProxy.setSelected(Boolean.parseBoolean(ConsoleFrame.getPreferences().get("useProxy", "false"))); + this.showProxySettings(); + this.setModal(true); + this.setLocation(50, 50); + this.setVisible(true); + } + + private void showProxySettings() { + if (chkUseProxy.isSelected()) { + this.pnlProxy.setVisible(true); + } + else { + this.pnlProxy.setVisible(false); + } + this.pack(); +// this.revalidate(); + this.repaint(); + } + + private void saveSettings() { + ConsoleFrame.getPreferences().put("serverAddress", txtServer.getText()); + ConsoleFrame.getPreferences().put("serverPort", txtPort.getText()); + ConsoleFrame.getPreferences().put("autoConnect", Boolean.toString(chkAutoConnect.isSelected())); + ConsoleFrame.getPreferences().put("proxyAddress", txtProxyServer.getText()); + ConsoleFrame.getPreferences().put("proxyPort", txtProxyPort.getText()); + ConsoleFrame.getPreferences().put("useProxy", Boolean.toString(chkUseProxy.isSelected())); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + txtServer = new javax.swing.JTextField(); + lblServer = new javax.swing.JLabel(); + lblPort = new javax.swing.JLabel(); + txtPort = new javax.swing.JTextField(); + txtPassword = new javax.swing.JTextField(); + lblUserName = new javax.swing.JLabel(); + btnConnect = new javax.swing.JButton(); + btnCancel = new javax.swing.JButton(); + chkAutoConnect = new javax.swing.JCheckBox(); + chkUseProxy = new javax.swing.JCheckBox(); + pnlProxy = new javax.swing.JPanel(); + lblProxyServer = new javax.swing.JLabel(); + txtProxyServer = new javax.swing.JTextField(); + lblProxyPort = new javax.swing.JLabel(); + txtProxyPort = new javax.swing.JTextField(); + jButton1 = new javax.swing.JButton(); + + setTitle("Connect"); + + lblServer.setLabelFor(txtServer); + lblServer.setText("Server:"); + + lblPort.setLabelFor(txtPort); + lblPort.setText("Port:"); + + txtPort.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + ConnectDialog.this.keyTyped(evt); + } + }); + + lblUserName.setLabelFor(txtPassword); + lblUserName.setText("Password:"); + + btnConnect.setText("Connect"); + btnConnect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnConnectActionPerformed(evt); + } + }); + + btnCancel.setText("Cancel"); + btnCancel.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCancelActionPerformed(evt); + } + }); + + chkAutoConnect.setText("Automatically connect to this server next time"); + chkAutoConnect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + chkAutoConnectActionPerformed(evt); + } + }); + + chkUseProxy.setText("Use Proxy"); + chkUseProxy.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + chkUseProxyActionPerformed(evt); + } + }); + + lblProxyServer.setLabelFor(txtServer); + lblProxyServer.setText("Server:"); + + lblProxyPort.setLabelFor(txtPort); + lblProxyPort.setText("Port:"); + + txtProxyPort.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyTyped(java.awt.event.KeyEvent evt) { + txtProxyPortkeyTyped(evt); + } + }); + + javax.swing.GroupLayout pnlProxyLayout = new javax.swing.GroupLayout(pnlProxy); + pnlProxy.setLayout(pnlProxyLayout); + pnlProxyLayout.setHorizontalGroup( + pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlProxyLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lblProxyPort) + .addComponent(lblProxyServer)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(txtProxyServer, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)) + .addGap(30, 30, 30)) + ); + pnlProxyLayout.setVerticalGroup( + pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlProxyLayout.createSequentialGroup() + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblProxyServer) + .addComponent(txtProxyServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblProxyPort) + .addComponent(txtProxyPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jButton1.setText("Find..."); + jButton1.setToolTipText("Find public server"); + jButton1.setName("findServerBtn"); // NOI18N + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addComponent(btnConnect) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCancel)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lblPort) + .addComponent(lblServer) + .addComponent(lblUserName)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(131, 131, 131)) + .addComponent(txtPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE) + .addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE) + .addComponent(chkUseProxy, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(txtServer, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButton1))))) + .addContainerGap()) + .addComponent(pnlProxy, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblServer) + .addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButton1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblPort)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblUserName)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkAutoConnect) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkUseProxy) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlProxy, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnCancel) + .addComponent(btnConnect)) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed + ConsoleFrame.getPreferences().put("autoConnect", Boolean.toString(chkAutoConnect.isSelected())); + this.setVisible(false); + }//GEN-LAST:event_btnCancelActionPerformed + + private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed + + if (txtPassword.getText().isEmpty()) { + JOptionPane.showMessageDialog(rootPane, "Please provide a password"); + return; + } + if (txtServer.getText().trim().isEmpty()) { + JOptionPane.showMessageDialog(rootPane, "Please provide a server address"); + return; + } + if (txtPort.getText().trim().isEmpty()) { + JOptionPane.showMessageDialog(rootPane, "Please provide a port number"); + return; + } + if (Integer.valueOf(txtPort.getText()) < 1 || Integer.valueOf(txtPort.getText()) > 65535 ) { + JOptionPane.showMessageDialog(rootPane, "Invalid port number"); + txtPort.setText(ConsoleFrame.getPreferences().get("serverPort", "")); + return; + } + + try { + setCursor(new Cursor(Cursor.WAIT_CURSOR)); + if (chkUseProxy.isSelected()) { + if (console.connect(txtPassword.getText(), txtServer.getText().trim(), Integer.valueOf(txtPort.getText()), txtProxyServer.getText().trim(), Integer.valueOf(txtProxyPort.getText()))) { + this.saveSettings(); + this.setVisible(false); + } + } + else { + if (console.connect(txtPassword.getText(), txtServer.getText().trim(), Integer.valueOf(txtPort.getText()))) { + this.saveSettings(); + this.setVisible(false); + } + } + } + finally { + setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + + }//GEN-LAST:event_btnConnectActionPerformed + + private void keyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_keyTyped + char c = evt.getKeyChar(); + if (!Character.isDigit(c)) + evt.consume(); + }//GEN-LAST:event_keyTyped + + private void chkAutoConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkAutoConnectActionPerformed + + // TODO add your handling code here: + }//GEN-LAST:event_chkAutoConnectActionPerformed + + private void txtProxyPortkeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtProxyPortkeyTyped + // TODO add your handling code here: + }//GEN-LAST:event_txtProxyPortkeyTyped + + private void chkUseProxyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkUseProxyActionPerformed + this.showProxySettings(); + }//GEN-LAST:event_chkUseProxyActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + BufferedReader in = null; + try { + URL serverListURL = new URL("http://mage.googlecode.com/files/server-list.txt"); + in = new BufferedReader(new InputStreamReader(serverListURL.openStream())); + + List servers = new ArrayList(); + String inputLine; + while ((inputLine = in.readLine()) != null) { + System.out.println("Found server: "+inputLine); + servers.add(inputLine); + } + + if (servers.size() == 0) { + JOptionPane.showMessageDialog(null, "Couldn't find any server."); + return; + } + + String selectedServer = (String) JOptionPane.showInputDialog(null, + "Choose MAGE Public Server:", "Input", + JOptionPane.INFORMATION_MESSAGE, null, servers.toArray(), + servers.get(0)); + if (selectedServer != null) { + String[] params = selectedServer.split(":"); + if (params.length == 3) { + this.txtServer.setText(params[1]); + this.txtPort.setText(params[2]); + } else { + JOptionPane.showMessageDialog(null, "Wrong server data format."); + } + } + + in.close(); + } catch(Exception ex) { + logger.error(ex,ex); + } finally { + if (in != null) try { in.close(); } catch (Exception e) {} + } + + }//GEN-LAST:event_jButton1ActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnCancel; + private javax.swing.JButton btnConnect; + private javax.swing.JCheckBox chkAutoConnect; + private javax.swing.JCheckBox chkUseProxy; + private javax.swing.JButton jButton1; + private javax.swing.JLabel lblPort; + private javax.swing.JLabel lblProxyPort; + private javax.swing.JLabel lblProxyServer; + private javax.swing.JLabel lblServer; + private javax.swing.JLabel lblUserName; + private javax.swing.JPanel pnlProxy; + private javax.swing.JTextField txtPassword; + private javax.swing.JTextField txtPort; + private javax.swing.JTextField txtProxyPort; + private javax.swing.JTextField txtProxyServer; + private javax.swing.JTextField txtServer; + // End of variables declaration//GEN-END:variables + +} diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.form b/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.form new file mode 100644 index 0000000000..950fd48075 --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.form @@ -0,0 +1,72 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.java b/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.java new file mode 100644 index 0000000000..724ff143cb --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.java @@ -0,0 +1,198 @@ +/* +* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +/* + * ConsoleFrame.java + * + * Created on May 13, 2011, 2:39:10 PM + */ + +package mage.server.console; + +import java.util.logging.Level; +import java.util.prefs.Preferences; +import javax.swing.Box; +import javax.swing.JOptionPane; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import mage.server.console.remote.Session; +import mage.utils.MageVersion; +import org.apache.log4j.Logger; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ConsoleFrame extends javax.swing.JFrame { + + private final static Logger logger = Logger.getLogger(ConsoleFrame.class); + + private static Session session; + private ConnectDialog connectDialog; + private static Preferences prefs = Preferences.userNodeForPackage(ConsoleFrame.class); + private final static MageVersion version = new MageVersion(0, 7, 2); + + /** + * @return the session + */ + public static Session getSession() { + return session; + } + + public static Preferences getPreferences() { + return prefs; + } + + public static MageVersion getVersion() { + return version; + } + + /** Creates new form ConsoleFrame */ + public ConsoleFrame() { + initComponents(); + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + session = new Session(this); + connectDialog = new ConnectDialog(); + } catch (Exception ex) { + logger.fatal("", ex); + } + } + + public boolean connect(String password, String serverName, int port) { + if (session.connect(password, serverName, port)) { + this.consolePanel1.start(); + return true; + } + return false; + } + + public boolean connect(String password, String serverName, int port, String proxyServer, int proxyPort) { + if (session.connect(password, serverName, port, proxyServer, proxyPort)) { + this.consolePanel1.start(); + return true; + } + return false; + } + + public void setStatusText(String status) { + this.lblStatus.setText(status); + } + + public void enableButtons() { + btnConnect.setEnabled(true); + btnConnect.setText("Disconnect"); + } + + public void disableButtons() { + btnConnect.setEnabled(true); + btnConnect.setText("Connect"); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jToolBar1 = new javax.swing.JToolBar(); + btnConnect = new javax.swing.JButton(); + lblStatus = new javax.swing.JLabel(); + consolePanel1 = new mage.server.console.ConsolePanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + + jToolBar1.setFloatable(false); + jToolBar1.setRollover(true); + + btnConnect.setText("Connect"); + btnConnect.setFocusable(false); + btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnConnect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnConnectActionPerformed(evt); + } + }); + jToolBar1.add(btnConnect); + + lblStatus.setText("Not Connected"); + jToolBar1.add(Box.createHorizontalGlue()); + jToolBar1.add(lblStatus); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 933, Short.MAX_VALUE) + .addComponent(consolePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 933, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(consolePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed + if (session.isConnected()) { + if (JOptionPane.showConfirmDialog(this, "Are you sure you want to disconnect?", "Confirm disconnect", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + this.consolePanel1.stop(); + session.disconnect(); + } + } else { + connectDialog.showDialog(this); + } + }//GEN-LAST:event_btnConnectActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new ConsoleFrame().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnConnect; + private mage.server.console.ConsolePanel consolePanel1; + private javax.swing.JToolBar jToolBar1; + private javax.swing.JLabel lblStatus; + // End of variables declaration//GEN-END:variables + +} diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form new file mode 100644 index 0000000000..f709629d2b --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form @@ -0,0 +1,219 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java new file mode 100644 index 0000000000..b1259c4831 --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java @@ -0,0 +1,423 @@ +/* +* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +/* + * ConsolePanel.java + * + * Created on 14-May-2011, 6:08:48 PM + */ +package mage.server.console; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import javax.swing.SwingWorker; +import javax.swing.table.AbstractTableModel; +import mage.server.console.remote.Session; +import mage.view.TableView; +import mage.view.UserView; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ConsolePanel extends javax.swing.JPanel { + + private TableUserModel tableUserModel; + private TableTableModel tableTableModel; + private UpdateUsersTask updateUsersTask; + private UpdateTablesTask updateTablesTask; + + /** Creates new form ConsolePanel */ + public ConsolePanel() { + this.tableUserModel = new TableUserModel(); + this.tableTableModel = new TableTableModel(); + initComponents(); + this.tblUsers.createDefaultColumnsFromModel(); + this.tblTables.createDefaultColumnsFromModel(); + } + + public void update(List users) { + int row = this.tblUsers.getSelectedRow(); + tableUserModel.loadData(users); + this.tblUsers.repaint(); + this.tblUsers.getSelectionModel().setSelectionInterval(row, row); + } + + public void update(Collection tables) { + int row = this.tblTables.getSelectedRow(); + tableTableModel.loadData(tables); + this.tblTables.repaint(); + this.tblTables.getSelectionModel().setSelectionInterval(row, row); + } + + + public void start() { + updateUsersTask = new UpdateUsersTask(ConsoleFrame.getSession(), this); + updateTablesTask = new UpdateTablesTask(ConsoleFrame.getSession(), ConsoleFrame.getSession().getMainRoomId(), this); + updateUsersTask.execute(); + updateTablesTask.execute(); + } + + public void stop() { + if (updateUsersTask != null && !updateUsersTask.isDone()) + updateUsersTask.cancel(true); + if (updateTablesTask != null && !updateTablesTask.isDone()) + updateTablesTask.cancel(true); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jSplitPane1 = new javax.swing.JSplitPane(); + jPanel1 = new javax.swing.JPanel(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + tblUsers = new javax.swing.JTable(); + jPanel4 = new javax.swing.JPanel(); + btnDisconnect = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jPanel5 = new javax.swing.JPanel(); + jScrollPane2 = new javax.swing.JScrollPane(); + tblTables = new javax.swing.JTable(); + jPanel6 = new javax.swing.JPanel(); + btnDelete = new javax.swing.JButton(); + + jSplitPane1.setDividerLocation(250); + jSplitPane1.setResizeWeight(0.5); + + tblUsers.setModel(tableUserModel); + jScrollPane1.setViewportView(tblUsers); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE) + ); + + jPanel4.setVerifyInputWhenFocusTarget(false); + + btnDisconnect.setText("Disconnect"); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(btnDisconnect) + .addContainerGap(164, Short.MAX_VALUE)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(btnDisconnect) + .addContainerGap(10, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + jSplitPane1.setLeftComponent(jPanel1); + + tblTables.setModel(tableTableModel); + jScrollPane2.setViewportView(tblTables); + + javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE) + ); + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) + ); + + btnDelete.setText("Remove"); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addComponent(btnDelete) + .addContainerGap(235, Short.MAX_VALUE)) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addComponent(btnDelete) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 0, 0) + .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + jSplitPane1.setRightComponent(jPanel2); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnDelete; + private javax.swing.JButton btnDisconnect; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JTable tblTables; + private javax.swing.JTable tblUsers; + // End of variables declaration//GEN-END:variables +} + +class TableUserModel extends AbstractTableModel { + private String[] columnNames = new String[]{"User Name", "Host", "Time Connected"}; + private UserView[] users = new UserView[0]; + + public void loadData(List users) { + this.users = users.toArray(new UserView[0]); + this.fireTableDataChanged(); + } + + @Override + public int getRowCount() { + return users.length; + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return users[arg0].getUserName(); + case 1: + return users[arg0].getHost(); + case 2: + return users[arg0].getConnectionTime().toString(); + case 3: + return users[arg0].getSessionId(); + } + return ""; + } + + @Override + public String getColumnName(int columnIndex) { + String colName = ""; + + if (columnIndex <= getColumnCount()) + colName = columnNames[columnIndex]; + + return colName; + } + + @Override + public Class getColumnClass(int columnIndex){ + return String.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + +} + +class TableTableModel extends AbstractTableModel { + private String[] columnNames = new String[]{"Table Name", "Owner", "Game Type", "Deck Type", "Status"}; + private TableView[] tables = new TableView[0]; + + + public void loadData(Collection tables) { + this.tables = tables.toArray(new TableView[0]); + this.fireTableDataChanged(); + } + + @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].getTableName(); + case 1: + return tables[arg0].getControllerName(); + case 2: + return tables[arg0].getGameType().toString(); + case 3: + return tables[arg0].getDeckType().toString(); + case 4: + return tables[arg0].getTableState().toString(); + case 5: + return tables[arg0].isTournament(); + case 6: + if (!tables[arg0].getGames().isEmpty()) + return tables[arg0].getGames().get(0); + return null; + case 7: + 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){ + return String.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + if (columnIndex != 5) + return false; + return true; + } + +} + +class UpdateUsersTask extends SwingWorker> { + + private Session session; + private ConsolePanel panel; + + UpdateUsersTask(Session session, ConsolePanel panel) { + this.session = session; + this.panel = panel; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + this.publish(session.getUsers()); + Thread.sleep(1000); + } + return null; + } + + @Override + protected void process(List> view) { + panel.update(view.get(0)); + } + +} + +class UpdateTablesTask extends SwingWorker> { + + private Session session; + private UUID roomId; + private ConsolePanel panel; + + UpdateTablesTask(Session session, UUID roomId, ConsolePanel panel) { + this.session = session; + this.roomId = roomId; + this.panel = panel; + } + + @Override + protected Void doInBackground() throws Exception { + while (!isCancelled()) { + this.publish(session.getTables(roomId)); + Thread.sleep(1000); + } + return null; + } + + @Override + protected void process(List> view) { + panel.update(view.get(0)); + } + +} \ No newline at end of file diff --git a/Mage.Server.Console/src/main/java/mage/server/console/remote/Session.java b/Mage.Server.Console/src/main/java/mage/server/console/remote/Session.java new file mode 100644 index 0000000000..4b747911d5 --- /dev/null +++ b/Mage.Server.Console/src/main/java/mage/server/console/remote/Session.java @@ -0,0 +1,724 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.server.console.remote; + +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import javax.swing.JOptionPane; +import mage.cards.decks.DeckCardLists; +import mage.game.GameException; +import mage.interfaces.MageException; +import mage.game.match.MatchOptions; +import mage.game.tournament.TournamentOptions; +import mage.interfaces.Server; +import mage.interfaces.ServerState; +import mage.server.console.ConsoleFrame; +import mage.view.DraftPickView; +import mage.view.GameTypeView; +import mage.view.TableView; +import mage.view.TournamentTypeView; +import mage.view.TournamentView; +import mage.view.UserView; +import org.apache.log4j.Logger; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class Session { + + private final static Logger logger = Logger.getLogger(Session.class); + private static ScheduledExecutorService sessionExecutor = Executors.newScheduledThreadPool(1); + + private UUID sessionId; + private Server server; + private ConsoleFrame frame; + private ServerState serverState; + private ScheduledFuture future; + + public Session(ConsoleFrame frame) { + this.frame = frame; + } + public boolean connect(String password, String serverName, int port) { + return connect(password, serverName, port, "", 0); + } + + public boolean connect(String password, String serverName, int port, String proxyServer, int proxyPort) { + if (isConnected()) { + disconnect(); + } + try { + System.setSecurityManager(null); + if (proxyServer.length() > 0) { + System.setProperty("socksProxyHost", proxyServer); + System.setProperty("socksProxyPort", Integer.toString(proxyPort)); + } + else { + System.clearProperty("socksProxyHost"); + System.clearProperty("socksProxyPort"); + } + Registry reg = LocateRegistry.getRegistry(serverName, port); + this.server = (Server) reg.lookup("mage-server"); + sessionId = server.registerAdmin(password, frame.getVersion()); + serverState = server.getServerState(); + future = sessionExecutor.scheduleWithFixedDelay(new ServerPinger(), 5, 5, TimeUnit.SECONDS); + logger.info("Connected to RMI server at " + serverName + ":" + port); + frame.setStatusText("Connected to " + serverName + ":" + port + " "); + frame.enableButtons(); + return true; + } catch (MageException ex) { + logger.fatal("", ex); + disconnect(); + JOptionPane.showMessageDialog(frame, "Unable to connect to server. " + ex.getMessage()); + } catch (RemoteException ex) { + logger.fatal("Unable to connect to server - ", ex); + disconnect(); + JOptionPane.showMessageDialog(frame, "Unable to connect to server. " + ex.getMessage()); + } catch (NotBoundException ex) { + logger.fatal("Unable to connect to server - ", ex); + } catch (Exception ex) { + logger.fatal("Unable to connect to server - ", ex); + } + return false; + } + + public void disconnect() { + + if (isConnected()) { + try { + server.deregisterClient(sessionId); + } catch (RemoteException ex) { + logger.fatal("Error disconnecting ...", ex); + } catch (MageException ex) { + logger.fatal("Error disconnecting ...", ex); + } + removeServer(); + } + } + + public void removeServer() { + if (future != null && !future.isDone()) + future.cancel(true); + server = null; + frame.setStatusText("Not connected"); + frame.disableButtons(); + logger.info("Disconnected ... "); + JOptionPane.showMessageDialog(frame, "Disconnected.", "Disconnected", JOptionPane.INFORMATION_MESSAGE); + } + + public void ack(String message) { + try { + server.ack(message, sessionId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + } + + public boolean ping() { + try { + return server.ping(sessionId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean isConnected() { + return server != null; + } + + public String[] getPlayerTypes() { + return serverState.getPlayerTypes(); + } + + public List getGameTypes() { + return serverState.getGameTypes(); + } + + public String[] getDeckTypes() { + return serverState.getDeckTypes(); + } + + public List getTournamentTypes() { + return serverState.getTournamentTypes(); + } + + public boolean isTestMode() { + if (serverState != null) + return serverState.isTestMode(); + return false; + } + + public UUID getMainRoomId() { + try { + return server.getMainRoomId(); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public UUID getRoomChatId(UUID roomId) { + try { + return server.getRoomChatId(roomId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public UUID getTableChatId(UUID tableId) { + try { + return server.getTableChatId(tableId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public UUID getGameChatId(UUID gameId) { + try { + return server.getGameChatId(gameId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public TableView getTable(UUID roomId, UUID tableId) { + try { + return server.getTable(roomId, tableId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public boolean watchTable(UUID roomId, UUID tableId) { + try { + server.watchTable(sessionId, roomId, tableId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean joinTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill, DeckCardLists deckList) { + try { + return server.joinTable(sessionId, roomId, tableId, playerName, playerType, skill, deckList); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } catch (GameException ex) { + handleGameException(ex); + } + return false; + } + + public boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill) { + try { + return server.joinTournamentTable(sessionId, roomId, tableId, playerName, playerType, skill); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } catch (GameException ex) { + handleGameException(ex); + } + return false; + } + + public Collection getTables(UUID roomId) throws Exception { + try { + return server.getTables(roomId); + } catch (RemoteException ex) { + handleRemoteException(ex); + throw new Exception(); + } catch (MageException ex) { + handleMageException(ex); + throw new Exception(); + } + } + + public TournamentView getTournament(UUID tournamentId) throws Exception { + try { + return server.getTournament(tournamentId); + } catch (RemoteException ex) { + handleRemoteException(ex); + throw new Exception(); + } catch (MageException ex) { + handleMageException(ex); + throw new Exception(); + } + } + + public UUID getTournamentChatId(UUID tournamentId) { + try { + return server.getTournamentChatId(tournamentId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public boolean sendPlayerUUID(UUID gameId, UUID data) { + try { + server.sendPlayerUUID(gameId, sessionId, data); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean sendPlayerBoolean(UUID gameId, boolean data) { + try { + server.sendPlayerBoolean(gameId, sessionId, data); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean sendPlayerInteger(UUID gameId, int data) { + try { + server.sendPlayerInteger(gameId, sessionId, data); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean sendPlayerString(UUID gameId, String data) { + try { + server.sendPlayerString(gameId, sessionId, data); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public DraftPickView sendCardPick(UUID draftId, UUID cardId) { + try { + return server.sendCardPick(draftId, sessionId, cardId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public boolean leaveChat(UUID chatId) { + try { + server.leaveChat(chatId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean sendChatMessage(UUID chatId, String message) { + try { + server.sendChatMessage(chatId, "", message); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean joinGame(UUID gameId) { + try { + server.joinGame(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean joinDraft(UUID draftId) { + try { + server.joinDraft(draftId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean joinTournament(UUID tournamentId) { + try { + server.joinTournament(tournamentId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean watchGame(UUID gameId) { + try { + server.watchGame(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean replayGame(UUID gameId) { + try { + server.replayGame(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public TableView createTable(UUID roomId, MatchOptions matchOptions) { + try { + return server.createTable(sessionId, roomId, matchOptions); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public TableView createTournamentTable(UUID roomId, TournamentOptions tournamentOptions) { + try { + return server.createTournamentTable(sessionId, roomId, tournamentOptions); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + public boolean isTableOwner(UUID roomId, UUID tableId) { + try { + return server.isTableOwner(sessionId, roomId, tableId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean removeTable(UUID roomId, UUID tableId) { + try { + server.removeTable(sessionId, roomId, tableId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean swapSeats(UUID roomId, UUID tableId, int seatNum1, int seatNum2) { + try { + server.swapSeats(sessionId, roomId, tableId, seatNum1, seatNum2); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean leaveTable(UUID roomId, UUID tableId) { + try { + server.leaveTable(sessionId, roomId, tableId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean startGame(UUID roomId, UUID tableId) { + try { + server.startMatch(sessionId, roomId, tableId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean startTournament(UUID roomId, UUID tableId) { + try { + server.startTournament(sessionId, roomId, tableId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean startChallenge(UUID roomId, UUID tableId, UUID challengeId) { + try { + server.startChallenge(sessionId, roomId, tableId, challengeId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean submitDeck(UUID tableId, DeckCardLists deck) { + try { + return server.submitDeck(sessionId, tableId, deck); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } catch (GameException ex) { + handleGameException(ex); + } + return false; + } + + public boolean concedeGame(UUID gameId) { + try { + server.concedeGame(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean stopWatching(UUID gameId) { + try { + server.stopWatching(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean startReplay(UUID gameId) { + try { + server.startReplay(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean stopReplay(UUID gameId) { + try { + server.stopReplay(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean nextPlay(UUID gameId) { + try { + server.nextPlay(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean previousPlay(UUID gameId) { + try { + server.previousPlay(gameId, sessionId); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public boolean cheat(UUID gameId, UUID playerId, DeckCardLists deckList) { + try { + server.cheat(gameId, sessionId, playerId, deckList); + return true; + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return false; + } + + public List getUsers() { + try { + return server.getUsers(sessionId); + } catch (RemoteException ex) { + handleRemoteException(ex); + } catch (MageException ex) { + handleMageException(ex); + } + return null; + } + + private void handleRemoteException(RemoteException ex) { + logger.fatal("Communication error", ex); + if (ex instanceof java.rmi.ConnectException) { + server = null; + frame.setStatusText("Not connected"); + frame.disableButtons(); + JOptionPane.showMessageDialog(frame, "Communication error - disconnecting.", "Error", JOptionPane.ERROR_MESSAGE); + } + else + JOptionPane.showMessageDialog(frame, "Communication error.", "Error", JOptionPane.ERROR_MESSAGE); + } + + private void handleMageException(MageException ex) { + logger.fatal("Server error", ex); + JOptionPane.showMessageDialog(frame, "Critical server error. Disconnecting", "Error", JOptionPane.ERROR_MESSAGE); + disconnect(); + frame.disableButtons(); + } + + private void handleGameException(GameException ex) { + logger.fatal("Game error", ex); + JOptionPane.showMessageDialog(frame, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } + + + public Server getServerRef() { + return server; + } + + class ServerPinger implements Runnable { + + private int missed = 0; + + @Override + public void run() { + if (!ping()) { + missed++; + if (missed > 10) { + logger.info("Connection to server timed out"); + removeServer(); + } + } + else { + missed = 0; + } + } + + } + +} \ No newline at end of file diff --git a/Mage.Server.Console/src/test/java/mage/server/console/AppTest.java b/Mage.Server.Console/src/test/java/mage/server/console/AppTest.java new file mode 100644 index 0000000000..2387d8bd34 --- /dev/null +++ b/Mage.Server.Console/src/test/java/mage/server/console/AppTest.java @@ -0,0 +1,38 @@ +package mage.server.console; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/Mage.Server/config/log4j.properties b/Mage.Server/config/log4j.properties index f1f6e4f3db..913fd6646f 100644 --- a/Mage.Server/config/log4j.properties +++ b/Mage.Server/config/log4j.properties @@ -5,7 +5,7 @@ log4j.rootLogger=debug, console, logfile 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=info +log4j.appender.console.Threshold=debug #file log log4j.appender.logfile=org.apache.log4j.FileAppender diff --git a/Mage.Server/plugins/mage-deck-constructed.jar b/Mage.Server/plugins/mage-deck-constructed.jar index 3647989d7d..81226541ab 100644 Binary files a/Mage.Server/plugins/mage-deck-constructed.jar and b/Mage.Server/plugins/mage-deck-constructed.jar differ diff --git a/Mage.Server/plugins/mage-deck-limited.jar b/Mage.Server/plugins/mage-deck-limited.jar index b4ca904cc5..fa0f9315a6 100644 Binary files a/Mage.Server/plugins/mage-deck-limited.jar and b/Mage.Server/plugins/mage-deck-limited.jar differ diff --git a/Mage.Server/plugins/mage-game-freeforall.jar b/Mage.Server/plugins/mage-game-freeforall.jar index 3d3417fd44..57958820b0 100644 Binary files a/Mage.Server/plugins/mage-game-freeforall.jar and b/Mage.Server/plugins/mage-game-freeforall.jar differ diff --git a/Mage.Server/plugins/mage-game-twoplayerduel.jar b/Mage.Server/plugins/mage-game-twoplayerduel.jar index 0c6f838e0c..ddeeca8392 100644 Binary files a/Mage.Server/plugins/mage-game-twoplayerduel.jar and b/Mage.Server/plugins/mage-game-twoplayerduel.jar differ diff --git a/Mage.Server/plugins/mage-tournament-booster-draft.jar b/Mage.Server/plugins/mage-tournament-booster-draft.jar index 9b81b4c1bf..bbd0b228a5 100644 Binary files a/Mage.Server/plugins/mage-tournament-booster-draft.jar and b/Mage.Server/plugins/mage-tournament-booster-draft.jar differ diff --git a/Mage.Server/plugins/mage-tournament-sealed.jar b/Mage.Server/plugins/mage-tournament-sealed.jar index e4a8584a98..9c5b2d1903 100644 Binary files a/Mage.Server/plugins/mage-tournament-sealed.jar and b/Mage.Server/plugins/mage-tournament-sealed.jar differ diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java index 70a1d5d1d8..7255ce4ee4 100644 --- a/Mage.Server/src/main/java/mage/server/Main.java +++ b/Mage.Server/src/main/java/mage/server/Main.java @@ -28,7 +28,6 @@ package mage.server; -import java.net.UnknownHostException; import mage.server.util.PluginClassLoader; import java.io.File; import java.io.FilenameFilter; @@ -60,6 +59,7 @@ public class Main { private static Logger logger = Logger.getLogger(Main.class); private final static String testModeArg = "-testMode="; + private final static String adminPasswordArg = "-adminPassword="; private final static String pluginFolder = "plugins"; private static MageVersion version = new MageVersion(0, 7, 2); @@ -88,14 +88,18 @@ public class Main { DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin)); } boolean testMode = false; + String adminPassword = ""; for (String arg: args) { if (arg.startsWith(testModeArg)) { testMode = Boolean.valueOf(arg.replace(testModeArg, "")); } + else if (arg.startsWith(adminPasswordArg)) { + adminPassword = arg.replace(adminPasswordArg, ""); + } } Copier.setLoader(classLoader); setServerAddress(config.getServerAddress()); - server = new ServerImpl(config.getPort(), config.getServerName(), testMode); + server = new ServerImpl(config.getPort(), config.getServerName(), testMode, adminPassword); } diff --git a/Mage.Server/src/main/java/mage/server/ServerImpl.java b/Mage.Server/src/main/java/mage/server/ServerImpl.java index c40e3fecb0..bbae5591cc 100644 --- a/Mage.Server/src/main/java/mage/server/ServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/ServerImpl.java @@ -62,6 +62,7 @@ import mage.view.DraftPickView; import mage.view.GameView; import mage.view.TableView; import mage.view.TournamentView; +import mage.view.UserView; import org.apache.log4j.Logger; /** @@ -74,14 +75,16 @@ public class ServerImpl extends RemoteServer implements Server { private static ExecutorService rmiExecutor = ThreadExecutor.getInstance().getRMIExecutor(); private boolean testMode; + private String password; - public ServerImpl(int port, String name, boolean testMode) { + public ServerImpl(int port, String name, boolean testMode, String password) { try { System.setSecurityManager(null); Registry reg = LocateRegistry.createRegistry(port); Server stub = (Server) UnicastRemoteObject.exportObject(this, port); reg.rebind(name, stub); this.testMode = testMode; + this.password = password; logger.info("Started MAGE server - listening on port " + port); if (testMode) logger.info("MAGE server running in test mode"); @@ -106,6 +109,16 @@ public class ServerImpl extends RemoteServer implements Server { SessionManager.getInstance().getSession(sessionId).ack(message); } + @Override + public boolean ping(UUID sessionId) { + Session session = SessionManager.getInstance().getSession(sessionId); + if (session != null) { + session.ping(); + return true; + } + return false; + } + @Override public UUID registerClient(String userName, UUID clientId, MageVersion version) throws MageException, RemoteException { @@ -113,7 +126,7 @@ public class ServerImpl extends RemoteServer implements Server { try { if (version.compareTo(Main.getVersion()) != 0) throw new MageException("Wrong client version " + version + ", expecting version " + Main.getVersion()); - sessionId = SessionManager.getInstance().createSession(userName, clientId); + sessionId = SessionManager.getInstance().createSession(userName, getClientHost(), clientId); logger.info("User " + userName + " connected from " + getClientHost()); } catch (Exception ex) { handleException(ex); @@ -121,6 +134,22 @@ public class ServerImpl extends RemoteServer implements Server { return sessionId; } + + @Override + public UUID registerAdmin(String password, MageVersion version) throws RemoteException, MageException { + UUID sessionId = null; + try { + if (version.compareTo(Main.getVersion()) != 0) + throw new MageException("Wrong client version " + version + ", expecting version " + Main.getVersion()); + if (!password.equals(this.password)) + throw new MageException("Wrong password"); + sessionId = SessionManager.getInstance().createSession(getClientHost()); + logger.info("Admin connected from " + getClientHost()); + } catch (Exception ex) { + handleException(ex); + } + return sessionId; + } @Override public TableView createTable(UUID sessionId, UUID roomId, MatchOptions options) throws MageException { @@ -236,7 +265,6 @@ public class ServerImpl extends RemoteServer implements Server { return null; } - @Override public TableView getTable(UUID roomId, UUID tableId) throws MageException { try { @@ -258,8 +286,8 @@ public class ServerImpl extends RemoteServer implements Server { Session session = SessionManager.getInstance().getSession(sessionId); if (session != null) { session.kill(); + logger.info("Client deregistered ..."); } - logger.info("Client deregistered ..."); } } ); @@ -812,4 +840,9 @@ public class ServerImpl extends RemoteServer implements Server { return GameManager.getInstance().getGameView(gameId, sessionId, playerId); } + @Override + public List getUsers(UUID sessionId) throws RemoteException, MageException { + return SessionManager.getInstance().getUsers(sessionId); + } + } diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index 871d94ed4a..feb81ba83e 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -28,7 +28,7 @@ package mage.server; -import java.util.logging.Level; +import java.util.Date; import java.util.UUID; import mage.cards.decks.Deck; import mage.interfaces.callback.CallbackServerSession; @@ -48,14 +48,31 @@ public class Session { private UUID sessionId; private UUID clientId; private String username; + private String host; private int messageId = 0; private String ackMessage; + private Date timeConnected; + private long lastPing; + private boolean isAdmin = false; private final CallbackServerSession callback = new CallbackServerSession(); - public Session(String userName, UUID clientId) { + public Session(String userName, String host, UUID clientId) { sessionId = UUID.randomUUID(); this.username = userName; + this.host = host; this.clientId = clientId; + this.isAdmin = false; + this.timeConnected = new Date(); + ping(); + } + + public Session(String host) { + sessionId = UUID.randomUUID(); + this.username = "Admin"; + this.host = host; + this.isAdmin = true; + this.timeConnected = new Date(); + ping(); } public UUID getId() { @@ -137,4 +154,25 @@ public class Session { return username; } + public void ping() { + this.lastPing = System.currentTimeMillis(); + if (logger.isTraceEnabled()) + logger.trace("Ping received from" + username + ":" + sessionId); + } + + public boolean stillAlive() { + return (System.currentTimeMillis() - lastPing) < 60000; + } + + public boolean isAdmin() { + return isAdmin; + } + + public String getHost() { + return host; + } + + public Date getConnectionTime() { + return timeConnected; + } } diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java index 2b5df343b3..597d498dcd 100644 --- a/Mage.Server/src/main/java/mage/server/SessionManager.java +++ b/Mage.Server/src/main/java/mage/server/SessionManager.java @@ -28,12 +28,17 @@ package mage.server; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import mage.interfaces.MageException; +import mage.view.UserView; import org.apache.log4j.Logger; /** @@ -44,11 +49,17 @@ public class SessionManager { private final static Logger logger = Logger.getLogger(SessionManager.class); private final static SessionManager INSTANCE = new SessionManager(); + private static ScheduledExecutorService sessionExecutor; public static SessionManager getInstance() { return INSTANCE; } + protected SessionManager() { + sessionExecutor = Executors.newScheduledThreadPool(1); + sessionExecutor.scheduleWithFixedDelay(new SessionChecker(), 30, 10, TimeUnit.SECONDS); + } + private ConcurrentHashMap sessions = new ConcurrentHashMap(); public Session getSession(UUID sessionId) { @@ -56,7 +67,7 @@ public class SessionManager { return sessions.get(sessionId); } - public UUID createSession(String userName, UUID clientId) throws MageException { + public UUID createSession(String userName, String host, UUID clientId) throws MageException { for (Session session: sessions.values()) { if (session.getUsername().equals(userName)) { if (session.getClientId().equals(clientId)) { @@ -68,16 +79,32 @@ public class SessionManager { } } } - Session session = new Session(userName, clientId); + Session session = new Session(userName, host, clientId); sessions.put(session.getId(), session); logger.info("Session " + session.getId() + " created for user " + userName); return session.getId(); } + public UUID createSession(String host) throws MageException { + Session session = new Session(host); + sessions.put(session.getId(), session); + logger.info("Admin session created"); + return session.getId(); + } + public void removeSession(UUID sessionId) { sessions.remove(sessionId); } + public void checkSessions() { + for (Session session: sessions.values()) { + if (!session.stillAlive()) { + logger.info("Client for user " + session.getUsername() + ":" + session.getId() + " timed out - releasing resources"); + session.kill(); + } + } + } + public Map getSessions() { Map map = new HashMap(); for (Map.Entry entry : sessions.entrySet()) { @@ -85,4 +112,25 @@ public class SessionManager { } return map; } + + List getUsers(UUID sessionId) { + List users = new ArrayList(); + Session admin = sessions.get(sessionId); + if (admin != null && admin.isAdmin()) { + for (Session session: sessions.values()) { + users.add(new UserView(session.getUsername(), session.getHost(), session.getId(), session.getConnectionTime())); + } + } + return users; + } + + class SessionChecker implements Runnable { + + @Override + public void run() { + checkSessions(); + } + + } + } diff --git a/Mage.Server/src/main/resources/log4j.properties b/Mage.Server/src/main/resources/log4j.properties index cdef4d6b9e..08d7f0e74f 100644 --- a/Mage.Server/src/main/resources/log4j.properties +++ b/Mage.Server/src/main/resources/log4j.properties @@ -1,5 +1,5 @@ #default levels -log4j.rootLogger=info, console +log4j.rootLogger=debug, console #console log log4j.appender.console=org.apache.log4j.ConsoleAppender diff --git a/Mage.Tests/plugins/AIMinimax.properties b/Mage.Tests/plugins/AIMinimax.properties index 0dbf3860df..16ddf022c0 100644 --- a/Mage.Tests/plugins/AIMinimax.properties +++ b/Mage.Tests/plugins/AIMinimax.properties @@ -4,4 +4,4 @@ evaluatorLifeFactor=2 evaluatorPermanentFactor=1 evaluatorCreatureFactor=1 evaluatorHandFactor=1 -maxThinkSeconds=30 \ No newline at end of file +maxThinkSeconds=10 \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java index 31c49f0852..d4987b7675 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java @@ -96,7 +96,7 @@ public abstract class MageTestBase { @BeforeClass public static void init() { - Logger.getRootLogger().setLevel(Level.DEBUG); +// Logger.getRootLogger().setLevel(Level.DEBUG); logger.info("Starting MAGE tests"); logger.info("Logging level: " + logger.getLevel()); deleteSavedGames(); diff --git a/Mage.Tests/src/test/resources/log4j.properties b/Mage.Tests/src/test/resources/log4j.properties index 605efa2a5e..71576f60a2 100644 --- a/Mage.Tests/src/test/resources/log4j.properties +++ b/Mage.Tests/src/test/resources/log4j.properties @@ -1,5 +1,5 @@ #default levels -log4j.rootLogger=debug, console, file, watchdog +log4j.rootLogger=info, console, file, watchdog #console log log4j.appender.console=org.apache.log4j.ConsoleAppender diff --git a/Mage/src/mage/target/TargetObject.java b/Mage/src/mage/target/TargetObject.java index b7be81f5fc..e813dac2a1 100644 --- a/Mage/src/mage/target/TargetObject.java +++ b/Mage/src/mage/target/TargetObject.java @@ -58,7 +58,7 @@ public abstract class TargetObject> extends TargetImpl this.minNumberOfTargets = minNumTargets; this.maxNumberOfTargets = maxNumTargets; this.zone = zone; - this.targetName = "card"; + this.targetName = "object"; this.notTarget = notTarget; } diff --git a/pom.xml b/pom.xml index a070a2754b..37325b8839 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 @@ -31,6 +30,7 @@ Mage.Client Mage.Plugins Mage.Server.Plugins + Mage.Server.Console Mage.Tests @@ -62,4 +62,4 @@ 0.7.2 - + \ No newline at end of file