From 9d754c881958b056bd72912862e1d93a1430e4f6 Mon Sep 17 00:00:00 2001 From: Zhi You Tan Date: Sun, 23 Jul 2017 20:42:21 +1200 Subject: [PATCH] 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] --- .../seng302/client/ClientPacketParser.java | 56 +++++------- src/main/java/seng302/client/ClientState.java | 32 +++++++ .../seng302/client/ClientToServerThread.java | 13 ++- .../seng302/controllers/LobbyController.java | 88 +++++++++++++++++-- .../gameServer/ServerToClientThread.java | 31 +++++-- src/main/resources/views/LobbyView.fxml | 16 ++-- src/main/resources/views/StartScreenView.fxml | 2 +- 7 files changed, 180 insertions(+), 58 deletions(-) diff --git a/src/main/java/seng302/client/ClientPacketParser.java b/src/main/java/seng302/client/ClientPacketParser.java index afe0dcf6..bfa644e4 100644 --- a/src/main/java/seng302/client/ClientPacketParser.java +++ b/src/main/java/seng302/client/ClientPacketParser.java @@ -38,7 +38,7 @@ public class ClientPacketParser { public static ConcurrentHashMap> 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 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 diff --git a/src/main/java/seng302/client/ClientState.java b/src/main/java/seng302/client/ClientState.java index ab870beb..ce27f99d 100644 --- a/src/main/java/seng302/client/ClientState.java +++ b/src/main/java/seng302/client/ClientState.java @@ -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 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 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 boats) { + ClientState.boats = boats; + } } diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java index 156f1fcd..681ea72f 100644 --- a/src/main/java/seng302/client/ClientToServerThread.java +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -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"); } diff --git a/src/main/java/seng302/controllers/LobbyController.java b/src/main/java/seng302/controllers/LobbyController.java index c87ad5ab..0d0c16d8 100644 --- a/src/main/java/seng302/controllers/LobbyController.java +++ b/src/main/java/seng302/controllers/LobbyController.java @@ -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> competitors = new ArrayList<>(); + private static ObservableList firstCompetitor = FXCollections.observableArrayList(); + private static ObservableList secondCompetitor = FXCollections.observableArrayList(); + private static ObservableList thirdCompetitor = FXCollections.observableArrayList(); + private static ObservableList fourthCompetitor = FXCollections.observableArrayList(); + private static ObservableList fifthCompetitor = FXCollections.observableArrayList(); + private static ObservableList sixthCompetitor = FXCollections.observableArrayList(); + private static ObservableList seventhCompetitor = FXCollections.observableArrayList(); + private static ObservableList 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 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 diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 504b5207..e69032f0 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -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; + } } diff --git a/src/main/resources/views/LobbyView.fxml b/src/main/resources/views/LobbyView.fxml index 71b952fc..1c327227 100644 --- a/src/main/resources/views/LobbyView.fxml +++ b/src/main/resources/views/LobbyView.fxml @@ -56,38 +56,38 @@ - + - + - + - + - + - + - + - + diff --git a/src/main/resources/views/StartScreenView.fxml b/src/main/resources/views/StartScreenView.fxml index a03d6829..67ec761f 100644 --- a/src/main/resources/views/StartScreenView.fxml +++ b/src/main/resources/views/StartScreenView.fxml @@ -37,7 +37,7 @@ - +