diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 43668bdf..0b36ab16 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -429,7 +429,6 @@ public class GameState implements Runnable { private void checkForLegProgression(ServerYacht yacht) { Integer currentMarkSeqID = yacht.getCurrentMarkSeqID(); CompoundMark currentMark = markOrder.getCurrentMark(currentMarkSeqID); -// System.out.println(yacht.getCurrentMarkSeqID()); Boolean hasProgressed; if (currentMarkSeqID == 0) { diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index ad6c6887..83fb304c 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -92,6 +92,9 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { // TODO: 14/07/17 wmu16 - Send out disconnect packet to clients try { + for (ServerToClientThread serverToClientThread : serverToClientThreads) { + serverToClientThread.terminate(); + } serverSocket.close(); return; } catch (IOException e) { @@ -172,6 +175,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { thread.sendSetupMessages(); } }); + serverToClientThread.addDisconnectListener(this::clientDisconnected); } /** @@ -181,11 +185,11 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { */ @Override public void clientDisconnected(Player player) { - try { - player.getSocket().close(); - } catch (Exception e) { - serverLog("Cannot disconnect the socket for the disconnected player.", 0); - } +// try { +// player.getSocket().close(); +// } catch (Exception e) { +// serverLog("Cannot disconnect the socket for the disconnected player.", 0); +// } serverLog("Player " + player.getYacht().getSourceId() + "'s socket disconnected", 0); GameState.removeYacht(player.getYacht().getSourceId()); GameState.removePlayer(player); @@ -193,11 +197,12 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { for (ServerToClientThread serverToClientThread : serverToClientThreads) { if (serverToClientThread.getSocket() == player.getSocket()) { closedConnection = serverToClientThread; - } else { + } else if (GameState.getCurrentStage() != GameStages.RACING){ serverToClientThread.sendSetupMessages(); } } serverToClientThreads.remove(closedConnection); + closedConnection.terminate(); } public void startGame() { diff --git a/src/main/java/seng302/gameServer/ServerListenThread.java b/src/main/java/seng302/gameServer/ServerListenThread.java index e05b76a9..2c220ca2 100644 --- a/src/main/java/seng302/gameServer/ServerListenThread.java +++ b/src/main/java/seng302/gameServer/ServerListenThread.java @@ -38,7 +38,7 @@ public class ServerListenThread implements Runnable { } public void run(){ - while (true){ + while (serverSocket != null && !serverSocket.isClosed()){ acceptConnection(); } } diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 0b735f44..3a9b4057 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -40,17 +40,20 @@ import seng302.model.stream.xml.generator.Regatta; import seng302.utilities.XMLGenerator; import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatLocationMessage; -import seng302.gameServer.messages.BoatSubMessage; import seng302.gameServer.messages.ClientType; import seng302.gameServer.messages.Message; -import seng302.gameServer.messages.RaceStatus; -import seng302.gameServer.messages.RaceStatusMessage; -import seng302.gameServer.messages.RaceType; import seng302.gameServer.messages.RegistrationResponseMessage; import seng302.gameServer.messages.RegistrationResponseStatus; import seng302.gameServer.messages.XMLMessage; import seng302.gameServer.messages.XMLMessageSubType; +import seng302.gameServer.messages.YachtEventCodeMessage; +import seng302.model.Player; import seng302.model.ServerYacht; +import seng302.model.stream.packets.PacketType; +import seng302.model.stream.packets.StreamPacket; +import seng302.model.stream.xml.generator.Race; +import seng302.model.stream.xml.generator.Regatta; +import seng302.utilities.XMLGenerator; /** * A class describing a single connection to a Client for the purposes of sending and receiving on @@ -67,6 +70,12 @@ public class ServerToClientThread implements Runnable, Observer { void notifyConnection (); } + // TODO: 17/08/17 this is only temporary disconnects should be handled consistently + @FunctionalInterface + interface DisconnectListener { + void notifyDisconnect (Player player); + } + private Logger logger = LoggerFactory.getLogger(ServerToClientThread.class); private Thread thread; @@ -86,8 +95,10 @@ public class ServerToClientThread implements Runnable, Observer { private XMLGenerator xml; private List connectionListeners = new ArrayList<>(); + private DisconnectListener disconnectListener; private ServerYacht yacht; + private Player player; public ServerToClientThread(Socket socket) { this.socket = socket; @@ -134,8 +145,9 @@ public class ServerToClientThread implements Runnable, Observer { ); yacht.addObserver(this); // TODO: yacht can notify mark rounding message hyi25 13/8/17 + player = new Player(socket, yacht); GameState.addYacht(sourceId, yacht); - GameState.addPlayer(new Player(socket, yacht)); + GameState.addPlayer(player); } @Override @@ -181,8 +193,7 @@ public class ServerToClientThread implements Runnable, Observer { int sync2; // TODO: 14/07/17 wmu16 - Work out how to fix this while loop - while (socket.isConnected()) { - + while (socket.isConnected() && !socket.isClosed()) { try { crcBuffer = new ByteArrayOutputStream(); sync1 = readByte(); @@ -200,7 +211,6 @@ public class ServerToClientThread implements Runnable, Observer { long computedCrc = checksum.getValue(); long packetCrc = Message.bytesToLong(getBytes(4)); if (computedCrc == packetCrc) { - //System.out.println("RECEIVED A PACKET"); switch (PacketType.assignPacketType(type, payload)) { case BOAT_ACTION: BoatAction actionType = ServerPacketParser @@ -237,6 +247,7 @@ public class ServerToClientThread implements Runnable, Observer { return; } } + logger.warn("Closed serverToClientThread" + thread, 1); } public void sendSetupMessages() { @@ -248,7 +259,11 @@ public class ServerToClientThread implements Runnable, Observer { } //@TODO calculate lat/lng values - xml.setRegatta(new Regatta("Party Parrot Test Server", "Bermuda Test Course", 57.6679590, 11.8503233)); + xml.setRegatta( + new Regatta( + "Party Parrot Test Server", "Bermuda Test Course", + 57.6679590, 11.8503233) + ); xml.setRace(race); XMLMessage xmlMessage; @@ -276,10 +291,12 @@ public class ServerToClientThread implements Runnable, Observer { private int readByte() throws Exception { int currentByte = -1; try { - // @TODO @FIX ConnectionReset Exception when a client disconnects before it is garbage collected currentByte = is.read(); crcBuffer.write(currentByte); + } catch (SocketException se) { + disconnectListener.notifyDisconnect(this.player); } catch (IOException e) { + disconnectListener.notifyDisconnect(this.player); logger.warn("Socket read failed", 1); } if (currentByte == -1) { @@ -306,8 +323,7 @@ public class ServerToClientThread implements Runnable, Observer { try { os.write(message.getBuffer()); } catch (SocketException e) { - //serverLog("Player " + sourceId + " side socket disconnected", 1); - return; + logger.warn("Player " + sourceId + " side socket disconnected", 1); } catch (IOException e) { logger.warn("Message send failed", 1); } @@ -358,4 +374,16 @@ public class ServerToClientThread implements Runnable, Observer { public void removeConnectionListener(ConnectionListener listener) { connectionListeners.remove(listener); } + + public void terminate () { + try { + socket.close(); + } catch (IOException ioe) { + logger.warn("IOException attempting to terminate serverToClientThread " + this.thread); + } + } + + public void addDisconnectListener(DisconnectListener disconnectListener) { + this.disconnectListener = disconnectListener; + } } diff --git a/src/main/java/seng302/visualiser/ClientToServerThread.java b/src/main/java/seng302/visualiser/ClientToServerThread.java index 11afdcb8..57256760 100644 --- a/src/main/java/seng302/visualiser/ClientToServerThread.java +++ b/src/main/java/seng302/visualiser/ClientToServerThread.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -15,10 +14,6 @@ import java.util.TimerTask; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.zip.CRC32; import java.util.zip.Checksum; -import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.ButtonType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import seng302.gameServer.messages.BoatAction; @@ -48,16 +43,20 @@ public class ClientToServerThread implements Runnable { void newPacket(); } + @FunctionalInterface + public interface DisconnectedFromHostListener { + void notifYDisconnection (String message); + } + private class ByteReadException extends Exception { private ByteReadException(String message) { super(message); } } - private static final int LOG_LEVEL = 1; - private Queue streamPackets = new ConcurrentLinkedQueue<>(); private List listeners = new ArrayList<>(); + private List disconnectionListeners = new ArrayList<>(); private Thread thread; private Socket socket; @@ -74,7 +73,6 @@ public class ClientToServerThread implements Runnable { private int clientId = -1; -// private Boolean updateClient = true; private ByteArrayOutputStream crcBuffer; private boolean socketOpen = true; @@ -101,20 +99,6 @@ public class ClientToServerThread implements Runnable { thread.start(); } - /** - * Prints out log messages and the time happened. - * Only perform task if log level is below LOG_LEVEL variable. - * - * @param message a string of message to be printed out - * @param logLevel an int for log level - */ - static void clientLog(String message, int logLevel) { - if (logLevel <= LOG_LEVEL) { - System.out.println( - "[CLIENT " + LocalDateTime.now().toLocalTime().toString() + "] " + message); - } - } - /** * Perform the thread loop. It exits the loop if ClientState connected to host * variable is false. @@ -123,7 +107,7 @@ public class ClientToServerThread implements Runnable { int sync1; int sync2; // TODO: 14/07/17 wmu16 - Work out how to fix this while loop - while(socketOpen) { + while(!socket.isClosed() && socket.isConnected() && socketOpen) { try { crcBuffer = new ByteArrayOutputStream(); sync1 = readByte(); @@ -155,24 +139,18 @@ public class ClientToServerThread implements Runnable { } } } else { - clientLog("Packet has been dropped", 1); + logger.warn("Packet has been dropped", 1); } } } catch (ByteReadException e) { - e.printStackTrace(); + logger.warn("Byte read exception on ClientToServerThread", 1); + notifyDisconnectListeners("Connection to server was interrupted"); closeSocket(); - Platform.runLater(() -> { - Alert alert = new Alert(AlertType.ERROR); - alert.setHeaderText("Host has disconnected"); - alert.setContentText("Cannot find Server"); - alert.showAndWait(); - }); - clientLog(e.getMessage(), 1); - return; } } + logger.warn("Closed connection to server", 1); + notifyDisconnectListeners("Connection to server was terminated"); closeSocket(); - clientLog("Closed connection to Server", 0); } public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) { @@ -181,8 +159,17 @@ public class ClientToServerThread implements Runnable { os.write(requestMessage.getBuffer()); } catch (IOException e) { logger.error("Could not send customization request"); + notifyDisconnectListeners("Could not communicate with server"); + closeSocket(); } + } + private void notifyDisconnectListeners (String message) { + if (socketOpen) { + for (DisconnectedFromHostListener listener : disconnectionListeners) { + listener.notifYDisconnection(message); + } + } } /** @@ -195,7 +182,8 @@ public class ClientToServerThread implements Runnable { os.write(requestMessage.getBuffer()); } catch (IOException e) { logger.error("Could not send registration request. Exiting"); - System.exit(1); + notifyDisconnectListeners("Failed to register with server"); + closeSocket(); } } @@ -211,7 +199,6 @@ public class ClientToServerThread implements Runnable { if (status.equals(RegistrationResponseStatus.SUCCESS_PLAYING)){ clientId = sourceId; - return; } @@ -225,11 +212,8 @@ public class ClientToServerThread implements Runnable { else{ alertErrorText = "Could not connect to server"; } - - Platform.runLater(() -> { - new Alert(AlertType.ERROR, alertErrorText, ButtonType.OK).showAndWait(); - System.exit(1); - }); + notifyDisconnectListeners(alertErrorText); + closeSocket(); } /** @@ -260,7 +244,7 @@ public class ClientToServerThread implements Runnable { new TimerTask() { @Override public void run() { - sendBoatAction(new BoatActionMessage(BoatAction.DOWNWIND)); + sendBoatActionMessage(new BoatActionMessage(BoatAction.DOWNWIND)); } }, 0, PACKET_SENDING_INTERVAL_MS ); @@ -273,14 +257,14 @@ public class ClientToServerThread implements Runnable { new TimerTask() { @Override public void run() { - sendBoatAction(new BoatActionMessage(BoatAction.UPWIND)); + sendBoatActionMessage(new BoatActionMessage(BoatAction.UPWIND)); } }, 0, PACKET_SENDING_INTERVAL_MS ); } break; default: - sendBoatAction(new BoatActionMessage(actionType)); + sendBoatActionMessage(new BoatActionMessage(actionType)); break; } } @@ -298,12 +282,14 @@ public class ClientToServerThread implements Runnable { * Sends a boat action of the given message type. * @param message The given message type. */ - private void sendBoatAction(BoatActionMessage message) { + private void sendBoatActionMessage(BoatActionMessage message) { if (clientId != -1) { try { os.write(message.getBuffer()); } catch (IOException e) { - clientLog("Could not write to server", 1); + logger.warn("IOException on attempting to sendBoatAction from Client"); + notifyDisconnectListeners("Cannot communicate with server"); + closeSocket(); } } } @@ -311,8 +297,9 @@ public class ClientToServerThread implements Runnable { private void closeSocket() { try { socket.close(); + socketOpen = false; } catch (IOException e) { - clientLog("Failed to close the socket", 1); + logger.warn("IOException on attempting to close ClientToServerSocket"); } } @@ -332,16 +319,28 @@ public class ClientToServerThread implements Runnable { listeners.remove(streamListener); } + public void addDisconnectionListener (DisconnectedFromHostListener listener) { + disconnectionListeners.add(listener); + } + + public void removeDisconnectionListener (DisconnectedFromHostListener listener) { + disconnectionListeners.remove(listener); + } + private int readByte() throws ByteReadException { int currentByte = -1; try { currentByte = is.read(); crcBuffer.write(currentByte); } catch (IOException e) { - clientLog("Read byte failed", 1); + logger.warn("IOException on readByte Client side", 1); + notifyDisconnectListeners("Cannot read from server."); + closeSocket(); } if (currentByte == -1) { - clientLog("InputStream reach end of stream", 1); + notifyDisconnectListeners("Cannot read from server."); + closeSocket(); + logger.warn("InputStream reach end of stream", 1); } return currentByte; } @@ -360,8 +359,7 @@ public class ClientToServerThread implements Runnable { } } - public int getClientId () { + int getClientId () { return clientId; } - } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 846fadd9..968d9a92 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -10,13 +10,14 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXMLLoader; import javafx.scene.Node; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; import seng302.gameServer.GameState; import seng302.gameServer.MainServerThread; import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatStatus; -import seng302.gameServer.messages.BoatAction; import seng302.model.ClientYacht; import seng302.model.RaceState; import seng302.model.stream.packets.StreamPacket; @@ -70,27 +71,32 @@ public class GameClient { */ public void runAsClient(String ipAddress, Integer portNumber) { try { - socketThread = new ClientToServerThread(ipAddress, portNumber); + startClientToServerThread(ipAddress, portNumber); + socketThread.addDisconnectionListener((cause) -> { + showConnectionError(cause); + Platform.runLater(this::loadStartScreen); + }); + socketThread.addStreamObserver(this::parsePackets); + LobbyController lobbyController = loadLobby(); + lobbyController.setSocketThread(socketThread); + lobbyController.setPlayerID(socketThread.getClientId()); + lobbyController.setPlayerListSource(clientLobbyList); + lobbyController.disableReadyButton(); + if (regattaData != null){ + lobbyController.setTitle(regattaData.getRegattaName()); + lobbyController.setCourseName(regattaData.getCourseName()); + } + else{ + lobbyController.setTitle(ipAddress); + lobbyController.setCourseName(""); + } + + lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); + this.lobbyController = lobbyController; } catch (IOException ioe) { - ioe.printStackTrace(); - System.out.println("Unable to connect to host..."); + showConnectionError("Unable to find server"); + Platform.runLater(this::loadStartScreen); } - - socketThread.addStreamObserver(this::parsePackets); - LobbyController lobbyController = loadLobby(); - lobbyController.disableReadyButton(); - - if (regattaData != null){ - lobbyController.setTitle(regattaData.getRegattaName()); - lobbyController.setCourseName(regattaData.getCourseName()); - } - else{ - lobbyController.setTitle(ipAddress); - lobbyController.setCourseName(""); - } - - lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); - this.lobbyController = lobbyController; } /** @@ -101,36 +107,38 @@ public class GameClient { public void runAsHost(String ipAddress, Integer portNumber) { server = new MainServerThread(); try { - socketThread = new ClientToServerThread(ipAddress, portNumber); - } catch (IOException ioe) { - ioe.printStackTrace(); - System.out.println("Unable to make local connection to host..."); - } - socketThread.addStreamObserver(this::parsePackets); - LobbyController lobbyController = loadLobby(); - lobbyController.setPlayerListSource(clientLobbyList); - - if (regattaData != null){ - lobbyController.setTitle("Hosting: " + regattaData.getRegattaName()); - lobbyController.setCourseName(regattaData.getCourseName()); - } - else{ - lobbyController.setTitle("Hosting: " + ipAddress); - lobbyController.setCourseName(""); - } - - lobbyController.addCloseListener(exitCause -> { - if (exitCause == CloseStatus.READY) { - GameState.resetStartTime(); - lobbyController.disableReadyButton(); - server.startGame(); - } else if (exitCause == CloseStatus.LEAVE) { - loadStartScreen(); + startClientToServerThread(ipAddress, portNumber); + socketThread.addDisconnectionListener((cause) -> { + Platform.runLater(this::loadStartScreen); + }); + LobbyController lobbyController = loadLobby(); + lobbyController.setSocketThread(socketThread); + lobbyController.setPlayerID(socketThread.getClientId()); + lobbyController.setPlayerListSource(clientLobbyList); + if (regattaData != null) { + lobbyController.setTitle("Hosting: " + regattaData.getRegattaName()); + lobbyController.setCourseName(regattaData.getCourseName()); + } else { + lobbyController.setTitle("Hosting: " + ipAddress); + lobbyController.setCourseName(""); } - }); - this.lobbyController = lobbyController; - //server.setGameClient(this); + lobbyController.addCloseListener(exitCause -> { + if (exitCause == CloseStatus.READY) { + GameState.resetStartTime(); + lobbyController.disableReadyButton(); + server.startGame(); + } else if (exitCause == CloseStatus.LEAVE) { + server.terminate(); + server = null; + loadStartScreen(); + } + }); + this.lobbyController = lobbyController; + } catch (IOException ioe) { + showConnectionError("Cannot connect to server as host"); + Platform.runLater(this::loadStartScreen); + } } private void loadStartScreen() { @@ -145,10 +153,24 @@ public class GameClient { holderPane.getChildren().clear(); holderPane.getChildren().add(fxmlLoader.load()); } catch (IOException e) { - e.printStackTrace(); + showConnectionError("JavaFX crashed. Please restart the app"); } } + private void showConnectionError (String message) { + Platform.runLater(() -> { + Alert alert = new Alert(AlertType.ERROR); + alert.setHeaderText("Connection Error"); + alert.setContentText(message); + alert.showAndWait(); + }); + } + + private void startClientToServerThread (String ipAddress, int portNumber) throws IOException { + socketThread = new ClientToServerThread(ipAddress, portNumber); + socketThread.addStreamObserver(this::parsePackets); + } + /** * Loads a view of the lobby into the clients pane * @@ -163,12 +185,7 @@ public class GameClient { } catch (IOException e) { e.printStackTrace(); } - LobbyController lobbyController = fxmlLoader.getController(); - lobbyController.setSocketThread(socketThread); - lobbyController.setPlayerListSource(clientLobbyList); - lobbyController.setPlayerID(socketThread.getClientId()); - - return lobbyController; + return fxmlLoader.getController(); } private void loadRaceView() { diff --git a/src/main/java/seng302/visualiser/GameView.java b/src/main/java/seng302/visualiser/GameView.java index 10ef749e..99a49021 100644 --- a/src/main/java/seng302/visualiser/GameView.java +++ b/src/main/java/seng302/visualiser/GameView.java @@ -278,7 +278,31 @@ public class GameView extends Pane { colour = Color.BLACK; } - //Creating mark arrows. + createMarkArrows(sequence); + + //Scale race to markers if there is no border. + if (borderPoints == null) { + rescaleRace(new ArrayList<>(markerObjects.keySet())); + } + //Move the Markers to initial position. + markerObjects.forEach(((mark, marker) -> { + Point2D p2d = findScaledXY(mark.getLat(), mark.getLng()); + marker.setLayoutX(p2d.getX()); + marker.setLayoutY(p2d.getY()); + })); + Platform.runLater(() -> { + markers.getChildren().clear(); + markers.getChildren().addAll(gates); + markers.getChildren().addAll(markerObjects.values()); + }); + } + + /** + * Calculates all the data needed for to create mark arrows. Requires that a course has been + * added to the gameview. + * @param sequence The order in which marks are traversed. + */ + private void createMarkArrows (List sequence) { for (int i=1; i < sequence.size()-1; i++) { //General case. double averageLat = 0; double averageLng = 0; @@ -298,7 +322,7 @@ public class GameView extends Pane { averageLng += mark.getLng(); } GeoPoint nextMarkAv = new GeoPoint(averageLat / numMarks, averageLng / numMarks); - // TODO: 16/08/17 This comparison is cancer and deserves to die. + // TODO: 16/08/17 This comparison doesn't need to exist but the alternative is to user server enum client side. for (Mark mark : course.get(i).getMarks()) { markerObjects.get(mark).addArrows( mark.getRoundingSide() == RoundingSide.STARBOARD ? MarkArrowFactory.RoundingSide.STARBOARD : MarkArrowFactory.RoundingSide.PORT, @@ -307,9 +331,11 @@ public class GameView extends Pane { ); } } + createStartLineArrows(); + createFinishLineArrows(); + } - // TODO: 16/08/17 Make this cleaner - //First mark case + private void createStartLineArrows () { double averageLat = 0; double averageLng = 0; int numMarks = 0; @@ -326,10 +352,12 @@ public class GameView extends Pane { GeoUtility.getBearing(mark, firstMarkAv) ); } - //Last Mark case - numMarks = 0; - averageLat = 0; - averageLng = 0; + } + + private void createFinishLineArrows () { + double numMarks = 0; + double averageLat = 0; + double averageLng = 0; for (Mark mark : course.get(course.size()-2).getMarks()) { numMarks += 1; averageLat += mark.getLat(); @@ -343,22 +371,6 @@ public class GameView extends Pane { GeoUtility.getBearing(mark, mark) ); } - - //Scale race to markers if there is no border. - if (borderPoints == null) { - rescaleRace(new ArrayList<>(markerObjects.keySet())); - } - //Move the Markers to initial position. - markerObjects.forEach(((mark, marker) -> { - Point2D p2d = findScaledXY(mark.getLat(), mark.getLng()); - marker.setLayoutX(p2d.getX()); - marker.setLayoutY(p2d.getY()); - })); - Platform.runLater(() -> { - markers.getChildren().clear(); - markers.getChildren().addAll(gates); - markers.getChildren().addAll(markerObjects.values()); - }); } /** diff --git a/src/main/java/seng302/visualiser/fxObjects/Marker.java b/src/main/java/seng302/visualiser/fxObjects/Marker.java index 64923b51..297a9c34 100644 --- a/src/main/java/seng302/visualiser/fxObjects/Marker.java +++ b/src/main/java/seng302/visualiser/fxObjects/Marker.java @@ -49,17 +49,13 @@ public class Marker extends Group { */ public void addArrows(MarkArrowFactory.RoundingSide roundingSide, double entryAngle, double exitAngle) { - + //Change Color.GRAY to this.colour to revert all gray arrows. enterArrows.add( - MarkArrowFactory.constructEntryArrow(roundingSide, entryAngle, exitAngle, colour) + MarkArrowFactory.constructEntryArrow(roundingSide, entryAngle, exitAngle, Color.GRAY) ); exitArrows.add( - MarkArrowFactory.constructExitArrow(roundingSide, exitAngle, colour) + MarkArrowFactory.constructExitArrow(roundingSide, exitAngle, Color.GRAY) ); -// Platform.runLater(() -> { -// this.getChildren().add(enterArrows.get(enterArrows.size()-1)); -// this.getChildren().add(exitArrows.get(exitArrows.size()-1)); -// }); } /** diff --git a/src/test/java/seng302/utilities/GeoUtilityTest.java b/src/test/java/seng302/utilities/GeoUtilityTest.java index a9a60148..936b5983 100644 --- a/src/test/java/seng302/utilities/GeoUtilityTest.java +++ b/src/test/java/seng302/utilities/GeoUtilityTest.java @@ -140,7 +140,6 @@ public class GeoUtilityTest { // for (int i = 0; i < 100000; i++) { // assertTrue(GeoUtility.isPointInTriangle(v1, v2, v3, p1)); // } -// System.out.println((System.nanoTime() - startTime) / 1000000000.0); // test for different orders of vertices, which should not affect the result assertTrue(GeoUtility.isPointInTriangle(v2, v1, v3, p1)); diff --git a/src/test/java/seng302/visualiser/ClientToServerTests/DisconnectionTest.java b/src/test/java/seng302/visualiser/ClientToServerTests/DisconnectionTest.java new file mode 100644 index 00000000..6bc3e9ad --- /dev/null +++ b/src/test/java/seng302/visualiser/ClientToServerTests/DisconnectionTest.java @@ -0,0 +1,20 @@ +package seng302.visualiser.ClientToServerTests; + +import org.junit.Assert; +import org.junit.Test; +import seng302.gameServer.MainServerThread; +import seng302.visualiser.ClientToServerThread; + +/** + * Created by cir27 on 17/08/17. + */ +public class DisconnectionTest { + @Test + public void testServerDisconnection () throws Exception { + MainServerThread serverThread = new MainServerThread(); + ClientToServerThread clientThread = new ClientToServerThread("localhost", 4942); + Thread.sleep(1000); + clientThread.addDisconnectionListener(message -> Assert.assertTrue(message != null)); + serverThread.terminate(); + } +}