From b7113b7ee8b1b28ff36494bfa6ab230defcb703d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 18 Feb 2021 11:42:11 +0100 Subject: [PATCH] Basics of client server communication and drawing of gamestates finished --- .idea/artifacts/Client.xml | 22 +++++ .idea/artifacts/Client_jar.xml | 8 -- Client/src/META-INF/MANIFEST.MF | 2 +- .../TicTacToe => game}/TicTacToe_Client.css | 0 .../TicTacToe => game}/TicTacToe_Client.java | 29 +++--- .../TicTacToe => game}/TicTacToe_Grid.png | Bin Client/src/networking/Client.java | 36 ++++++-- Server/res/META-INF/MANIFEST.MF | 3 + Server/src/game/TicTacToe_Server.java | 41 +++++++++ Server/src/networking/Server.java | 84 ++++++++++++++---- out/artifacts/Client/Client.html | 43 +++++++++ out/artifacts/Client/Client.jnlp | 15 ++++ out/production/Client/META-INF/MANIFEST.MF | 2 +- .../Login.css => game/TicTacToe_Client.css} | 0 .../TicTacToe => game}/TicTacToe_Grid.png | Bin 15 files changed, 238 insertions(+), 47 deletions(-) create mode 100644 .idea/artifacts/Client.xml delete mode 100644 .idea/artifacts/Client_jar.xml rename Client/src/{games/TicTacToe => game}/TicTacToe_Client.css (100%) rename Client/src/{games/TicTacToe => game}/TicTacToe_Client.java (80%) rename Client/src/{games/TicTacToe => game}/TicTacToe_Grid.png (100%) create mode 100644 Server/res/META-INF/MANIFEST.MF create mode 100644 Server/src/game/TicTacToe_Server.java create mode 100644 out/artifacts/Client/Client.html create mode 100644 out/artifacts/Client/Client.jnlp rename out/production/Client/{games/TicTacToe/Login.css => game/TicTacToe_Client.css} (100%) rename out/production/Client/{games/TicTacToe => game}/TicTacToe_Grid.png (100%) diff --git a/.idea/artifacts/Client.xml b/.idea/artifacts/Client.xml new file mode 100644 index 0000000..43d929f --- /dev/null +++ b/.idea/artifacts/Client.xml @@ -0,0 +1,22 @@ + + + $PROJECT_DIR$/out/artifacts/Client + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/artifacts/Client_jar.xml b/.idea/artifacts/Client_jar.xml deleted file mode 100644 index 4de7eb1..0000000 --- a/.idea/artifacts/Client_jar.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts/Client_jar - - - - - \ No newline at end of file diff --git a/Client/src/META-INF/MANIFEST.MF b/Client/src/META-INF/MANIFEST.MF index d3e52b4..b851779 100644 --- a/Client/src/META-INF/MANIFEST.MF +++ b/Client/src/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: networking.Client +Main-Class: game.TicTacToe_Client diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.css b/Client/src/game/TicTacToe_Client.css similarity index 100% rename from Client/src/games/TicTacToe/TicTacToe_Client.css rename to Client/src/game/TicTacToe_Client.css diff --git a/Client/src/games/TicTacToe/TicTacToe_Client.java b/Client/src/game/TicTacToe_Client.java similarity index 80% rename from Client/src/games/TicTacToe/TicTacToe_Client.java rename to Client/src/game/TicTacToe_Client.java index 5828e0a..aee4a00 100644 --- a/Client/src/games/TicTacToe/TicTacToe_Client.java +++ b/Client/src/game/TicTacToe_Client.java @@ -1,4 +1,4 @@ -package games.TicTacToe; +package game; import javafx.application.Application; import javafx.event.EventHandler; @@ -26,8 +26,6 @@ public class TicTacToe_Client extends Application { grid.setGridLinesVisible(true); } - - private void drawCross(int column, int row){ Text cross = new Text("X"); cross.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200)); @@ -40,7 +38,6 @@ public class TicTacToe_Client extends Application { grid.add(circle, column, row); } - private void drawEmptyField(int column, int row) { Text emptyField = new Text(" "); emptyField.setFont(Font.font("Tahoma", FontWeight.NORMAL, 200)); @@ -53,8 +50,8 @@ public class TicTacToe_Client extends Application { return; } for (int i = 0; i < gameState.length(); i++){ - int column = i % 3; - int row = i / 3; + int column = i / 3; + int row = i % 3; if (gameState.charAt(i) == 'x'){ this.drawCross(column, row); } else if (gameState.charAt(i) == 'o'){ @@ -73,8 +70,16 @@ public class TicTacToe_Client extends Application { scene.setOnMousePressed(new EventHandler() { @Override public void handle(MouseEvent event) { - client.sendToServer(String.format("(%f|%f)", event.getX(), event.getY())); - client.getGameState(); + client.sendToServer("update"); + client.sendToServer(String.format("%f|%f", event.getX(), event.getY())); + String gameState = client.getResponse(); + if (gameState.length() == 9) { + drawBoard(gameState); + } else { + int column = (int) event.getX() / 300; + int row = (int) event.getY() / 300; + System.err.printf("You are not allowed to place at %f|%f%n", column, row); + } } }); return scene; @@ -82,6 +87,9 @@ public class TicTacToe_Client extends Application { @Override public void start(Stage primaryStage) { + client = new Client("localhost", 2589, "TestClient"); + client.handshake(); + primaryStage.setTitle("TicTacToe"); primaryStage.setResizable(false); @@ -91,10 +99,7 @@ public class TicTacToe_Client extends Application { primaryStage.show(); - this.drawBoard("---------"); - - client = new Client("localhost", 2589, "TestClient"); - client.handshake(); + this.drawBoard(client.getGameState()); } public static void main(String[] args) { diff --git a/Client/src/games/TicTacToe/TicTacToe_Grid.png b/Client/src/game/TicTacToe_Grid.png similarity index 100% rename from Client/src/games/TicTacToe/TicTacToe_Grid.png rename to Client/src/game/TicTacToe_Grid.png diff --git a/Client/src/networking/Client.java b/Client/src/networking/Client.java index bf6ab0c..ebb1a7c 100644 --- a/Client/src/networking/Client.java +++ b/Client/src/networking/Client.java @@ -2,6 +2,8 @@ package networking; import logging.ClientLogger; import logging.LogType; + +import javax.swing.*; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -37,8 +39,9 @@ public class Client { out.writeInt(165313125); out.flush(); success = in.readInt() == 200; - if (success){ + if (success) { out.writeUTF(name); + out.flush(); serverName = in.readUTF(); clientLogger.printLog("You successfully connected to me", serverName, success, LogType.Log); } else { @@ -55,18 +58,37 @@ public class Client { out.writeUTF(message); out.flush(); success = in.readInt() == 200; + clientLogger.printLog(String.format("Sent the message: %s", message), serverName, success, LogType.Log); } catch (IOException e) { e.printStackTrace(); } } - public String getGameState(){ + public String getResponse() { try { - out.writeUTF("gamestate"); - return in.readUTF(); + String message = in.readUTF(); + clientLogger.printLog(String.format("Message recieved: %s", message), serverName, success, LogType.Log); + return message; + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } + + public String getGameState() { + this.sendToServer("gameState"); + String gameState = this.getResponse(); + return gameState; + } + + public void exitProcess(){ + try { + out.writeUTF("exit()"); + out.flush(); + success = in.readInt()==200; + clientLogger.printLog("Closing connection to server", serverName, success, LogType.Log); } catch (IOException e) { e.printStackTrace(); - return ""; } } @@ -74,6 +96,8 @@ public class Client { return success; } - public String getName(){return name;} + public String getName() { + return name; + } } \ No newline at end of file diff --git a/Server/res/META-INF/MANIFEST.MF b/Server/res/META-INF/MANIFEST.MF new file mode 100644 index 0000000..9ae8574 --- /dev/null +++ b/Server/res/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: networking.Server + diff --git a/Server/src/game/TicTacToe_Server.java b/Server/src/game/TicTacToe_Server.java new file mode 100644 index 0000000..f7220fa --- /dev/null +++ b/Server/src/game/TicTacToe_Server.java @@ -0,0 +1,41 @@ +package game; + +import java.nio.charset.StandardCharsets; + +public class TicTacToe_Server { + + private String gameState; + + public TicTacToe_Server(){ + gameState = "---------"; + } + + public void setGameState(String gameState) { + this.gameState = gameState; + } + + public String getGameState() { + return gameState; + } + + public int makeClientMove(String input) { + int column = Double.valueOf(input.split("\\|")[0]).intValue() / 300; + int row = Double.valueOf(input.split("\\|")[1]).intValue() / 300; + int index = column * 3 + row; + + if (isLegalMove(column, row)) { + byte[] gameStateBytes = gameState.getBytes(); + gameStateBytes[index] = (byte) 'x'; + gameState = new String(gameStateBytes, StandardCharsets.UTF_8); + return 200; + } else { + return 404; + } + } + + private boolean isLegalMove(int column, int row){ + int index = column * 3 + row; + return gameState.charAt(index) == '-'; + } + +} diff --git a/Server/src/networking/Server.java b/Server/src/networking/Server.java index 5f4b2fe..9b15e51 100644 --- a/Server/src/networking/Server.java +++ b/Server/src/networking/Server.java @@ -1,5 +1,6 @@ package networking; +import game.TicTacToe_Server; import logging.LogType; import logging.ServerLogger; @@ -15,7 +16,8 @@ public class Server { private HashMap clientNames; private HashMap outstreams; private HashMap instreams; - private ServerLogger logger; + private TicTacToe_Server ticTacToe_server; + private ServerLogger serverLogger; private Scanner scanner; private int requiredConnections; @@ -26,11 +28,12 @@ public class Server { clientNames = new HashMap<>(); outstreams = new HashMap<>(); instreams = new HashMap<>(); + ticTacToe_server = new TicTacToe_Server(); scanner = new Scanner(System.in); - logger = new ServerLogger(); + serverLogger = new ServerLogger(); requiredConnections = 1; - logger.printLog("Server started successfully", LogType.Log); + serverLogger.printLog("Server started successfully", LogType.Log); } catch (IOException e) { e.printStackTrace(); } @@ -39,7 +42,7 @@ public class Server { public void connectClients(){ try { int id = 0; - logger.printLog(String.format("Waiting for %d clients to connect ...", requiredConnections), LogType.Log); + serverLogger.printLog(String.format("Waiting for %d clients to connect ...", requiredConnections), LogType.Log); while(clients.size() < requiredConnections) { Socket momentaryClient = serverSocket.accept(); clients.put(id, momentaryClient); @@ -62,7 +65,7 @@ public class Server { clientNames.put(client, instreams.get(client).readUTF()); outstreams.get(client).writeUTF(serverSocket.getInetAddress().getHostAddress()+":"+serverSocket.getLocalPort()); outstreams.get(client).flush(); - logger.printLog(String.format("%s got connected", clientNames.get(client)), LogType.Log); + serverLogger.printLog(String.format("%s got connected", clientNames.get(client)), LogType.Log); } else { outstreams.get(client).writeInt(403); outstreams.get(client).flush(); @@ -74,19 +77,16 @@ public class Server { } } - public void getMessages(){ + public void ticTacToe_gameloop(){ for (Socket client: clients.values()) { try { - while (true) { + while (!client.isClosed()) { String message = instreams.get(client).readUTF(); - if (!message.equalsIgnoreCase("exit()")) { - logger.printLog(message, clientNames.get(client), LogType.Message); - } else { - outstreams.get(client).writeInt(200); - logger.printLog(String.format("%s closed the connection",clientNames.get(client)), LogType.Log); - break; - } + serverLogger.printLog(message, clientNames.get(client), LogType.Message); outstreams.get(client).writeInt(200); + outstreams.get(client).flush(); + serverLogger.printLog("Sent verification code", clientNames.get(client), LogType.Log); + this.gameFlow(message, client); } } catch (IOException e) { e.printStackTrace(); @@ -97,10 +97,56 @@ public class Server { } } } - clients.clear(); - System.out.println("Do you want to keep the server alive and wait for other clients ? [y]/[n]"); - if (scanner.nextLine().equalsIgnoreCase("y")){ - this.connectClients(); + } + + public void gameFlow(String input, Socket client){ + switch (input){ + case "gameState": + try { + outstreams.get(client).writeUTF(ticTacToe_server.getGameState()); + outstreams.get(client).flush(); + serverLogger.printLog("Sent gameState", clientNames.get(client), LogType.Log); + break; + } catch (IOException e) { + e.printStackTrace(); + } + + case "update": + try { + String position = instreams.get(client).readUTF(); + serverLogger.printLog(position, clientNames.get(client), LogType.Message); + outstreams.get(client).writeInt(200); + outstreams.get(client).flush(); + serverLogger.printLog("Sent verification code", clientNames.get(client), LogType.Log); + int verificationCode = ticTacToe_server.makeClientMove(position); + if (verificationCode == 200) { + String gameState = ticTacToe_server.getGameState(); + outstreams.get(client).writeUTF(gameState); + outstreams.get(client).flush(); + serverLogger.printLog(String.format("Sent gameState: %s", gameState), clientNames.get(client), LogType.Log); + break; + } else { + outstreams.get(client).writeUTF(" "); + outstreams.get(client).flush(); + serverLogger.printLog(String.format("Move is not allowed!"), clientNames.get(client), LogType.Error); + break; + } + } catch (IOException e) { + e.printStackTrace(); + } + + case "exit()": + try { + outstreams.get(client).writeInt(200); + outstreams.get(client).flush(); + outstreams.get(client).close(); + instreams.get(client).close(); + client.close(); + serverLogger.printLog(String.format("%s closed the connection",clientNames.get(client)), LogType.Log); + break; + } catch (IOException e) { + e.printStackTrace(); + } } } @@ -108,6 +154,6 @@ public class Server { Server server = new Server(2589); server.connectClients(); server.handshake(); - server.getMessages(); + server.ticTacToe_gameloop(); } } \ No newline at end of file diff --git a/out/artifacts/Client/Client.html b/out/artifacts/Client/Client.html new file mode 100644 index 0000000..af4b518 --- /dev/null +++ b/out/artifacts/Client/Client.html @@ -0,0 +1,43 @@ + + + + + + + +

Test page for Client

+ Webstart: click to launch this app as webstart


+ + +
+ diff --git a/out/artifacts/Client/Client.jnlp b/out/artifacts/Client/Client.jnlp new file mode 100644 index 0000000..eff4374 --- /dev/null +++ b/out/artifacts/Client/Client.jnlp @@ -0,0 +1,15 @@ + + + + Client + Unknown + Client + + + + + + + + + diff --git a/out/production/Client/META-INF/MANIFEST.MF b/out/production/Client/META-INF/MANIFEST.MF index d3e52b4..b851779 100644 --- a/out/production/Client/META-INF/MANIFEST.MF +++ b/out/production/Client/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: networking.Client +Main-Class: game.TicTacToe_Client diff --git a/out/production/Client/games/TicTacToe/Login.css b/out/production/Client/game/TicTacToe_Client.css similarity index 100% rename from out/production/Client/games/TicTacToe/Login.css rename to out/production/Client/game/TicTacToe_Client.css diff --git a/out/production/Client/games/TicTacToe/TicTacToe_Grid.png b/out/production/Client/game/TicTacToe_Grid.png similarity index 100% rename from out/production/Client/games/TicTacToe/TicTacToe_Grid.png rename to out/production/Client/game/TicTacToe_Grid.png