LobbyView now can change to RaceView upon race start packet received.

Added port number text field in start screen controller.
Created a client state.

#story[1055] #pair[hyi25, zyt10]
This commit is contained in:
Zhi You Tan
2017-07-21 16:14:45 +12:00
parent d37cbd263e
commit e891ed8a64
12 changed files with 157 additions and 47 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() {
@@ -200,6 +197,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;
@@ -25,14 +26,10 @@ public class ClientToServerThread extends Thread {
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();
}
}
@@ -46,7 +43,7 @@ public class ClientToServerThread extends Thread {
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,16 +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);
setContentPane("/views/RaceView.fxml");
}
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;
@@ -68,26 +73,32 @@ public class StartScreenController {
// new GameServerThread("Fuck you");
// get the lobby controller so that we can pass the game server thread to it
setContentPane("/views/LobbyView.fxml");
} catch (UnknownHostException e) {
System.err.println("COULD NOT FIND YOUR IP ADDRESS!");
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setHeaderText("Cannot host");
alert.setContentText("Oops, failed to host, try to restart.");
alert.showAndWait();
e.printStackTrace();
}
}
@FXML
public void connectButtonPressed() {
// TODO: 10/07/17 wmu16 - Finish function
String ipAddress = ipTextField.getText().trim().toLowerCase();
try {
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();
}
}
@@ -1,5 +1,6 @@
package seng302.gameServer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -28,6 +29,7 @@ public class GameState {
public GameState(String hostIpAddress) {
GameState.hostIpAddress = hostIpAddress;
players = new ArrayList<>();
yachts = new HashMap<>();
currentStage = GameStages.LOBBYING;
isRaceStarted = false;
//set this when game stage changes to prerace
@@ -32,7 +32,7 @@ public class MainServerThread extends Thread implements PacketBufferDelegate, Cl
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<>();
@@ -73,7 +73,6 @@ public class MainServerThread extends Thread implements PacketBufferDelegate, Cl
updateClients();
while (!packetBuffer.isEmpty()){
System.out.println("WHATUPPP");
try {
StreamPacket packet = packetBuffer.take();
ClientPacketParser.parsePacket(packet);
@@ -83,9 +82,6 @@ public class MainServerThread extends Thread implements PacketBufferDelegate, Cl
}
}
System.out.println("WHOOPSIES");
// TODO: 14/07/17 wmu16 - Send out disconnect packet to clients
try {
serverSocket.close();
@@ -111,7 +107,6 @@ public class MainServerThread extends Thread implements PacketBufferDelegate, Cl
@Override
public boolean addToBuffer(StreamPacket streamPacket) {
System.out.println("HEY HI");
return packetBuffer.add(streamPacket);
}
@@ -50,7 +50,7 @@ public class ServerToClientThread extends Thread {
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));
// GameState.addYacht(sourceId, new Yacht("Kappa", "Kap", new GeoPoint(0.0, 0.0), 0.0));
}
public void run() {
@@ -58,14 +58,13 @@ public class ServerToClientThread extends Thread {
int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
while(true) {
//System.out.print(".");
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
ChatterMessage chatterMessage = new ChatterMessage(4, 14, "Hello, it's me");
sendMessage(chatterMessage);
//ChatterMessage chatterMessage = new ChatterMessage(4, 14, "Chatter message");
//sendMessage(chatterMessage);
// try {
// GameState.outputState(os);