From 473f6bcad99becb55f1fdb9bb7258fd6caeb9dd2 Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Sat, 14 May 2011 23:28:07 -0400 Subject: [PATCH] fixed client/server ping + added server console --- .hgignore | 7 +- Mage.Client/plugins/mage-counter-plugin.jar | Bin 5594 -> 5617 bytes Mage.Client/plugins/mage-theme-plugin.jar | Bin 3801639 -> 3801634 bytes Mage.Client/pom.xml | 5 + .../client/dialog/NewTournamentDialog.form | 8 +- .../client/dialog/NewTournamentDialog.java | 7 +- .../main/java/mage/client/remote/Session.java | 84 +- .../java/mage/client/table/TablesPanel.java | 5 +- .../client/table/TournamentPlayerPanel.form | 6 +- .../client/table/TournamentPlayerPanel.java | 6 +- Mage.Common/src/mage/interfaces/Server.java | 7 + Mage.Common/src/mage/view/UserView.java | 67 ++ Mage.Server.Console/pom.xml | 33 + .../mage/server/console/ConnectDialog.form | 240 ++++++ .../mage/server/console/ConnectDialog.java | 410 ++++++++++ .../mage/server/console/ConsoleFrame.form | 72 ++ .../mage/server/console/ConsoleFrame.java | 198 +++++ .../mage/server/console/ConsolePanel.form | 219 ++++++ .../mage/server/console/ConsolePanel.java | 423 ++++++++++ .../mage/server/console/remote/Session.java | 724 ++++++++++++++++++ .../java/mage/server/console/AppTest.java | 38 + Mage.Server/config/log4j.properties | 2 +- Mage.Server/plugins/mage-deck-constructed.jar | Bin 3191 -> 3172 bytes Mage.Server/plugins/mage-deck-limited.jar | Bin 2391 -> 2396 bytes Mage.Server/plugins/mage-game-freeforall.jar | Bin 5286 -> 5294 bytes .../plugins/mage-game-twoplayerduel.jar | Bin 4894 -> 4896 bytes .../plugins/mage-tournament-booster-draft.jar | Bin 5721 -> 5723 bytes .../plugins/mage-tournament-sealed.jar | Bin 5049 -> 5051 bytes .../src/main/java/mage/server/Main.java | 8 +- .../src/main/java/mage/server/ServerImpl.java | 41 +- .../src/main/java/mage/server/Session.java | 42 +- .../main/java/mage/server/SessionManager.java | 52 +- .../src/main/resources/log4j.properties | 2 +- Mage.Tests/plugins/AIMinimax.properties | 2 +- .../test/serverside/base/MageTestBase.java | 2 +- .../src/test/resources/log4j.properties | 2 +- Mage/src/mage/target/TargetObject.java | 2 +- pom.xml | 6 +- 38 files changed, 2657 insertions(+), 63 deletions(-) create mode 100644 Mage.Common/src/mage/view/UserView.java create mode 100644 Mage.Server.Console/pom.xml create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.form create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConnectDialog.java create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.form create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConsoleFrame.java create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java create mode 100644 Mage.Server.Console/src/main/java/mage/server/console/remote/Session.java create mode 100644 Mage.Server.Console/src/test/java/mage/server/console/AppTest.java 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 7114efce248e723838f50102f2d1b128fe5c2515..4cd8c3e86e142552e899035942b20b1caedd34fe 100644 GIT binary patch delta 4469 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 delta 1595 zcmZY92~ZPP7y#f+0y#9{kVFY6Q8`qSB?m#-2=Ty*a*P7OgG*5f;m{%!8dMr%J%&(f z#o*#-iz2A?DB=~Jf{GPKg~(wYidIAsP!vIJL8yfOo6)qiJM-;(|C@L2?E6c$KPMdn ztfj#et1$@i4CHC|u-sVvd0P3nudbw~K$CWlT*c4Mbx$h8u>IM&c8%=Va((J|9OWkJ zo1Mzan93Mr^!QpHg_x$tjVSiANdj{jK$1{k+OO55U1}163@E?~SOY4c0XkrSF<>lU z0v50Vw!jY9gK@wCumJ~*2NQrJ-~uP$3?_m}zy*sE5SKK!Z*sPw`uZ)fC&L3Re zdLZ6qfpcbCUBa=8d-~hETd=B{OJ#vx_V@Mv8KoilyeqHzsGQ>~YU+A!>oT$)4;+dC`Nf`;46PD(-@ znoj6uJ-%GAw2Em>|6y=T!O@+;%a1OepL|3%{G;dLsmV!3hKs*EDBof8ory)W>7BNr z%L4+emXPJWzHDIwZCfB^Yae$;l~+H@L%eTGq`l+WV)lp3>_azkuJI3Y|7(rG=F4~0 zZ_>5>X$2SkkOb0nXYDrLQ;wmI-cx+IGNLI=CGh_J#9h&bb5)X+2`bw|Ee_ZIs<@?V zdvQUkZ;V+MBdK0rRMYaN_5jYHJi4S(^;Om>bNq{E-@n-X=emNV5mR;R^VW0MGMw^G z6(xtARy<0hMsKrO){7?%s_yDFPc*Ka0@H5Ak#1xB{+o7jC1)1SdY(l+XjiN6boaX! zrkEHfe$af-L#bZU=a*TM8|~6;ys2xXcU{&|a~D>1hl%dRDUA!bzj&(})AqhJJZmc# zxet`QW@fI9xN`c;sRr?_4ZgPafuY9OZotv@`l{nd_A!Kmlmy83fI z4c<>Wf`oU3XkSQ$Q5e)*8yd2tqa#S*c{?OH#EUd$h;02ufFwL4B9oFHbkAF>q(ELE zk=YbWW|5my%*PkwQ-JplV=kjJ4(?>ae0+#)e(FS&R+hjH>6v!}qR-P4h5uOtZyCm% zNuBs16Xr-MKR8G(2s9zB9hGRK=CmbGzEWL?Ut z#Ps-VujI7Ef7YNQL~6Vz*E~p}AxI`2K`iHh{gi48@P?6(3%`VkC~kZdpUp>6{=cUn z4z@G@!h*yaCbISh6MkNj37P+3wI*P zoC|wpO!GjKd0+t1i1GfHL@XnT4d)S^P`sEVbKqJ23+S;C_>Styz#B=jU~2s^2F-s1 DaGzXH 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 3647989d7d0afaf8be3e1704bfbe762d4206dabf..81226541ab2d2db488c37554395f9d5e0b02f11b 100644 GIT binary patch delta 1041 zcmew^@kD|*z?+$civa|7v@D;K%wf1b{VREGc7Fz>blm2dzqam zFt%;3Pfi_>F3)%iq$8EC*{c1BeYy;+}e9t&9D0;?97{>y3%rj6M=1>I`q*rgQA zivG>W!0?Tgfx&dLBb(vm58UjNkFxRCr=?0C{CxUU!iAjHb;A33hHv~POw>-4LG5<3s>P%$lVQCY~}&~obI+4H*l zTnxLy=k2u2xVG{8Z`)h-1$#@HuQ*4D@`Zax>bQa7 z!W>jjDjsxS@?0SGMqfbk!L>_WwlByExab@BwCoNG|D(T4cj?M5_RpC6VAuO2Y#%rD zCu}?+dSUsC)fzIPK!R{_&RMjE~wf)&E3q zO!`r{Wrawq_Ocwth4X^fW;88N@SpzA+dt~-3yC?Et4uePZ?>^Y3tYM~=-!8rDU(F6 z<^B7V`O@vv+P6YJvF1wkK?loq)=!B(U0JgrsH)LU?x>}siObUjn~i_%*LTEgW}e-x z@GP@6T}$%=@2k%#R_RsQiW5z5mwbO6{l)U&-Jfe0vj%(cf4l$C`k3d(#gS*9X?AUT z#<}3|*0-E%Z(ApC*KZOMdh=jGq0|kdy4Fh%>|x1>1C#*m68eYNu-B|hqrR)si5vI9Uo4P=aK{)P|YRH z#K}0>j!{+{pLTwjIY90I|F4?-fJ+XnosnCT<^TWdtdkFLOHH=m=8*^a7Oob^(1UY8 z8hI!0=Qc#Lh=Tzm)41470B=?{ QkQ^5f-eh86DCGq40A)a%ApigX delta 1016 zcmaDN@m+#9z?+$civa}Y?z5iAtHL{HpS9h;t8eeu0fi<`w9Bv)SBtq(lz6^XR{UGs zjlzu|lP(`^ve5a>6E22=Q-|~Xs9o)FV28!m##70z8X6K1jZ_aLL-H9wNPAp-T|Q+y`>E0{P<%+}>ZbI@s=a zKj+cDDg(W}*|7|<;%Lc z_d&06S^(quhG4c;*B!a-OCKCqx&41l(**Z<={B>o^X_eG%#F?Mx9PVjvFm$(!#T%z z-{JkH+P~`igtjgzIJ-np;FD(PB((~jvM;Mv^sdh;32o;)=sBq-C$_D2F6;DVoY_f! zu8|v=Ql9YXN1JcRPhPZtX5kvupo8Ca>enxoJ@&Hh{L+$MyE$hg6|$6yFZ8|Gzr5=Q ztEcciN#p6V^LD5lj17oQyR3S5Hb>{0nagg+$1m#V%)7omS69M$mHB_M`^J7<`DZh3 zU02PX$8byjcHe``_tKd?>?)-^*0051#fzbc} diff --git a/Mage.Server/plugins/mage-deck-limited.jar b/Mage.Server/plugins/mage-deck-limited.jar index b4ca904cc5da2bb8b5bc5ca4a5ce65769e1ba0e4..fa0f9315a69a29b6b5cc79b2ef7bc4f673e6b36a 100644 GIT binary patch delta 918 zcmcaEbVrCUz?+$civa|7v@Exq$fwM*9YmW>W&!ih$V2G&DqwoEIO7gRFl+KL{N$hBsUo!T?sJwF&37+$e5Fc>mS4&czKFUZf;tH{ln8xos++d!mtUVSTP z_0}h8snQ2O2TSryT6-b)&DxAly{oTHYf(|xT>QUw)02E_Rgq5u^0Ie}-+$c6C$#d2 za)9u>Q%$e+SF{-zEC59h=c+lGalmpZGhG4d;3zh8l-yfV<{r&$eo`r0ckp;P# zD^gdxm3`eR{Ur6#-0%6f9y1gkHWB`}Ho~w*Gb*I(5N~jp!;0r2+Or;L-nhK9{_x~5 zTPwEo$gHN=1WjdrzTk`6F+9{hu78R zdH*rP(isOhot<#BRx1Fexndx;0H=}3KUr1l{d5>NX^Zll5#>3%rswQhpEIH{u}&gA zJUqOWJ5L35cNu^FoWuL&%-5cZotL^ld2`zY=X~zI^tDL%a&YBNp>8ju%R-aA8=Cex zFvd>5@+2pA{+T;I3rzRKFa&rrGKnxF(m5!-!vH6Y!7zCqn=Cl_Pu|aF2T9b7?D`Of z3A+h|k;Co?VQgf#gfQN*J3-ZOgz%!|fXP!if;d6>2<+dvrwzGnA1kks9VgcT) RY#_V2fbb*}14AvC2LKf5hME8X delta 890 zcmca3bX|xqz?+$civa|hcFeJz$fwNG2%=3Vvw-<$p9y}GOZJi5A0SJKmO)0DsOr>Y*kA9tvU|60Zuw|txP zjzOLu8A95hZ+h_R@~gPlS>1)6eFp?ra_nVSN$J~PfBUht$l{8pGj4BA(*0dxweYg_ z>Dxy>O8vk2zHUadYNtef_^bl1)e1akJJ)Xd;1{rH=7aDPt=>G`F2`r@{-NiVK6P!7 za^gG#AFqjyAElQV39Vc^=>g+4BWci+t;wOuiI?7ef`t$9%|qMGITaGIyG!js@tD!v~i-n+ zVilik(`1&PJ9fSKWyP)MJNfF7*OP%rK2=66L@)2>~)-9L+ z&hvgLRl8%xW``>-&lbpD-0v^?k$aNb4&yXEYnwvPrris6om-Z@%Un<>(%5r{ui?=|NIqPS(jx7Sn&3=NY6L< z!4FJi0^n4}0ZwH(kJbejPCmsNm8Iz$THxs$X0R#1z-XJ1!A2v4paNdLKm#KKlLt?= zymhtCojJeR^n&qK<0ntO^iS#Qe(>3NR^RLTX?0{ z{VU~J8q?Z`Pnj43ycwB9m=P&^axa@PIB8El!e$3aux#x55QZhY34~F|?g(LQW4DAb zKC?SP)o_IHqNMK0vp9kjKzRi08({t^24V|PMuLJRjT>2Esekf+R=&w@oC0hWY#>)6pLq9g zW4Runq1ozPU2y%rah*qj5Hpw`oJuM|XuF)i2*}H^vFi{~fWW^gdbRvvfzpIos)p4D0vReUPsyx^z*^h3n7Gya}f{ zHpwqA32Is9<)9uhKhl785zpC!44sogKdN#~Y6r<-}c7y z$B~fWb=J2w9AH{D<@S`K*+F{OihK=)OX6;x;ouSwfVSKPON%Aq z-?Yz1ZG9mU^JAsy`qH9{J5xiK?hLy2Cgxea>#T)W-#q<%$@j_aM@(mA%{`w49mx#R z+&t;@509lEy7s(1VmUd&XsSb|@a_NJZol}wO5S(PcrF^ZV#xus75bB3PI`IK$tdgE z%in+RRm)%a_hLE=@Xnjql^NH+$FL7I!?! zRFHSUq-4TTiM)Upe^_DZjRTb4>||zIYZXt<67Z-$$aTnohv7oC!heAql}qO)C2nY5 zAT3vRNxnmG+QDmHYnuP=-D?|X>LKz}N7%Mps&aBiz+Fr6_bIkJgR4Khy?FWSrv=BX z+BbC8Jr}Xg-jgZNwCw(Kvr^CINJ|c;?0NV9oKih5^!32%D|@@Xc%DDq^npFVn~_O` z8J6@JmrphnGyx_4$r*z7;6%Ji&;U%|6*L9YqC&1CzQfyj+AW;BGkgG%h delta 915 zcmZ3dxlEHcz?+$civa{|SK3VERbjRPQYKTFLA=unVCtPJh}ta1n8FTb)N)K^0y9Lp z{lJXLX}nq>fytA3jluLuUJqV{EmLg+Yt5ehV`N}>K3R^>zW$1VNbR=$N<90_UiPd$ z5y0Kl!(pwpqbuLrCx3V3?IkKN&**IWf7j&fm+BOOXA3PYE!DrD*~|IJ>!f=E+uT!5 zFUnW5C$G{~RJCn5uw~I3#tk8sKYykA=M}Up4n2Kmp2_$>*j`M+^#`|43Ou}Y$05GhBnt(bJ9pf_3);ObnHs_U+gU>|mFp;f zz^y11KUFp5HOXNijRu|377F2;*4ZuXEIpulR#7c|$@75J3b&aX6P!7xPEk{1-m+Y7 zPhv~_<5C~Kz5DN~q<>G)+MS$OY_i>}l_kAqUd&e4;}6z! z*PPz=_jRe>5|j7qmK~j`qaD}4b^Gx2`o+>mw{OhdAL+41*+|o9-t|+wk80{C1Z_H& zf9_$7g4C)a1Ko@D=VedY>*RjdYpJw+80p1zi~H5o_H>=S^6mH9&E>Uk<5^U-H4h%WoM@^tQ>FEutRa&B!Fe3{UctEd@TO@Pgs9)mxvsjk|0PF095&cE&u=k diff --git a/Mage.Server/plugins/mage-game-twoplayerduel.jar b/Mage.Server/plugins/mage-game-twoplayerduel.jar index 0c6f838e0c7a1201994f479114cc94cc48057c4b..ddeeca83920c4292268cad6d7dd88796032a29ed 100644 GIT binary patch delta 965 zcmbQIwm^+Hz?+$civa|7wk)5>tHQhkNSRDw2JucSfT?$?AZoK1<6c%U;~JYE6PTgS zISI^|yoXy0Bry3Uw=tNO=kXSDshMMUIw-@BgNcFRH!A~!Im6`rf>M*^g(N1gwfu0PmY$5z@;`v zp3B|uKfIGqXz5eq0_nWfK{NC>t7l(ry402HAh1lLo=K_HFWi3mmsv+t=2bpR%I;#` zohfyxreIH{O#H?Br*B*DiP*S8;F!_DM6njdd-V|#?DxIS*GHR z)uJb#4bo}cZ{VXf)A1+wmV-hoPfxnQSeBr*%<;w*S(yphk*nWFc8Pi%E%JCF_tMhm zcGB4$t_7V_UhsWkE7_v;TIRU#i@-hmx4iT^{zQ1DddcPTCdXaxm1pRD=nWOPYhDz( zN%qBTsZ*Dg>MgkbpWe`DQ=7Ky><;^18xF|mMc+u{HjI98S@lY5RM3ZW#l`^&Mgn^n zicJnN-uwE%VaxabR>l+gDrZi}&pMQOmTlM9oz_oMRThaC-FYndsO_cNpJ4H)AFms3 zx+asy)yul%-cq;EEqw>)t^2cFZtJUyiWNz#&K#|HtlHOT(W$j+R&R>7*5?J%+;=1(TVy>0H`EIyr zZQn7on!U>F`S<3nyVD)LSuL#8ByR1J_x@?>)%+ip0y#h_(C+Nd;r*MqZ4axG4O4{Xb8UeKAdc+!3I?TKA|HimAq9?VTR z(7Z?FD0gxhQ|`e#ue#T+FR$359CAxSlkd@enVQ8@L#K-L9p3jfSop?DQCZJMndka- zN#_*ZZ$9*TTG95rsdLBO%!!Zq1H2iTM3^D@1DvvF^P7Nj$mC1>_F%qD>dQEO@iW7?tG*uuYsA9H$Q1cNTiewg8PYM!FlDuvnk*+tUog_{b_T#cJhAGDtw^5)@o*?oKY6V1-= zR`Dqsjs6nLww_q{i_vSbOWNusDJ@@pJVgs8-{j{O@iO`3J#V2?%w?vaA{REk&}Dam z(gb3ZRjU}bGK=P}T6Ul;xM-7I&aKLqDs}TG-7VmYQ92&XviYg~WvNBS!*aB$7)q}@ zl#B8+K3>)>UX!@GHFm4O>eh8JUT=cjx$ary@d;J%&6&EuU+Trf z!wh{o)xVFsYkoWNx~H;O_MEj@QSOSj6R&r6o;&eU(qG_q&-)MI!C}k)yLG!6?$8$H z;wU|_B}sE;6Lah?d0Wd>&c`1_E~%-Do$=JrV6&d@-1?%*^hMKBTQiGi>qnb!%I`GZ zFsE>hy3xVysTVb@r#^qJu9s>a+wk|d&BcJwhC-MBb?ZF-DR%yxYxsH7;dDLC0`@D{ zZDI#XH8!T$$|V+rJ-h z_*nUV@!R#RswxSu)fae9ubWboJcYHM5tjTo7=TI4ZiCKE@e*KCEC*scSbC9}B+OOM zd%~Nm*+78dLT$o3g9lNbZ`zf1WDANrE!=rvi(jzgWFs}P{QGa@*1x#1IpB%ld~3cf z8`(o|_@5Fpk;=X-qkr~g!}j*0QPRv=$&t$+M90o`wB&qwyFXVTT=$8Di07PpU%D*Y zWm4U_r+*WFXZ%*@`Vr$5_5t3EOd`zS%)tW69h2wsn}E{& z0S_>JM!*M5OAC5}vqQR|6_{Qk=nSS`2}bjxWRJ-~LJ0RYOC5U`|i4<9u90E0t{ Jt%n~Z4glemj4A*C diff --git a/Mage.Server/plugins/mage-tournament-booster-draft.jar b/Mage.Server/plugins/mage-tournament-booster-draft.jar index 9b81b4c1bf9af8f4f0de78dbe903fe985cee57a4..bbd0b228a581bf13c164d89b1501ba7c7b83c81c 100644 GIT binary patch delta 911 zcmcbqb6bZuz?+$civa|7wJe{=tHQh!NSRDw2JucSfT?%dAZoJ=V-*vaF_ZZ>gfX41 zl@%-^&-0!U#F#9|rv;|%_>94H310wjWX&8q$&X9tvN16*@K3(T7g+x!Emiv9S7*&; z$IYU*diRQkhQ*X_OHsM$Df##P?r9?R=`D_OixwB}?>iqlA;fE+LDnJXNRHaARc6a> zCB#f><8;w-nlCv?>v;M7?LUN$YQ$MSd$yqR_`UbvGyWg^bgi(au|7Bdz2XKHLGfDx zjyJV9oI7r0aNqax;+g)ar|6+(eH-hdXP*q~dM-MquNLt-pwBZoC~eJ;lT+G+R-T>o zK=7KO_M#aED{Uhb!Z)qkm!=uwpn5X0so&$g;;9d^3)v3n1}v&xCbewQ?nUPk@38Q{ z`@P`U^uCMgTl@+xmorWOal?H>!~@4`UK4~QE^eK2%b;}eiF0SP588Y&Z`AwrrFDf_ z{o9W(*4ryR->cbT%H0B1)+JTGTNiQ8YqH&2Bwu%F zmGkijXOixnKX>QqMTc%J->F6amTy{9!T7HD;PR!?^(VKt&7Co;z-39$n~FH?-Ah0J zZuEM|`l~|ZIm<ltqlxum{`rGv{ zK4&R^{$EyihSR+O+kKClMDE}EniIe5#FzDlCPzQiDAv9sy!W+r^Y3t{lU5T)F-t2Z*y$CM@^6DlV3P#kMsZ29d*dgNm@a!Zj@g+4>vzvQ>OhHnC&L=9`rJ@J^+8Y_hM= zz54YllRfi}x?EfE!sv0hH=pXOiRCAE1YP@eZjYv?zQt&ZVEZTtvK|1?S){rE delta 911 zcmcbub5n;mz?+$civa|}0=*{ksxXHFDU&J8Al_*OF!fFwL~WK~tYQK)W-|YVFs8G$ zvVukAdEPUE7?TD0w7|3-pD~y&;S1oESnX_g()7wPHYNrJ-pLpF0_&fqrS?4dnKvwNKxX5qW*{_g}kv^+tP2C&etVzx_ITN5sR9 z!lj1lC88~gcW!7f$8$HC3jgUTseh>1#<=L)C&fySN6n|gC6_el^IZ0NvSrWmAjhsV zE}j=TUe7e0Hs$r19G(D=i&yMF@faNu)ywGW>v*29@+O}!?*lQ7i@H;Fr(X2EDRLpN zi|zTppw~g_AD@eC-N$F)bX=?H=!fz}6J^2=bnN3?Xfici==~QP{u1YZNh=nfn78pw z{UN#S-*#{(IknlPyl`sMTlTQz&4cE>Q!dZ?G^gm$3aKrZ59`axaQ^r>-#F~egzK!D z(|^TY%U`mv|Luh9olC;5W%e>3F?noNlM`Y2Cz$Jq;+HN@4}~Y*%TzosihTKU>)$ue zm145Z#?6-I(b?DCf9tF=2|cxIe#fdb)r#|RcDi@#J@%RU9I0~LIM0LS{>DWU)7+jv zXP&yL``o#_y*^hW#6qGMMV~ibWFFKsQT&L_+7CXep1F;$Y-XN&DW{|IDQ{EV{o4M0 zOIF<9zkO>0m!)%M&2bC8`m)D2_j*tKw*Js!*@qh2mEUxp`?~kwU2R2IUq^;j0p`pT zF7O45{b2_sH(^kE;{c^MyP%KNN+m#E&16Hti25)gO<69zrC~C2X31N;o@q5h`?>3j z`{o~(h4W7F2*_;w$u2x^%9@pj)DKTi`><|@=yb7P;SJX+^Urz~<;=0V9<#Rd&`)bU zS?`>(o)q4$Jnem3pM)&po1^;B&-1nQ=Y=Z#2SeBXWDf9VWD;S9r+GV2+6RNlTtZr) z+F#Sp>1xyDD7lP@d!bxCSOC$|UPZqHP(-%aX!L*oY0$S>C S7LDaa_4ixR47T@zAo~HOD23Gk diff --git a/Mage.Server/plugins/mage-tournament-sealed.jar b/Mage.Server/plugins/mage-tournament-sealed.jar index e4a8584a986fa0ba2feb2686d16141e94d4c4764..9c5b2d19035014db78f3d18df5008491ebaf2955 100644 GIT binary patch delta 927 zcmdm~zFVC)z?+$civa|7wJe{=tHQh!NSRDw2JucSfT?%dAZoJ=V>uI;F^%~%gwez1 z!3-9;&iRND#F)H?TMJCT_oc0{bFQb_|3||V8$>>*rI-JNNo0P z1CiQ!^{t%MTc4z*N+0}uS%PQQ+6(L6tj*Z;Xw_y_<&%D=Uew>;s#0&Q%=1Y=R`%}V z>Y8;;OM*Vl3>2Ps%ISswZ1v<-vd2_2XE-cT`qHVmvZ&^FZU6efo=3gO@BC(cfAjcb zN8fv$eCgxiKc4@4#>Y2J<&l%LlE!V8#Ci_(vRjADCkY*1y2C-w=J*DOD>3%R`VFmK z=1gv4`E$rXGxb;(`!W-cCEL83)FaNX=}0=Xq%5&9=H#wlvz9Js@S3!lrToMJ#Zw=c z7qT6&4OnEoOlsMp+l$UEyvx%6t=+kIdf!F%ExrZDcUa5{%li{TAH-ernjj>xz?Ey7 zuIU2d`d_mf>gL%AUln^ZEpNANUU#eW#tqtO=Fw3fj%_p!Gn{DXXnA?DT-A?M2K9A& z|31FlV)JR&qx(_aub27uNM}_)DSfu6xTx;9VAAZ5vj0|98ve79idp!^I9x&Ds`n~U z-w!e}FQ)#!wt2Nx371~bQ{^|GVoGO5mS(=2(rq&}^(c2e#~kaLd%HSoqa~Uv->JE1 z9c_HRbyM@sJMufH#4Y?j*D}4MZN(f(_b>macm0r`G~t1$@px zPKvY+vVXVVMPB&M`v2RvCh+}q;Qi6a9aNKjd~&zHQmefYtmT1P?8> zKl)GRLD}4epA{oEPyRFQP;>dk(rYQ2x4%zpQ@Xi!#z`rW*n2-N%}VYq)0=Iu?#L~_ z7J090e;5P28JR?wVVQw(`Q#3M6Hs=Tyr175oSGR048XLBfHjyd5{LuSmj$xHw4-1Q sm|h^50H&FRtiZH`kTaNW6N=(R$qkd=3Wf8cguvuL;Uu<{9 delta 935 zcmdn3zEhnyz?+$civa}q*LqImRbl1>QYKTFLA=unVCtPVh}tZ}Sk44yOk@5GVf3(h zFoQ*|b3S4OF(&Wf)&kQnxsAcJJdc--4sq)WBzZe-9ezGz!m@!O_7m}LXAS^w3 z0}pGxZ~hzu5u54pjbVG6PMWP+CHhn(bk&qxW!1G+-7$|HhBxyw9>% zhpO-y$nF0q{mjy%^~w1uFFu5X`_$gE$Qcp#3wFP+E|FC)+_dq` zUC*h^zbkBx9p`V`?mJ2QOLl!VzjU_DRG-W<9Cuj~IqI#;P94}jCn2_|tTCpdFR@|8 z-Z~$-$v>8S@?{hH(2^MSc}|%9$`FN#Gqp5lB`^mkc+Na`rk#=Nr1VGA^A3vZ3LS&5 zD9>wNs>eSggW(&Imoeq_M0*qp6Umx4NyG!Y&7v6+EaE{ zI~F-EEM65LUKg+_cna%(22k3Q03|*SP~x*YxoX#mLLjdUh;3nsM75sx#73@W0|AB$ zwgvwS9;{JWC?X)CZ#P%2&dzx= z>|_r7VGQtQWD;S9WeP^m$zA*=plmVuAiq60RWl11fN3)UYcO3R5C^8O3S@(6XTcaS sy+|+tOtT7EfoUfpXE5C%6vc~@D<;1e3g<-$g2}r`705~m)@Bjb+ 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