diff --git a/.gitattributes b/.gitattributes index 079cffe58de..2c7001749d7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14292,19 +14292,24 @@ src/main/java/forge/net/NetServer.java -text src/main/java/forge/net/client/INetClient.java -text src/main/java/forge/net/client/NetClient.java -text src/main/java/forge/net/client/package-info.java -text -src/main/java/forge/net/client/state/ClientState.java -text -src/main/java/forge/net/client/state/ClientStateUnauthorized.java -text +src/main/java/forge/net/client/state/ConnectedClientState.java -text src/main/java/forge/net/client/state/IClientState.java -text +src/main/java/forge/net/client/state/InLobbyClientState.java -text +src/main/java/forge/net/client/state/UnauthorizedClientState.java -text src/main/java/forge/net/client/state/package-info.java -text src/main/java/forge/net/package-info.java -text +src/main/java/forge/net/protocol/incoming/AuthorizePacket.java -text src/main/java/forge/net/protocol/incoming/ChatPacket.java -text src/main/java/forge/net/protocol/incoming/EchoPacket.java -text +src/main/java/forge/net/protocol/incoming/IncorrectPacket.java -text src/main/java/forge/net/protocol/incoming/Packet.java -text 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/EchoMessage.java -text -src/main/java/forge/net/protocol/outcoming/Message.java -text +src/main/java/forge/net/protocol/outcoming/IMessage.java -text +src/main/java/forge/net/protocol/outcoming/IncorrectPacketMessage.java -text src/main/java/forge/net/protocol/outcoming/UnknownPacketMessage.java -text src/main/java/forge/net/protocol/package-info.java -text src/main/java/forge/package-info.java svneol=native#text/plain diff --git a/src/main/html/js/main.js b/src/main/html/js/main.js index 891db02b970..964ea5230c2 100644 --- a/src/main/html/js/main.js +++ b/src/main/html/js/main.js @@ -4,31 +4,30 @@ if (!window.WebSocket) var server = new CWebSocket(); var listener = { onOpen : function() { - server.send('websockets are open for communications!'); - $('#input').fadeIn(); + $('#input').slideDown(); }, onMessage : function(m) { if (m.data) { - $('#messages').append(makeLi("incoming", m.data)); - var messageBox = $('#messages')[0]; - messageBox.scrollTop = messageBox.scrollHeight - messageBox.clientHeight; + addLi("incoming", m.data); } }, onClose : function(m) { - $('#messages').append(makeLi("error", "Connection was closed (" + m.code + "): " + m.reason)); + addLi("error", "Connection was closed (" + m.code + "): " + m.reason); onDisconnectClicked(); $('#input').fadeOut(); } }; server.addListener(listener); -function makeLi(className, text) { +function addLi(className, text) { var spanText = document.createElement('li'); spanText.className = className; spanText.innerHTML = text; - return spanText; + var messageBox = $('#messages')[0]; + messageBox.appendChild(spanText); + messageBox.scrollTop = messageBox.scrollHeight - messageBox.clientHeight; } function onConnectClicked() { @@ -48,7 +47,7 @@ function onDisconnectClicked() { function onSendClicked() { var toSend = $("#input input").val(); $("#input input").val(""); - $('#messages').append(makeLi("outcoming", toSend)); + addLi("outcoming", toSend); server.send(toSend) } diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 8589c833d54..958586e2c6a 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -46,6 +46,7 @@ import forge.gui.match.VMatchUI; import forge.gui.match.controllers.CDock; import forge.gui.toolbox.CardFaceSymbols; import forge.gui.toolbox.FSkin; +import forge.net.NetServer; import forge.properties.NewConstants; import forge.quest.data.QuestPreferences.QPref; import forge.quest.io.QuestDataIO; @@ -316,4 +317,14 @@ public enum FControl { public SoundSystem getSoundSystem() { return soundSystem; } + + /** + * TODO: Write javadoc for this method. + * @return + */ + private final NetServer server = new NetServer(); + public NetServer getServer() { + // TODO Auto-generated method stub + return server; + } } diff --git a/src/main/java/forge/gui/home/CHomeUI.java b/src/main/java/forge/gui/home/CHomeUI.java index 9766202e982..7b2bb90fa57 100644 --- a/src/main/java/forge/gui/home/CHomeUI.java +++ b/src/main/java/forge/gui/home/CHomeUI.java @@ -8,7 +8,6 @@ import forge.gui.deckeditor.controllers.CEditorConstructed; import forge.gui.framework.EDocID; import forge.gui.framework.ICDoc; import forge.gui.home.sanctioned.VSubmenuConstructed; -import forge.net.NetServer; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; @@ -56,7 +55,6 @@ public enum CHomeUI implements ICDoc { /* (non-Javadoc) * @see forge.view.home.ICDoc#intialize() */ - private final NetServer server = new NetServer(); @SuppressWarnings("serial") @Override @@ -80,14 +78,18 @@ public enum CHomeUI implements ICDoc { VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setCommand(new Command() { @Override public void execute() { - server.listen(); + FControl.SINGLETON_INSTANCE.getServer().listen(); + VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setEnabled(true); + VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setEnabled(false); } }); VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setCommand(new Command() { @Override public void execute() { - server.stop(); + FControl.SINGLETON_INSTANCE.getServer().stop(); + VHomeUI.SINGLETON_INSTANCE.getLblStopServer().setEnabled(false); + VHomeUI.SINGLETON_INSTANCE.getLblStartServer().setEnabled(true); } }); } diff --git a/src/main/java/forge/gui/home/VHomeUI.java b/src/main/java/forge/gui/home/VHomeUI.java index d6a9c68a58e..d0d4c9642a9 100644 --- a/src/main/java/forge/gui/home/VHomeUI.java +++ b/src/main/java/forge/gui/home/VHomeUI.java @@ -59,7 +59,6 @@ import forge.gui.home.variant.VSubmenuPlanechase; import forge.gui.home.variant.VSubmenuVanguard; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FSkin; -import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.view.FView; @@ -162,6 +161,7 @@ public enum VHomeUI implements IVTopLevelUI { if ( Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_MODE_ENABLED) ) { pnlButtons.add(lblStartServer, "w 170px!, h 25px!, gap 0 10px 10px 0, sx 2 "); pnlButtons.add(lblStopServer, "w 50px!, h 25px!, gap 0 0 10px 0"); + lblStopServer.setEnabled(false); } pnlMenu.add(pnlButtons, "w 230px!, gap 10px 0 10px 10px"); diff --git a/src/main/java/forge/net/NetServer.java b/src/main/java/forge/net/NetServer.java index a328295bc93..5eec5b6e367 100644 --- a/src/main/java/forge/net/NetServer.java +++ b/src/main/java/forge/net/NetServer.java @@ -7,6 +7,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import javax.servlet.http.HttpServletRequest; +import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -27,6 +28,18 @@ public class NetServer { private final Server srv = new Server(); private final Set _openSockets = new CopyOnWriteArraySet(); + public NetServer() { + SelectChannelConnector connector= new SelectChannelConnector(); + connector.setPort(81); + srv.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(); + ServletHolder sh = new ServletHolder(new GameServlet()); + context.addServlet(sh, "/*"); + //context.setContextPath("/"); + srv.setHandler(context); + } + @SuppressWarnings("serial") public class GameServlet extends WebSocketServlet { @@ -86,19 +99,10 @@ public class NetServer { public void listen() { if (!srv.isStarted()) { - SelectChannelConnector connector= new SelectChannelConnector(); - connector.setPort(81); - srv.addConnector(connector); - - ServletContextHandler context = new ServletContextHandler(); - ServletHolder sh = new ServletHolder(new GameServlet()); - context.addServlet(sh, "/*"); - //context.setContextPath("/"); - srv.setHandler(context); - URI serverUri = null; try { srv.start(); + Connector connector = srv.getConnectors()[0]; int port = connector.getLocalPort(); String host = connector.getHost(); serverUri = new URI(String.format("ws://%s:%d/", host == null ? "localhost" : host ,port)); diff --git a/src/main/java/forge/net/client/INetClient.java b/src/main/java/forge/net/client/INetClient.java index e1710e0b1cf..fca8fdc04c2 100644 --- a/src/main/java/forge/net/client/INetClient.java +++ b/src/main/java/forge/net/client/INetClient.java @@ -1,6 +1,8 @@ package forge.net.client; -import forge.net.protocol.outcoming.Message; +import forge.game.player.LobbyPlayer; +import forge.net.client.state.IClientState; +import forge.net.protocol.outcoming.IMessage; /** * TODO: Write javadoc for this type. @@ -12,6 +14,12 @@ public interface INetClient { * TODO: Write javadoc for this method. * @param echoMessage */ - void send(Message echoMessage); + void send(IMessage message); + + void setPlayer(LobbyPlayer lobbyPlayer); + LobbyPlayer getPlayer(); + + + void replaceState(IClientState old, IClientState newState); } diff --git a/src/main/java/forge/net/client/NetClient.java b/src/main/java/forge/net/client/NetClient.java index d6dab980862..6f792e66d2a 100644 --- a/src/main/java/forge/net/client/NetClient.java +++ b/src/main/java/forge/net/client/NetClient.java @@ -1,27 +1,32 @@ package forge.net.client; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.LinkedBlockingDeque; + import forge.game.player.LobbyPlayer; -import forge.game.player.PlayerType; import forge.net.IClientSocket; import forge.net.IConnectionObserver; -import forge.net.client.state.ClientStateUnauthorized; +import forge.net.client.state.ConnectedClientState; +import forge.net.client.state.UnauthorizedClientState; import forge.net.client.state.IClientState; import forge.net.protocol.incoming.Packet; import forge.net.protocol.incoming.PacketOpcode; -import forge.net.protocol.outcoming.Message; +import forge.net.protocol.outcoming.IMessage; public class NetClient implements IConnectionObserver, INetClient{ private final IClientSocket socket; - private IClientState state = new ClientStateUnauthorized(this); + private BlockingDeque state = new LinkedBlockingDeque(); private LobbyPlayer player = null; public NetClient(IClientSocket clientSocket) { socket = clientSocket; + state.push(new ConnectedClientState(this)); + state.push(new UnauthorizedClientState(this)); } public void autorized() { - player = new LobbyPlayer(PlayerType.REMOTE, "Guest"); + } /* (non-Javadoc) @@ -33,16 +38,42 @@ public class NetClient implements IConnectionObserver, INetClient{ } + @Override + public final LobbyPlayer getPlayer() { + return player; + } + + /** Receives input from network client */ @Override public void onMessage(String data) { Packet p = PacketOpcode.decode(data); - state.onPacket(p); + for(IClientState s : state) { + if ( s.processPacket(p) ) + break; + } } @Override - public void send(Message message) { + public void send(IMessage message) { socket.send(message.toNetString()); } + /* (non-Javadoc) + * @see forge.net.client.INetClient#setPlayer(forge.game.player.LobbyPlayer) + */ + @Override + public final void setPlayer(LobbyPlayer lobbyPlayer) { + player = lobbyPlayer; + } + + /* (non-Javadoc) + * @see forge.net.client.INetClient#replaceState(forge.net.client.state.IClientState, forge.net.client.state.IClientState) + */ + @Override + public synchronized void replaceState(IClientState old, IClientState newState) { + state.removeFirstOccurrence(old); + state.push(newState); + } + } diff --git a/src/main/java/forge/net/client/state/ClientState.java b/src/main/java/forge/net/client/state/ClientState.java deleted file mode 100644 index d546d591c80..00000000000 --- a/src/main/java/forge/net/client/state/ClientState.java +++ /dev/null @@ -1,37 +0,0 @@ -package forge.net.client.state; - -import forge.net.client.INetClient; -import forge.net.protocol.incoming.EchoPacket; -import forge.net.protocol.incoming.Packet; -import forge.net.protocol.outcoming.EchoMessage; -import forge.net.protocol.outcoming.UnknownPacketMessage; - -/** - * TODO: Write javadoc for this type. - * - */ -public abstract class ClientState implements IClientState { - - private final INetClient client; - - protected ClientState(INetClient client) - { - this.client = client; - } - - @Override - public void onPacket(Packet packet ) { - switch( packet.getOpCode() ) { - case Echo: - EchoPacket p = (EchoPacket)packet; - client.send(new EchoMessage(p.getMessage())); - break; - - default: - client.send(new UnknownPacketMessage()); - break; - - } - } - -} diff --git a/src/main/java/forge/net/client/state/ClientStateUnauthorized.java b/src/main/java/forge/net/client/state/ClientStateUnauthorized.java deleted file mode 100644 index 02c9ab5951e..00000000000 --- a/src/main/java/forge/net/client/state/ClientStateUnauthorized.java +++ /dev/null @@ -1,19 +0,0 @@ -package forge.net.client.state; - -import forge.net.client.INetClient; - -/** - * TODO: Write javadoc for this type. - * - */ -public class ClientStateUnauthorized extends ClientState implements IClientState { - - /** - * TODO: Write javadoc for Constructor. - * @param client - */ - public ClientStateUnauthorized(INetClient client) { - super(client); - } - -} diff --git a/src/main/java/forge/net/client/state/ConnectedClientState.java b/src/main/java/forge/net/client/state/ConnectedClientState.java new file mode 100644 index 00000000000..d846d2d47d5 --- /dev/null +++ b/src/main/java/forge/net/client/state/ConnectedClientState.java @@ -0,0 +1,40 @@ +package forge.net.client.state; + +import forge.net.client.INetClient; +import forge.net.protocol.incoming.EchoPacket; +import forge.net.protocol.incoming.IncorrectPacket; +import forge.net.protocol.incoming.Packet; +import forge.net.protocol.outcoming.EchoMessage; +import forge.net.protocol.outcoming.IncorrectPacketMessage; +import forge.net.protocol.outcoming.UnknownPacketMessage; + + + +public class ConnectedClientState implements IClientState { + + private final INetClient client; + + public ConnectedClientState(INetClient client) { + this.client = client; + } + + @Override + public boolean processPacket(Packet packet ) { + switch( packet.getOpCode() ) { + case Echo: + EchoPacket pe = (EchoPacket)packet; + client.send(new EchoMessage(pe.getMessage())); + return true; + + case Incorrect: + IncorrectPacket pi = (IncorrectPacket)packet; + client.send(new IncorrectPacketMessage(pi)); + return true; + + default: + client.send(new UnknownPacketMessage()); + return true; + } + } + +} diff --git a/src/main/java/forge/net/client/state/IClientState.java b/src/main/java/forge/net/client/state/IClientState.java index ccd0bb5e461..6ec944780d1 100644 --- a/src/main/java/forge/net/client/state/IClientState.java +++ b/src/main/java/forge/net/client/state/IClientState.java @@ -7,5 +7,5 @@ import forge.net.protocol.incoming.Packet; * */ public interface IClientState { - void onPacket(Packet data); + boolean processPacket(Packet data); } diff --git a/src/main/java/forge/net/client/state/InLobbyClientState.java b/src/main/java/forge/net/client/state/InLobbyClientState.java new file mode 100644 index 00000000000..cf1c28d4242 --- /dev/null +++ b/src/main/java/forge/net/client/state/InLobbyClientState.java @@ -0,0 +1,21 @@ +package forge.net.client.state; + +import forge.net.client.INetClient; +import forge.net.protocol.incoming.Packet; + +/** + * TODO: Write javadoc for this type. + * + */ +public class InLobbyClientState implements IClientState { + + private final INetClient client; + protected InLobbyClientState(INetClient client) { + this.client = client; + } + + @Override + public boolean processPacket(Packet data) { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/forge/net/client/state/UnauthorizedClientState.java b/src/main/java/forge/net/client/state/UnauthorizedClientState.java new file mode 100644 index 00000000000..65eee7ec5e9 --- /dev/null +++ b/src/main/java/forge/net/client/state/UnauthorizedClientState.java @@ -0,0 +1,44 @@ +package forge.net.client.state; + +import forge.game.player.LobbyPlayer; +import forge.game.player.PlayerType; +import forge.net.client.INetClient; +import forge.net.protocol.incoming.AuthorizePacket; +import forge.net.protocol.incoming.Packet; +import forge.net.protocol.incoming.PacketOpcode; +import forge.net.protocol.outcoming.AuthorizationSuccessfulMessage; + +/** + * TODO: Write javadoc for this type. + * + */ +public class UnauthorizedClientState implements IClientState { + + /** + * TODO: Write javadoc for Constructor. + * @param client + */ + private final INetClient client; + public UnauthorizedClientState(INetClient client) { + this.client = client; + } + + + @Override + public boolean processPacket(Packet packet) { + if( packet.getOpCode() == PacketOpcode.Authorize ) { + AuthorizePacket p = (AuthorizePacket)packet; + if( true ) { // check credentials here! + client.send(new AuthorizationSuccessfulMessage(p.getUsername())); + + + client.setPlayer(new LobbyPlayer(PlayerType.REMOTE, p.getUsername())); + client.replaceState(this, new InLobbyClientState(client)); + return true; + } + } + + return false; + } + +} diff --git a/src/main/java/forge/net/protocol/incoming/AuthorizePacket.java b/src/main/java/forge/net/protocol/incoming/AuthorizePacket.java new file mode 100644 index 00000000000..d5121921281 --- /dev/null +++ b/src/main/java/forge/net/protocol/incoming/AuthorizePacket.java @@ -0,0 +1,46 @@ +package forge.net.protocol.incoming; + +import org.apache.commons.lang3.StringUtils; + +import forge.util.TextUtil; + +/** + * TODO: Write javadoc for this type. + * + */ +public class AuthorizePacket extends Packet { + private final String username; + private final String password; + + private AuthorizePacket(String name, String pass) { + super(PacketOpcode.Authorize); + username = name; + password = pass; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + + public static Packet parse(String data) { + String[] parts = TextUtil.splitWithParenthesis(data, ' ', '\"', '\"'); + if(parts.length == 1 || parts.length == 2) { + if(!StringUtils.isAlphanumericSpace(parts[0])) + return new IncorrectPacket(PacketOpcode.Authorize, 0, parts[0]); + if( parts.length == 1) + return new AuthorizePacket(parts[0], null); + + if(!StringUtils.isAsciiPrintable(parts[1])) + return new IncorrectPacket(PacketOpcode.Authorize, 1, parts[1]); + else + return new AuthorizePacket(parts[0], parts[1]); + } + return UnknownPacket.parse(data); + } + +} diff --git a/src/main/java/forge/net/protocol/incoming/EchoPacket.java b/src/main/java/forge/net/protocol/incoming/EchoPacket.java index a76f5b73c0a..4c5fcd43799 100644 --- a/src/main/java/forge/net/protocol/incoming/EchoPacket.java +++ b/src/main/java/forge/net/protocol/incoming/EchoPacket.java @@ -8,10 +8,15 @@ package forge.net.protocol.incoming; public class EchoPacket extends Packet { private final String message; - public EchoPacket(String data) { + private EchoPacket(String data) { super(PacketOpcode.Echo); message = data; } + + public static EchoPacket parse(String data) { + return new EchoPacket(data); + } + public String getMessage() { return message; } diff --git a/src/main/java/forge/net/protocol/incoming/IncorrectPacket.java b/src/main/java/forge/net/protocol/incoming/IncorrectPacket.java new file mode 100644 index 00000000000..b09c832f019 --- /dev/null +++ b/src/main/java/forge/net/protocol/incoming/IncorrectPacket.java @@ -0,0 +1,32 @@ +package forge.net.protocol.incoming; + +/** + * TODO: Write javadoc for this type. + * + */ +public class IncorrectPacket extends Packet { + + private final PacketOpcode intendedCode; + private final int index; + private final String sParam; + + public IncorrectPacket(PacketOpcode code, int iParameter, String value) { + super(PacketOpcode.Incorrect); + intendedCode = code; + index = iParameter; + sParam = value; + } + + public String getString() { + return sParam; + } + + public int getIndex() { + return index; + } + + public PacketOpcode getIntendedCode() { + return intendedCode; + } + +} diff --git a/src/main/java/forge/net/protocol/incoming/PacketOpcode.java b/src/main/java/forge/net/protocol/incoming/PacketOpcode.java index b7eeace6a20..856ce870765 100644 --- a/src/main/java/forge/net/protocol/incoming/PacketOpcode.java +++ b/src/main/java/forge/net/protocol/incoming/PacketOpcode.java @@ -8,7 +8,10 @@ package forge.net.protocol.incoming; public enum PacketOpcode { Echo("/echo"), Chat("/s"), - Unknown(""); + Authorize("/auth"), + + Incorrect(null), + Unknown(null); @@ -18,6 +21,10 @@ public enum PacketOpcode { opcode = code; } + public final String getOpcode() { + return opcode; + } + /** * TODO: Write javadoc for this method. * @param data @@ -25,11 +32,11 @@ public enum PacketOpcode { */ public static Packet decode(String data) { for(PacketOpcode s : PacketOpcode.values()) { - if ( data.startsWith(s.opcode) ) + if ( s.opcode != null && data.startsWith(s.opcode) ) return decodePacket(s, data.substring(s.opcode.length()).trim()); } if( data.startsWith("/") ) - return new UnknownPacket(data.substring(1)); + return UnknownPacket.parse(data.substring(1)); else return new ChatPacket(data); } @@ -38,9 +45,11 @@ public enum PacketOpcode { private static Packet decodePacket(PacketOpcode code, String data) { switch(code) { case Echo: - return new EchoPacket(data); + return EchoPacket.parse(data); + case Authorize: + return AuthorizePacket.parse(data); default: - return new UnknownPacket(data); + return UnknownPacket.parse(data); } } } diff --git a/src/main/java/forge/net/protocol/incoming/UnknownPacket.java b/src/main/java/forge/net/protocol/incoming/UnknownPacket.java index 9aa5c326aee..302fa23617b 100644 --- a/src/main/java/forge/net/protocol/incoming/UnknownPacket.java +++ b/src/main/java/forge/net/protocol/incoming/UnknownPacket.java @@ -8,12 +8,20 @@ package forge.net.protocol.incoming; public class UnknownPacket extends Packet { private final String message; - public UnknownPacket(String data) { + private UnknownPacket(String data) { super(PacketOpcode.Unknown); message = data; } public String getMessage() { return message; } + /** + * TODO: Write javadoc for this method. + * @param substring + * @return + */ + public static Packet parse(String substring) { + return new UnknownPacket(substring); + } } diff --git a/src/main/java/forge/net/protocol/outcoming/AuthorizationSuccessfulMessage.java b/src/main/java/forge/net/protocol/outcoming/AuthorizationSuccessfulMessage.java new file mode 100644 index 00000000000..22ae896f133 --- /dev/null +++ b/src/main/java/forge/net/protocol/outcoming/AuthorizationSuccessfulMessage.java @@ -0,0 +1,21 @@ +package forge.net.protocol.outcoming; + +/** + * TODO: Write javadoc for this type. + * + */ +public class AuthorizationSuccessfulMessage implements IMessage { + + private final String username; + + public AuthorizationSuccessfulMessage(String user) { + username = user; + } + + @Override + public String toNetString() { + // TODO Auto-generated method stub + return "Authorization Successful. Welcome, " + username; + } + +} diff --git a/src/main/java/forge/net/protocol/outcoming/EchoMessage.java b/src/main/java/forge/net/protocol/outcoming/EchoMessage.java index 6fd57b9a9b7..1452d98e8ea 100644 --- a/src/main/java/forge/net/protocol/outcoming/EchoMessage.java +++ b/src/main/java/forge/net/protocol/outcoming/EchoMessage.java @@ -4,7 +4,7 @@ package forge.net.protocol.outcoming; * TODO: Write javadoc for this type. * */ -public class EchoMessage extends Message { +public class EchoMessage implements IMessage { private final String message; diff --git a/src/main/java/forge/net/protocol/outcoming/Message.java b/src/main/java/forge/net/protocol/outcoming/IMessage.java similarity index 52% rename from src/main/java/forge/net/protocol/outcoming/Message.java rename to src/main/java/forge/net/protocol/outcoming/IMessage.java index c5ea23d4016..deaba591a45 100644 --- a/src/main/java/forge/net/protocol/outcoming/Message.java +++ b/src/main/java/forge/net/protocol/outcoming/IMessage.java @@ -4,6 +4,6 @@ package forge.net.protocol.outcoming; * TODO: Write javadoc for this type. * */ -public abstract class Message { - public abstract String toNetString(); +public interface IMessage { + public String toNetString(); } diff --git a/src/main/java/forge/net/protocol/outcoming/IncorrectPacketMessage.java b/src/main/java/forge/net/protocol/outcoming/IncorrectPacketMessage.java new file mode 100644 index 00000000000..065bff4013e --- /dev/null +++ b/src/main/java/forge/net/protocol/outcoming/IncorrectPacketMessage.java @@ -0,0 +1,18 @@ +package forge.net.protocol.outcoming; + +import forge.net.protocol.incoming.IncorrectPacket; + + +public class IncorrectPacketMessage implements IMessage { + + IncorrectPacket badPacket; + public IncorrectPacketMessage(IncorrectPacket packet) { + badPacket = packet; + } + + @Override + public String toNetString() { + return String.format("Wrong syntax for %s command: parameter #%d is %s", badPacket.getIntendedCode().getOpcode(), 1+badPacket.getIndex(), badPacket.getString()); + } + +} diff --git a/src/main/java/forge/net/protocol/outcoming/UnknownPacketMessage.java b/src/main/java/forge/net/protocol/outcoming/UnknownPacketMessage.java index 1806206285c..da4b0a7562f 100644 --- a/src/main/java/forge/net/protocol/outcoming/UnknownPacketMessage.java +++ b/src/main/java/forge/net/protocol/outcoming/UnknownPacketMessage.java @@ -4,7 +4,7 @@ package forge.net.protocol.outcoming; * TODO: Write javadoc for this type. * */ -public class UnknownPacketMessage extends Message { +public class UnknownPacketMessage implements IMessage { /* (non-Javadoc) * @see forge.net.protocol.outcoming.Message#toNetString() diff --git a/src/main/java/forge/util/TextUtil.java b/src/main/java/forge/util/TextUtil.java index df55cd34510..a85abcab2c7 100644 --- a/src/main/java/forge/util/TextUtil.java +++ b/src/main/java/forge/util/TextUtil.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; /** * TODO: Write javadoc for this type. @@ -58,14 +59,16 @@ public class TextUtil { */ public static String[] splitWithParenthesis(CharSequence input, char delimiter, int maxEntries, char openPar, char closePar, boolean skipEmpty) { List result = new ArrayList(); + // Assume that when equal non-zero parenthesis are passed, they need to be discarded + boolean trimParenthesis = openPar == closePar && openPar > 0; int nPar = 0; int len = input.length(); int start = 0; int idx = 1; for (int iC = 0; iC < len; iC++ ) { char c = input.charAt(iC); - if( openPar > 0 && c == openPar ) nPar++; - if( closePar > 0 && c == closePar ) { nPar = nPar > 0 ? nPar - 1 : 0; } + if( closePar > 0 && c == closePar && nPar > 0 ) { nPar--; } + else if( openPar > 0 && c == openPar ) nPar++; if( c == delimiter && nPar == 0 && idx < maxEntries) { if( iC > start || !skipEmpty ) { @@ -79,7 +82,8 @@ public class TextUtil { if( len > start || !skipEmpty ) result.add(input.subSequence(start, len).toString()); - return result.toArray(ArrayUtils.EMPTY_STRING_ARRAY); + String[] toReturn = result.toArray(ArrayUtils.EMPTY_STRING_ARRAY); + return trimParenthesis ? StringUtils.stripAll(toReturn, String.valueOf(openPar)) : toReturn; } /**