diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index 83ffce61e4..5d8c4a9738 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -166,7 +166,6 @@ public interface MageServer { GameView getGameView(UUID gameId, String sessionId, UUID playerId) throws MageException; // priority, undo, concede, mana pool - void sendPlayerAction(PlayerAction playerAction, UUID gameId, String sessionId, Object data) throws MageException; //tournament methods @@ -214,6 +213,8 @@ public interface MageServer { void endUserSession(String sessionId, String userSessionId) throws MageException; + void muteUser(String sessionId, String userName, long durationMinutes) throws MageException; + void removeTable(String sessionId, UUID tableId) throws MageException; void sendBroadcastMessage(String sessionId, String message) throws MageException; diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java index a58b7442f7..9b2b54831f 100644 --- a/Mage.Common/src/mage/remote/SessionImpl.java +++ b/Mage.Common/src/mage/remote/SessionImpl.java @@ -27,6 +27,11 @@ */ package mage.remote; +import java.io.IOException; +import java.lang.reflect.UndeclaredThrowableException; +import java.net.*; +import java.util.*; +import java.util.concurrent.TimeUnit; import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.cards.decks.InvalidDeckException; @@ -56,12 +61,6 @@ import org.jboss.remoting.transport.bisocket.Bisocket; import org.jboss.remoting.transport.socket.SocketWrapper; import org.jboss.remoting.transporter.TransporterClient; -import java.io.IOException; -import java.lang.reflect.UndeclaredThrowableException; -import java.net.*; -import java.util.*; -import java.util.concurrent.TimeUnit; - /** * * @author BetaSteward_at_googlemail.com @@ -103,6 +102,7 @@ public class SessionImpl implements Session { // intended to be used with handleRemotingTaskExceptions for sharing the common exception // handling. public interface RemotingTask { + public boolean run() throws Throwable; } @@ -127,8 +127,8 @@ public class SessionImpl implements Session { } else if (cause instanceof NoSuchMethodException) { // NoSuchMethodException is thrown on an invocation of an unknow JBoss remoting // method, so it's likely to be because of a version incompatibility. - addMessage = "The following method is not available in the server, probably the " + - "server version is not compatible to the client: " + cause.getMessage(); + addMessage = "The following method is not available in the server, probably the " + + "server version is not compatible to the client: " + cause.getMessage(); } if (addMessage.isEmpty()) { logger.fatal("", ex); @@ -341,24 +341,25 @@ public class SessionImpl implements Session { /** * I'll explain the meaning of "secondaryBindPort" and - * "secondaryConnectPort", and maybe that will help. The Remoting - * bisocket transport creates two ServerSockets on the server. The - * "primary" ServerSocket is used to create connections used for - * ordinary invocations, e.g., a request to create a JMS consumer, - * and the "secondary" ServerSocket is used to create "control" - * connections for internal Remoting messages. The port for the - * primary ServerSocket is configured by the "serverBindPort" - * parameter, and the port for the secondary ServerSocket is, by - * default, chosen randomly. The "secondaryBindPort" parameter can - * be used to assign a specific port to the secondary ServerSocket. - * Now, if there is a translating firewall between the client and - * server, the client should be given the value of the port that is + * "secondaryConnectPort", and maybe that will help. The + * Remoting bisocket transport creates two ServerSockets on the + * server. The "primary" ServerSocket is used to create + * connections used for ordinary invocations, e.g., a request to + * create a JMS consumer, and the "secondary" ServerSocket is + * used to create "control" connections for internal Remoting + * messages. The port for the primary ServerSocket is configured + * by the "serverBindPort" parameter, and the port for the + * secondary ServerSocket is, by default, chosen randomly. The + * "secondaryBindPort" parameter can be used to assign a + * specific port to the secondary ServerSocket. Now, if there is + * a translating firewall between the client and server, the + * client should be given the value of the port that is * translated to the actual binding port of the secondary * ServerSocket. For example, your configuration will tell the - * secondary ServerSocket to bind to port 14000, and it will tell - * the client to connect to port 14001. It assumes that there is a - * firewall which will translate 14001 to 14000. Apparently, that's - * not happening. + * secondary ServerSocket to bind to port 14000, and it will + * tell the client to connect to port 14001. It assumes that + * there is a firewall which will translate 14001 to 14000. + * Apparently, that's not happening. */ // secondaryBindPort - the port to which the secondary server socket is to be bound. By default, an arbitrary port is selected. // secondaryConnectPort - the port clients are to use to connect to the secondary server socket. @@ -1424,6 +1425,21 @@ public class SessionImpl implements Session { return false; } + @Override + public boolean muteUserChat(String userName, long durationMinutes) { + try { + if (isConnected()) { + server.muteUser(sessionId, userName, durationMinutes); + return true; + } + } catch (MageException ex) { + handleMageException(ex); + } catch (Throwable t) { + handleThrowable(t); + } + return false; + } + private void handleThrowable(Throwable t) { logger.fatal("Communication error", t); // Probably this can cause hanging the client under certain circumstances as the disconnect method is synchronized @@ -1456,12 +1472,12 @@ public class SessionImpl implements Session { String email = connection.getEmail(); return email == null ? "" : email; } - + private String getAuthToken() { String authToken = connection.getAuthToken(); return authToken == null ? "" : authToken; } - + @Override public boolean updatePreferencesForServer(UserData userData) { try { diff --git a/Mage.Common/src/mage/remote/interfaces/Connect.java b/Mage.Common/src/mage/remote/interfaces/Connect.java index 3eeff3eebe..f14a252ee7 100644 --- a/Mage.Common/src/mage/remote/interfaces/Connect.java +++ b/Mage.Common/src/mage/remote/interfaces/Connect.java @@ -24,7 +24,7 @@ * 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.remote.interfaces; import mage.remote.Connection; @@ -47,7 +47,7 @@ public interface Connect { void disconnect(boolean showMessage); void reconnect(Throwable throwable); - + boolean ping(); boolean isConnected(); @@ -56,5 +56,7 @@ public interface Connect { boolean endUserSession(String userSessionId); + boolean muteUserChat(String userName, long durationMinute); + String getSessionId(); } diff --git a/Mage.Common/src/mage/view/UserView.java b/Mage.Common/src/mage/view/UserView.java index 3850a17042..29cd831588 100644 --- a/Mage.Common/src/mage/view/UserView.java +++ b/Mage.Common/src/mage/view/UserView.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,7 +20,7 @@ * 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. @@ -42,13 +42,15 @@ public class UserView implements Serializable { private final String sessionId; private final Date timeConnected; private final String gameInfo; + private final String userState; - public UserView(String userName, String host, String sessionId, Date timeConnected, String gameInfo) { + public UserView(String userName, String host, String sessionId, Date timeConnected, String gameInfo, String userState) { this.userName = userName; this.host = host; this.sessionId = sessionId; this.timeConnected = timeConnected; this.gameInfo = gameInfo; + this.userState = userState; } public String getUserName() { @@ -71,4 +73,8 @@ public class UserView implements Serializable { return gameInfo; } + public String getUserState() { + return userState; + } + } 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 index 3bcc254936..68a4f4baf6 100644 --- a/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.form @@ -52,8 +52,8 @@ - - + + @@ -64,12 +64,12 @@ - + - + @@ -101,10 +101,16 @@ - - + + + - + + + + + + @@ -114,8 +120,10 @@ + - + + @@ -137,6 +145,21 @@ + + + + + + + + + + + + + + + @@ -159,7 +182,7 @@ - + @@ -171,12 +194,15 @@ - + - + + + + @@ -205,8 +231,9 @@ + - + @@ -214,7 +241,7 @@ - + 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 index 7f9c21e3d0..6806072d1f 100644 --- a/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java +++ b/Mage.Server.Console/src/main/java/mage/server/console/ConsolePanel.java @@ -24,9 +24,9 @@ * 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 @@ -63,7 +63,9 @@ public class ConsolePanel extends javax.swing.JPanel { private UpdateUsersTask updateUsersTask; private UpdateTablesTask updateTablesTask; - /** Creates new form ConsolePanel */ + /** + * Creates new form ConsolePanel + */ public ConsolePanel() { this.tableUserModel = new TableUserModel(); this.tableTableModel = new TableTableModel(); @@ -91,7 +93,6 @@ public class ConsolePanel extends javax.swing.JPanel { this.tblTables.getSelectionModel().setSelectionInterval(row, row); } - public void start() { updateUsersTask = new UpdateUsersTask(ConsoleFrame.getSession(), this); updateTablesTask = new UpdateTablesTask(ConsoleFrame.getSession(), ConsoleFrame.getSession().getMainRoomId(), this); @@ -108,10 +109,10 @@ public class ConsolePanel extends javax.swing.JPanel { } } - /** 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. + /** + * 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 @@ -125,6 +126,8 @@ public class ConsolePanel extends javax.swing.JPanel { jPanel4 = new javax.swing.JPanel(); btnDisconnect = new javax.swing.JButton(); btnEndSession = new javax.swing.JButton(); + btnMuteUser = new javax.swing.JButton(); + sliderMuteDurationMinutes = new javax.swing.JSlider(); jPanel2 = new javax.swing.JPanel(); jPanel5 = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); @@ -142,11 +145,11 @@ public class ConsolePanel extends javax.swing.JPanel { jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 358, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 347, Short.MAX_VALUE) ); jPanel4.setVerifyInputWhenFocusTarget(false); @@ -165,23 +168,41 @@ public class ConsolePanel extends javax.swing.JPanel { } }); + btnMuteUser.setText("Mute user"); + btnMuteUser.setActionCommand("Mute 1h"); + btnMuteUser.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnMuteUserActionPerformed(evt); + } + }); + + sliderMuteDurationMinutes.setMaximum(3600); + sliderMuteDurationMinutes.setValue(60); + 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, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) + .addContainerGap() + .addComponent(btnDisconnect) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnEndSession) - .addContainerGap(8, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(sliderMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(btnMuteUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(50, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnDisconnect) - .addComponent(btnEndSession)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(btnEndSession) + .addComponent(btnMuteUser)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 9, Short.MAX_VALUE) + .addComponent(sliderMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); @@ -195,8 +216,8 @@ public class ConsolePanel extends javax.swing.JPanel { 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)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); jSplitPane1.setLeftComponent(jPanel1); @@ -208,11 +229,13 @@ public class ConsolePanel extends javax.swing.JPanel { jPanel5.setLayout(jPanel5Layout); jPanel5Layout.setHorizontalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 306, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 351, Short.MAX_VALUE) ); jPanel5Layout.setVerticalGroup( jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE) + .addGroup(jPanel5Layout.createSequentialGroup() + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) ); btnRemoveTable.setLabel("Remove Table"); @@ -227,14 +250,15 @@ public class ConsolePanel extends javax.swing.JPanel { jPanel6Layout.setHorizontalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() .addComponent(btnRemoveTable) - .addContainerGap(170, Short.MAX_VALUE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel6Layout.setVerticalGroup( jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel6Layout.createSequentialGroup() .addComponent(btnRemoveTable) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(31, Short.MAX_VALUE)) ); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); @@ -242,13 +266,13 @@ public class ConsolePanel extends javax.swing.JPanel { 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, 301, 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) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); @@ -258,7 +282,7 @@ public class ConsolePanel extends javax.swing.JPanel { 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) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -268,22 +292,28 @@ public class ConsolePanel extends javax.swing.JPanel { private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDisconnectActionPerformed int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow()); - ConsoleFrame.getSession().disconnectUser((String)tableUserModel.getValueAt(row, 3)); + ConsoleFrame.getSession().disconnectUser((String) tableUserModel.getValueAt(row, TableUserModel.POS_SESSION_ID)); }//GEN-LAST:event_btnDisconnectActionPerformed private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed int row = this.tblTables.convertRowIndexToModel(tblTables.getSelectedRow()); - ConsoleFrame.getSession().removeTable((UUID)tableTableModel.getValueAt(row, 7)); + ConsoleFrame.getSession().removeTable((UUID) tableTableModel.getValueAt(row, 7)); }//GEN-LAST:event_btnRemoveTableActionPerformed private void btnEndSessionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndSessionActionPerformed int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow()); - ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, 3)); + ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, TableUserModel.POS_GAME_INFO)); }//GEN-LAST:event_btnEndSessionActionPerformed + private void btnMuteUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMuteUserActionPerformed + int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow()); + ConsoleFrame.getSession().muteUserChat((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME), sliderMuteDurationMinutes.getValue()); + }//GEN-LAST:event_btnMuteUserActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnDisconnect; private javax.swing.JButton btnEndSession; + private javax.swing.JButton btnMuteUser; private javax.swing.JButton btnRemoveTable; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; @@ -294,13 +324,22 @@ public class ConsolePanel extends javax.swing.JPanel { private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JSlider sliderMuteDurationMinutes; private javax.swing.JTable tblTables; private javax.swing.JTable tblUsers; // End of variables declaration//GEN-END:variables } class TableUserModel extends AbstractTableModel { - private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected", "SessionId", "Gameinfo"}; + + public static final int POS_USER_NAME = 0; + public static final int POS_HOST = 1; + public static final int POS_TIME_CONNECTED = 2; + public static final int POS_SESSION_ID = 3; + public static final int POS_GAME_INFO = 4; + public static final int POS_USER_STATE = 5; + + private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected", "SessionId", "Gameinfo", "User State"}; private UserView[] users = new UserView[0]; private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss"); @@ -322,16 +361,18 @@ class TableUserModel extends AbstractTableModel { @Override public Object getValueAt(int arg0, int arg1) { switch (arg1) { - case 0: + case POS_USER_NAME: return users[arg0].getUserName(); - case 1: + case POS_HOST: return users[arg0].getHost(); - case 2: + case POS_TIME_CONNECTED: return formatter.format(users[arg0].getConnectionTime()); - case 3: + case POS_SESSION_ID: return users[arg0].getSessionId(); - case 4: + case POS_GAME_INFO: return users[arg0].getGameInfo(); + case POS_USER_STATE: + return users[arg0].getUserState(); } return ""; } @@ -348,7 +389,7 @@ class TableUserModel extends AbstractTableModel { } @Override - public Class getColumnClass(int columnIndex){ + public Class getColumnClass(int columnIndex) { return String.class; } @@ -360,10 +401,10 @@ class TableUserModel extends AbstractTableModel { } class TableTableModel extends AbstractTableModel { + private final 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(); @@ -397,7 +438,7 @@ class TableTableModel extends AbstractTableModel { case 6: if (!tables[arg0].getGames().isEmpty()) { return tables[arg0].getGames().get(0); - } + } return null; case 7: return tables[arg0].getTableId(); @@ -417,7 +458,7 @@ class TableTableModel extends AbstractTableModel { } @Override - public Class getColumnClass(int columnIndex){ + public Class getColumnClass(int columnIndex) { return String.class; } @@ -497,7 +538,8 @@ class UpdateUsersTask extends SwingWorker> { logger.fatal("Update Users Task error", ex); } catch (ExecutionException ex) { logger.fatal("Update Users Task error", ex); - } catch (CancellationException ex) {} + } catch (CancellationException ex) { + } } } @@ -537,6 +579,7 @@ class UpdateTablesTask extends SwingWorker> { logger.fatal("Update Tables Task error", ex); } catch (ExecutionException ex) { logger.fatal("Update Tables Task error", ex); - } catch (CancellationException ex) {} + } catch (CancellationException ex) { + } } } diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 85a968b099..ef8d8a78e7 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -28,7 +28,11 @@ package mage.server; import java.security.SecureRandom; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; @@ -36,6 +40,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutorService; +import javax.management.timer.Timer; import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; @@ -100,6 +105,8 @@ public class MageServerImpl implements MageServer { private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); private static final SecureRandom RANDOM = new SecureRandom(); + private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd hh:mm:ss"); + private final String adminPassword; private final boolean testMode; private final LinkedHashMap activeAuthTokens = new LinkedHashMap() { @@ -1062,8 +1069,13 @@ public class MageServerImpl implements MageServer { public List execute() throws MageException { List users = new ArrayList<>(); for (User user : UserManager.getInstance().getUsers()) { - - users.add(new UserView(user.getName(), user.getHost(), user.getSessionId(), user.getConnectionTime(), user.getGameInfo())); + users.add(new UserView( + user.getName(), + user.getHost(), + user.getSessionId(), + user.getConnectionTime(), + user.getGameInfo(), + user.getUserState().toString())); } return users; } @@ -1080,6 +1092,22 @@ public class MageServerImpl implements MageServer { }); } + @Override + public void muteUser(final String sessionId, final String userName, final long durationMinutes) throws MageException { + execute("muteUser", sessionId, new Action() { + @Override + public void execute() { + User user = UserManager.getInstance().getUserByName(userName); + if (user != null) { + Date muteUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE)); + user.showUserMessage("Admin info", "You were muted for chat messages until " + dateFormat.format(muteUntil) + "."); + // user.setChatMuteUntil(new Date() + duationMinutes); + } + + } + }); + } + @Override public void endUserSession(final String sessionId, final String userSessionId) throws MageException { execute("endUserSession", sessionId, new Action() {