Server incubation

This commit is contained in:
Maxmtg
2013-04-13 22:00:41 +00:00
parent 9c032e8d27
commit cac89ede5a
21 changed files with 476 additions and 0 deletions

20
.gitattributes vendored
View File

@@ -14286,7 +14286,27 @@ src/main/java/forge/model/BuildInfo.java -text
src/main/java/forge/model/FModel.java svneol=native#text/plain src/main/java/forge/model/FModel.java svneol=native#text/plain
src/main/java/forge/model/MultipleForgeJarsFoundError.java -text src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
src/main/java/forge/model/package-info.java svneol=native#text/plain src/main/java/forge/model/package-info.java svneol=native#text/plain
src/main/java/forge/net/IClientSocket.java -text
src/main/java/forge/net/IConnectionObserver.java -text
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/IClientState.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/package-info.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/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/EchoMessage.java -text
src/main/java/forge/net/protocol/outcoming/Message.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 src/main/java/forge/package-info.java svneol=native#text/plain
src/main/java/forge/properties/ForgePreferences.java svneol=native#text/plain src/main/java/forge/properties/ForgePreferences.java svneol=native#text/plain
src/main/java/forge/properties/NewConstants.java svneol=native#text/plain src/main/java/forge/properties/NewConstants.java svneol=native#text/plain

View File

@@ -0,0 +1,7 @@
package forge.net;
public interface IClientSocket {
boolean isOpen();
void send(String message);
void close(String farewell);
}

View File

@@ -0,0 +1,9 @@
package forge.net;
public interface IConnectionObserver {
/** Notifies that the client is gone, it's too late to send anything */
public void onConnectionClosed();
/** Notifies of an incoming message */
public void onMessage(String data);
}

View File

@@ -0,0 +1,124 @@
package forge.net;
import java.io.IOException;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
import forge.error.BugReporter;
import forge.net.client.NetClient;
/**
* TODO: Write javadoc for this type.
*
*/
public class NetServer {
private final Server srv = new Server();
private final Set<ClientSocket> _openSockets = new CopyOnWriteArraySet<ClientSocket>();
@SuppressWarnings("serial")
public class GameServlet extends WebSocketServlet
{
@Override
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
System.out.printf("Connection from %s recieved%n", request.getRemoteAddr());
return new ClientSocket();
}
}
public class ClientSocket implements WebSocket.OnTextMessage, IClientSocket
{
private Connection _connection;
private IConnectionObserver _client;
@Override
public void onClose(int closeCode, String message) {
System.out.println("Lost connection: " + closeCode + ", " + message);
_openSockets.remove(_client);
_client.onConnectionClosed();
}
public void send(String data) {
try {
_connection.sendMessage(data);
} catch (IOException e) {
BugReporter.reportException(e);
}
}
@Override
public void onMessage(String data) {
System.out.println("Received: " + data);
_client.onMessage(data);
}
public boolean isOpen() {
return _connection.isOpen();
}
@Override
public void onOpen(Connection connection) {
_connection = connection;
_client = new NetClient(this);
_openSockets.add(this);
send("CardForge server welcomes you.");
}
@Override
public void close(String farewell) {
_connection.close(1000, farewell);
}
}
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();
int port = connector.getLocalPort();
String host = connector.getHost();
serverUri = new URI(String.format("ws://%s:%d/", host == null ? "localhost" : host ,port));
} catch (Exception e) {
BugReporter.reportException(e);
}
System.out.println("Server started @ " + serverUri);
}
else {
System.out.println("Server was already started");
}
}
public void stop() {
try {
srv.stop();
} catch (Exception e) {
BugReporter.reportException(e);
}
}
}

View File

@@ -0,0 +1,17 @@
package forge.net.client;
import forge.net.protocol.outcoming.Message;
/**
* TODO: Write javadoc for this type.
*
*/
public interface INetClient {
/**
* TODO: Write javadoc for this method.
* @param echoMessage
*/
void send(Message echoMessage);
}

View File

@@ -0,0 +1,48 @@
package forge.net.client;
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.IClientState;
import forge.net.protocol.incoming.Packet;
import forge.net.protocol.incoming.PacketOpcode;
import forge.net.protocol.outcoming.Message;
public class NetClient implements IConnectionObserver, INetClient{
private final IClientSocket socket;
private IClientState state = new ClientStateUnauthorized(this);
private LobbyPlayer player = null;
public NetClient(IClientSocket clientSocket) {
socket = clientSocket;
}
public void autorized() {
player = new LobbyPlayer(PlayerType.REMOTE, "Guest");
}
/* (non-Javadoc)
* @see forge.net.client.IConnectionObserver#onConnectionClosed()
*/
@Override
public void onConnectionClosed() {
// Tell the game, the client is gone.
}
@Override
public void onMessage(String data) {
Packet p = PacketOpcode.decode(data);
state.onPacket(p);
}
@Override
public void send(Message message) {
socket.send(message.toNetString());
}
}

View File

@@ -0,0 +1,3 @@
/** Model (as in model-view-controller) for Forge. */
package forge.net.client;

View File

@@ -0,0 +1,37 @@
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;
}
}
}

View File

@@ -0,0 +1,19 @@
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);
}
}

View File

@@ -0,0 +1,11 @@
package forge.net.client.state;
import forge.net.protocol.incoming.Packet;
/**
* TODO: Write javadoc for this type.
*
*/
public interface IClientState {
void onPacket(Packet data);
}

View File

@@ -0,0 +1,3 @@
/** Model (as in model-view-controller) for Forge. */
package forge.net.client.state;

View File

@@ -0,0 +1,18 @@
package forge.net.protocol.incoming;
/**
* TODO: Write javadoc for this type.
*
*/
public class ChatPacket extends Packet {
private final String message;
public ChatPacket(String data) {
super(PacketOpcode.Chat);
message = data;
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,19 @@
package forge.net.protocol.incoming;
/**
* TODO: Write javadoc for this type.
*
*/
public class EchoPacket extends Packet {
private final String message;
public EchoPacket(String data) {
super(PacketOpcode.Echo);
message = data;
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,18 @@
package forge.net.protocol.incoming;
/**
* TODO: Write javadoc for this type.
*
*/
public abstract class Packet {
private final PacketOpcode opCode;
public Packet(PacketOpcode code) {
opCode = code;
}
public final PacketOpcode getOpCode() {
return opCode;
}
}

View File

@@ -0,0 +1,46 @@
package forge.net.protocol.incoming;
/**
* TODO: Write javadoc for this type.
*
*/
public enum PacketOpcode {
Echo("/echo"),
Chat("/s"),
Unknown("");
private final String opcode;
private PacketOpcode(String code) {
opcode = code;
}
/**
* TODO: Write javadoc for this method.
* @param data
* @return
*/
public static Packet decode(String data) {
for(PacketOpcode s : PacketOpcode.values()) {
if ( data.startsWith(s.opcode) )
return decodePacket(s, data.substring(s.opcode.length()).trim());
}
if( data.startsWith("/") )
return new UnknownPacket(data.substring(1));
else
return new ChatPacket(data);
}
private static Packet decodePacket(PacketOpcode code, String data) {
switch(code) {
case Echo:
return new EchoPacket(data);
default:
return new UnknownPacket(data);
}
}
}

View File

@@ -0,0 +1,19 @@
package forge.net.protocol.incoming;
/**
* TODO: Write javadoc for this type.
*
*/
public class UnknownPacket extends Packet {
private final String message;
public UnknownPacket(String data) {
super(PacketOpcode.Unknown);
message = data;
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,3 @@
/** Model (as in model-view-controller) for Forge. */
package forge.net.protocol.incoming;

View File

@@ -0,0 +1,26 @@
package forge.net.protocol.outcoming;
/**
* TODO: Write javadoc for this type.
*
*/
public class EchoMessage extends Message {
private final String message;
/**
* TODO: Write javadoc for Constructor.
* @param message2
*/
public EchoMessage(String message) {
this.message = message;
}
@Override
public String toNetString() {
return String.format("System: %s", message);
}
}

View File

@@ -0,0 +1,9 @@
package forge.net.protocol.outcoming;
/**
* TODO: Write javadoc for this type.
*
*/
public abstract class Message {
public abstract String toNetString();
}

View File

@@ -0,0 +1,17 @@
package forge.net.protocol.outcoming;
/**
* TODO: Write javadoc for this type.
*
*/
public class UnknownPacketMessage extends Message {
/* (non-Javadoc)
* @see forge.net.protocol.outcoming.Message#toNetString()
*/
@Override
public String toNetString() {
return "Unkown packet received";
}
}

View File

@@ -0,0 +1,3 @@
/** Model (as in model-view-controller) for Forge. */
package forge.net.protocol;