diff --git a/src/main/java/seng302/client/ClientPacketParser.java b/src/main/java/seng302/client/ClientPacketParser.java index 3fa5b9ea..b9f59e0c 100644 --- a/src/main/java/seng302/client/ClientPacketParser.java +++ b/src/main/java/seng302/client/ClientPacketParser.java @@ -36,8 +36,6 @@ public class ClientPacketParser { public static ConcurrentHashMap> markLocations = new ConcurrentHashMap<>(); public static ConcurrentHashMap> boatLocations = new ConcurrentHashMap<>(); - private String threadName; - private Thread t; private static boolean newRaceXmlReceived = false; private static boolean raceStarted = false; private static XMLParser xmlObject; @@ -48,11 +46,10 @@ public class ClientPacketParser { private static Map boatsPos = new ConcurrentSkipListMap<>(); private static double windDirection = 0; private static Double windSpeed = 0d; - private static Long currentTimeLong; + private static Long currentTimeLong; private static String currentTimeString; private static boolean appRunning; - //CONVERSION CONSTANTS private static final Double MS_TO_KNOTS = 1.94384; @@ -121,7 +118,7 @@ public class ClientPacketParser { */ private static void extractHeartBeat(StreamPacket packet) { long heartbeat = bytesToLong(packet.getPayload()); - System.out.println("heartbeat = " + heartbeat); + System.out.println("[CLIENT] Received heartbeat = " + heartbeat); } private static String getTimeZoneString() { @@ -173,8 +170,10 @@ public class ClientPacketParser { if (raceStatus == 4 || raceStatus == 8) { raceFinished = true; raceStarted = false; + ClientState.setRaceStarted(false); } else if (!raceStarted) { raceStarted = true; + ClientState.setRaceStarted(true); raceFinished = false; } timeSinceStart = timeTillStart; @@ -200,6 +199,9 @@ public class ClientPacketParser { Long estTimeAtFinish = bytesToLong( Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20))); boat.setEstimateTimeAtFinish(estTimeAtFinish); + +// FOR DEBUGGING: + // boatsPos.put(estTimeAtFinish, boat); // String boatStatus = "SourceID: " + boatStatusSourceID; // boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)]; diff --git a/src/main/java/seng302/client/ClientState.java b/src/main/java/seng302/client/ClientState.java new file mode 100644 index 00000000..ab870beb --- /dev/null +++ b/src/main/java/seng302/client/ClientState.java @@ -0,0 +1,46 @@ +package seng302.client; + +import com.sun.org.apache.xpath.internal.operations.Bool; + +/** + * Created by zyt10 on 21/07/17. + */ +public class ClientState { + + private static String hostIp = ""; + private static Boolean isHost = false; + private static Boolean raceStarted = false; + private static Boolean connectedToHost = false; + + public static String getHostIp() { + return hostIp; + } + + public static void setHostIp(String hostIp) { + ClientState.hostIp = hostIp; + } + + public static Boolean isHost() { + return isHost; + } + + public static void setHost(Boolean isHost) { + ClientState.isHost = isHost; + } + + public static Boolean isRaceStarted() { + return raceStarted; + } + + public static void setRaceStarted(Boolean raceStarted) { + ClientState.raceStarted = raceStarted; + } + + public static Boolean isConnectedToHost() { + return connectedToHost; + } + + public static void setConnectedToHost(Boolean connectedToHost) { + ClientState.connectedToHost = connectedToHost; + } +} diff --git a/src/main/java/seng302/client/ClientStateQueryingRunnable.java b/src/main/java/seng302/client/ClientStateQueryingRunnable.java new file mode 100644 index 00000000..d2fb9220 --- /dev/null +++ b/src/main/java/seng302/client/ClientStateQueryingRunnable.java @@ -0,0 +1,28 @@ +package seng302.client; + +import java.util.List; +import java.util.Observable; + +/** + * Created by zyt10 on 21/07/17. + */ +public class ClientStateQueryingRunnable extends Observable implements Runnable { + + private Boolean terminate = false; + + public ClientStateQueryingRunnable() {} + + @Override + public void run() { + while(!terminate) { + if (ClientState.isRaceStarted() && ClientState.isConnectedToHost()) { + setChanged(); + notifyObservers(); + } + } + } + + public void terminate() { + terminate = true; + } +} diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java index f2f73c7b..90ff4e63 100644 --- a/src/main/java/seng302/client/ClientToServerThread.java +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import java.net.UnknownHostException; import java.util.zip.CRC32; import java.util.zip.Checksum; @@ -30,14 +31,10 @@ public class ClientToServerThread implements Runnable { private Boolean updateClient = true; private ByteArrayOutputStream crcBuffer; - public ClientToServerThread(String ipAddress, Integer portNumber){ - try { + public ClientToServerThread(String ipAddress, Integer portNumber) throws Exception{ socket = new Socket(ipAddress, portNumber); is = socket.getInputStream(); os = socket.getOutputStream(); - } catch (IOException e) { - e.printStackTrace(); - } Integer allocatedID = threeWayHandshake(); if (allocatedID != null) { @@ -64,7 +61,7 @@ public class ClientToServerThread implements Runnable { int sync1; int sync2; // TODO: 14/07/17 wmu16 - Work out how to fix this while loop - while(true) { + while(ClientState.isConnectedToHost()) { try { //Perform a write if it is time to as delegated by the MainServerThread if (updateClient) { diff --git a/src/main/java/seng302/controllers/LobbyController.java b/src/main/java/seng302/controllers/LobbyController.java index eb3d7b75..f63b8d68 100644 --- a/src/main/java/seng302/controllers/LobbyController.java +++ b/src/main/java/seng302/controllers/LobbyController.java @@ -6,7 +6,10 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.net.URL; import java.util.Enumeration; +import java.util.Observable; +import java.util.Observer; import java.util.ResourceBundle; +import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; @@ -17,6 +20,7 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.scene.text.Text; +import seng302.client.ClientStateQueryingRunnable; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; @@ -24,7 +28,7 @@ import seng302.gameServer.GameState; * A class describing the actions of the lobby screen * Created by wmu16 on 10/07/17. */ -public class LobbyController implements Initializable{ +public class LobbyController implements Initializable, Observer{ @FXML private ListView competitorsListView; @@ -34,6 +38,7 @@ public class LobbyController implements Initializable{ private Text lobbyIpText; private static ObservableList competitors; + private ClientStateQueryingRunnable clientStateQueryingRunnable; private void setContentPane(String jfxUrl) { try { @@ -53,11 +58,27 @@ public class LobbyController implements Initializable{ @Override public void initialize(URL location, ResourceBundle resources) { lobbyIpText.setText("Lobby Host IP: " + getLocalHostIp()); - } - - public void initialize() { competitors = FXCollections.observableArrayList(); competitorsListView.setItems(competitors); + + // set up client state query thread, so that when it receives the race-started packet + // it can switch to the race view + ClientStateQueryingRunnable clientStateQueryingRunnable = new ClientStateQueryingRunnable(); + clientStateQueryingRunnable.addObserver(this); + Thread clientStateQueryingThread = new Thread(clientStateQueryingRunnable, "Client State querying thread"); + clientStateQueryingThread.setDaemon(true); + clientStateQueryingThread.start(); + } + + @Override + public void update(Observable o, Object arg) { + Platform.runLater(new Runnable() { + @Override + public void run() { + switchToRaceView(); + clientStateQueryingRunnable.terminate(); + } + }); } private String getLocalHostIp() { @@ -94,15 +115,16 @@ public class LobbyController implements Initializable{ public void leaveLobbyButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function! setContentPane("/views/StartScreenView.fxml"); - System.out.println("Leaving lobby!"); GameState.setCurrentStage(GameStages.CANCELLED); // TODO: 20/07/17 wmu16 - Implement some way of terminating the game } - @FXML public void readyButtonPressed() { GameState.setCurrentStage(GameStages.RACING); + } + + private void switchToRaceView() { setContentPane("/views/RaceView.fxml"); } } diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 16eac429..e2cadecd 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -96,12 +96,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel startingBoats = new ArrayList<>(ClientPacketParser.getBoats().values()); includedCanvasController.setup(this); - includedCanvasController.initializeCanvas(); +// includedCanvasController.initializeCanvas(); initializeUpdateTimer(); initialiseFPSCheckBox(); initialiseAnnotationSlider(); initialiseBoatSelectionComboBox(); - includedCanvasController.timer.start(); +// includedCanvasController.timer.start(); selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView()); } @@ -283,7 +283,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel event -> { updateRaceTime(); updateWindDirection(); - updateOrder(); +// updateOrder(); updateBoatSelectionComboBox(); }) ); diff --git a/src/main/java/seng302/controllers/StartScreenController.java b/src/main/java/seng302/controllers/StartScreenController.java index 588e1b57..c70cf8b1 100644 --- a/src/main/java/seng302/controllers/StartScreenController.java +++ b/src/main/java/seng302/controllers/StartScreenController.java @@ -2,10 +2,13 @@ package seng302.controllers; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; +import seng302.client.ClientState; import seng302.client.ClientToServerThread; import seng302.gameServer.GameState; import seng302.gameServer.MainServerThread; @@ -23,6 +26,8 @@ public class StartScreenController { @FXML private TextField ipTextField; @FXML + private TextField portTextField; + @FXML private GridPane startScreen2; private Controller controller; @@ -69,24 +74,33 @@ public class StartScreenController { // get the lobby controller so that we can pass the game server thread to it setContentPane("/views/LobbyView.fxml"); } catch (UnknownHostException e) { + alert.setHeaderText("Cannot host"); + alert.setContentText("Oops, failed to host, try to restart."); + alert.showAndWait(); System.err.println("COULD NOT FIND YOUR IP ADDRESS!"); e.printStackTrace(); } - } - @FXML public void connectButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function - String ipAddress = ipTextField.getText().trim().toLowerCase(); try { // TODO: 22/07/17 wmu 16 - make this port number some static constant somewhere perhaps a config file? ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, 4950); + String ipAddress = ipTextField.getText().trim().toLowerCase(); + Integer port = Integer.valueOf(portTextField.getText().trim()); + + ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, port); controller.setClientToServerThread(clientToServerThread); + clientToServerThread.start(); + ClientState.setConnectedToHost(true); setContentPane("/views/LobbyView.fxml"); - } catch (Exception e){ - e.printStackTrace(); + } catch (Exception e) { + Alert alert = new Alert(AlertType.ERROR); + alert.setHeaderText("Cannot reach the host"); + alert.setContentText("Please check your host IP address."); + alert.showAndWait(); } } diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 63cb9f92..70c5653c 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -37,6 +37,7 @@ public class GameState { yachts = new HashMap<>(); //set this when game stage changes to prerace previousUpdateTime = System.currentTimeMillis(); + yachts = new HashMap<>(); } public static String getHostIpAddress() { diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index c9924a29..3294c9a2 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -34,7 +34,7 @@ public class MainServerThread implements Runnable, PacketBufferDelegate, ClientC try { serverSocket = new ServerSocket(PORT); } catch (IOException e) { - System.out.println("IO error in server thread handler upon trying to make new server socket"); + serverLog("IO error in server thread handler upon trying to make new server socket", 0); } packetBuffer = new PriorityBlockingQueue<>(); @@ -80,7 +80,6 @@ public class MainServerThread implements Runnable, PacketBufferDelegate, ClientC updateClients(); while (!packetBuffer.isEmpty()){ - System.out.println("WHATUPPP"); try { StreamPacket packet = packetBuffer.take(); ClientPacketParser.parsePacket(packet); @@ -90,9 +89,6 @@ public class MainServerThread implements Runnable, PacketBufferDelegate, ClientC } } - System.out.println("WHOOPSIES"); - - // TODO: 14/07/17 wmu16 - Send out disconnect packet to clients try { serverSocket.close(); @@ -118,7 +114,6 @@ public class MainServerThread implements Runnable, PacketBufferDelegate, ClientC @Override public boolean addToBuffer(StreamPacket streamPacket) { - System.out.println("HEY HI"); return packetBuffer.add(streamPacket); } diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 8f61a091..f519ada6 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -90,7 +90,6 @@ public class ServerToClientThread implements Runnable { int sync2; // TODO: 14/07/17 wmu16 - Work out how to fix this while loop while(true) { - //System.out.print("."); try { if (initialisedRace) { diff --git a/src/main/resources/views/LobbyView.fxml b/src/main/resources/views/LobbyView.fxml index 4e413c61..11830847 100644 --- a/src/main/resources/views/LobbyView.fxml +++ b/src/main/resources/views/LobbyView.fxml @@ -55,9 +55,9 @@ - + - + diff --git a/src/main/resources/views/StartScreenView.fxml b/src/main/resources/views/StartScreenView.fxml index 295faef8..a03d6829 100644 --- a/src/main/resources/views/StartScreenView.fxml +++ b/src/main/resources/views/StartScreenView.fxml @@ -15,8 +15,8 @@ - - + + @@ -33,10 +33,13 @@ + + + @@ -44,5 +47,13 @@ + + + + + + + +