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;
@@ -52,7 +50,6 @@ public class ClientPacketParser {
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);
+2 -2
View File
@@ -55,9 +55,9 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<AnchorPane focusTraversable="true" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<ListView fx:id="competitorsListView" layoutX="154.0" layoutY="59.0" prefHeight="266.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<ListView fx:id="competitorsListView" focusTraversable="false" layoutX="154.0" layoutY="59.0" prefHeight="266.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</children>
+16 -5
View File
@@ -15,8 +15,8 @@
<GridPane fx:id="startScreen2" nodeOrientation="LEFT_TO_RIGHT" prefWidth="800.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.StartScreenController">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="442.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="358.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
@@ -33,10 +33,13 @@
</font>
</Label>
<Button mnemonicParsing="false" onAction="#hostButtonPressed" prefHeight="25.0" prefWidth="175.0" text="Host" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
<Button mnemonicParsing="false" onAction="#connectButtonPressed" prefHeight="25.0" prefWidth="147.0" text="Connect" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<TextField fx:id="ipTextField" maxWidth="-Infinity" prefHeight="25.0" prefWidth="200.0" text="localhost" GridPane.halignment="RIGHT" GridPane.rowIndex="4">
<Button mnemonicParsing="false" onAction="#connectButtonPressed" prefHeight="25.0" prefWidth="147.0" text="Connect" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
<Insets left="5.0" right="5.0" />
</GridPane.margin></Button>
<TextField fx:id="ipTextField" alignment="CENTER" maxWidth="-Infinity" prefHeight="25.0" prefWidth="148.0" promptText="Host IP" text="127.0.0.1" GridPane.halignment="RIGHT" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="5.0" right="85.0" top="10.0" />
</GridPane.margin>
</TextField>
<Text fill="WHITE" strokeType="OUTSIDE" strokeWidth="0.0" text="OR" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" GridPane.rowIndex="3">
@@ -44,5 +47,13 @@
<Font size="21.0" />
</font>
</Text>
<TextField fx:id="portTextField" alignment="CENTER" maxWidth="75.0" prefHeight="25.0" prefWidth="55.0" promptText="Port" text="4950" GridPane.halignment="RIGHT" GridPane.rowIndex="4">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets left="5.0" right="5.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>