summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/kz/ilotterytea/maxon/MaxonServer.java64
-rw-r--r--server/src/kz/ilotterytea/maxon/PlayerConnection.java66
-rw-r--r--server/src/kz/ilotterytea/maxon/ServerHandlers.java27
-rw-r--r--server/src/main/resources/logback.xml2
4 files changed, 155 insertions, 4 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);
+ }
+}
diff --git a/server/src/main/resources/logback.xml b/server/src/main/resources/logback.xml
index 4b08185..df24417 100644
--- a/server/src/main/resources/logback.xml
+++ b/server/src/main/resources/logback.xml
@@ -9,7 +9,7 @@
</encoder>
</appender>
- <root level="info">
+ <root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</configuration>