merge with master

Squashed commit of the following:

commit ec0d0c3531
Merge: cb2ef90 15492cb
Author: SemvdH <45453592+SemvdH@users.noreply.github.com>
Date:   Sat Jun 6 22:43:28 2020 +0200

    Merge pull request #10 from SemvdH/Connections

    Connections

commit 15492cb91d
Author: MickWerf <mickwerf@outlook.com>
Date:   Sat Jun 6 16:50:32 2020 +0200

    Fixed test build issue

commit 4b7eaaa641
Merge: 9349e6c c07c860
Author: MickWerf <mickwerf@outlook.com>
Date:   Sat Jun 6 16:47:59 2020 +0200

    Merge branch 'master' into Connections

    * master:
      optimize imports
      fixed memory leaks
      made only possible to select own factions characters
      made character only able to move in some position
      added character squares he can move
      added stuff
      add square to selected character

    # Conflicts:
    #	core/src/netwerkprog/game/client/MainGame.java
    #	core/src/netwerkprog/game/util/game/GameCharacter.java

commit 9349e6ce48
Author: MickWerf <mickwerf@outlook.com>
Date:   Sat Jun 6 16:42:44 2020 +0200

    Finished Server/Client registration and communications

commit 3dbffa4ffb
Author: MickWerf <mickwerf@outlook.com>
Date:   Sat Jun 6 15:44:53 2020 +0200

    Finished server side registration.

commit f942bbbc92
Author: MickWerf <mickwerf@outlook.com>
Date:   Sat Jun 6 15:02:45 2020 +0200

    Connections, Applied Data objects, removed parsers and Made genereric data handling
This commit is contained in:
Sem van der Hoeven
2020-06-06 22:50:47 +02:00
parent 272a3c6966
commit 8d99753f7c
15 changed files with 307 additions and 212 deletions

View File

@@ -1,104 +0,0 @@
package netwerkprog.game.client;
import netwerkprog.game.util.application.Controller;
import netwerkprog.game.util.data.Data;
import netwerkprog.game.util.data.ParserCallback;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;
public class Client extends Controller implements ParserCallback {
private final int port;
private final String hostname;
private final Parser parser;
private boolean isConnected = true;
private Socket socket;
private Thread receiveThread;
private DataOutputStream outputStream;
public Client(String hostname) {
this.port = Data.port();
this.hostname = hostname;
this.parser = new Parser(this);
}
/**
* Starts the client process.
*/
@Override
public void run() {
this.connect();
this.receiveThread.start();
}
/**
* Connects the client to the server.
*/
public void connect() {
System.out.println("[CLIENT] connecting to server on port " + this.port);
try {
this.socket = new Socket(this.hostname, this.port);
DataInputStream in = new DataInputStream(socket.getInputStream());
this.outputStream = new DataOutputStream(socket.getOutputStream());
this.receiveThread = new Thread( () -> receive(in));
} catch (IOException e) {
System.out.println("[CLIENT] there was an error connecting : " + e.getMessage());
StringBuilder sb = new StringBuilder(" Stacktrace : ");
Arrays.stream(e.getStackTrace()).forEach(n -> sb.append("\t\t").append(n).append("\n"));
System.out.println(sb.toString());
}
}
/**
* Sends a message to the server.
* @param message The message to send.
*/
public void send(String message) {
try {
this.outputStream.writeUTF(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Receives a message from the server.
* @param in The inputStream
*/
public void receive(DataInputStream in) {
while (isConnected) {
try {
this.parser.parse(in.readUTF());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void disconnect() {
this.isConnected = false;
try {
this.receiveThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
send("Disconnect");
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDataReceived(String data) {
System.out.println(data);
}
}

View File

@@ -18,10 +18,13 @@ import netwerkprog.game.client.game.characters.Agent;
import netwerkprog.game.client.game.characters.Hacker;
import netwerkprog.game.client.game.characters.Team;
import netwerkprog.game.client.game.characters.abilities.BodySwap;
import netwerkprog.game.client.game.connections.Client;
import netwerkprog.game.client.game.map.GameInputProcessor;
import netwerkprog.game.client.game.map.GameTile;
import netwerkprog.game.client.game.map.Map;
import netwerkprog.game.client.game.map.MapRenderer;
import netwerkprog.game.util.data.Data;
import netwerkprog.game.util.data.DataCallback;
import netwerkprog.game.util.game.Faction;
import netwerkprog.game.util.game.GameCharacter;
import netwerkprog.game.util.graphics.FrameRate;
@@ -29,7 +32,7 @@ import netwerkprog.game.util.graphics.TextRenderer;
import java.awt.*;
public class MainGame extends ApplicationAdapter {
public class MainGame extends ApplicationAdapter implements DataCallback {
SpriteBatch batch;
float screenWidth;
float screenHeight;
@@ -106,7 +109,7 @@ public class MainGame extends ApplicationAdapter {
// playSong();
// connectToServer();
connectToServer();
}
public void initCharacters() {
@@ -155,7 +158,7 @@ public class MainGame extends ApplicationAdapter {
private void connectToServer() {
client = new Thread(new Client("localhost"));
client = new Thread(new Client("localhost", this));
try {
client.start();
} catch (Exception e) {
@@ -285,4 +288,8 @@ public class MainGame extends ApplicationAdapter {
return team;
}
@Override
public void onDataReceived(Data data) {
}
}

View File

@@ -1,15 +0,0 @@
package netwerkprog.game.client;
import netwerkprog.game.util.data.ParserCallback;
public class Parser {
private final ParserCallback callback;
public Parser(ParserCallback callback) {
this.callback = callback;
}
public void parse(String data) {
callback.onDataReceived(data);
}
}

View File

@@ -0,0 +1,127 @@
package netwerkprog.game.client.game.connections;
import netwerkprog.game.util.application.Controller;
import netwerkprog.game.util.data.ConnectionData;
import netwerkprog.game.util.data.Data;
import netwerkprog.game.util.data.DataCallback;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Arrays;
public class Client extends Controller {
private final int port;
private final String hostname;
private boolean isConnected;
private Socket socket;
private Thread receiveThread;
private DataCallback callback;
private ObjectOutputStream outputStream;
private boolean connecting;
public Client(String hostname, DataCallback callback) {
this.port = Data.port();
this.hostname = hostname;
this.callback = callback;
}
/**
* Starts the client process.
*/
@Override
public void run() {
this.connect();
this.receiveThread.start();
}
/**
* Connects the client to the server.
*/
public void connect() {
System.out.println("[CLIENT] connecting to server on port " + this.port);
this.connecting = true;
try {
this.socket = new Socket(this.hostname, this.port);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
this.outputStream = new ObjectOutputStream(socket.getOutputStream());
register(in);
this.receiveThread = new Thread( () -> receive(in));
} catch (IOException e) {
this.connecting = false;
System.out.println("[CLIENT] there was an error connecting : " + e.getMessage());
StringBuilder sb = new StringBuilder(" Stacktrace : ");
Arrays.stream(e.getStackTrace()).forEach(n -> sb.append("\t\t").append(n).append("\n"));
System.out.println(sb.toString());
}
}
public void register(ObjectInputStream in) {
while (connecting) {
String username = "DEV";
send(new ConnectionData("Connect", username));
try {
Object object = in.readObject();
if (object instanceof Data) {
Data data = (Data) object;
if (data.getPayload() instanceof ConnectionData) {
ConnectionData connectionData = (ConnectionData) data.getPayload();
if (connectionData.getAction().equals("Connect") && connectionData.getMessage().equals("Confirm")){
this.connecting = false;
this.isConnected = true;
}
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* Sends a message to the server.
* @param data The message to send.
*/
public void send(Data data) {
try {
this.outputStream.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Receives a message from the server.
* @param in The inputStream
*/
public void receive(ObjectInputStream in) {
while (isConnected) {
try {
Object object = in.readObject();
if (object instanceof Data) {
callback.onDataReceived((Data) object);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public void disconnect() {
this.isConnected = false;
try {
this.receiveThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
send(new ConnectionData("Disconnect", "DEV"));
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,43 +0,0 @@
package netwerkprog.game.server;
import netwerkprog.game.client.game.characters.DevTest1;
import netwerkprog.game.client.game.characters.DevTest2;
import netwerkprog.game.client.game.characters.DevTest3;
import netwerkprog.game.server.controllers.DataController;
import netwerkprog.game.util.data.ParserCallback;
import java.util.Scanner;
public class Parser {
private final ParserCallback callback;
private Scanner scanner;
private final DataController dataController;
public Parser(ParserCallback callback) {
this.callback = callback;
this.dataController = new DataController();
this.dataController.addAllCharacters(new DevTest1(), new DevTest2(), new DevTest3());
}
public void parse(String request) {
String data = "";
this.scanner = new Scanner(request);
scanner.useDelimiter("~");
String type = scanner.next();
String name = scanner.next();
if (type.equals("character")) {
try {
data = dataController.getCharacter(name).toString();
} catch (IllegalArgumentException ex) {
data = ex.getMessage();
}
}
callback.onDataReceived(data);
}
}

View File

@@ -1,16 +1,19 @@
package netwerkprog.game.server;
import netwerkprog.game.server.controllers.DataController;
import netwerkprog.game.server.controllers.SessionController;
import java.util.HashMap;
public class Server {
private SessionController sessionController;
private DataController dataController;
private Thread sessionThread;
private HashMap<String, Thread> gameThreads;
public void start() {
this.sessionController = new SessionController();
this.sessionController = new SessionController(this);
this.dataController = new DataController();
this.gameThreads = new HashMap<>();
this.sessionThread = new Thread(sessionController);
@@ -32,4 +35,8 @@ public class Server {
// gameThreads.get(game).start();
// }
}
public DataController getDataController() {
return dataController;
}
}

View File

@@ -1,38 +1,35 @@
package netwerkprog.game.server;
import netwerkprog.game.server.controllers.DataController;
import netwerkprog.game.server.controllers.SessionController;
import netwerkprog.game.util.data.ParserCallback;
import netwerkprog.game.util.data.ConnectionData;
import netwerkprog.game.util.data.Data;
import netwerkprog.game.util.data.DataCallback;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ServerClient implements Runnable, ParserCallback {
private DataInputStream in;
private DataOutputStream out;
public class ServerClient implements Runnable {
private ObjectInputStream in;
private ObjectOutputStream out;
private final String name;
private final SessionController server;
private final Parser parser;
private final DataCallback callback;
private boolean isConnected;
public ServerClient(String name, Socket socket, SessionController server) {
public ServerClient(String name, ObjectInputStream in, ObjectOutputStream out, SessionController server, DataController dataController) {
this.name = name;
this.server = server;
this.parser = new Parser(this);
try {
this.in = new DataInputStream(socket.getInputStream());
this.out = new DataOutputStream(socket.getOutputStream());
this.isConnected = true;
} catch (IOException e) {
this.isConnected = false;
e.printStackTrace();
}
this.callback = dataController;
this.in = in;
this.out = out;
this.isConnected = true;
}
public void writeUTF(String text) {
public void writeData(Data data) {
try {
this.out.writeUTF(text);
this.out.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
@@ -42,14 +39,26 @@ public class ServerClient implements Runnable, ParserCallback {
public void run() {
while (this.isConnected) {
try {
String received = this.in.readUTF();
this.parser.parse(received);
Object object = this.in.readObject();
if (object instanceof Data) {
Data data = (Data) object;
if (data.getPayload() instanceof ConnectionData) {
ConnectionData connectionData = (ConnectionData) data.getPayload();
if (connectionData.getAction().equals("Disconnect")) {
this.isConnected = false;
//todo properly remove thread.
}
} else {
callback.onDataReceived((Data) this.in.readObject());
}
}
} catch (IOException e) {
System.out.println("[SERVERCLIENT] caught exception - " + e.getMessage());
System.out.println("[SERVERCLIENT] terminating failing connection...");
this.isConnected = false;
System.out.println("[SERVERCLIENT] done!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@@ -57,9 +66,4 @@ public class ServerClient implements Runnable, ParserCallback {
public String getName() {
return this.name;
}
@Override
public void onDataReceived(String data) {
writeUTF(data);
}
}

View File

@@ -1,11 +1,14 @@
package netwerkprog.game.server.controllers;
import netwerkprog.game.util.data.CharacterData;
import netwerkprog.game.util.data.Data;
import netwerkprog.game.util.data.DataCallback;
import netwerkprog.game.util.game.GameCharacter;
import java.util.Arrays;
import java.util.HashSet;
public class DataController {
public class DataController implements DataCallback {
private final HashSet<GameCharacter> gameCharacters;
public DataController() {
@@ -44,4 +47,15 @@ public class DataController {
}
throw new IllegalArgumentException("The character does not exist.");
}
@Override
public void onDataReceived(Data data) {
switch (data.getType()) {
case "Character" :
if (data.getPayload() instanceof CharacterData) {
}
break;
}
}
}

View File

@@ -1,11 +1,13 @@
package netwerkprog.game.server.controllers;
import netwerkprog.game.server.Server;
import netwerkprog.game.server.ServerClient;
import netwerkprog.game.util.application.Controller;
import netwerkprog.game.util.data.ConnectionData;
import netwerkprog.game.util.data.Data;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
@@ -17,12 +19,14 @@ import java.util.Set;
* The sessionController manages any connections from new clients and assigns individual threads to said clients.
*/
public class SessionController extends Controller {
private Server server;
private ServerSocket serverSocket;
private final ArrayList<ServerClient> clients = new ArrayList<>();
private final HashMap<String, Thread> clientThreads = new HashMap<>();
private boolean listening;
public SessionController() {
public SessionController(Server server) {
this.server = server;
this.listening = true;
}
@@ -59,43 +63,66 @@ public class SessionController extends Controller {
try {
System.out.println("[SERVER] got new client on " + socket.getInetAddress().getHostAddress());
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
outputStream.writeUTF("Enter username: ");
String username = inputStream.readUTF();
String username = "";
boolean registering = true;
while (registering) {
outputStream.writeObject(new ConnectionData("Connect", "Please give a username"));
Object object = inputStream.readObject();
if (object instanceof Data) {
Data data = (Data) object;
if (data instanceof ConnectionData) {
ConnectionData connectionData = (ConnectionData) data.getPayload();
if (connectionData.getAction().equals("Connect")) {
username = connectionData.getMessage();
outputStream.writeObject(new ConnectionData("Connect", "Confirm"));
registering = false;
} else {
//todo error messaging.
}
} else {
//todo error messaging.
}
} else {
//todo error messaging.
}
}
System.out.println("[SERVER] got username " + username);
ServerClient serverClient = new ServerClient(username, socket, this);
ServerClient serverClient = new ServerClient(username, inputStream, outputStream, this, server.getDataController());
Thread t = new Thread(serverClient);
t.start();
this.clientThreads.put(username,t);
this.clients.add(serverClient);
} catch (IOException ex) {
} catch (IOException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
/**
* Sends a server message to all connected clients.
* @param text message.
* @param data message.
*/
public void serverMessage(String text) {
public void serverMessage(Data data) {
for (ServerClient serverClient : clients) {
serverClient.writeUTF(text);
serverClient.writeData(data);
}
}
/**
* Sends a message to a specific user.
* @param name user.
* @param text message.
* @param data message.
*/
public void personalMessage(String name, String text) {
public void personalMessage(String name, Data data) {
for (ServerClient serverClient : clients) {
if (serverClient.getName().equals(name)) {
serverClient.writeUTF(text);
serverClient.writeData(data);
break;
}
}
@@ -113,7 +140,7 @@ public class SessionController extends Controller {
e.printStackTrace();
}
this.clientThreads.remove(serverClient.getName());
this.serverMessage(serverClient.getName() + " left!");
//this.serverMessage(serverClient.getName() + " left!");
}
/**

View File

@@ -0,0 +1,17 @@
package netwerkprog.game.util.data;
import netwerkprog.game.util.game.GameCharacter;
import java.io.Serializable;
public class CharacterData extends Data implements Serializable {
private final String name;
private final GameCharacter character;
public CharacterData(String name, GameCharacter character) {
super("Character");
super.setPayload(this);
this.name = name;
this.character = character;
}
}

View File

@@ -0,0 +1,23 @@
package netwerkprog.game.util.data;
import java.io.Serializable;
public class ConnectionData extends Data implements Serializable {
private final String action;
private final String message;
public ConnectionData(String action, String message) {
super("Connection");
super.setPayload(this);
this.action = action;
this.message = message;
}
public String getAction() {
return action;
}
public String getMessage() {
return message;
}
}

View File

@@ -1,7 +1,32 @@
package netwerkprog.game.util.data;
public class Data {
import java.io.Serializable;
public class Data implements Serializable {
public static int port() {
return 8000;
}
private String objectType;
private Data payload;
public Data(String type) {
this.objectType = type;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
public void setPayload(Data payload) {
this.payload = payload;
}
public String getType() {
return objectType;
}
public Data getPayload() {
return payload;
}
}

View File

@@ -0,0 +1,5 @@
package netwerkprog.game.util.data;
public interface DataCallback {
void onDataReceived(Data data);
}

View File

@@ -6,13 +6,14 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import netwerkprog.game.client.game.map.GameTile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
public abstract class GameCharacter extends Actor implements Comparable<GameCharacter> {
public abstract class GameCharacter extends Actor implements Comparable<GameCharacter>, Serializable {
protected String name;
protected Faction faction;
protected HashSet<Ability> abilities;

View File

@@ -8,7 +8,7 @@ public class RestartSessionControllerTest {
SessionController sessionController;
Thread sessionThread;
sessionController = new SessionController();
sessionController = new SessionController(null);
sessionThread = new Thread(sessionController);
sessionThread.start();