diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index e79e6610..aaea82cf 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -698,7 +698,6 @@ public class GameState implements Runnable { public static void endRace () { yachts.forEach((id, yacht) -> yacht.setBoatStatus(BoatStatus.FINISHED)); currentStage = GameStages.FINISHED; - System.out.println("FOR FUCKS SAKE YOU FUCKING DEGENERATE"); } public static void setSpeedMultiplier (double multiplier) { diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index e0b55618..45a88185 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -61,7 +61,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { //You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app. while (!terminated) { - System.out.println("CUNT GF" + GameState.getCurrentStage()); try { Thread.sleep(1000 / CLIENT_UPDATES_PER_SECOND); } catch (InterruptedException e) { @@ -88,9 +87,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { //FINISHED else if (GameState.getCurrentStage() == GameStages.FINISHED) { broadcastMessage(makeRaceStatusMessage()); - System.out.println("BUT I WAS HERE CUNTFACE"); try { - Thread.sleep(100); //Hackish fix to make sure all threads have broadcasted + Thread.sleep(1000); //Hackish fix to make sure all threads have sent closing RaceStatus terminate(); } catch (InterruptedException ie) { serverLog("Thread interrupted while waiting to terminate clients", 1); @@ -102,7 +100,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { serverToClientThread.terminate(); } serverSocket.close(); - System.out.println("closed"); } catch (IOException e) { System.out.println("IO error in server thread handler upon closing socket"); } @@ -245,7 +242,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { for (Player player : GameState.getPlayers()) { ServerYacht y = player.getYacht(); - System.out.println(y.getBoatStatus()); BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(), y.getLegNumber(), 0, 0, 1234L, @@ -268,7 +264,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { raceStatus = RaceStatus.PREPARATORY; } } else if (GameState.getCurrentStage() == GameStages.FINISHED) { - System.out.println("WHAT THE FUCKING FUCK"); raceStatus = RaceStatus.TERMINATED; } else { raceStatus = RaceStatus.STARTED; @@ -281,7 +276,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { } public void terminate() { - System.out.println("done"); terminated = true; } diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index b78d9a15..2b447cf1 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -386,9 +386,6 @@ public class ServerToClientThread implements Runnable, Observer { Arrays.copyOfRange(chatterPayload, 3, 3 + chatterPayload.length) ); String[] words = chatterText.split("\\s+"); - for (String s : words) { - System.out.println(s); - } if (words.length > 2 && isHost) { switch (words[2].trim()) { case ">speed": @@ -396,19 +393,18 @@ public class ServerToClientThread implements Runnable, Observer { GameState.setSpeedMultiplier(Double.valueOf(words[3])); GameState.broadcastChatter(new ChatterMessage( Byte.toUnsignedInt(chatterPayload[1]), - words[0] + "Host has set speed modifier to x" + words[3] + "SERVER: Speed modifier set to x" + words[3] )); } catch (Exception e) { logger.error("cannot parse >speed value"); } return; case ">finish": - System.out.println(words[2].trim()); - GameState.endRace(); GameState.broadcastChatter(new ChatterMessage( chatterPayload[1], - words[0] + "Host has ended the game" + "SERVER: Game will now finish" )); + GameState.endRace(); return; } } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index d6cf73fe..00ea7f37 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -26,7 +26,6 @@ import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Slider; -import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; @@ -50,6 +49,7 @@ import seng302.visualiser.controllers.annotations.ImportantAnnotationController; import seng302.visualiser.controllers.annotations.ImportantAnnotationDelegate; import seng302.visualiser.controllers.annotations.ImportantAnnotationsState; import seng302.visualiser.fxObjects.BoatObject; +import seng302.visualiser.fxObjects.ChatHistory; /** * Controller class that manages the display of a race @@ -63,7 +63,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel @FXML private Button chatSend; @FXML - private TextArea chatHistory; + private Pane chatHistoryHolder; @FXML private TextField chatInput; @FXML @@ -98,6 +98,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel private GameView gameView; private RaceState raceState; + private ChatHistory chatHistory; + private Timeline timerTimeline; private Timer timer = new Timer(); private List> sparkLineData = new ArrayList<>(); @@ -122,9 +124,19 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel chatInput.setText(chatInput.getText().substring(0, CHAT_LIMIT)); } }); - chatHistory.textProperty().addListener((obs, oldValue, newValue) -> { - chatHistory.setScrollTop(Double.MAX_VALUE); - }); + chatHistory = new ChatHistory(); + chatHistoryHolder.getChildren().addAll(chatHistory); + chatHistory.prefWidthProperty().bind( + chatHistoryHolder.widthProperty() + ); + chatHistory.prefHeightProperty().bind( + chatHistoryHolder.heightProperty() + ); +// chatHistory.setFitToWidth(true); +// chatHistory.setFitToHeight(true); +// chatHistory.textProperty().addListener((obs, oldValue, newValue) -> { +// chatHistory.setScrollTop(Double.MAX_VALUE); +// }); } public void loadRace ( @@ -136,12 +148,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel this.markers = raceData.getCompoundMarks(); this.raceState = raceState; - initializeUpdateTimer(); - initialiseFPSCheckBox(); - initialiseAnnotationSlider(); - initialiseBoatSelectionComboBox(); - initialiseSparkLine(); - raceState.getPlayerPositions().addListener((ListChangeListener) c -> { while (c.next()) { if (c.wasPermutated()) { @@ -181,6 +187,12 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel gameView.enableZoom(); } }); + + initializeUpdateTimer(); + initialiseFPSCheckBox(); + initialiseAnnotationSlider(); + initialiseBoatSelectionComboBox(); + initialiseSparkLine(); } /** @@ -665,7 +677,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel } public void updateChatHistory(Paint playerColour, String newMessage) { - Platform.runLater(() -> chatHistory.appendText(newMessage + "\n\n")); +// Platform.runLater(() -> chatHistory.appendText(newMessage + "\n\n")); + Platform.runLater(() -> chatHistory.addMessage(playerColour, newMessage)); } } \ No newline at end of file diff --git a/src/main/java/seng302/visualiser/controllers/StartScreenController.java b/src/main/java/seng302/visualiser/controllers/StartScreenController.java index 1a9db1a1..d10cbea6 100644 --- a/src/main/java/seng302/visualiser/controllers/StartScreenController.java +++ b/src/main/java/seng302/visualiser/controllers/StartScreenController.java @@ -10,8 +10,6 @@ import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.GridPane; -import seng302.gameServer.GameState; import seng302.visualiser.GameClient; /** @@ -23,111 +21,32 @@ public class StartScreenController implements Initializable { @FXML private TextField ipTextField; @FXML - private TextField portTextField; - @FXML - private GridPane startScreen2; - @FXML private AnchorPane holder; - GameClient gameClient; + private GameClient gameClient; public void initialize(URL url, ResourceBundle resourceBundle) { -// gameClient = new GameClient(holder); - } -// -// /** -// * Loads the fxml content into the parent pane -// * @param jfxUrl -// * @return the controller of the fxml -// */ -// private Object setContentPane(String jfxUrl) { -// try { -// AnchorPane contentPane = (AnchorPane) startScreen2.getParent(); -// contentPane.getChildren().removeAll(); -// contentPane.getChildren().clear(); -// contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); -// FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(jfxUrl)); -// contentPane.getChildren().addAll((Pane) fxmlLoader.load()); -// -// return fxmlLoader.getController(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// return null; -// } + } /** - * 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 client to server thread and connects to own ip. - * Switches to the lobby screen + * Creates an instance of GameClient and runs it as a host. */ @FXML public void hostButtonPressed() { -// new GameState(getLocalHostIp()); gameClient = new GameClient(holder); gameClient.runAsHost(getLocalHostIp(), 4942); -// try { -//// String ipAddress = InetAddress.getLocalHost().getHostAddress(); -//// new GameState(ipAddress); -//// new MainServerThread(); -//// ClientToServerThread clientToServerThread = new ClientToServerThread("localhost", 4950); -//// controller.setClientToServerThread(clientToServerThread); -// // get the lobby controller so that we can pass the game server thread to it -// new GameState(getLocalHostIp()); -// MainServerThread mainServerThread = new MainServerThread(); -//// ClientState.setHost(true); -// // host will connect and handshake to itself after setting up the server -// // TODO: 24/07/17 wmu16 - Make port number some static global type constant? -//// ClientToServerThread clientToServerThread = new ClientToServerThread(ClientState.getHostIp(), 4942); -//// ClientState.setConnectedToHost(true); -//// controller.setClientToServerThread(clientToServerThread); -// LobbyController lobbyController = (LobbyController) setContentPane("/views/LobbyView.fxml"); -// lobbyController.setMainServerThread(mainServerThread); -// } 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. + * Creates an instance of GameClient and runs it has a client. */ @FXML public void connectButtonPressed() { - // TODO: 10/07/17 wmu16 - Finish function gameClient = new GameClient(holder); gameClient.runAsClient(ipTextField.getText().trim().toLowerCase(), 4942); - -// try { -// 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) { -// 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. @@ -162,7 +81,6 @@ public class StartScreenController implements Initializable { 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/visualiser/fxObjects/ChatHistory.java b/src/main/java/seng302/visualiser/fxObjects/ChatHistory.java new file mode 100644 index 00000000..3354f72b --- /dev/null +++ b/src/main/java/seng302/visualiser/fxObjects/ChatHistory.java @@ -0,0 +1,59 @@ +package seng302.visualiser.fxObjects; + +import java.util.Arrays; +import javafx.collections.ListChangeListener; +import javafx.scene.Node; +import javafx.scene.control.ScrollPane; +import javafx.scene.paint.Paint; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; + +/** + * Extension of a ScrollPane that contains a TextFlow. Has an addMessage() function to parse and + * display chatter text. + */ +public class ChatHistory extends ScrollPane { + + private TextFlow textFlow = new TextFlow(); + + public ChatHistory() { + this.setContent(textFlow); + this.setFitToWidth(true); + this.setFitToHeight(true); + this.setMaxHeight(Double.MAX_VALUE); + this.setMaxWidth(Double.MAX_VALUE); + this.setVbarPolicy(ScrollBarPolicy.ALWAYS); + this.setHbarPolicy(ScrollBarPolicy.NEVER); + textFlow.getChildren().addListener((ListChangeListener) c -> { + this.setVvalue(1.0); + }); + } + + /** + * Adds a message to chat history. Messages should be either of the form: + * "[HH:MM:ss] \: \" or + * "SERVER: \" + * @param colour The colour of the user sending the message + * @param Text The chatter text message to be displayed + */ + public void addMessage (Paint colour, String Text) { + String[] words = Text.split(":"); + if (words[0].trim().equals("SERVER")) { + Text text = new Text(Text + "\n\n"); + text.setStyle("-fx-font-weight: bolder"); + textFlow.getChildren().add(text); + } else { + Text timePlayer = new Text( + String.join(":", Arrays.copyOfRange(words, 0, 3)) + ":" + ); + timePlayer.setStyle("-fx-font-weight: bold"); + timePlayer.setFill(colour); + Text message = new Text( + String.join(":", Arrays.copyOfRange(words, 3, words.length)) + "\n\n" + ); + message.wrappingWidthProperty().bind(this.widthProperty()); + textFlow.getChildren().addAll(timePlayer, message); + } + + } +} diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index eae9b797..f1473f5e 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -9,47 +9,29 @@ - + - + - - + + - - + + - + - + - + -