From af9f1417f1d4891542eeb0eb8c9e27e64beb6dfe Mon Sep 17 00:00:00 2001 From: Zhi You Tan Date: Wed, 26 Jul 2017 16:01:41 +1200 Subject: [PATCH] Documented client packet parser, client state, client state querying runnable, client to server thread and replaced e.printStackTrace() with client log messages. --- .../seng302/client/ClientPacketParser.java | 17 ++++-- src/main/java/seng302/client/ClientState.java | 13 ++--- .../client/ClientStateQueryingRunnable.java | 13 ++++- .../seng302/client/ClientToServerThread.java | 55 +++++++++++-------- 4 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/main/java/seng302/client/ClientPacketParser.java b/src/main/java/seng302/client/ClientPacketParser.java index 4198dc55..578344fa 100644 --- a/src/main/java/seng302/client/ClientPacketParser.java +++ b/src/main/java/seng302/client/ClientPacketParser.java @@ -59,6 +59,7 @@ public class ClientPacketParser { */ public ClientPacketParser() { } + /** * Looks at the type of the packet then sends it to the appropriate parser to extract the * specific data associated with that packet type @@ -108,7 +109,7 @@ public class ClientPacketParser { } } catch (NullPointerException e) { System.out.println("Error parsing packet"); - e.printStackTrace(); +// e.printStackTrace(); } } @@ -185,7 +186,6 @@ public class ClientPacketParser { int noBoats = payload[22]; int raceType = payload[23]; - clientStateBoats = ClientState.getBoats(); for (int i = 0; i < noBoats; i++) { long boatStatusSourceID = bytesToLong( Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20))); @@ -206,7 +206,9 @@ public class ClientPacketParser { boat.setEstimateTimeAtNextMark(estTimeAtNextMark); boat.setEstimateTimeAtFinish(estTimeAtFinish); - Yacht clientBoat = clientStateBoats.get((int) boatStatusSourceID); + // Update Client State boats when receive race status packet. + // Potentially could replace boats in ClientPacketParser. + Yacht clientBoat = ClientState.getBoats().get((int) boatStatusSourceID); clientBoat.setBoatStatus((boatStatus)); setBoatLegPosition(clientBoat, boatLegNumber); clientBoat.setPenaltiesAwarded(boatPenaltyAwarded); @@ -215,9 +217,12 @@ public class ClientPacketParser { clientBoat.setEstimateTimeAtFinish(estTimeAtFinish); } - // 3 is race started + // 3 is race started. + // ClientState race started flag will be set to true if race started, else set false. if (raceStatus == 3) { ClientState.setRaceStarted(true); + } else { + ClientState.setRaceStarted(false); } } @@ -286,8 +291,10 @@ public class ClientPacketParser { xmlObject.constructXML(doc, messageType); if (messageType == 7) { //7 is the boat XML boats = xmlObject.getBoatXML().getCompetingBoats(); + // Set/Update the ClientState boats after receiving new boat xml. + // Flag boatsUpdated in ClientState to true. ClientState.setBoats(xmlObject.getBoatXML().getCompetingBoats()); - ClientState.setDirtyState(true); + ClientState.setBoatsUpdated(true); } if (messageType == 6) { //6 is race info xml newRaceXmlReceived = true; diff --git a/src/main/java/seng302/client/ClientState.java b/src/main/java/seng302/client/ClientState.java index 64512a1b..c96be561 100644 --- a/src/main/java/seng302/client/ClientState.java +++ b/src/main/java/seng302/client/ClientState.java @@ -1,8 +1,5 @@ package seng302.client; -import com.sun.org.apache.xpath.internal.operations.Bool; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import seng302.models.Yacht; @@ -17,7 +14,7 @@ public class ClientState { private static Boolean raceStarted = false; private static Boolean connectedToHost = false; private static Map boats = new ConcurrentHashMap<>(); - private static Boolean dirtyState = true; + private static Boolean boatsUpdated = true; private static String clientSourceId = ""; public static String getHostIp() { @@ -56,12 +53,12 @@ public class ClientState { return boats; } - public static Boolean isDirtyState() { - return dirtyState; + public static Boolean isBoatsUpdated() { + return boatsUpdated; } - public static void setDirtyState(Boolean dirtyState) { - ClientState.dirtyState = dirtyState; + public static void setBoatsUpdated(Boolean boatsUpdated) { + ClientState.boatsUpdated = boatsUpdated; } public static String getClientSourceId() { diff --git a/src/main/java/seng302/client/ClientStateQueryingRunnable.java b/src/main/java/seng302/client/ClientStateQueryingRunnable.java index 67cf1dbf..576d7b24 100644 --- a/src/main/java/seng302/client/ClientStateQueryingRunnable.java +++ b/src/main/java/seng302/client/ClientStateQueryingRunnable.java @@ -12,6 +12,10 @@ public class ClientStateQueryingRunnable extends Observable implements Runnable public ClientStateQueryingRunnable() {} + /** + * Notifies observers "game started" if ClientState raceStarted flag is true and terminates itself. + * Notifies observers "update players" if ClientState boatsUpdated flag is true and resets the flag to false; + */ @Override public void run() { while(!terminate) { @@ -29,14 +33,19 @@ public class ClientStateQueryingRunnable extends Observable implements Runnable terminate(); } - if (ClientState.isDirtyState()) { + if (ClientState.isBoatsUpdated()) { setChanged(); notifyObservers("update players"); - ClientState.setDirtyState(false); + ClientState.setBoatsUpdated(false); } } } + /** + * Used to terminate the thread. + * + * Currently called by the main while loop when game started is detected. + */ public void terminate() { terminate = true; } diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java index 1e76bd07..1a8156b7 100644 --- a/src/main/java/seng302/client/ClientToServerThread.java +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -15,7 +15,8 @@ import seng302.server.messages.BoatActionMessage; import seng302.server.messages.Message; /** - * Created by kre39 on 13/07/17. + * A class describing a single connection to a Server for the purposes of sending and receiving on + * its own thread. */ public class ClientToServerThread implements Runnable { @@ -30,8 +31,19 @@ public class ClientToServerThread implements Runnable { private OutputStream os; private Boolean updateClient = true; - private ByteArrayOutputStream crcBuffer; + private ByteArrayOutputStream crcBuffer; + /** + * Constructor for ClientToServerThread which takes in ipAddress and portNumber and attempts to + * connect to the specified ipAddress and port. + * + * Upon successful socket connection, threeWayHandshake will be preformed and the instance will + * be put on a thread and run immediately. + * + * @param ipAddress a string of ip address to be connected to + * @param portNumber an integer port number + * @throws Exception SocketConnection if fail to connect to ip address and port number combination + */ public ClientToServerThread(String ipAddress, Integer portNumber) throws Exception{ socket = new Socket(ipAddress, portNumber); is = socket.getInputStream(); @@ -40,7 +52,7 @@ public class ClientToServerThread implements Runnable { Integer allocatedID = threeWayHandshake(); if (allocatedID != null) { ourID = allocatedID; - clientLog("Successful handshake. Allocated ID: " + ourID, 1); + clientLog("Successful handshake. Allocated ID: " + ourID, 0); ClientState.setClientSourceId(String.valueOf(ourID)); } else { clientLog("Unsuccessful handshake", 1); @@ -50,31 +62,30 @@ public class ClientToServerThread implements Runnable { thread = new Thread(this); thread.start(); - } + /** + * Prints out log message and time happened. + * Only perform task if log level is below LOG_LEVEL variable. + * + * @param message a string of message to be printed out + * @param logLevel an int for log level + */ static void clientLog(String message, int logLevel){ if(logLevel <= LOG_LEVEL){ System.out.println("[CLIENT " + LocalDateTime.now().toLocalTime().toString() + "] " + message); } } + /** + * Perform the thread loop. Will exit loop if ClientState connected to host variable is false. + */ public void run() { int sync1; int sync2; // TODO: 14/07/17 wmu16 - Work out how to fix this while loop while(ClientState.isConnectedToHost()) { try { - //Perform a write if it is time to as delegated by the MainServerThread - if (updateClient) { - // TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream -// try { -// GameState.outputState(os); -// } catch (IOException e) { -// System.out.println("IO error in server thread upon writing to output stream"); -// } - updateClient = false; - } crcBuffer = new ByteArrayOutputStream(); sync1 = readByte(); sync2 = readByte(); @@ -101,7 +112,7 @@ public class ClientToServerThread implements Runnable { } } catch (Exception e) { closeSocket(); - e.printStackTrace(); + clientLog("Disconnected from server", 1); return; } } @@ -111,7 +122,7 @@ public class ClientToServerThread implements Runnable { /** - * Listens for an allocated sourceID and returns it to the server if recieved + * Listens for an allocated sourceID and returns it to the server if received * @return the sourceID allocated to us by the server */ private Integer threeWayHandshake() { @@ -120,14 +131,15 @@ public class ClientToServerThread implements Runnable { try { ourSourceID = is.read(); } catch (IOException e) { - e.printStackTrace(); + clientLog("Three way handshake failed", 1); + } if (ourSourceID != null) { try { os.write(ourSourceID); return ourSourceID; } catch (IOException e) { - e.printStackTrace(); + clientLog("Three way handshake failed", 1); return null; } } @@ -143,8 +155,7 @@ public class ClientToServerThread implements Runnable { try { os.write(boatActionMessage.getBuffer()); } catch (IOException e) { - clientLog("COULD NOT WRITE TO SERVER", 0); - e.printStackTrace(); + clientLog("Could not write to server", 1); } } @@ -153,7 +164,7 @@ public class ClientToServerThread implements Runnable { try { socket.close(); } catch (IOException e) { - clientLog("Failed to close the socket", 0); + clientLog("Failed to close the socket", 1); } } @@ -164,7 +175,7 @@ public class ClientToServerThread implements Runnable { currentByte = is.read(); crcBuffer.write(currentByte); } catch (IOException e) { - e.printStackTrace(); + clientLog("Read byte failed", 1); } if (currentByte == -1){ throw new Exception();