diff options
Diffstat (limited to 'server/src/kz/ilotterytea')
| -rw-r--r-- | server/src/kz/ilotterytea/maxon/MaxonServer.java | 64 | ||||
| -rw-r--r-- | server/src/kz/ilotterytea/maxon/PlayerConnection.java | 66 | ||||
| -rw-r--r-- | server/src/kz/ilotterytea/maxon/ServerHandlers.java | 27 |
3 files changed, 154 insertions, 3 deletions
diff --git a/server/src/kz/ilotterytea/maxon/MaxonServer.java b/server/src/kz/ilotterytea/maxon/MaxonServer.java index 7a38a7f..91ba049 100644 --- a/server/src/kz/ilotterytea/maxon/MaxonServer.java +++ b/server/src/kz/ilotterytea/maxon/MaxonServer.java @@ -1,36 +1,83 @@ package kz.ilotterytea.maxon; +import kz.ilotterytea.maxon.shared.Identity; +import kz.ilotterytea.maxon.shared.exceptions.PlayerKickException; import org.java_websocket.WebSocket; +import org.java_websocket.framing.CloseFrame; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; +import java.io.ObjectInputStream; import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Optional; public class MaxonServer extends WebSocketServer { private static MaxonServer instance; private final Logger log; + private final ArrayList<PlayerConnection> connections; private MaxonServer() { super(new InetSocketAddress(31084)); this.log = LoggerFactory.getLogger(MaxonServer.class); + this.connections = new ArrayList<>(); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { - log.info("{} connected!", conn.getRemoteSocketAddress().getAddress().getHostAddress()); + PlayerConnection connection = new PlayerConnection(conn); + log.info("{} ({}) connected!", connection, conn.getRemoteSocketAddress().getAddress().getHostAddress()); + this.connections.add(connection); } @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { - log.info("Connection {} has been closed! ({} {} {})", conn, code, reason, remote); + Optional<PlayerConnection> connection = this.connections.stream().filter((x) -> x.getConnection().equals(conn)).findFirst(); + if (connection.isPresent()) { + log.info("{} has left! Reason: {} {}", connection.get(), code, reason); + this.connections.remove(connection.get()); + } else { + log.info("Unknown connection was closed! Reason: {} {}", code, reason); + } } @Override public void onMessage(WebSocket conn, String message) { - log.info("{} says {}", conn, message); + this.connections.removeIf((x) -> x.getConnection().equals(conn)); + conn.send("Invalid input."); + conn.close(CloseFrame.UNEXPECTED_CONDITION); + } + + @Override + public void onMessage(WebSocket conn, ByteBuffer message) { + Optional<PlayerConnection> playerConnection = this.connections.stream().filter((x) -> x.getConnection().equals(conn)).findFirst(); + + if (playerConnection.isEmpty()) { + conn.close(5001, "Your PlayerConnection was not found!"); + return; + } + + PlayerConnection c = playerConnection.get(); + + try { + // Deserialize the object + ByteArrayInputStream bais = new ByteArrayInputStream(message.array()); + ObjectInputStream ois = new ObjectInputStream(bais); + Object obj = ois.readObject(); + + if (obj instanceof Identity identity) ServerHandlers.handleIdentity(c, identity); + else kickConnection(c, PlayerKickException.internalServerError()); + } catch (PlayerKickException e) { + kickConnection(c, e); + } catch (Exception e) { + log.error("An exception was thrown while processing message", e); + kickConnection(c, PlayerKickException.internalServerError()); + } } @Override @@ -45,8 +92,19 @@ public class MaxonServer extends WebSocketServer { setConnectionLostTimeout(100); } + public void kickConnection(PlayerConnection connection, PlayerKickException e) { + connection.send(e); + connection.getConnection().close(); + this.connections.remove(connection); + log.debug("Kicked out {}! Reason: {}", connection, e.getMessage()); + } + public static MaxonServer getInstance() { if (instance == null) instance = new MaxonServer(); return instance; } + + public ArrayList<PlayerConnection> getPlayerConnections() { + return connections; + } } diff --git a/server/src/kz/ilotterytea/maxon/PlayerConnection.java b/server/src/kz/ilotterytea/maxon/PlayerConnection.java new file mode 100644 index 0000000..79b46d0 --- /dev/null +++ b/server/src/kz/ilotterytea/maxon/PlayerConnection.java @@ -0,0 +1,66 @@ +package kz.ilotterytea.maxon; + +import kz.ilotterytea.maxon.shared.Identity; +import org.java_websocket.WebSocket; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.sql.Timestamp; + +public class PlayerConnection { + private static int TOTAL_CONNECTION_IDS = 0; + + private final int id; + private final WebSocket connection; + private Identity identity; + + private final Timestamp connectedTimestamp; + + public PlayerConnection(WebSocket connection) { + this.connection = connection; + this.connectedTimestamp = new Timestamp(System.currentTimeMillis()); + + this.id = TOTAL_CONNECTION_IDS; + TOTAL_CONNECTION_IDS++; + } + + public int getId() { + return id; + } + + public WebSocket getConnection() { + return connection; + } + + public Identity getIdentity() { + return identity; + } + + public void setIdentity(Identity identity) { + this.identity = identity; + } + + public Timestamp getConnectedTimestamp() { + return connectedTimestamp; + } + + public void send(Object object) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) { + objectOutputStream.writeObject(object); + } catch (IOException ignored) { + + } + + this.connection.send(byteArrayOutputStream.toByteArray()); + } + + @Override + public String toString() { + return "PlayerConnection{" + + "id=" + id + + '}'; + } +} diff --git a/server/src/kz/ilotterytea/maxon/ServerHandlers.java b/server/src/kz/ilotterytea/maxon/ServerHandlers.java new file mode 100644 index 0000000..43468b3 --- /dev/null +++ b/server/src/kz/ilotterytea/maxon/ServerHandlers.java @@ -0,0 +1,27 @@ +package kz.ilotterytea.maxon; + +import kz.ilotterytea.maxon.shared.Acknowledge; +import kz.ilotterytea.maxon.shared.Identity; +import kz.ilotterytea.maxon.shared.exceptions.PlayerKickException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServerHandlers { + private static final Logger log = LoggerFactory.getLogger(ServerHandlers.class); + private static final MaxonServer server = MaxonServer.getInstance(); + + public static void handleIdentity(PlayerConnection connection, Identity identity) { + if (server.getPlayerConnections() + .stream() + .filter((x) -> x.getIdentity() != null) + .anyMatch((x) -> x.getIdentity().equals(identity) && x.getId() != connection.getId()) + ) { + server.kickConnection(connection, PlayerKickException.loggedIn()); + return; + } + + connection.setIdentity(identity); + connection.send(new Acknowledge(identity)); + log.debug("Successfully identified {} for {}", identity, connection); + } +} |
