diff --git a/src/main/java/seng302/client/ClientPacketParser.java b/src/main/java/seng302/client/ClientPacketParser.java index 3fa5b9ea..85c86fbc 100644 --- a/src/main/java/seng302/client/ClientPacketParser.java +++ b/src/main/java/seng302/client/ClientPacketParser.java @@ -36,11 +36,9 @@ public class ClientPacketParser { public static ConcurrentHashMap> markLocations = new ConcurrentHashMap<>(); public static ConcurrentHashMap> boatLocations = new ConcurrentHashMap<>(); - private String threadName; - private Thread t; 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; @@ -48,10 +46,10 @@ public class ClientPacketParser { private static Map 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; - + private static Map clientStateBoats = new ConcurrentHashMap<>(); //CONVERSION CONSTANTS private static final Double MS_TO_KNOTS = 1.94384; @@ -121,7 +119,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 +171,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; @@ -186,41 +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); -// 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){ @@ -288,9 +282,10 @@ public class ClientPacketParser { xmlObject.constructXML(doc, messageType); if (messageType == 7) { //7 is the boat XML boats = xmlObject.getBoatXML().getCompetingBoats(); + ClientState.setBoats(xmlObject.getBoatXML().getCompetingBoats()); + ClientState.setDirtyState(true); } if (messageType == 6) { //6 is race info xml - newRaceXmlReceived = true; } } @@ -378,7 +373,7 @@ public class ClientPacketParser { //type 1 is a racing yacht and type 3 is a mark, needed for updating positions of the mark and boat if (deviceType == 1){ Yacht boat = boats.get((int) boatId); -// boat.setVelocity(groundSpeed); + boat.setVelocity(groundSpeed); BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); //add a new priority que to the boatLocations HashMap diff --git a/src/main/java/seng302/client/ClientState.java b/src/main/java/seng302/client/ClientState.java new file mode 100644 index 00000000..64512a1b --- /dev/null +++ b/src/main/java/seng302/client/ClientState.java @@ -0,0 +1,78 @@ +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; + +/** + * Used by the client to store static variables to be used in game. + */ +public class ClientState { + + private static String hostIp = ""; + 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; + } + + 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; + } + + 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/ClientStateQueryingRunnable.java b/src/main/java/seng302/client/ClientStateQueryingRunnable.java new file mode 100644 index 00000000..a71d045b --- /dev/null +++ b/src/main/java/seng302/client/ClientStateQueryingRunnable.java @@ -0,0 +1,40 @@ +package seng302.client; + +import java.util.Observable; + +/** + * Used by LobbyController to run a separate thread-loop + * updates the controller when change is detected. + */ +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(); +// } + // Sleeping the thread so it will respond to the if statement below + // if you know a better fix, pls tell me :) -ryan + try { + Thread.sleep(0); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (ClientState.isDirtyState()) { + setChanged(); + notifyObservers(); + ClientState.setDirtyState(false); + } + } + } + + public void terminate() { + terminate = true; + } +} diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java index f2f73c7b..0f405819 100644 --- a/src/main/java/seng302/client/ClientToServerThread.java +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -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,19 +31,16 @@ public class ClientToServerThread implements Runnable { private Boolean updateClient = true; private ByteArrayOutputStream crcBuffer; - public ClientToServerThread(String ipAddress, Integer portNumber){ - try { - socket = new Socket(ipAddress, portNumber); - is = socket.getInputStream(); - os = socket.getOutputStream(); - } catch (IOException e) { - e.printStackTrace(); - } + public ClientToServerThread(String ipAddress, Integer portNumber) throws Exception{ + 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(); @@ -64,7 +62,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) { @@ -99,14 +97,17 @@ public class ClientToServerThread implements Runnable { } else { System.err.println("Packet has been dropped"); } + } + } catch (Exception e) { closeSocket(); e.printStackTrace(); 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 eb3d7b75..8454d7dd 100644 --- a/src/main/java/seng302/controllers/LobbyController.java +++ b/src/main/java/seng302/controllers/LobbyController.java @@ -5,18 +5,28 @@ 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; +import javafx.application.Platform; import javafx.collections.FXCollections; 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; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.scene.text.Text; +import seng302.client.ClientState; +import seng302.client.ClientStateQueryingRunnable; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; @@ -24,16 +34,56 @@ 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; @FXML private GridPane lobbyScreen; @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; + @FXML + private ImageView thirdImageView; + @FXML + private ImageView fourthImageView; + @FXML + private ImageView fifthImageView; + @FXML + private ImageView sixthImageView; + @FXML + private ImageView seventhImageView; + @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) { try { @@ -52,57 +102,128 @@ public class LobbyController implements Initializable{ @Override public void initialize(URL location, ResourceBundle resources) { - lobbyIpText.setText("Lobby Host IP: " + getLocalHostIp()); + if (ClientState.isHost()) + lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp()); + else + lobbyIpText.setText("Connected to IP: "); + 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 + ClientStateQueryingRunnable clientStateQueryingRunnable = new ClientStateQueryingRunnable(); + clientStateQueryingRunnable.addObserver(this); + Thread clientStateQueryingThread = new Thread(clientStateQueryingRunnable, "Client State querying thread"); + clientStateQueryingThread.setDaemon(true); + clientStateQueryingThread.start(); } - public void initialize() { - competitors = FXCollections.observableArrayList(); - competitorsListView.setItems(competitors); - } - - private String getLocalHostIp() { - String ipAddress = null; - try { - Enumeration e = NetworkInterface.getNetworkInterfaces(); - while (e.hasMoreElements()) { - NetworkInterface ni = e.nextElement(); - if (ni.isLoopback()) - continue; - if(ni.isPointToPoint()) - continue; - if(ni.isVirtual()) - continue; - - Enumeration addresses = ni.getInetAddresses(); - while(addresses.hasMoreElements()) { - InetAddress address = addresses.nextElement(); - if(address instanceof Inet4Address) { // skip all ipv6 - ipAddress = address.getHostAddress(); - } - } + @Override + public void update(Observable o, Object arg) { + Platform.runLater(new Runnable() { + @Override + public void run() { +// switchToRaceView(); + initialiseListView(); +// clientStateQueryingRunnable.terminate(); } - } catch (Exception e) { - e.printStackTrace(); + }); + } + + private void initialiseListView() { + firstListView.getItems().clear(); + secondListView.getItems().clear(); + thirdListView.getItems().clear(); + fourthListView.getItems().clear(); + fifthListView.getItems().clear(); + sixthListView.getItems().clear(); + seventhListView.getItems().clear(); + eighthListView.getItems().clear(); + + competitors = new ArrayList<>(); + Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor, + fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor); + + for (ObservableList ol : competitors) { + ol.removeAll(); } - if (ipAddress == null) { - System.out.println("[HOST] Cannot obtain local host ip address."); + + 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++; + } } - return ipAddress; + + + + firstListView.setItems(firstCompetitor); + secondListView.setItems(secondCompetitor); + thirdListView.setItems(thirdCompetitor); + fourthListView.setItems(fourthCompetitor); + fifthListView.setItems(fifthCompetitor); + sixthListView.setItems(sixthCompetitor); + seventhListView.setItems(seventhCompetitor); + eighthListView.setItems(eighthCompetitor); + } + + 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); + Image image2 = new Image(getClass().getResourceAsStream("/ParrotGif/calum.gif")); + secondImageView.setImage(image2); + Image image3 = new Image(getClass().getResourceAsStream("/ParrotGif/haoming.gif")); + thirdImageView.setImage(image3); + Image image4 = new Image(getClass().getResourceAsStream("/ParrotGif/kusal.gif")); + fourthImageView.setImage(image4); + Image image5 = new Image(getClass().getResourceAsStream("/ParrotGif/michael.gif")); + fifthImageView.setImage(image5); + Image image6 = new Image(getClass().getResourceAsStream("/ParrotGif/peter.gif")); + sixthImageView.setImage(image6); + Image image7 = new Image(getClass().getResourceAsStream("/ParrotGif/ryan.gif")); + seventhImageView.setImage(image7); + Image image8 = new Image(getClass().getResourceAsStream("/ParrotGif/will.gif")); + eighthImageView.setImage(image8); } @FXML 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 + ClientState.setConnectedToHost(false); } - @FXML public void readyButtonPressed() { GameState.setCurrentStage(GameStages.RACING); + } + + private void switchToRaceView() { setContentPane("/views/RaceView.fxml"); } } diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 16eac429..e2cadecd 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -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(); }) ); diff --git a/src/main/java/seng302/controllers/StartScreenController.java b/src/main/java/seng302/controllers/StartScreenController.java index 588e1b57..0cf7f594 100644 --- a/src/main/java/seng302/controllers/StartScreenController.java +++ b/src/main/java/seng302/controllers/StartScreenController.java @@ -1,11 +1,17 @@ package seng302.controllers; +import java.net.Inet4Address; +import java.net.NetworkInterface; +import java.util.Enumeration; 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 +29,8 @@ public class StartScreenController { @FXML private TextField ipTextField; @FXML + private TextField portTextField; + @FXML private GridPane startScreen2; private Controller controller; @@ -54,43 +62,99 @@ public class StartScreenController { /** * ATTEMPTS TO: * Sets up a new game state with your IP address as designated as the host. - * Starts a thread to listen for incoming connections + * Starts a thread to listen for incoming connections. + * Starts a client to server thread and connects to own ip. * Switches to the lobby screen */ @FXML public void hostButtonPressed() { try { String ipAddress = InetAddress.getLocalHost().getHostAddress(); - new GameState(ipAddress); - new MainServerThread(); - ClientToServerThread clientToServerThread = new ClientToServerThread("localhost", 4950); - controller.setClientToServerThread(clientToServerThread); -// new GameServerThread("Fuck you"); // get the lobby controller so that we can pass the game server thread to it + new GameState(getLocalHostIp()); + new MainServerThread(); + ClientState.setHost(true); + // host will connect and handshake to itself after setting up the server + ClientToServerThread clientToServerThread = new ClientToServerThread(ClientState.getHostIp(), 4950); + ClientState.setConnectedToHost(true); + controller.setClientToServerThread(clientToServerThread); 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(); } + } - + /** + * ATTEMPTS TO: + * Connect to an ip address and port using the ip and port specified on start screen. + * Starts a Client To Server Thread to maintain connection to host. + * Switch view to lobby view. + */ @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); + ClientState.setHost(false); + ClientState.setConnectedToHost(true); + controller.setClientToServerThread(clientToServerThread); 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(); } } public void setController(Controller controller) { this.controller = controller; } + + /** + * Gets the local host ip address and sets this ip to ClientState. + * Only runs by the host. + * + * @return the localhost ip address + */ + private String getLocalHostIp() { + String ipAddress = null; + try { + Enumeration e = NetworkInterface.getNetworkInterfaces(); + while (e.hasMoreElements()) { + NetworkInterface ni = e.nextElement(); + if (ni.isLoopback()) + continue; + if(ni.isPointToPoint()) + continue; + if(ni.isVirtual()) + continue; + + Enumeration addresses = ni.getInetAddresses(); + while(addresses.hasMoreElements()) { + InetAddress address = addresses.nextElement(); + if(address instanceof Inet4Address) { // skip all ipv6 + ipAddress = address.getHostAddress(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + if (ipAddress == null) { + System.out.println("[HOST] Cannot obtain local host ip address."); + } + ClientState.setHostIp(ipAddress); + return ipAddress; + } } diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 63cb9f92..70c5653c 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -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() { diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index c9924a29..3294c9a2 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -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); } diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 8f61a091..5f97b538 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Random; import java.util.zip.CRC32; import java.util.zip.Checksum; +import org.apache.commons.io.IOUtils; import seng302.models.Player; import seng302.models.Yacht; import seng302.models.stream.packets.PacketType; @@ -20,6 +21,13 @@ import seng302.models.xml.XMLGenerator; import seng302.server.messages.BoatActionType; import seng302.server.messages.BoatLocationMessage; import seng302.server.messages.Message; + +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.server.messages.XMLMessage; import seng302.server.messages.XMLMessageSubType; import seng302.utilities.GeoPoint; @@ -89,8 +97,76 @@ 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/boats1.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); +// System.out.println("[server] send message 1 " + message); +// +// try { +// Thread.sleep(3000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// inputStream = getClass().getResourceAsStream("/server_config/boats.xml"); +// writer = new StringWriter(); +// try { +// IOUtils.copy(inputStream, writer); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// xml = writer.toString(); +// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0); +// sendMessage(message); +// System.out.println("[server] send message 2 " + message); +// +// try { +// Thread.sleep(3000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// inputStream = getClass().getResourceAsStream("/server_config/boats2.xml"); +// writer = new StringWriter(); +// try { +// IOUtils.copy(inputStream, writer); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// xml = writer.toString(); +// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0); +// sendMessage(message); +// System.out.println("[server] send message 3 " + message); +// +// try { +// Thread.sleep(3000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// inputStream = getClass().getResourceAsStream("/server_config/boats.xml"); +// writer = new StringWriter(); +// try { +// IOUtils.copy(inputStream, writer); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// xml = writer.toString(); +// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0); +// sendMessage(message); +// System.out.println("[server] send message 4 " + message); + //------- + while(true) { - //System.out.print("."); try { if (initialisedRace) { @@ -275,6 +351,8 @@ public class ServerToClientThread implements Runnable { } } + } + public Thread getThread() { return thread; diff --git a/src/main/resources/ParrotGif/alistair.gif b/src/main/resources/ParrotGif/alistair.gif new file mode 100644 index 00000000..ce003789 Binary files /dev/null and b/src/main/resources/ParrotGif/alistair.gif differ diff --git a/src/main/resources/ParrotGif/calum.gif b/src/main/resources/ParrotGif/calum.gif new file mode 100644 index 00000000..03d495ed Binary files /dev/null and b/src/main/resources/ParrotGif/calum.gif differ diff --git a/src/main/resources/ParrotGif/haoming.gif b/src/main/resources/ParrotGif/haoming.gif new file mode 100644 index 00000000..33b26de6 Binary files /dev/null and b/src/main/resources/ParrotGif/haoming.gif differ diff --git a/src/main/resources/ParrotGif/kusal.gif b/src/main/resources/ParrotGif/kusal.gif new file mode 100644 index 00000000..1372928c Binary files /dev/null and b/src/main/resources/ParrotGif/kusal.gif differ diff --git a/src/main/resources/ParrotGif/michael.gif b/src/main/resources/ParrotGif/michael.gif new file mode 100644 index 00000000..83ea1dff Binary files /dev/null and b/src/main/resources/ParrotGif/michael.gif differ diff --git a/src/main/resources/ParrotGif/parrot.gif b/src/main/resources/ParrotGif/parrot.gif new file mode 100644 index 00000000..458ad859 Binary files /dev/null and b/src/main/resources/ParrotGif/parrot.gif differ diff --git a/src/main/resources/ParrotGif/peter.gif b/src/main/resources/ParrotGif/peter.gif new file mode 100644 index 00000000..470b46cf Binary files /dev/null and b/src/main/resources/ParrotGif/peter.gif differ diff --git a/src/main/resources/ParrotGif/ryan.gif b/src/main/resources/ParrotGif/ryan.gif new file mode 100644 index 00000000..b518c777 Binary files /dev/null and b/src/main/resources/ParrotGif/ryan.gif differ diff --git a/src/main/resources/ParrotGif/will.gif b/src/main/resources/ParrotGif/will.gif new file mode 100644 index 00000000..e7b762de Binary files /dev/null and b/src/main/resources/ParrotGif/will.gif differ diff --git a/src/main/resources/server_config/boats1.xml b/src/main/resources/server_config/boats1.xml new file mode 100644 index 00000000..401e7bf6 --- /dev/null +++ b/src/main/resources/server_config/boats1.xml @@ -0,0 +1,171 @@ + + + 2015-08-28T17:32:59+0100 + 12 + 219 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/server_config/boats2.xml b/src/main/resources/server_config/boats2.xml new file mode 100644 index 00000000..c7255771 --- /dev/null +++ b/src/main/resources/server_config/boats2.xml @@ -0,0 +1,161 @@ + + + 2015-08-28T17:32:59+0100 + 12 + 219 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/server_config/boats3.xml b/src/main/resources/server_config/boats3.xml new file mode 100644 index 00000000..401e7bf6 --- /dev/null +++ b/src/main/resources/server_config/boats3.xml @@ -0,0 +1,171 @@ + + + 2015-08-28T17:32:59+0100 + 12 + 219 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/views/LobbyView.fxml b/src/main/resources/views/LobbyView.fxml index 4e413c61..1c327227 100644 --- a/src/main/resources/views/LobbyView.fxml +++ b/src/main/resources/views/LobbyView.fxml @@ -1,5 +1,6 @@ + @@ -13,14 +14,14 @@ - + - - + + @@ -28,7 +29,7 @@ - + @@ -41,27 +42,96 @@ + + + @@ -44,5 +47,13 @@ + + + + + + + +