mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Server instance moved to FControl,
HomeUI buttons get enabled/disabled to indicate server status Server - clientstates form a chain of responsibility for packets processing packets for autorization (no checks performed, used to get player's name)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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<ClientSocket> _openSockets = new CopyOnWriteArraySet<ClientSocket>();
|
||||
|
||||
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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<IClientState> state = new LinkedBlockingDeque<IClientState>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,5 +7,5 @@ import forge.net.protocol.incoming.Packet;
|
||||
*
|
||||
*/
|
||||
public interface IClientState {
|
||||
void onPacket(Packet data);
|
||||
boolean processPacket(Packet data);
|
||||
}
|
||||
|
||||
21
src/main/java/forge/net/client/state/InLobbyClientState.java
Normal file
21
src/main/java/forge/net/client/state/InLobbyClientState.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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<String> result = new ArrayList<String>();
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user