diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java index 79d2de3f..7c4bfea4 100644 --- a/src/main/java/seng302/client/ClientToServerThread.java +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -17,12 +17,15 @@ import seng302.server.messages.Message; */ public class ClientToServerThread implements Runnable { + private static final int LOG_LEVEL = 1; + private Thread thread; + private Integer ourID; + private Socket socket; private InputStream is; private OutputStream os; - private static final int LOG_LEVEL = 1; private Boolean updateClient = true; private ByteArrayOutputStream crcBuffer; @@ -36,6 +39,16 @@ public class ClientToServerThread implements Runnable { e.printStackTrace(); } + Integer allocatedID = threeWayHandshake(); + if (allocatedID != null) { + ourID = allocatedID; + clientLog("Successful handshake. Allocated ID: " + ourID, 1); + } else { + clientLog("Unsuccessful handhsake", 1); + closeSocket(); + return; + } + thread = new Thread(this); thread.start(); @@ -96,6 +109,33 @@ public class ClientToServerThread implements Runnable { } + + /** + * Listens for an allocated sourceID and returns it to the server if recieved + * @return the sourceID allocated to us by the server + */ + private Integer threeWayHandshake() { + Integer ourSourceID = null; + while (true) { + try { + ourSourceID = is.read(); + } catch (IOException e) { + e.printStackTrace(); + } + if (ourSourceID != null) { + try { + os.write(ourSourceID); + return ourSourceID; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + } + } + + + /** * Send the post-start race course information */ diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 879fc8e9..e9b1bfc7 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -121,4 +121,14 @@ public class GameState { yacht.update(timeInterval); } } + + + /** + * Generates a new ID based off the size of current players + 1 + * @return a playerID to be allocated to a new connetion + */ + public static Integer getUniquePlayerID() { + // TODO: 22/07/17 wmu16 - This may not be robust enough and may have to be improved on. + return yachts.size() + 1; + } } diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 72dbd53a..9b7f15fd 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -47,11 +47,19 @@ public class ServerToClientThread implements Runnable { } catch (IOException e) { System.out.println("IO error in server thread upon grabbing streams"); } -// threeWayHandshake(); - GameState.addPlayer(new Player(socket)); - Random rand = new Random(); - sourceId = rand.nextInt(100000); - GameState.addYacht(sourceId, new Yacht("Kappa", "Kap", new GeoPoint(0.0, 0.0), 0.0)); + + //Attempt threeway handshake with connection + sourceId = GameState.getUniquePlayerID(); + if (threeWayHandshake(sourceId)) { + serverLog("Successful handshake. Client allocated id: " + sourceId, 1); + GameState.addYacht(sourceId, + new Yacht("Kappa", "Kap", new GeoPoint(0.0, 0.0), 0.0)); + GameState.addPlayer(new Player(socket)); //Is this neccesary??? + } else { + serverLog("Unsuccessful handshake. Connection rejected", 1); + closeSocket(); + return; + } thread = new Thread(this); thread.start(); @@ -113,7 +121,7 @@ public class ServerToClientThread implements Runnable { } } } catch (Exception e) { - serverLog("ERROR OCCURED, CLOSING SERVER CONNETION: " + socket.getRemoteSocketAddress().toString(), 1); + serverLog("ERROR OCCURRED, CLOSING SERVER CONNECTION: " + socket.getRemoteSocketAddress().toString(), 1); closeSocket(); return; } @@ -132,28 +140,32 @@ public class ServerToClientThread implements Runnable { * if so, sends a confirmation packet back to that connection * Creates a player instance with that ID and this thread and adds it to the GameState * If not, close the socket and end the threads execution + * @param id the id to try and assign to the connection + * @return A boolean indicating if it was a successful handshake */ - private void threeWayHandshake() { -// // TODO: 13/07/17 Finish using AC35 -// Integer playerID = GameState.getUniquePlayerID(); -// Integer confirmationID = null; -// Integer identificationAttempt = 0 -// while (!userIdentified) { -// os.write(playerID); //Send out new ID looking for echo -// confirmationID = is.read(); -// if (playerID == idConfirmation) { //ID is echoed back. Connection is a client -// os.write( some determined confirmation message ); //Confirm to client -// GameState.addPlayer(new Player(playerID, this)); //Create a player in game state for client -// userIdentified = true; -// } else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home. -// closeSocket(); -// return; -// } -// identificationAttempt++; -// } + private Boolean threeWayHandshake(Integer id) { + Integer confirmationID = null; + Integer identificationAttempt = 0; + while (!userIdentified) { + try { + os.write(id); //Send out new ID looking for echo + confirmationID = is.read(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (id.equals(confirmationID)) { //ID is echoed back. Connection is a client + return true; + } else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home. + return false; + } + identificationAttempt++; + } + + return true; } - public void closeSocket() { + private void closeSocket() { try { socket.close(); } catch (IOException e) {