From c0323c168cc52fe4686c1288e7f39fb26718cd66 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 9 Jan 2014 13:26:25 +0100 Subject: [PATCH] Added user info text that user can set. Addd chat whisper command. Some minor changes to chat. Impoved display of user list. --- Mage.Client/sounds/OnPlayerWhispered.wav | Bin 0 -> 20336 bytes .../main/java/mage/client/chat/ChatPanel.java | 346 ++++++++++-------- .../client/remote/CallbackClientImpl.java | 242 +++++------- .../java/mage/client/table/TablesPanel.form | 6 +- .../java/mage/client/table/TablesPanel.java | 7 +- .../java/mage/client/util/AudioManager.java | 6 + .../src/mage/interfaces/MageServer.java | 2 +- .../mage/remote/interfaces/ServerState.java | 3 +- Mage.Common/src/mage/view/ChatMessage.java | 20 +- Mage.Common/src/mage/view/UsersView.java | 62 ++++ .../main/java/mage/server/ChatManager.java | 65 +++- .../main/java/mage/server/ChatSession.java | 43 ++- .../main/java/mage/server/MageServerImpl.java | 3 +- .../src/main/java/mage/server/User.java | 15 +- .../java/mage/server/game/GameController.java | 15 +- .../main/java/mage/server/game/GamesRoom.java | 3 +- .../java/mage/server/game/GamesRoomImpl.java | 27 +- .../tournament/TournamentController.java | 11 +- Mage/src/mage/game/GameImpl.java | 2 +- 19 files changed, 522 insertions(+), 356 deletions(-) create mode 100644 Mage.Client/sounds/OnPlayerWhispered.wav create mode 100644 Mage.Common/src/mage/view/UsersView.java diff --git a/Mage.Client/sounds/OnPlayerWhispered.wav b/Mage.Client/sounds/OnPlayerWhispered.wav new file mode 100644 index 0000000000000000000000000000000000000000..ad26c3a9d41acf1221745abe8849d44bf0caf78f GIT binary patch literal 20336 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 players = new ArrayList(); private final TableModel tableModel; - /** * Chat message color for opponents. */ - private static final Color OPPONENT_COLOR = new Color(0, 230, 64); - + private static final Color OPPONENT_COLOR = new Color(238, 230, 133); /** * Chat message color for client player. */ private static final Color MY_COLOR = new Color(0, 230, 64); - /** * Chat message color for timestamps. */ private static final Color TIMESTAMP_COLOR = new Color(255, 255, 0, 120); - /** * Chat message color for messages. */ private static final Color MESSAGE_COLOR = Color.white; - /** - * This will be a chat that will be connected to {this} and will handle redirected messages; - * Mostly used to redirect user messages to another window. + * Chat message color for personal infos. + */ + private static final Color USER_INFO_COLOR = Color.YELLOW; + /** + * Chat message color for status infos. + */ + private static final Color STATUS_COLOR = Color.CYAN; + /** + * This will be a chat that will be connected to {this} and will handle + * redirected messages; Mostly used to redirect user messages to another + * window. */ private ChatPanel connectedChat; - /** - * Parent chat this chat connected to. - * Used to send messages using parent chat as it is the only one connected to server. + * Parent chat this chat connected to. Used to send messages using parent + * chat as it is the only one connected to server. */ private ChatPanel parentChatRef; - /** * Selected extended view mode. */ private VIEW_MODE extendedViewMode = VIEW_MODE.NONE; public enum VIEW_MODE { + NONE, GAME, CHAT } - /** * Controls the output start messages as the chat panel is created * @@ -112,11 +115,10 @@ public class ChatPanel extends javax.swing.JPanel { private ChatType chatType = ChatType.DEFAULT; public enum ChatType { + DEFAULT, GAME, TABLES, TOURNAMENT } - private boolean startMessageDone = false; - /** * Maps message colors to {@link Color}. */ @@ -128,9 +130,12 @@ public class ChatPanel extends javax.swing.JPanel { colorMap.put(MessageColor.ORANGE, Color.orange); colorMap.put(MessageColor.BLUE, Color.blue); colorMap.put(MessageColor.RED, Color.red); + colorMap.put(MessageColor.YELLOW, Color.YELLOW); } - /** Creates new form ChatPanel */ + /** + * Creates new form ChatPanel + */ public ChatPanel() { this(false); } @@ -138,7 +143,9 @@ public class ChatPanel extends javax.swing.JPanel { /** * @param addPlayersTab if true, adds chat/players tabs */ - /** Creates new form ChatPanel */ + /** + * Creates new form ChatPanel + */ public ChatPanel(boolean addPlayersTab) { tableModel = new TableModel(); initComponents(); @@ -174,7 +181,6 @@ public class ChatPanel extends javax.swing.JPanel { this.startMessageDone = startMessageDone; } - public void connect(UUID chatId) { session = MageFrame.getSession(); this.chatId = chatId; @@ -190,38 +196,50 @@ public class ChatPanel extends javax.swing.JPanel { } /** - * Display message in the chat. - * Use different colors for timestamp, username and message. + * Display message in the chat. Use different colors for timestamp, username + * and message. * * @param username message sender * @param message message itself * @param time timestamp * @param color Preferred color. Not used. */ - public void receiveMessage(String username, String message, String time, MessageColor color) { - if (extendedViewMode.equals(VIEW_MODE.GAME)) { + public void receiveMessage(String username, String message, String time, MessageType messageType, MessageColor color) { + if (time != null) { this.txtConversation.append(TIMESTAMP_COLOR, time + " "); - Color textColor = MESSAGE_COLOR; - if (color.equals(MessageColor.ORANGE)) { - textColor = Color.ORANGE; - } - this.txtConversation.append(textColor, (username.isEmpty() ? "" : username + ":") + message + "\n"); - } else { - this.txtConversation.append(TIMESTAMP_COLOR, time + " "); - Color userColor; - Color textColor = MESSAGE_COLOR; - if (parentChatRef != null) { - userColor = parentChatRef.session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR; - } else { - userColor = session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR; - if (color.equals(MessageColor.ORANGE)) { - userColor = Color.ORANGE; - textColor = userColor; - } - } - this.txtConversation.append(userColor, username + ": "); - this.txtConversation.append(textColor, message + "\n"); } + Color userColor; + Color textColor; + String userSeparator = " "; + switch (messageType) { + case STATUS: // a message to all chat user + textColor = STATUS_COLOR; + userColor = STATUS_COLOR; + break; + case USER_INFO: // a personal message + textColor = USER_INFO_COLOR; + userColor = USER_INFO_COLOR; + break; + default: + if (parentChatRef != null) { + userColor = parentChatRef.session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR; + } else { + userColor = session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR; + } + textColor = MESSAGE_COLOR; + userSeparator = ": "; + } + if (color.equals(MessageColor.ORANGE)) { + textColor = Color.ORANGE; + } + if (color.equals(MessageColor.YELLOW)) { + textColor = Color.YELLOW; + } + if (username != null && !username.isEmpty()) { + this.txtConversation.append(userColor, username); + this.txtConversation.append(userColor, userSeparator); + } + this.txtConversation.append(textColor, message + "\n"); } public String getText() { @@ -258,16 +276,16 @@ public class ChatPanel extends javax.swing.JPanel { public void useExtendedView(VIEW_MODE extendedViewMode) { this.extendedViewMode = extendedViewMode; - this.txtConversation.setExtBackgroundColor(new Color(0,0,0,100)); - this.txtConversation.setBackground(new Color(0,0,0,0)); - this.txtConversation.setForeground(new Color(255,255,255)); + this.txtConversation.setExtBackgroundColor(new Color(0, 0, 0, 100)); + this.txtConversation.setBackground(new Color(0, 0, 0, 0)); + this.txtConversation.setForeground(new Color(255, 255, 255)); this.jScrollPaneTxt.setOpaque(false); this.jScrollPaneTxt.getViewport().setOpaque(false); } public void setSplitDividerLocation(int location) { if (jSplitPane1 != null) { - jSplitPane1.setDividerLocation(location); + jSplitPane1.setDividerLocation(location); } } @@ -278,66 +296,74 @@ public class ChatPanel extends javax.swing.JPanel { return this.jSplitPane1.getDividerLocation(); } -class TableModel extends AbstractTableModel { - private String[] columnNames = new String[]{"Players"}; - private List players = new ArrayList(0); + class TableModel extends AbstractTableModel { - public void loadData(List players) { - this.players = players; - JTableHeader th = jTablePlayers.getTableHeader(); - TableColumnModel tcm = th.getColumnModel(); - TableColumn tc = tcm.getColumn(0); - tc.setHeaderValue(new StringBuilder("Players").append(" (").append(this.players.size()).append(")").toString()); - th.repaint(); - this.fireTableDataChanged(); - } + private String[] columnNames = new String[]{"Players", "Info", "Games"}; + private UsersView[] players = new UsersView[0]; - @Override - public int getRowCount() { - return players.size(); - } - - @Override - public int getColumnCount() { - return columnNames.length; - } - - @Override - public Object getValueAt(int arg0, int arg1) { - return players.get(arg0); - } - - @Override - public String getColumnName(int columnIndex) { - String colName = ""; - - if (columnIndex <= getColumnCount()) { - colName = columnNames[columnIndex]; + public void loadData(Collection players) throws MageRemoteException { + this.players = players.toArray(new UsersView[0]); + JTableHeader th = jTablePlayers.getTableHeader(); + TableColumnModel tcm = th.getColumnModel(); + TableColumn tc = tcm.getColumn(0); + tc.setHeaderValue(new StringBuilder("Players").append(" (").append(this.players.length).append(")").toString()); + th.repaint(); + this.fireTableDataChanged(); } - return colName; - } + @Override + public int getRowCount() { + return players.length; + } - @Override - public Class getColumnClass(int columnIndex){ - return String.class; - } + @Override + public int getColumnCount() { + return columnNames.length; + } - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return false; - } + @Override + public Object getValueAt(int arg0, int arg1) { + switch (arg1) { + case 0: + return players[arg0].getUserName(); + case 1: + return players[arg0].getInfoState(); + case 2: + return players[arg0].getInfoGames(); + } + 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; + } + } public void clear() { this.txtConversation.setText(""); } - /** 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 @@ -395,17 +421,15 @@ class TableModel extends AbstractTableModel { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(txtMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE) - .addComponent(jScrollPaneTxt, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE) - ); + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(txtMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE) + .addComponent(jScrollPaneTxt, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE)); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jScrollPaneTxt, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) - ); + .addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))); jTablePlayers = null; jScrollPanePlayers = null; } @@ -422,35 +446,42 @@ class TableModel extends AbstractTableModel { } }//GEN-LAST:event_txtMessageKeyTyped - public void setPlayers(Collection players) { - if (players != null) { - boolean update; - int size = players.size(); - List list = new ArrayList(players); - Collections.sort(list, String.CASE_INSENSITIVE_ORDER); - if (size != this.players.size()) { - update = true; - } else { - update = false; - for (int i = 0; i < size; i++) { - if (!list.get(i).equals(this.players.get(i))) { - update = true; - break; - } - } - } - if (update) { - synchronized (tableModel) { - this.players = list; - tableModel.loadData(this.players); - } - } - - } else { + // public void setPlayers(Collection players) { + public void setPlayers(List> view) { + try { + // TODO: sort by user name + tableModel.loadData(view.get(0)); + } catch (Exception ex) { this.players.clear(); } - } +// if (players != null) { +// boolean update; +// int size = players.size(); +// List list = new ArrayList(players); +// Collections.sort(list, String.CASE_INSENSITIVE_ORDER); +// if (size != this.players.size()) { +// update = true; +// } else { +// update = false; +// for (int i = 0; i < size; i++) { +// if (!list.get(i).equals(this.players.get(i))) { +// update = true; +// break; +// } +// } +// } +// if (update) { +// synchronized (tableModel) { +// this.players = list; +// tableModel.loadData(this.players); +// } +// } +// +// } else { +// this.players.clear(); +// } + } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane jScrollPanePlayers; private javax.swing.JScrollPane jScrollPaneTxt; @@ -459,5 +490,4 @@ class TableModel extends AbstractTableModel { private mage.client.components.ColorPane txtConversation; private javax.swing.JTextField txtMessage; // End of variables declaration//GEN-END:variables - } diff --git a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java index e96569dd15..2f39f10e58 100644 --- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java +++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java @@ -1,34 +1,32 @@ /* -* 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. -*/ - + * 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.client.remote; -import java.util.LinkedList; import java.util.List; import java.util.UUID; import javax.swing.JOptionPane; @@ -49,6 +47,7 @@ import mage.interfaces.callback.ClientCallback; import mage.utils.CompressUtil; import mage.view.AbilityPickerView; import mage.view.ChatMessage; +import mage.view.ChatMessage.MessageType; import mage.view.DeckView; import mage.view.DraftClientMessage; import mage.view.DraftView; @@ -58,7 +57,6 @@ import mage.view.GameView; import mage.view.TableClientMessage; import org.apache.log4j.Logger; - /** * * @author BetaSteward_at_googlemail.com @@ -66,7 +64,6 @@ import org.apache.log4j.Logger; public class CallbackClientImpl implements CallbackClient { private static final Logger logger = Logger.getLogger(CallbackClientImpl.class); - private UUID clientId; private MageFrame frame; private int messageId = 0; @@ -92,25 +89,19 @@ public class CallbackClientImpl implements CallbackClient { TableClientMessage message = (TableClientMessage) callback.getData(); GameManager.getInstance().setCurrentPlayerUUID(message.getPlayerId()); gameStarted(message.getGameId(), message.getPlayerId()); - } - else if(callback.getMethod().equals("startTournament")) { + } else if (callback.getMethod().equals("startTournament")) { TableClientMessage message = (TableClientMessage) callback.getData(); tournamentStarted(message.getGameId(), message.getPlayerId()); - } - else if(callback.getMethod().equals("startDraft")) { + } else if (callback.getMethod().equals("startDraft")) { TableClientMessage message = (TableClientMessage) callback.getData(); draftStarted(message.getGameId(), message.getPlayerId()); - } - else if (callback.getMethod().equals("replayGame")) { + } else if (callback.getMethod().equals("replayGame")) { replayGame(callback.getObjectId()); - } - else if (callback.getMethod().equals("showTournament")) { + } else if (callback.getMethod().equals("showTournament")) { showTournament((UUID) callback.getObjectId()); - } - else if (callback.getMethod().equals("watchGame")) { + } else if (callback.getMethod().equals("watchGame")) { watchGame((UUID) callback.getObjectId()); - } - else if (callback.getMethod().equals("chatMessage")) { + } else if (callback.getMethod().equals("chatMessage")) { ChatMessage message = (ChatMessage) callback.getData(); ChatPanel panel = MageFrame.getChat(callback.getObjectId()); if (panel != null) { @@ -120,22 +111,25 @@ public class CallbackClientImpl implements CallbackClient { case PlayerLeft: AudioManager.playPlayerLeft(); break; - case PlayerSubmittedDeck: + case PlayerSubmittedDeck: AudioManager.playPlayerSubmittedDeck(); break; + case PlayerWhispered: + AudioManager.playPlayerWhispered(); + break; } } - // send start message to chat if needed + // send start message to chat if not done yet if (!panel.isStartMessageDone()) { createChatStartMessage(panel); } - // send the message itself - if (message.isUserMessage() && panel.getConnectedChat() != null) { - panel.getConnectedChat().receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), ChatMessage.MessageColor.BLACK); + // send the message to subchat if exists and it's not a game message + if (!message.getMessageType().equals(MessageType.GAME) && panel.getConnectedChat() != null) { + panel.getConnectedChat().receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getMessageType(), ChatMessage.MessageColor.BLACK); } else { - panel.receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getColor()); + panel.receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getMessageType(), message.getColor()); } - + } } else if (callback.getMethod().equals("serverMessage")) { if (callback.getData() != null) { @@ -149,119 +143,100 @@ public class CallbackClientImpl implements CallbackClient { } else if (callback.getMethod().equals("joinedTable")) { TableClientMessage message = (TableClientMessage) callback.getData(); joinedTable(message.getRoomId(), message.getTableId(), message.getFlag()); - } - else if (callback.getMethod().equals("replayInit")) { + } else if (callback.getMethod().equals("replayInit")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.init((GameView) callback.getData()); } - } - else if (callback.getMethod().equals("replayDone")) { + } else if (callback.getMethod().equals("replayDone")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.endMessage((String) callback.getData(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("replayUpdate")) { + } else if (callback.getMethod().equals("replayUpdate")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.updateGame((GameView) callback.getData()); } - } - else if (callback.getMethod().equals("gameInit")) { + } else if (callback.getMethod().equals("gameInit")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.init((GameView) callback.getData()); } - } - else if (callback.getMethod().equals("gameOver")) { + } else if (callback.getMethod().equals("gameOver")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.endMessage((String) callback.getData(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gameError")) { + } else if (callback.getMethod().equals("gameError")) { frame.showErrorDialog("Game Error", (String) callback.getData()); - } - else if (callback.getMethod().equals("gameAsk")) { + } else if (callback.getMethod().equals("gameAsk")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.ask(message.getMessage(), message.getGameView(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gameTarget")) { + } else if (callback.getMethod().equals("gameTarget")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.pickTarget(message.getMessage(), message.getCardsView(), message.getGameView(), message.getTargets(), message.isFlag(), message.getOptions(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gameSelect")) { + } else if (callback.getMethod().equals("gameSelect")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.select(message.getMessage(), message.getGameView(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gameChooseAbility")) { + } else if (callback.getMethod().equals("gameChooseAbility")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.pickAbility((AbilityPickerView) callback.getData()); } - } - else if (callback.getMethod().equals("gameChoosePile")) { + } else if (callback.getMethod().equals("gameChoosePile")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.pickPile(message.getMessage(), message.getPile1(), message.getPile2()); } - } - else if (callback.getMethod().equals("gameChoose")) { + } else if (callback.getMethod().equals("gameChoose")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.getChoice(message.getMessage(), message.getStrings()); } - } - else if (callback.getMethod().equals("gamePlayMana")) { + } else if (callback.getMethod().equals("gamePlayMana")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.playMana(message.getMessage(), message.getGameView(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gamePlayXMana")) { + } else if (callback.getMethod().equals("gamePlayXMana")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.playXMana(message.getMessage(), message.getGameView(), callback.getMessageId()); } - } - else if (callback.getMethod().equals("gameSelectAmount")) { + } else if (callback.getMethod().equals("gameSelectAmount")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.getAmount(message.getMin(), message.getMax(), message.getMessage()); } - } - else if (callback.getMethod().equals("gameUpdate")) { + } else if (callback.getMethod().equals("gameUpdate")) { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.updateGame((GameView) callback.getData()); } - } - else if (callback.getMethod().equals("endGameInfo")) { + } else if (callback.getMethod().equals("endGameInfo")) { MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData()); - } - else if (callback.getMethod().equals("showUserMessage")) { + } else if (callback.getMethod().equals("showUserMessage")) { List messageData = (List) callback.getData(); if (messageData.size() == 2) { JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE); } - } - else if (callback.getMethod().equals("gameInform")) { + } else if (callback.getMethod().equals("gameInform")) { if (callback.getMessageId() > messageId) { GameClientMessage message = (GameClientMessage) callback.getData(); @@ -269,76 +244,62 @@ public class CallbackClientImpl implements CallbackClient { if (panel != null) { panel.inform(message.getMessage(), message.getGameView(), callback.getMessageId()); } - } - else { + } else { logger.warn("message out of sequence - ignoring"); } - } - else if (callback.getMethod().equals("gameInformPersonal")) { + } else if (callback.getMethod().equals("gameInformPersonal")) { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { JOptionPane.showMessageDialog(panel, message.getMessage(), "Game message", JOptionPane.INFORMATION_MESSAGE); } - } - else if (callback.getMethod().equals("sideboard")) { + } else if (callback.getMethod().equals("sideboard")) { TableClientMessage message = (TableClientMessage) callback.getData(); DeckView deckView = message.getDeck(); Deck deck = DeckUtil.construct(deckView); if (message.getFlag()) { construct(deck, message.getTableId(), message.getTime()); - } - else { + } else { sideboard(deck, message.getTableId(), message.getTime()); } - } - else if (callback.getMethod().equals("construct")) { + } else if (callback.getMethod().equals("construct")) { TableClientMessage message = (TableClientMessage) callback.getData(); DeckView deckView = message.getDeck(); Deck deck = DeckUtil.construct(deckView); construct(deck, message.getTableId(), message.getTime()); - } - else if (callback.getMethod().equals("draftOver")) { + } else if (callback.getMethod().equals("draftOver")) { DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { panel.hideDraft(); } - } - else if (callback.getMethod().equals("draftPick")) { + } else if (callback.getMethod().equals("draftPick")) { DraftClientMessage message = (DraftClientMessage) callback.getData(); DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { panel.loadBooster(message.getDraftPickView()); } - } - else if (callback.getMethod().equals("draftUpdate")) { + } else if (callback.getMethod().equals("draftUpdate")) { DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { panel.updateDraft((DraftView) callback.getData()); } - } - else if (callback.getMethod().equals("draftInform")) { + } else if (callback.getMethod().equals("draftInform")) { if (callback.getMessageId() > messageId) { DraftClientMessage message = (DraftClientMessage) callback.getData(); - } - else { + } else { logger.warn("message out of sequence - ignoring"); } - } - else if (callback.getMethod().equals("draftInit")) { + } else if (callback.getMethod().equals("draftInit")) { DraftClientMessage message = (DraftClientMessage) callback.getData(); DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { panel.loadBooster(message.getDraftPickView()); } - } - else if (callback.getMethod().equals("tournamentInit")) { - + } else if (callback.getMethod().equals("tournamentInit")) { } messageId = callback.getMessageId(); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } @@ -353,24 +314,26 @@ public class CallbackClientImpl implements CallbackClient { } switch (usedPanel.getChatType()) { case GAME: - usedPanel.receiveMessage("", "You may use hot keys to play faster: " + "" + - "\nTurn Mousewheel - Show big image of card your mousepointer hovers over" + - "\nF2 - Confirm \"Ok\", \"Yes\" or \"Done\" button" + - "\nF4 - Skip current turn but stop on declare attackers" + - "\nF9 - Skip everything until your next turn" + - "\nF3 - Undo F4/F9", "", ChatMessage.MessageColor.ORANGE); + usedPanel.receiveMessage("", new StringBuilder("You may use hot keys to play faster:") + .append("\nTurn Mousewheel - Show big image of card your mousepointer hovers over") + .append("\nF2 - Confirm \"Ok\", \"Yes\" or \"Done\" button") + .append("\nF4 - Skip current turn but stop on declare attackers/blockers and something on the stack") + .append("\nF9 - Skip everything until your next turn") + .append("\nF3 - Undo F4/F9").toString(), + null, MessageType.USER_INFO, ChatMessage.MessageColor.ORANGE); break; case TOURNAMENT: - usedPanel.receiveMessage("", "On this panel you can see the players, their state and the results of the games of the tournament. Also you can chat with the competitors of the tournament.", "", ChatMessage.MessageColor.ORANGE); + usedPanel.receiveMessage("", new StringBuilder("On this panel you can see the players, their state and the results of the games of the tournament. Also you can chat with the competitors of the tournament.").toString(), + null, MessageType.USER_INFO, ChatMessage.MessageColor.ORANGE); break; case TABLES: - usedPanel.receiveMessage("", - "Download card images by using the \"Images\" menu to the top right ." + - "\nDownload icons and symbols by using the \"Symbols\" menu to the top right.", - "", ChatMessage.MessageColor.ORANGE); + usedPanel.receiveMessage("", new StringBuilder("Download card images by using the \"Images\" menu to the top right .") + .append("\nDownload icons and symbols by using the \"Symbols\" menu to the top right.") + .append("\n\\list - Show a list of available chat commands.").toString(), + null, MessageType.USER_INFO, ChatMessage.MessageColor.ORANGE); break; - } + } } public UUID getId() { @@ -380,18 +343,16 @@ public class CallbackClientImpl implements CallbackClient { private void joinedTable(UUID roomId, UUID tableId, boolean isTournament) { try { frame.showTableWaitingDialog(roomId, tableId, isTournament); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } - } + } protected void gameStarted(final UUID gameId, final UUID playerId) { try { frame.showGame(gameId, playerId); logger.info("Game " + gameId + " started for player " + playerId); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } @@ -404,8 +365,7 @@ public class CallbackClientImpl implements CallbackClient { try { frame.showDraft(draftId); logger.info("Draft " + draftId + " started for player " + playerId); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } @@ -414,23 +374,21 @@ public class CallbackClientImpl implements CallbackClient { try { frame.showTournament(tournamentId); logger.info("Tournament " + tournamentId + " started for player " + playerId); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } /** * Shows the tournament info panel for a tournament - * + * * @param tournamentId */ protected void showTournament(UUID tournamentId) { try { frame.showTournament(tournamentId); logger.info("Showing tournament " + tournamentId); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } @@ -439,17 +397,16 @@ public class CallbackClientImpl implements CallbackClient { try { frame.watchGame(gameId); logger.info("Watching game " + gameId); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } + protected void replayGame(UUID gameId) { try { frame.replayGame(gameId); logger.info("Replaying game"); - } - catch (Exception ex) { + } catch (Exception ex) { handleException(ex); } } @@ -466,5 +423,4 @@ public class CallbackClientImpl implements CallbackClient { logger.fatal("Client error\n", ex); frame.showError("Error: " + ex.getMessage()); } - } diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form index 15a2afcdc5..2b595ba00c 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.form +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.form @@ -28,12 +28,12 @@ - + - + @@ -128,7 +128,7 @@ - + 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 a0643ceda4..f2bd481bbc 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -79,6 +79,7 @@ import mage.remote.MageRemoteException; import mage.remote.Session; import mage.view.MatchView; import mage.view.TableView; +import mage.view.UsersView; import org.apache.log4j.Logger; /** @@ -827,7 +828,7 @@ class UpdateTablesTask extends SwingWorker> { } -class UpdatePlayersTask extends SwingWorker> { +class UpdatePlayersTask extends SwingWorker> { private Session session; private UUID roomId; @@ -851,8 +852,8 @@ class UpdatePlayersTask extends SwingWorker> { } @Override - protected void process(List> players) { - chat.setPlayers(players.get(0)); + protected void process(List> players) { + chat.setPlayers(players); } @Override diff --git a/Mage.Client/src/main/java/mage/client/util/AudioManager.java b/Mage.Client/src/main/java/mage/client/util/AudioManager.java index afa3515182..ad1417e53d 100644 --- a/Mage.Client/src/main/java/mage/client/util/AudioManager.java +++ b/Mage.Client/src/main/java/mage/client/util/AudioManager.java @@ -48,6 +48,7 @@ public class AudioManager { audioManager.playerJoinedTable = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerJoinedTable.wav"); audioManager.playerSubmittedDeck = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerSubmittedDeck.wav"); + audioManager.playerWhispered = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerWhispered.wav"); audioManager.playerLeft = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerLeft.wav"); audioManager.playerWon = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerWon.wav"); audioManager.playerLost = audioManager.loadClip(Constants.BASE_SOUND_PATH + "OnPlayerLost.wav"); @@ -127,6 +128,10 @@ public class AudioManager { checkAndPlayClip(getManager().playerJoinedTable); } + public static void playPlayerWhispered() { + checkAndPlayClip(getManager().playerWhispered); + } + public static void playPlayerSubmittedDeck() { checkAndPlayClip(getManager().playerSubmittedDeck); } @@ -207,6 +212,7 @@ public class AudioManager { private Clip playerJoinedTable = null; private Clip playerSubmittedDeck = null; + private Clip playerWhispered = null; private Clip playerLeft = null; private Clip playerWon = null; private Clip playerLost = null; diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index 1eec04c50e..fb36a5d965 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -62,7 +62,7 @@ public interface MageServer { // server state methods ServerState getServerState() throws MageException; - List getConnectedPlayers(UUID roomId) throws MageException; + List getConnectedPlayers(UUID roomId) throws MageException; List getFinishedMatches(UUID roomId) throws MageException; Object getServerMessagesCompressed(String sessionId) throws MageException; // messages of the day diff --git a/Mage.Common/src/mage/remote/interfaces/ServerState.java b/Mage.Common/src/mage/remote/interfaces/ServerState.java index eb82685fa2..06f9ad3825 100644 --- a/Mage.Common/src/mage/remote/interfaces/ServerState.java +++ b/Mage.Common/src/mage/remote/interfaces/ServerState.java @@ -35,6 +35,7 @@ import mage.view.UserView; import java.util.Collection; import java.util.List; import java.util.UUID; +import mage.view.UsersView; /** * @author noxx @@ -45,7 +46,7 @@ public interface ServerState { List getUsers(); - Collection getConnectedPlayers(UUID roomId) throws MageRemoteException; + Collection getConnectedPlayers(UUID roomId) throws MageRemoteException; List getServerMessages(); diff --git a/Mage.Common/src/mage/view/ChatMessage.java b/Mage.Common/src/mage/view/ChatMessage.java index ef6536f500..873ebce28d 100644 --- a/Mage.Common/src/mage/view/ChatMessage.java +++ b/Mage.Common/src/mage/view/ChatMessage.java @@ -42,13 +42,18 @@ public class ChatMessage implements Serializable { private String message; private MessageColor color; private SoundToPlay soundToPlay; + private MessageType messageType; public enum MessageColor { - BLACK, RED, GREEN, BLUE, ORANGE; + BLACK, RED, GREEN, BLUE, ORANGE, YELLOW; + } + + public enum MessageType { + USER_INFO, STATUS, GAME, TALK, WHISPER; } public enum SoundToPlay { - PlayerLeft, PlayerSubmittedDeck; + PlayerLeft, PlayerSubmittedDeck, PlayerWhispered; } public ChatMessage(String username, String message, String time, MessageColor color) { @@ -56,10 +61,15 @@ public class ChatMessage implements Serializable { } public ChatMessage(String username, String message, String time, MessageColor color, SoundToPlay soundToPlay) { + this(username, message, time, color, MessageType.TALK, soundToPlay); + } + + public ChatMessage(String username, String message, String time, MessageColor color, MessageType messageType, SoundToPlay soundToPlay) { this.username = username; this.message = message; this.time = time; this.color = color; + this.messageType = messageType; this.soundToPlay = soundToPlay; } @@ -72,7 +82,7 @@ public class ChatMessage implements Serializable { } public boolean isUserMessage() { - return color != null && color.equals(MessageColor.BLUE); + return color != null && (color.equals(MessageColor.BLUE) || color.equals(MessageColor.YELLOW)); } public boolean isStatusMessage() { @@ -91,4 +101,8 @@ public class ChatMessage implements Serializable { return soundToPlay; } + public MessageType getMessageType() { + return messageType; + } + } diff --git a/Mage.Common/src/mage/view/UsersView.java b/Mage.Common/src/mage/view/UsersView.java new file mode 100644 index 0000000000..ee634c2457 --- /dev/null +++ b/Mage.Common/src/mage/view/UsersView.java @@ -0,0 +1,62 @@ +/* +* 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.view; + +import java.io.Serializable; + +/** + * + * @author LevelX2 + */ +public class UsersView implements Serializable { + + private static final long serialVersionUID = 1L; + + private String userName; + private String infoState; + private String infoGames; + + public UsersView(String userName, String infoState, String infoGames) { + this.userName = userName; + this.infoState = infoState; + this.infoGames = infoGames; + } + + public String getUserName() { + return userName; + } + + public String getInfoState() { + return infoState; + } + + public String getInfoGames() { + return infoGames; + } + +} diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java index a3eeebcad0..2f10f0a626 100644 --- a/Mage.Server/src/main/java/mage/server/ChatManager.java +++ b/Mage.Server/src/main/java/mage/server/ChatManager.java @@ -28,10 +28,11 @@ package mage.server; -import mage.view.ChatMessage.MessageColor; - +import java.util.Locale; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import mage.view.ChatMessage.MessageColor; +import mage.view.ChatMessage.MessageType; import mage.view.ChatMessage.SoundToPlay; /** @@ -69,17 +70,69 @@ public class ChatManager { } public void broadcast(UUID chatId, String userName, String message, MessageColor color) { - chatSessions.get(chatId).broadcast(userName, message, color); + this.broadcast(chatId, userName, message, color, true); } public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime) { - chatSessions.get(chatId).broadcast(userName, message, color, withTime); + this.broadcast(chatId, userName, message, color, withTime, MessageType.TALK); } - public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, SoundToPlay soundToPlay) { - chatSessions.get(chatId).broadcast(userName, message, color, withTime, soundToPlay); + public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, MessageType messageType) { + this.broadcast(chatId, userName, message, color, withTime, messageType, null); } + public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) { + if (message.startsWith("\\")) { + User user = UserManager.getInstance().findUser(userName); + if (user != null && performUserCommand(user, message, chatId)) { + return; + } + } + chatSessions.get(chatId).broadcast(userName, message, color, withTime, messageType, soundToPlay); + } + + + private boolean performUserCommand(User user, String message, UUID chatId) { + String command = message.trim().toUpperCase(Locale.ENGLISH); + if (command.equals("\\I") || command.equals("\\INFO")) { + user.setInfo(""); + chatSessions.get(chatId).broadcastInfoToUser(user,message); + return true; + } + if (command.startsWith("\\I ") || command.startsWith("\\INFO ")) { + user.setInfo(message.substring(command.startsWith("\\I ") ? 3 : 6)); + chatSessions.get(chatId).broadcastInfoToUser(user,message); + return true; + } + if (command.startsWith("\\W ") || command.startsWith("\\WHISPER ")) { + String rest = message.substring(command.startsWith("\\W ") ? 3 : 9); + int first = rest.indexOf(" "); + if (first > 1) { + String userToName = rest.substring(0,first); + rest = rest.substring(first + 1).trim(); + User userTo = UserManager.getInstance().findUser(userToName); + if (userTo != null) { + chatSessions.get(chatId).broadcastWhisperToUser(user, userTo, rest); + } else { + message += new StringBuilder("\nUser ").append(userToName).append(" not found").toString(); + chatSessions.get(chatId).broadcastInfoToUser(user,message); + } + return true; + } + } + if (command.equals("\\L") || command.equals("\\LIST")) { + message += new StringBuilder("\nList of commands:") + .append("\n\\info - set a info text to your player") + .append("\n\\list - Show a list of commands") + .append("\n\\whisper - Whiper to a player").toString(); + chatSessions.get(chatId).broadcastInfoToUser(user,message); + return true; + } + return false; + } + + + /** * * use mainly for announcing that a user connection was lost or that a user has reconnected diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 4f92b2bcbf..a07d5de69d 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -37,6 +37,7 @@ import java.util.concurrent.ConcurrentHashMap; import mage.interfaces.callback.ClientCallback; import mage.view.ChatMessage; import mage.view.ChatMessage.MessageColor; +import mage.view.ChatMessage.MessageType; import mage.view.ChatMessage.SoundToPlay; import org.apache.log4j.Logger; @@ -47,6 +48,8 @@ import org.apache.log4j.Logger; public class ChatSession { private static final Logger logger = Logger.getLogger(ChatSession.class); + private static final Calendar cal = new GregorianCalendar(); + private ConcurrentHashMap clients = new ConcurrentHashMap(); private UUID chatId; private DateFormat timeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT); @@ -60,7 +63,7 @@ public class ChatSession { if (user != null && !clients.containsKey(userId)) { String userName = user.getName(); clients.put(userId, userName); - broadcast(userName, " has joined", MessageColor.BLUE); + broadcast(null, new StringBuilder(userName).append(" has joined").toString(), MessageColor.BLUE, true, MessageType.STATUS); logger.debug(userName + " joined chat " + chatId); } } @@ -80,22 +83,46 @@ public class ChatSession { default: message = " has left chat"; } - broadcast(userName, message, MessageColor.BLUE); + broadcast(null, new StringBuilder(userName).append(message).toString(), MessageColor.BLUE, true, MessageType.STATUS); logger.debug(userName + message + " " + chatId); } } + public boolean broadcastInfoToUser(User toUser, String message) { + if (clients.containsKey(toUser.getId())) { + toUser.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(null, message, timeFormatter.format(cal.getTime()), MessageColor.ORANGE, MessageType.USER_INFO, null))); + return true; + } + return false; + } + + public boolean broadcastWhisperToUser(User fromUser, User toUser, String message) { + if (clients.containsKey(toUser.getId())) { + toUser.fireCallback(new ClientCallback("chatMessage", chatId, + new ChatMessage(new StringBuilder("Whisper from ").append(fromUser.getName()).toString(), message, timeFormatter.format(cal.getTime()), MessageColor.YELLOW, MessageType.WHISPER, SoundToPlay.PlayerWhispered))); + if (clients.containsKey(fromUser.getId())) { + fromUser.fireCallback(new ClientCallback("chatMessage", chatId, + new ChatMessage(new StringBuilder("Whisper to ").append(toUser.getName()).toString(), message, timeFormatter.format(cal.getTime()), MessageColor.YELLOW, MessageType.WHISPER, null))); + return true; + } + } + return false; + } + public void broadcast(String userName, String message, MessageColor color) { - broadcast(userName, message, color, true); + this.broadcast(userName, message, color, true); } public void broadcast(String userName, String message, MessageColor color, boolean withTime) { - broadcast(userName, message, color, withTime, null); + this.broadcast(userName, message, color, withTime, MessageType.TALK); } - public void broadcast(String userName, String message, MessageColor color, boolean withTime, SoundToPlay soundToPlay) { - if (!message.isEmpty()) { - Calendar cal = new GregorianCalendar(); + public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType) { + this.broadcast(userName, message, color, withTime, messageType, null); + } + + public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) { + if (!message.isEmpty()) { final String msg = message; final String time = (withTime ? timeFormatter.format(cal.getTime()):""); final String username = userName; @@ -103,7 +130,7 @@ public class ChatSession { for (UUID userId: clients.keySet()) { User user = UserManager.getInstance().getUser(userId); if (user != null) { - user.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(username, msg, time, color, soundToPlay))); + user.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(username, msg, time, color, messageType, soundToPlay))); } else { kill(userId, User.DisconnectReason.CleaningUp); diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index e4b00b104a..13f101dd75 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -78,6 +78,7 @@ import mage.view.TableView; import mage.view.TournamentView; import mage.view.UserDataView; import mage.view.UserView; +import mage.view.UsersView; import org.apache.log4j.Logger; /** @@ -291,7 +292,7 @@ public class MageServerImpl implements MageServer { @Override //FIXME: why no sessionId here??? - public List getConnectedPlayers(UUID roomId) throws MageException { + public List getConnectedPlayers(UUID roomId) throws MageException { try { GamesRoom room = GamesRoomManager.getInstance().getRoom(roomId); if (room != null) { diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 59b101a7a8..a6e4bd83e8 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -66,6 +66,7 @@ public class User { private String userName; private String sessionId = ""; private String host; + private String info; private Date connectionTime = new Date(); private Date lastActivity = new Date(); private UserState userState; @@ -305,7 +306,7 @@ public class User { return this.userData; } - public String getUserInfo() { + public String getGameInfo() { StringBuilder sb = new StringBuilder(); if (gameSessions.size() > 0) { sb.append("G: ").append(gameSessions.size()); @@ -316,10 +317,14 @@ public class User { } sb.append("T: ").append(tournamentSessions.size()); } - if (sb.length() > 0) { - sb.insert(0, " - ["); - sb.append("]"); - } return sb.toString(); } + + public String getInfo() { + return info; + } + + public void setInfo(String Info) { + this.info = Info; + } } diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 81e8ecedee..6888c760fd 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -76,7 +76,9 @@ import mage.server.util.ThreadExecutor; import mage.utils.timer.PriorityTimer; import mage.view.AbilityPickerView; import mage.view.CardsView; +import mage.view.ChatMessage; import mage.view.ChatMessage.MessageColor; +import mage.view.ChatMessage.MessageType; import mage.view.GameView; import mage.view.PermanentView; import org.apache.log4j.Logger; @@ -133,11 +135,11 @@ public class GameController implements GameCallback { updateGame(); break; case INFO: - ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, ChatMessage.MessageType.GAME); logger.debug(game.getId() + " " + event.getMessage()); break; case STATUS: - ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime()); + ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), ChatMessage.MessageType.GAME); logger.debug(game.getId() + " " + event.getMessage()); break; case ERROR: @@ -272,7 +274,7 @@ public class GameController implements GameCallback { gameSession.setUserData(user.getUserData()); user.addGame(playerId, gameSession); logger.debug(new StringBuilder("Player ").append(playerId).append(" has joined game ").append(game.getId()).toString()); - ChatManager.getInstance().broadcast(chatId, "", new StringBuilder(game.getPlayer(playerId).getName()).append(" has joined the game").toString(), MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", new StringBuilder(game.getPlayer(playerId).getName()).append(" has joined the game").toString(), MessageColor.ORANGE, true, MessageType.GAME); checkStart(); } @@ -321,7 +323,7 @@ public class GameController implements GameCallback { GameWatcher gameWatcher = new GameWatcher(userId, game, false); watchers.put(userId, gameWatcher); gameWatcher.init(); - ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE); + ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS); } } @@ -329,7 +331,7 @@ public class GameController implements GameCallback { watchers.remove(userId); User user = UserManager.getInstance().getUser(userId); if (user != null) { - ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE); + ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS); } } @@ -405,12 +407,11 @@ public class GameController implements GameCallback { public void timeout(UUID userId) { if (userPlayerMap.containsKey(userId)) { - ; StringBuilder sb = new StringBuilder(game.getPlayer(userPlayerMap.get(userId)).getName()) .append(" has timed out (player had priority and was not active for ") .append(ConfigSettings.getInstance().getMaxSecondsIdle()) .append(" seconds ) - Auto concede."); - ChatManager.getInstance().broadcast(chatId, "", sb.toString() , MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", sb.toString() , MessageColor.BLACK, true, MessageType.STATUS); concede(userId); } } diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java index e08489c8f6..b6abe9ee7e 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java @@ -38,6 +38,7 @@ import mage.game.tournament.TournamentOptions; import mage.server.Room; import mage.view.MatchView; import mage.view.TableView; +import mage.view.UsersView; /** * @@ -47,7 +48,7 @@ public interface GamesRoom extends Room { List getTables(); List getFinished(); - List getPlayers(); + List getPlayers(); boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList) throws MageException; boolean joinTournamentTable(UUID userId, UUID tableId, String name, String playerType, int skill) throws GameException; TableView createTable(UUID userId, MatchOptions options); diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java index 3a01266284..95e1d2ec2f 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java @@ -38,9 +38,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import mage.constants.TableState; import mage.MageException; import mage.cards.decks.DeckCardLists; +import mage.constants.TableState; import mage.game.GameException; import mage.game.Table; import mage.game.match.MatchOptions; @@ -51,9 +51,9 @@ import mage.server.User; import mage.server.UserManager; import mage.view.MatchView; import mage.view.TableView; +import mage.view.UsersView; import org.apache.log4j.Logger; - /** * * @author BetaSteward_at_googlemail.com @@ -65,7 +65,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { private static ScheduledExecutorService updateExecutor = Executors.newSingleThreadScheduledExecutor(); private static List tableView = new ArrayList(); private static List matchView = new ArrayList(); - private static List playersView = new ArrayList(); + private static List usersView = new ArrayList(); private ConcurrentHashMap tables = new ConcurrentHashMap(); @@ -109,16 +109,16 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } tableView = tableList; matchView = matchList; - List players = new ArrayList(); + List users = new ArrayList(); for (User user : UserManager.getInstance().getUsers()) { - StringBuilder sb = new StringBuilder(user.getName()); - sb.append(user.getUserInfo()); + StringBuilder sb = new StringBuilder(user.getGameInfo()); if (!user.isConnected()) { sb.append(" (discon.)"); } - players.add(sb.toString()); + users.add(new UsersView(user.getName(), user.getInfo(), sb.toString())); } - playersView = players; + Collections.sort(users, new UserNameSorter()); + usersView = users; } @Override @@ -190,8 +190,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } @Override - public List getPlayers() { - return playersView; + public List getPlayers() { + return usersView; } } @@ -202,3 +202,10 @@ class TimestampSorter implements Comparator { return one.getCreateTime().compareTo(two.getCreateTime()); } } + +class UserNameSorter implements Comparator { + @Override + public int compare(UsersView one, UsersView two) { + return one.getUserName().compareTo(two.getUserName()); + } +} \ No newline at end of file diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index 53832c72dc..099af813c9 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -54,6 +54,7 @@ import mage.server.draft.DraftManager; import mage.server.game.GamesRoomManager; import mage.server.util.ThreadExecutor; import mage.view.ChatMessage.MessageColor; +import mage.view.ChatMessage.MessageType; import mage.view.ChatMessage.SoundToPlay; import mage.view.TournamentView; import org.apache.log4j.Logger; @@ -91,7 +92,7 @@ public class TournamentController { public void event(TableEvent event) { switch (event.getEventType()) { case INFO: - ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS); logger.debug(tournament.getId() + " " + event.getMessage()); break; case START_DRAFT: @@ -137,7 +138,7 @@ public class TournamentController { if (!player.getPlayer().isHuman()) { player.setJoined(); logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId()); - ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS); } } checkStart(); @@ -151,7 +152,7 @@ public class TournamentController { TournamentPlayer player = tournament.getPlayer(playerId); player.setJoined(); logger.debug("player " + playerId + " has joined tournament " + tournament.getId()); - ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK); + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS); checkStart(); } @@ -247,7 +248,7 @@ public class TournamentController { TournamentPlayer player = tournament.getPlayer(playerId); if (player != null && !player.hasQuit()) { tournamentSessions.get(playerId).submitDeck(deck); - ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has submitted his tournament deck", MessageColor.BLACK, true, SoundToPlay.PlayerSubmittedDeck); + ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has submitted his tournament deck", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerSubmittedDeck); } } } @@ -275,7 +276,7 @@ public class TournamentController { TournamentPlayer tPlayer = tournament.getPlayer(playerId); if (tPlayer != null) { if (started) { - ChatManager.getInstance().broadcast(chatId, "", tPlayer.getPlayer().getName() + " has quit the tournament", MessageColor.BLACK, true, SoundToPlay.PlayerLeft); + ChatManager.getInstance().broadcast(chatId, "", tPlayer.getPlayer().getName() + " has quit the tournament", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerLeft); String info; if (tournament.isDoneConstructing()) { info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString(); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 6cc8fc00f8..8474f9f20f 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -558,7 +558,7 @@ public abstract class GameImpl> implements Game, Serializa boolean wasPaused = state.isPaused(); state.resume(); if (!isGameOver()) { - fireInformEvent("Turn " + Integer.toString(state.getTurnNum())); + fireInformEvent(new StringBuilder("Turn ").append(state.getTurnNum()).toString()); if (checkStopOnTurnOption()) { return; }