Basics of client server communication and drawing of gamestates finished
This commit is contained in:
22
.idea/artifacts/Client.xml
generated
Normal file
22
.idea/artifacts/Client.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="javafx" name="Client">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/Client</output-path>
|
||||
<properties id="javafx-properties">
|
||||
<options>
|
||||
<option name="appClass" value="game.TicTacToe_Client" />
|
||||
<option name="description" value="" />
|
||||
<option name="height" value="" />
|
||||
<option name="htmlPlaceholderId" value="" />
|
||||
<option name="title" value="" />
|
||||
<option name="vendor" value="" />
|
||||
<option name="version" value="" />
|
||||
<option name="width" value="" />
|
||||
</options>
|
||||
</properties>
|
||||
<root id="root">
|
||||
<element id="archive" name="Client.jar">
|
||||
<element id="module-output" name="Client" />
|
||||
</element>
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
8
.idea/artifacts/Client_jar.xml
generated
8
.idea/artifacts/Client_jar.xml
generated
@@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="Client:jar">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/Client_jar</output-path>
|
||||
<root id="archive" name="Client.jar">
|
||||
<element id="module-output" name="Client" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
@@ -1,3 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: networking.Client
|
||||
Main-Class: game.TicTacToe_Client
|
||||
|
||||
|
||||
@@ -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<MouseEvent>() {
|
||||
@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) {
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -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;
|
||||
@@ -39,6 +41,7 @@ public class Client {
|
||||
success = in.readInt() == 200;
|
||||
if (success) {
|
||||
out.writeUTF(name);
|
||||
out.flush();
|
||||
serverName = in.readUTF();
|
||||
clientLogger.printLog("You successfully connected to me", serverName, success, LogType.Log);
|
||||
} else {
|
||||
@@ -55,25 +58,46 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasSucceeded() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public String getName(){return name;}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
3
Server/res/META-INF/MANIFEST.MF
Normal file
3
Server/res/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: networking.Server
|
||||
|
||||
41
Server/src/game/TicTacToe_Server.java
Normal file
41
Server/src/game/TicTacToe_Server.java
Normal file
@@ -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) == '-';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Socket, String> clientNames;
|
||||
private HashMap<Socket, DataOutputStream> outstreams;
|
||||
private HashMap<Socket, DataInputStream> 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();
|
||||
}
|
||||
}
|
||||
43
out/artifacts/Client/Client.html
Normal file
43
out/artifacts/Client/Client.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<html><head>
|
||||
<SCRIPT src="http://java.com/js/dtjava.js"></SCRIPT>
|
||||
<script>
|
||||
function launchApplication(jnlpfile) {
|
||||
dtjava.launch( {
|
||||
url : 'Client.jnlp'
|
||||
},
|
||||
{
|
||||
javafx : '8.0+'
|
||||
},
|
||||
{}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function javafxEmbedClient_id() {
|
||||
dtjava.embed(
|
||||
{
|
||||
id : 'Client_id',
|
||||
url : 'Client.jnlp',
|
||||
placeholder : 'javafx-app-placeholder',
|
||||
width : '900',
|
||||
height : '900'
|
||||
},
|
||||
{
|
||||
javafx : '8.0+'
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
<!-- Embed FX application into web page once page is loaded -->
|
||||
dtjava.addOnloadCallback(javafxEmbedClient_id);
|
||||
</script>
|
||||
|
||||
</head><body>
|
||||
<h2>Test page for <b>Client</b></h2>
|
||||
<b>Webstart:</b> <a href='Client.jnlp' onclick="return launchApplication('Client.jnlp');">click to launch this app as webstart</a><br><hr><br>
|
||||
|
||||
<!-- Applet will be inserted here -->
|
||||
<div id='javafx-app-placeholder'></div>
|
||||
</body></html>
|
||||
15
out/artifacts/Client/Client.jnlp
Normal file
15
out/artifacts/Client/Client.jnlp
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="Client.jnlp">
|
||||
<information>
|
||||
<title>Client</title>
|
||||
<vendor>Unknown</vendor>
|
||||
<description>Client</description>
|
||||
<offline-allowed/>
|
||||
</information>
|
||||
<resources>
|
||||
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
|
||||
<jar href="Client.jar" size="9642" download="eager" />
|
||||
</resources>
|
||||
<jfx:javafx-desc width="900" height="900" main-class="game.TicTacToe_Client" name="Client" />
|
||||
<update check="background"/>
|
||||
</jnlp>
|
||||
@@ -1,3 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: networking.Client
|
||||
Main-Class: game.TicTacToe_Client
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Reference in New Issue
Block a user