Combined SingleServer and MultiServer into one class

This commit is contained in:
2021-03-20 16:30:54 +01:00
parent fa7bda4230
commit 1b4bcd1ec2
16 changed files with 115 additions and 339 deletions

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: networking.TicTacToe_Server

View File

@@ -1,3 +0,0 @@
Manifest-Version: 1.0
Main-Class: networking.SinglePlayerServer

View File

@@ -1,229 +0,0 @@
package networking;
import res.TicTacToe_Server;
import logging.LogType;
import logging.ServerLogger;
import java.awt.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
public class MultiPlayerServer {
private ServerSocket serverSocket;
private HashMap<Integer, Socket> clients;
private HashMap<Socket, String> clientNames;
private HashMap<Socket, DataOutputStream> outstreams;
private HashMap<Socket, DataInputStream> instreams;
private TicTacToe_Server ticTacToe_server;
private ServerLogger serverLogger;
private Scanner scanner;
private int requiredConnections;
public MultiPlayerServer(int port) {
try {
serverSocket = new ServerSocket(port);
clients = new HashMap<>();
clientNames = new HashMap<>();
outstreams = new HashMap<>();
instreams = new HashMap<>();
ticTacToe_server = new TicTacToe_Server();
scanner = new Scanner(System.in);
serverLogger = new ServerLogger();
requiredConnections = 2;
serverLogger.printLog("Server started successfully", LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
}
public void connectClients() {
try {
int id = 0;
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);
outstreams.put(momentaryClient, new DataOutputStream(momentaryClient.getOutputStream()));
instreams.put(momentaryClient, new DataInputStream(momentaryClient.getInputStream()));
id++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void handshake() {
for (Socket client : clients.values()) {
try {
int handshakeValue = instreams.get(client).readInt();
if (handshakeValue == 165313125) {
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
clientNames.put(client, instreams.get(client).readUTF());
serverLogger.printLog(String.format("Client \"%s\" got connected", clientNames.get(client)), LogType.Log);
} else {
outstreams.get(client).writeInt(403);
outstreams.get(client).flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void ticTacToe_gameloop() {
while (clients.size() == 2) {
for (Socket client : clients.values()) {
try {
String message = instreams.get(client).readUTF();
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();
try {
client.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
}
public void sendGameState(){
try {
int index = 0;
for (DataOutputStream outstream: outstreams.values()) {
outstream.writeUTF(ticTacToe_server.getGameState());
outstream.flush();
serverLogger.printLog("Sent gameState", clientNames.get(index), LogType.Log);
index++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void gameFlow(String input, Socket client){
switch (input){
case "ready":
gameFlow("gameState", client);
break;
case "gameState":
sendGameState();
break;
case "clientMove":
try {
//Get position (X|Y)
String position = instreams.get(client).readUTF();
serverLogger.printLog(position, clientNames.get(client), LogType.Message);
//Send confirmation (2ßß)
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
serverLogger.printLog("Sent verification code", clientNames.get(client), LogType.Log);
boolean moveAllowed = ticTacToe_server.makeClientMove(position);
if (moveAllowed) {
sendGameState();
} else {
//send " "
outstreams.get(client).writeUTF("userInput");
outstreams.get(client).flush();
serverLogger.printLog("Requested userInput", LogType.Log);
serverLogger.printLog(String.format("Move is not allowed!"), clientNames.get(client), LogType.Error);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
case "computerMove":
ticTacToe_server.makeComputerMove();
sendGameState();
try {
outstreams.get(client).writeUTF("userInput");
outstreams.get(client).flush();
serverLogger.printLog("Requested userInput", LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
break;
case "serverType":
try {
outstreams.get(client).writeBoolean(true);
outstreams.get(client).flush();
serverLogger.printLog("Sent serverType", clientNames.get(client), LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
break;
case "isClientOne":
for (Map.Entry<Integer, Socket> entry : clients.entrySet()) {
if (Objects.equals(client, entry.getValue())) {
try {
outstreams.get(client).writeBoolean(entry.getKey() == 0);
outstreams.get(client).flush();
serverLogger.printLog("Sent isPlayerOne", clientNames.get(client), LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
case "gameEnded":
try {
boolean gameEnded = ticTacToe_server.gameEnded();
outstreams.get(client).writeBoolean(gameEnded);
if (gameEnded) {
//send coordinates
String coordinates = "";
for (Point point: ticTacToe_server.getWinCoordinates()) {
coordinates += point.x + ";" + point.y + ";";
}
//send winning fields
outstreams.get(client).writeUTF(coordinates);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
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);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
public static void main(String[] args) {
MultiPlayerServer server = new MultiPlayerServer(2589);
server.connectClients();
server.handshake();
server.ticTacToe_gameloop();
}
}

View File

@@ -1,8 +1,8 @@
package networking;
import res.TicTacToe_Server;
import logging.LogType;
import logging.ServerLogger;
import res.TicTacToe_GameRules;
import java.awt.*;
import java.io.DataInputStream;
@@ -13,30 +13,31 @@ import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
public class SinglePlayerServer {
public class TicTacToe_Server {
private ServerSocket serverSocket;
private HashMap<Integer, Socket> clients;
private HashMap<Socket, String> clientNames;
private HashMap<Socket, Boolean> clientMoveAuthorizations;
private HashMap<Socket, DataOutputStream> outstreams;
private HashMap<Socket, DataInputStream> instreams;
private TicTacToe_Server ticTacToe_server;
private TicTacToe_GameRules ticTacToe_gameRules;
private ServerLogger serverLogger;
private Scanner scanner;
private int requiredConnections;
public SinglePlayerServer(int port){
public TicTacToe_Server(int port, int requiredConnections) {
try {
serverSocket = new ServerSocket(port);
clients = new HashMap<>();
clientNames = new HashMap<>();
clientMoveAuthorizations = new HashMap<>();
outstreams = new HashMap<>();
instreams = new HashMap<>();
ticTacToe_server = new TicTacToe_Server();
scanner = new Scanner(System.in);
ticTacToe_gameRules = new TicTacToe_GameRules();
serverLogger = new ServerLogger();
requiredConnections = 1;
this.requiredConnections = requiredConnections;
serverLogger.printLog("Server started successfully", LogType.Log);
} catch (IOException e) {
@@ -44,11 +45,15 @@ public class SinglePlayerServer {
}
}
public void connectClients(){
private boolean isSingleServer() {
return requiredConnections == 1;
}
public void connectClients() {
try {
int id = 0;
serverLogger.printLog(String.format("Waiting for %d clients to connect ...", requiredConnections), LogType.Log);
while(clients.size() < requiredConnections) {
while (clients.size() < requiredConnections) {
Socket momentaryClient = serverSocket.accept();
clients.put(id, momentaryClient);
outstreams.put(momentaryClient, new DataOutputStream(momentaryClient.getOutputStream()));
@@ -60,15 +65,15 @@ public class SinglePlayerServer {
}
}
public void handshake(){
for (Socket client: clients.values()) {
public void handshake() {
for (Socket client : clients.values()) {
try {
int handshakeValue = instreams.get(client).readInt();
if (handshakeValue == 165313125) {
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
clientNames.put(client, instreams.get(client).readUTF());
serverLogger.printLog(String.format("Client: \"%s\" got connected", clientNames.get(client)), LogType.Log);
serverLogger.printLog(String.format("Client \"%s\" got connected", clientNames.get(client)), LogType.Log);
} else {
outstreams.get(client).writeInt(403);
outstreams.get(client).flush();
@@ -80,32 +85,15 @@ public class SinglePlayerServer {
}
}
public void ticTacToe_gameloop(){
for (Socket client: clients.values()) {
try {
while (!client.isClosed()) {
//Get instruction
String message = instreams.get(client).readUTF();
serverLogger.printLog(message, clientNames.get(client), LogType.Message);
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
serverLogger.printLog("Sent verification code", "200", clientNames.get(client), LogType.Log);
this.gameFlow(message, client);
}
} catch (IOException e) {
e.printStackTrace();
try {
client.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public void sendGameState() {
for (Socket client : clients.values()) {
sendGameState(client);
}
}
public void sendGameState(Socket client){
public void sendGameState(Socket client) {
try {
String gameState = ticTacToe_server.getGameState();
String gameState = ticTacToe_gameRules.getGameState();
outstreams.get(client).writeUTF(gameState);
outstreams.get(client).flush();
serverLogger.printLog("Sent gameState", gameState, clientNames.get(client), LogType.Log);
@@ -114,28 +102,59 @@ public class SinglePlayerServer {
}
}
public void gameFlow(String input, Socket client){
switch (input){
public String handleInput(Socket client){
String message = null;
try {
message = instreams.get(client).readUTF();
serverLogger.printLog(message, clientNames.get(client), LogType.Message);
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
serverLogger.printLog("Sent verification code", "200", clientNames.get(client), LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
return message;
}
public void ticTacToe_gameloop() {
if (isSingleServer()) {
Socket client = clients.get(0);
//SingleServer GameLoop
while (!client.isClosed()) {
//Get instruction
this.gameFlow(handleInput(client), client);
}
} else {
//MultiServer GameLoop
gameFlow("gameState");
}
}
public void gameFlow(String input){
this.gameFlow(input, null);
}
public void gameFlow(String input, Socket client) {
switch (input) {
case "ready":
gameFlow("gameState", client);
if (isSingleServer()){
sendGameState();
} else {
sendGameState(client);
}
break;
case "gameState":
sendGameState(client);
sendGameState();
break;
case "clientMove":
try {
//Get position (X|Y)
String position = instreams.get(client).readUTF();
serverLogger.printLog(position, clientNames.get(client), LogType.Message);
//Send confirmation (2ßß)
outstreams.get(client).writeInt(200);
outstreams.get(client).flush();
serverLogger.printLog("Sent verification code", "200", clientNames.get(client), LogType.Log);
boolean moveAllowed = ticTacToe_server.makeClientMove(position);
String position = handleInput(client);
boolean moveAllowed = ticTacToe_gameRules.makeClientMove(position);
if (moveAllowed) {
sendGameState(client);
sendGameState();
} else {
//send " "
outstreams.get(client).writeUTF("userInput");
@@ -149,8 +168,8 @@ public class SinglePlayerServer {
break;
case "computerMove":
ticTacToe_server.makeComputerMove();
sendGameState(client);
ticTacToe_gameRules.makeComputerMove();
sendGameState();
try {
outstreams.get(client).writeUTF("userInput");
outstreams.get(client).flush();
@@ -189,12 +208,12 @@ public class SinglePlayerServer {
case "gameEnded":
try {
boolean gameEnded = ticTacToe_server.gameEnded();
boolean gameEnded = ticTacToe_gameRules.gameEnded();
outstreams.get(client).writeBoolean(gameEnded);
if (gameEnded) {
//send coordinates
String coordinates = "";
for (Point point: ticTacToe_server.getWinCoordinates()) {
for (Point point : ticTacToe_gameRules.getWinCoordinates()) {
coordinates += point.x + ";" + point.y + ";";
}
//send winning fields
@@ -211,23 +230,24 @@ public class SinglePlayerServer {
outstreams.get(client).close();
instreams.get(client).close();
client.close();
serverLogger.printLog(String.format("%s closed the connection",clientNames.get(client)), LogType.Log);
serverLogger.printLog(String.format("%s closed the connection", clientNames.get(client)), LogType.Log);
} catch (IOException e) {
e.printStackTrace();
}
break;
case "reset":
ticTacToe_server.resetGameState();
this.sendGameState(client);
ticTacToe_gameRules.resetGameState();
this.sendGameState();
break;
}
}
public static void main(String[] args) {
SinglePlayerServer server = new SinglePlayerServer(2589);
TicTacToe_Server server = new TicTacToe_Server(2589, Integer.valueOf(args[0]));
server.connectClients();
server.handshake();
server.ticTacToe_gameloop();
}
}
}

View File

@@ -5,13 +5,13 @@ import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.Random;
public class TicTacToe_Server {
public class TicTacToe_GameRules {
private String gameState;
private Integer[][] board;
Point startWin, endWin;
public TicTacToe_Server(){
public TicTacToe_GameRules(){
gameState = "---------";
}