Merge remote-tracking branch 'origin/Story62_Swtich_To_RaceView_When_Race_Start' into Merging_GameLoop_with_Broadcast

# Conflicts:
#	src/main/java/seng302/controllers/LobbyController.java
#	src/main/java/seng302/controllers/StartScreenController.java
#	src/main/java/seng302/gameServer/ServerToClientThread.java
This commit is contained in:
Kusal Ekanayake
2017-07-24 14:37:56 +12:00
12 changed files with 154 additions and 39 deletions
@@ -36,8 +36,6 @@ public class ClientPacketParser {
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markLocations = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> 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<Integer, Yacht> 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)];
@@ -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;
}
}
@@ -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;
}
}
@@ -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) {
@@ -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");
}
}
@@ -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();
})
);
@@ -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();
}
}
@@ -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() {
@@ -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);
}
@@ -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) {