summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-01-20 23:32:34 +0500
committerilotterytea <iltsu@alright.party>2025-01-20 23:42:02 +0500
commit8ecc23455f36da01c373b99a536ecd326b26c01a (patch)
tree448977fed53ad8a04cf2c80357032c405b0ca1f8 /server/src
parent8d8eb55d4f3ad98eba837e702ee79187f735f177 (diff)
feat: connection between server and game
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java110
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java67
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java26
-rw-r--r--server/src/main/java/kz/ilotterytea/frogartha/server/ServerLauncher.java9
4 files changed, 209 insertions, 3 deletions
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java b/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java
new file mode 100644
index 0000000..f6a9847
--- /dev/null
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/FrogarthaServer.java
@@ -0,0 +1,110 @@
+package kz.ilotterytea.frogartha.server;
+
+import kz.ilotterytea.frogartha.domain.Identity;
+import kz.ilotterytea.frogartha.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 FrogarthaServer extends WebSocketServer {
+ private static FrogarthaServer instance;
+
+ private final Logger log;
+ private final ArrayList<PlayerConnection> players;
+
+ private FrogarthaServer() {
+ super(new InetSocketAddress(20015));
+ this.log = LoggerFactory.getLogger(FrogarthaServer.class);
+ this.players = new ArrayList<>();
+ }
+
+ @Override
+ public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
+ PlayerConnection player = new PlayerConnection(webSocket);
+ log.info("{} ({}) connected!", player, webSocket.getRemoteSocketAddress().getAddress().getHostAddress());
+ this.players.add(player);
+ }
+
+ @Override
+ public void onClose(WebSocket webSocket, int i, String s, boolean b) {
+ Optional<PlayerConnection> player = this.players.stream().filter((x) -> x.getConnection().equals(webSocket)).findFirst();
+
+ if (player.isPresent()) {
+ log.info("{} has let! Reason: {} {}", player.get(), i, s);
+ } else {
+ log.info("Unknown connection was closed! Reason: {} {}", i, s);
+ }
+ }
+
+ @Override
+ public void onMessage(WebSocket webSocket, String s) {
+ this.players.removeIf((x) -> x.getConnection().equals(webSocket));
+ webSocket.send("Invalid input.");
+ webSocket.close(CloseFrame.UNEXPECTED_CONDITION);
+ }
+
+ @Override
+ public void onMessage(WebSocket conn, ByteBuffer message) {
+ Optional<PlayerConnection> optionalPlayer = this.players.stream().filter((x) -> x.getConnection().equals(conn)).findFirst();
+
+ if (optionalPlayer.isEmpty()) {
+ conn.close();
+ return;
+ }
+
+ PlayerConnection player = optionalPlayer.get();
+
+ try {
+ // Deserializing the object
+ ByteArrayInputStream bais = new ByteArrayInputStream(message.array());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ Object obj = ois.readObject();
+
+ if (obj instanceof Identity) ServerHandlers.handleIdentity(player, (Identity) obj);
+ else throw PlayerKickException.internalServerError();
+ } catch (PlayerKickException e) {
+ kickConnection(player, e);
+ } catch (Exception e) {
+ log.error("An exception was thrown while processing message", e);
+ kickConnection(player, PlayerKickException.internalServerError());
+ }
+ }
+
+ @Override
+ public void onError(WebSocket webSocket, Exception e) {
+ log.error("Something went error", e);
+ }
+
+ @Override
+ public void onStart() {
+ log.info("Running the server on port {}", getPort());
+ setConnectionLostTimeout(0);
+ setConnectionLostTimeout(100);
+ }
+
+ public void kickConnection(PlayerConnection player, PlayerKickException exception) {
+ player.send(exception);
+ player.getConnection().close();
+ players.remove(player);
+ log.debug("Kicked out {}! Reason: {}", player, exception.getMessage());
+ }
+
+ public static FrogarthaServer getInstance() {
+ if (instance == null) instance = new FrogarthaServer();
+ return instance;
+ }
+
+ public ArrayList<PlayerConnection> getPlayers() {
+ return players;
+ }
+}
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java b/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java
new file mode 100644
index 0000000..c62dce5
--- /dev/null
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/PlayerConnection.java
@@ -0,0 +1,67 @@
+package kz.ilotterytea.frogartha.server;
+
+import kz.ilotterytea.frogartha.domain.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.id = TOTAL_CONNECTION_IDS;
+ TOTAL_CONNECTION_IDS++;
+
+ this.connectedTimestamp = new Timestamp(System.currentTimeMillis());
+ this.identity = null;
+ }
+
+ public void send(Object object) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(object);
+ } catch (IOException ignored) {
+
+ }
+
+ this.connection.send(baos.toByteArray());
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public WebSocket getConnection() {
+ return connection;
+ }
+
+ public Timestamp getConnectedTimestamp() {
+ return connectedTimestamp;
+ }
+
+ public Identity getIdentity() {
+ return identity;
+ }
+
+ public void setIdentity(Identity identity) {
+ this.identity = identity;
+ }
+
+ @Override
+ public String toString() {
+ return "PlayerConnection{" +
+ "id=" + id +
+ '}';
+ }
+}
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
new file mode 100644
index 0000000..87dc17d
--- /dev/null
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerHandlers.java
@@ -0,0 +1,26 @@
+package kz.ilotterytea.frogartha.server;
+
+import kz.ilotterytea.frogartha.domain.Acknowledge;
+import kz.ilotterytea.frogartha.domain.Identity;
+import kz.ilotterytea.frogartha.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 FrogarthaServer server = FrogarthaServer.getInstance();
+
+ public static void handleIdentity(PlayerConnection player, Identity identity) {
+ if (server.getPlayers()
+ .stream()
+ .filter((x) -> x.getIdentity() != null)
+ .anyMatch((x) -> x.getIdentity().equals(identity) && x.getId() != player.getId())) {
+ server.kickConnection(player, PlayerKickException.loggedIn());
+ return;
+ }
+
+ player.setIdentity(identity);
+ player.send(new Acknowledge(player));
+ log.debug("Successfully identified {} for {}", identity, player);
+ }
+}
diff --git a/server/src/main/java/kz/ilotterytea/frogartha/server/ServerLauncher.java b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerLauncher.java
index fc7c1e5..8c07f64 100644
--- a/server/src/main/java/kz/ilotterytea/frogartha/server/ServerLauncher.java
+++ b/server/src/main/java/kz/ilotterytea/frogartha/server/ServerLauncher.java
@@ -1,8 +1,11 @@
package kz.ilotterytea.frogartha.server;
-/** Launches the server application. */
+/**
+ * Launches the server application.
+ */
public class ServerLauncher {
public static void main(String[] args) {
- // TODO Implement server application.
+ FrogarthaServer server = FrogarthaServer.getInstance();
+ server.start();
}
-} \ No newline at end of file
+}