Implemented list views initialisation which will set the first pane to be your source id (after three way handshake) and the remaining pane to be the source id of other players based on boats.xml received.

Updated client parser and client state to save a list of player's boat

WIP: refresh list view to show the latest update in players

#story[1055]
This commit is contained in:
Zhi You Tan
2017-07-23 20:42:21 +12:00
parent e11ceed28c
commit 9d754c8819
7 changed files with 180 additions and 58 deletions
@@ -38,7 +38,7 @@ public class ClientPacketParser {
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatLocations = new ConcurrentHashMap<>();
private static boolean newRaceXmlReceived = false;
private static boolean raceStarted = false;
private static XMLParser xmlObject;
private static XMLParser xmlObject = new XMLParser();
private static boolean raceFinished = false;
private static boolean streamStatus = false;
private static long timeSinceStart = -1;
@@ -49,6 +49,7 @@ public class ClientPacketParser {
private static Long currentTimeLong;
private static String currentTimeString;
private static boolean appRunning;
private static Map<Integer, Yacht> clientStateBoats = new ConcurrentHashMap<>();
//CONVERSION CONSTANTS
private static final Double MS_TO_KNOTS = 1.94384;
@@ -185,44 +186,35 @@ 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)));
Yacht boat = boats.get((int) boatStatusSourceID);
boat.setBoatStatus((int) payload[28 + (i * 20)]);
setBoatLegPosition(boat, (int) payload[29 + (i * 20)]);
boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
Long estTimeAtNextMark = bytesToLong(
int boatStatus = (int) payload[28 + (i * 20)];
int boatLegNumber = (int) payload[29 + (i * 20)];
int boatPenaltyAwarded = (int) payload[30 + (i * 20)];
int boatPenaltyServed = (int) payload[31 + (i * 20)];
long estTimeAtNextMark = bytesToLong(
Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20)));
boat.setEstimateTimeAtNextMark(estTimeAtNextMark);
Long estTimeAtFinish = bytesToLong(
long estTimeAtFinish = bytesToLong(
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
Yacht boat = boats.get((int) boatStatusSourceID);
boat.setBoatStatus((boatStatus));
setBoatLegPosition(boat, boatLegNumber);
boat.setPenaltiesAwarded(boatPenaltyAwarded);
boat.setPenaltiesServed(boatPenaltyServed);
boat.setEstimateTimeAtNextMark(estTimeAtNextMark);
boat.setEstimateTimeAtFinish(estTimeAtFinish);
// FOR DEBUGGING:
// boatsPos.put(estTimeAtFinish, boat);
// String boatStatus = "SourceID: " + boatStatusSourceID;
// boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)];
// boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)];
// boatStatus += "\nPenaltiesAwarded: " + (int)payload[29 + (i * 20)];
// boatStatus += "\nPenaltiesServed: " + (int)payload[30 + (i * 20)];
// boatStatus += "\nEstTimeAtNextMark: " + bytesToLong(Arrays.copyOfRange(payload,31 + (i * 20),37+ (i * 20)));
// boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20)));
// boatStatuses.add(boatStatus);
Yacht clientBoat = clientStateBoats.get((int) boatStatusSourceID);
clientBoat.setBoatStatus((boatStatus));
setBoatLegPosition(clientBoat, boatLegNumber);
clientBoat.setPenaltiesAwarded(boatPenaltyAwarded);
clientBoat.setPenaltiesServed(boatPenaltyServed);
clientBoat.setEstimateTimeAtNextMark(estTimeAtNextMark);
clientBoat.setEstimateTimeAtFinish(estTimeAtFinish);
}
// if (isRaceStarted()) {
// int pos = 1;
// for (Yacht yacht : boatsPos.values()) {
// yacht.setPosition(String.valueOf(pos));
// pos++;
// }
// } else {
// for (Yacht yacht : boatsPos.values()) {
// yacht.setPosition("-");
// }
// }
}
private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
@@ -269,7 +261,6 @@ public class ClientPacketParser {
* @param packet Packet parsed in to use the payload
*/
private static void extractXmlMessage(StreamPacket packet) {
byte[] payload = packet.getPayload();
int messageType = payload[9];
@@ -291,6 +282,7 @@ public class ClientPacketParser {
xmlObject.constructXML(doc, messageType);
if (messageType == 7) { //7 is the boat XML
boats = xmlObject.getBoatXML().getCompetingBoats();
ClientState.setBoats(xmlObject.getBoatXML().getCompetingBoats());
}
if (messageType == 6) { //6 is race info xml
@@ -1,6 +1,11 @@
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;
/**
* Created by zyt10 on 21/07/17.
@@ -11,6 +16,9 @@ public class ClientState {
private static Boolean isHost = false;
private static Boolean raceStarted = false;
private static Boolean connectedToHost = false;
private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
private static Boolean dirtyState = true;
private static String clientSourceId = "";
public static String getHostIp() {
return hostIp;
@@ -43,4 +51,28 @@ public class ClientState {
public static void setConnectedToHost(Boolean connectedToHost) {
ClientState.connectedToHost = connectedToHost;
}
public static Map<Integer, Yacht> getBoats() {
return boats;
}
public static Boolean isDirtyState() {
return dirtyState;
}
public static void setDirtyState(Boolean dirtyState) {
ClientState.dirtyState = dirtyState;
}
public static String getClientSourceId() {
return clientSourceId;
}
public static void setClientSourceId(String clientSourceId) {
ClientState.clientSourceId = clientSourceId;
}
public static void setBoats(Map<Integer, Yacht> boats) {
ClientState.boats = boats;
}
}
@@ -32,14 +32,15 @@ public class ClientToServerThread implements Runnable {
private ByteArrayOutputStream crcBuffer;
public ClientToServerThread(String ipAddress, Integer portNumber) throws Exception{
socket = new Socket(ipAddress, portNumber);
is = socket.getInputStream();
os = socket.getOutputStream();
socket = new Socket(ipAddress, portNumber);
is = socket.getInputStream();
os = socket.getOutputStream();
Integer allocatedID = threeWayHandshake();
if (allocatedID != null) {
ourID = allocatedID;
clientLog("Successful handshake. Allocated ID: " + ourID, 1);
ClientState.setClientSourceId(String.valueOf(ourID));
} else {
clientLog("Unsuccessful handhsake", 1);
closeSocket();
@@ -96,13 +97,17 @@ public class ClientToServerThread implements Runnable {
} else {
System.err.println("Packet has been dropped");
}
}
} catch (Exception e) {
closeSocket();
System.out.println("this exception");
return;
}
}
closeSocket();
System.out.println("[CLIENT] Disconnected from server");
}
@@ -5,7 +5,10 @@ import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.ResourceBundle;
@@ -15,6 +18,7 @@ import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
@@ -39,6 +43,22 @@ public class LobbyController implements Initializable, Observer{
@FXML
private Text lobbyIpText;
@FXML
private ListView firstListView;
@FXML
private ListView secondListView;
@FXML
private ListView thirdListView;
@FXML
private ListView fourthListView;
@FXML
private ListView fifthListView;
@FXML
private ListView sixthListView;
@FXML
private ListView seventhListView;
@FXML
private ListView eighthListView;
@FXML
private ImageView firstImageView;
@FXML
private ImageView secondImageView;
@@ -55,7 +75,15 @@ public class LobbyController implements Initializable, Observer{
@FXML
private ImageView eighthImageView;
private static ObservableList competitors;
private static List<ObservableList<String>> competitors = new ArrayList<>();
private static ObservableList<String> firstCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> secondCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> thirdCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> fourthCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> fifthCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> sixthCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
private ClientStateQueryingRunnable clientStateQueryingRunnable;
private void setContentPane(String jfxUrl) {
@@ -79,10 +107,9 @@ public class LobbyController implements Initializable, Observer{
lobbyIpText.setText("Lobby Host IP: " + getLocalHostIp());
else
lobbyIpText.setText("Connected to IP: ");
initialiseImageView();
competitors = FXCollections.observableArrayList();
// competitorsListView.setItems(competitors);
initialiseListView();
// initialiseLobbyControllerThread();
// initialiseImageView(); // parrot gif init
// set up client state query thread, so that when it receives the race-started packet
// it can switch to the race view
@@ -99,11 +126,60 @@ public class LobbyController implements Initializable, Observer{
@Override
public void run() {
switchToRaceView();
// initialiseListView();
clientStateQueryingRunnable.terminate();
}
});
}
private void initialiseListView() {
firstListView.setItems(firstCompetitor);
secondListView.setItems(secondCompetitor);
thirdListView.setItems(thirdCompetitor);
fourthListView.setItems(fourthCompetitor);
fifthListView.setItems(fifthCompetitor);
sixthListView.setItems(sixthCompetitor);
seventhListView.setItems(seventhCompetitor);
eighthListView.setItems(eighthCompetitor);
competitors = new ArrayList<>();
Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
for (ObservableList<String> ol : competitors) {
ol = FXCollections.observableArrayList();
}
firstCompetitor.add(ClientState.getClientSourceId());
int competitorIndex = 1;
for (Integer yachtId : ClientState.getBoats().keySet()) {
// break if there are more than 7 competitors
if (competitorIndex >= 8) {
break;
}
if (!yachtId.equals(ClientState.getClientSourceId())) {
competitors.get(competitorIndex).add(String.valueOf(yachtId));
competitorIndex++;
}
}
}
private void initialiseLobbyControllerThread() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
}
});
}
});
thread.start();
}
private void initialiseImageView() {
Image image1 = new Image(getClass().getResourceAsStream("/ParrotGif/alistair.gif"));
firstImageView.setImage(image1);
@@ -159,7 +235,7 @@ public class LobbyController implements Initializable, Observer{
setContentPane("/views/StartScreenView.fxml");
GameState.setCurrentStage(GameStages.CANCELLED);
// TODO: 20/07/17 wmu16 - Implement some way of terminating the game
ClientState.setHost(false);
ClientState.setConnectedToHost(false);
}
@FXML
@@ -2,12 +2,11 @@ package seng302.gameServer;
import java.util.Random;
import seng302.client.ClientPacketParser;
import org.apache.commons.io.IOUtils;
import seng302.models.Player;
import seng302.models.Yacht;
import seng302.models.stream.packets.PacketType;
import seng302.models.stream.packets.StreamPacket;
import seng302.server.messages.Heartbeat;
import seng302.server.messages.BoatActionType;
import seng302.server.messages.Message;
@@ -15,6 +14,8 @@ import java.io.*;
import java.net.Socket;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import seng302.server.messages.XMLMessage;
import seng302.server.messages.XMLMessageSubType;
import seng302.utilities.GeoPoint;
/**
@@ -78,6 +79,20 @@ public class ServerToClientThread implements Runnable {
int sync1;
int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
// used by ryan to simulate sending boats.xml
// InputStream inputStream = getClass().getResourceAsStream("/server_config/boats.xml");
// StringWriter writer = new StringWriter();
// try {
// IOUtils.copy(inputStream, writer);
// } catch (IOException e) {
// e.printStackTrace();
// }
// String xml = writer.toString();
// Message message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
// sendMessage(message);
//-------
while(true) {
try {
@@ -92,9 +107,11 @@ public class ServerToClientThread implements Runnable {
updateClient = false;
}
crcBuffer = new ByteArrayOutputStream();
sync1 = readByte();
sync2 = readByte();
//checking if it is the start of the packet
if(sync1 == 0x47 && sync2 == 0x83) {
int type = readByte();
@@ -204,11 +221,6 @@ public class ServerToClientThread implements Runnable {
}
}
public Thread getThread() {
return thread;
}
public void sendMessage(Message message){
try {
os.write(message.getBuffer());
@@ -216,4 +228,9 @@ public class ServerToClientThread implements Runnable {
e.printStackTrace();
}
}
public Thread getThread() {
return thread;
}
}
+8 -8
View File
@@ -56,38 +56,38 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<ListView fx:id="firstListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin>
</ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
<ListView fx:id="secondListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin>
</ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3">
<ListView fx:id="thirdListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin></ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4">
<ListView fx:id="fourthListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin>
</ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4" GridPane.rowIndex="1">
<ListView fx:id="eighthListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin></ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<ListView fx:id="fifthListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin></ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
<ListView fx:id="sixthListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin></ListView>
<ListView prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3" GridPane.rowIndex="1">
<ListView fx:id="seventhListView" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="40.0" right="40.0" top="10.0" />
</GridPane.margin></ListView>
@@ -37,7 +37,7 @@
<GridPane.margin>
<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">
<TextField fx:id="ipTextField" alignment="CENTER" maxWidth="-Infinity" prefHeight="25.0" prefWidth="148.0" promptText="Host IP" text="132.181.14." GridPane.halignment="RIGHT" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="5.0" right="85.0" top="10.0" />
</GridPane.margin>