diff --git a/.gitattributes b/.gitattributes index 2bcd427163b..b3fd1a84bc9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13914,6 +13914,7 @@ src/main/java/forge/card/trigger/TriggerWaiting.java -text src/main/java/forge/card/trigger/WrappedAbility.java -text src/main/java/forge/card/trigger/ZCTrigger.java svneol=native#text/plain src/main/java/forge/card/trigger/package-info.java svneol=native#text/plain +src/main/java/forge/control/ChatArea.java -text src/main/java/forge/control/ControlBazaarUI.java -text src/main/java/forge/control/FControl.java -text src/main/java/forge/control/KeyboardShortcuts.java -text @@ -14321,6 +14322,7 @@ src/main/java/forge/net/protocol/incoming/PacketOpcode.java -text src/main/java/forge/net/protocol/incoming/UnknownPacket.java -text src/main/java/forge/net/protocol/incoming/package-info.java -text src/main/java/forge/net/protocol/outcoming/AuthorizationSuccessfulMessage.java -text +src/main/java/forge/net/protocol/outcoming/ChatMessage.java -text src/main/java/forge/net/protocol/outcoming/EchoMessage.java -text src/main/java/forge/net/protocol/outcoming/IMessage.java -text src/main/java/forge/net/protocol/outcoming/IncorrectPacketMessage.java -text diff --git a/src/main/html/css/core.css b/src/main/html/css/core.css index e3471229eba..17c13f8f4bd 100644 --- a/src/main/html/css/core.css +++ b/src/main/html/css/core.css @@ -7,7 +7,7 @@ div.wrap { width: 640px; margin: 100px auto;} .title input {width: 300px; } .title span { display: inline-block; width: 120px; text-align: right; } -.messages { height: 20ex; overflow: auto; background-color: #fff; padding: 4px; border: 1px solid black; list-style: none; } +.messages { height: 30ex; overflow: auto; background-color: #fff; padding: 4px; border: 1px solid black; list-style: none; } .messages .incoming { color: #006; } .messages .incoming:before { content: "<< "} .messages .outcoming { color: #060; } diff --git a/src/main/java/forge/control/ChatArea.java b/src/main/java/forge/control/ChatArea.java new file mode 100644 index 00000000000..4b73d573148 --- /dev/null +++ b/src/main/java/forge/control/ChatArea.java @@ -0,0 +1,9 @@ +package forge.control; + +/** How 'loudly' the message should sound */ +public enum ChatArea { + Room, + Match, + Whisper, // that is private + Server +} diff --git a/src/main/java/forge/control/Lobby.java b/src/main/java/forge/control/Lobby.java index cc8ffb68bc5..f79a2fad669 100644 --- a/src/main/java/forge/control/Lobby.java +++ b/src/main/java/forge/control/Lobby.java @@ -9,6 +9,7 @@ import forge.game.player.LobbyPlayerAi; import forge.game.player.LobbyPlayerHuman; import forge.game.player.LobbyPlayerRemote; import forge.gui.toolbox.FSkin; +import forge.net.client.INetClient; import forge.util.MyRandom; /** @@ -61,7 +62,7 @@ public class Lobby { private Map remotePlayers = new ConcurrentHashMap(); private final LobbyPlayerHuman guiPlayer = new LobbyPlayerHuman("Human"); - + private final LobbyPlayerAi system = new LobbyPlayerAi("System"); public final LobbyPlayerHuman getGuiPlayer() { return guiPlayer; @@ -99,13 +100,15 @@ public class Lobby { * @param name * @return */ - public synchronized LobbyPlayer findOrCreateRemotePlayer(String name) { + public synchronized LobbyPlayer findOrCreateRemotePlayer(String name, INetClient client) { if (remotePlayers.containsKey(name)) return remotePlayers.get(name); - LobbyPlayerRemote res = new LobbyPlayerRemote(name); + LobbyPlayerRemote res = new LobbyPlayerRemote(name, client); + speak(ChatArea.Room, system, res.getName() + " has joined the server."); // have to load avatar from remote user's preferences here remotePlayers.put(name, res); + return res; } @@ -114,4 +117,10 @@ public class Lobby { } + public void speak(ChatArea room, LobbyPlayer player, String message) { + getGuiPlayer().hear(player, message); + for(LobbyPlayer remote : remotePlayers.values()) { + remote.hear(player, message); + } + } } diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java index e7e83b4c325..bb18d805835 100644 --- a/src/main/java/forge/game/MatchController.java +++ b/src/main/java/forge/game/MatchController.java @@ -7,9 +7,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import com.google.common.collect.Iterables; - - import forge.Constant.Preferences; import forge.FThreads; import forge.Singletons; @@ -188,12 +185,6 @@ public class MatchController { currentGame.setAge(GameAge.Mulligan); getInput().clearInput(); - //getInput().setNewInput(currentGame); - - -// Thread thGame = new GameInputUpdatesThread(this, currentGame); -// thGame.setName("Game input updater"); -// thGame.start(); // TODO restore this functionality!!! //VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getDocument().setVisible(Preferences.DEV_MODE); diff --git a/src/main/java/forge/game/player/LobbyPlayer.java b/src/main/java/forge/game/player/LobbyPlayer.java index 1adf0a33553..73c103810fc 100644 --- a/src/main/java/forge/game/player/LobbyPlayer.java +++ b/src/main/java/forge/game/player/LobbyPlayer.java @@ -77,4 +77,6 @@ public abstract class LobbyPlayer implements IHasIcon { } public abstract Player getPlayer(GameState gameState); // factory method to create player + + public abstract void hear(LobbyPlayer player, String message); } diff --git a/src/main/java/forge/game/player/LobbyPlayerAi.java b/src/main/java/forge/game/player/LobbyPlayerAi.java index 57e504fb269..bc42736989e 100644 --- a/src/main/java/forge/game/player/LobbyPlayerAi.java +++ b/src/main/java/forge/game/player/LobbyPlayerAi.java @@ -22,11 +22,11 @@ public class LobbyPlayerAi extends LobbyPlayer { return PlayerType.COMPUTER; } - /* (non-Javadoc) - * @see forge.game.player.LobbyPlayer#getPlayer(forge.game.GameState) - */ @Override public Player getPlayer(GameState game) { return new AIPlayer(this, game); } + + @Override + public void hear(LobbyPlayer player, String message) { /* Local AI is deaf. */ } } \ No newline at end of file diff --git a/src/main/java/forge/game/player/LobbyPlayerHuman.java b/src/main/java/forge/game/player/LobbyPlayerHuman.java index ff19175733e..eb9b4be0513 100644 --- a/src/main/java/forge/game/player/LobbyPlayerHuman.java +++ b/src/main/java/forge/game/player/LobbyPlayerHuman.java @@ -1,6 +1,7 @@ package forge.game.player; import forge.game.GameState; +import forge.gui.FNetOverlay; public class LobbyPlayerHuman extends LobbyPlayer { public LobbyPlayerHuman(String name) { @@ -16,4 +17,8 @@ public class LobbyPlayerHuman extends LobbyPlayer { public Player getPlayer(GameState game) { return new HumanPlayer(this, game); } + + public void hear(LobbyPlayer player, String message) { + FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message); + } } \ No newline at end of file diff --git a/src/main/java/forge/game/player/LobbyPlayerRemote.java b/src/main/java/forge/game/player/LobbyPlayerRemote.java index 25eff93ba38..5d704bfc6ae 100644 --- a/src/main/java/forge/game/player/LobbyPlayerRemote.java +++ b/src/main/java/forge/game/player/LobbyPlayerRemote.java @@ -3,10 +3,16 @@ package forge.game.player; import org.apache.commons.lang.NotImplementedException; import forge.game.GameState; +import forge.net.client.INetClient; +import forge.net.protocol.outcoming.ChatMessage; public class LobbyPlayerRemote extends LobbyPlayer { - public LobbyPlayerRemote(String name) { + + private final INetClient connection; + + public LobbyPlayerRemote(String name, INetClient netClient) { // This is actually a doubtful idea - this means 1 window per player. super(name); + connection = netClient; } @Override @@ -22,4 +28,9 @@ public class LobbyPlayerRemote extends LobbyPlayer { // Cannot create remote players yet throw new NotImplementedException(); } + + @Override + public void hear(LobbyPlayer player, String message) { + connection.send(new ChatMessage(player.getName(), message)); + } } \ No newline at end of file diff --git a/src/main/java/forge/gui/FNetOverlay.java b/src/main/java/forge/gui/FNetOverlay.java index 3fbc2a35b64..a47a4a14a34 100644 --- a/src/main/java/forge/gui/FNetOverlay.java +++ b/src/main/java/forge/gui/FNetOverlay.java @@ -20,6 +20,9 @@ import javax.swing.ScrollPaneConstants; import org.apache.commons.lang3.StringUtils; import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.control.ChatArea; +import forge.control.Lobby; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FTextArea; @@ -56,7 +59,9 @@ public enum FNetOverlay { txtInput.setText(""); if ( StringUtils.isBlank(message) ) return; - addMessage("You", message); + + Lobby lobby = Singletons.getControl().getLobby(); + lobby.speak(ChatArea.Room, lobby.getGuiPlayer(), message); } }; @@ -98,7 +103,7 @@ public enum FNetOverlay { } public void showUp(String message) { - txtLog.setText(message + "\n"); + txtLog.setText(message); pnl.setVisible(true); } @@ -135,7 +140,7 @@ public enum FNetOverlay { SimpleDateFormat inFormat = new SimpleDateFormat("HH:mm:ss"); public void addMessage(String origin, String message) { - String toAdd = String.format("[%s] %s: %s%n", inFormat.format(new Date()), origin, message); + String toAdd = String.format("%n[%s] %s: %s", inFormat.format(new Date()), origin, message); txtLog.append(toAdd); } } diff --git a/src/main/java/forge/net/client/NetClient.java b/src/main/java/forge/net/client/NetClient.java index 835ade2ad6b..9aa28373669 100644 --- a/src/main/java/forge/net/client/NetClient.java +++ b/src/main/java/forge/net/client/NetClient.java @@ -66,7 +66,7 @@ public class NetClient implements IConnectionObserver, INetClient{ */ @Override public final void createPlayer(String name) { - player = Singletons.getControl().getLobby().findOrCreateRemotePlayer(name); + player = Singletons.getControl().getLobby().findOrCreateRemotePlayer(name, this); } /* (non-Javadoc) diff --git a/src/main/java/forge/net/client/state/InLobbyClientState.java b/src/main/java/forge/net/client/state/InLobbyClientState.java index a5b301590a3..75fe7e01043 100644 --- a/src/main/java/forge/net/client/state/InLobbyClientState.java +++ b/src/main/java/forge/net/client/state/InLobbyClientState.java @@ -1,10 +1,11 @@ package forge.net.client.state; +import forge.Singletons; +import forge.control.ChatArea; import forge.net.client.INetClient; import forge.net.protocol.incoming.ChatPacket; import forge.net.protocol.incoming.IPacket; import forge.net.protocol.incoming.PacketOpcode; -import forge.net.protocol.outcoming.EchoMessage; /** * TODO: Write javadoc for this type. @@ -22,8 +23,10 @@ public class InLobbyClientState implements IClientState { if( data.getOpCode() == PacketOpcode.Chat) { ChatPacket cp = (ChatPacket) data; - // should actually find all players in a lobby and send it to them - client.send(new EchoMessage("chat - " + cp.getMessage())); + // if ( not muted ) + Singletons.getControl().getLobby().speak(ChatArea.Room, client.getPlayer(), cp.getMessage()); + // else + // client.send("You are banned and cannot speak"); return true; } return false; diff --git a/src/main/java/forge/net/protocol/outcoming/ChatMessage.java b/src/main/java/forge/net/protocol/outcoming/ChatMessage.java new file mode 100644 index 00000000000..aea189e2134 --- /dev/null +++ b/src/main/java/forge/net/protocol/outcoming/ChatMessage.java @@ -0,0 +1,24 @@ +package forge.net.protocol.outcoming; + +/** + * TODO: Write javadoc for this type. + * + */ +public class ChatMessage implements IMessage { + + private final String player; + private final String message; + + public ChatMessage(String playerName, String message) { + // TODO Auto-generated constructor stub + this.message = message; + this.player = playerName; + } + + @Override + public String toNetString() { + // TODO Auto-generated method stub + return String.format("%s: %s", player, message); + } + +}