diff --git a/pom.xml b/pom.xml index 1488c740..5674a2f6 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ 1.8 1.8 + UTF-8 diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index b41ec834..961eb415 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -9,12 +9,12 @@ import java.util.Map; import java.util.Random; import java.util.Set; import javafx.scene.paint.Color; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import seng302.gameServer.messages.*; -import seng302.model.*; import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatStatus; import seng302.gameServer.messages.ChatterMessage; @@ -38,10 +38,6 @@ import seng302.model.token.TokenType; import seng302.utilities.GeoUtility; import seng302.utilities.XMLParser; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import java.util.*; - /** * A Static class to hold information about the current state of the game (model) * Also contains logic for updating itself on regular time intervals on its own thread @@ -77,6 +73,7 @@ public class GameState implements Runnable { private static Double speedMultiplier = 1d; private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat. + private static Boolean playerHasLeftFlag; private static String hostIpAddress; private static List players; @@ -106,6 +103,7 @@ public class GameState implements Runnable { players = new ArrayList<>(); GameState.hostIpAddress = hostIpAddress; customizationFlag = false; + playerHasLeftFlag = false; speedMultiplier = 1.0; currentStage = GameStages.LOBBYING; isRaceStarted = false; @@ -839,8 +837,16 @@ public class GameState implements Runnable { customizationFlag = false; } + public static void setPlayerHasLeftFlag(Boolean flag) { + playerHasLeftFlag = flag; + } + + public static Boolean getPlayerHasLeftFlag() { + return playerHasLeftFlag; + } + public static Integer getNumberOfPlayers(){ - Integer numPlayers = 0; + Integer numPlayers = 1; for(Player p : getPlayers()){ if(p.getSocket().isConnected()){ diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index d15eea08..81a052fb 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -1,5 +1,15 @@ package seng302.gameServer; +import java.io.IOException; +import java.io.StringReader; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -16,17 +26,6 @@ import seng302.utilities.GeoUtility; import seng302.utilities.XMLGenerator; import seng302.utilities.XMLParser; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.io.StringReader; -import java.net.ServerSocket; -import java.util.ArrayList; -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; - /** * A class describing the overall server, which creates and collects server threads for each client * Created by wmu16 on 13/07/17. @@ -115,6 +114,20 @@ 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) { + if (GameState.getPlayerHasLeftFlag()) { + for (ServerToClientThread stc : serverToClientThreads) { + if (!stc.isSocketOpen()) { + GameState.getYachts().remove(stc.getSourceId()); + sendSetupMessages(); + try { + stc.getSocket().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + GameState.setPlayerHasLeftFlag(false); + } try { Thread.sleep(1000 / CLIENT_UPDATES_PER_SECOND); } catch (InterruptedException e) { @@ -183,21 +196,21 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { if (Math.floorMod(random.nextInt(), 2) == 0){ direction += random.nextInt(4); - windSpeed += random.nextInt(20) + 50; + windSpeed += random.nextInt(20) + 459; } else{ direction -= random.nextInt(4); - windSpeed -= random.nextInt(20) + 50; + windSpeed -= random.nextInt(20) + 459; } direction = Math.floorMod(direction, 360); if (windSpeed > MAX_WIND_SPEED){ - windSpeed -= random.nextInt(1000); + windSpeed -= random.nextInt(500); } if (windSpeed <= MIN_WIND_SPEED){ - windSpeed += random.nextInt(1000); + windSpeed += random.nextInt(500); } GameState.setWindSpeed(Double.valueOf(windSpeed)); diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index 74048f07..1138f53d 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -95,6 +95,10 @@ public class ServerToClientThread implements Runnable { thread.start(); } + public Integer getSourceId() { + return sourceId; + } + private void setUpPlayer(){ BufferedReader fn; String fName = ""; @@ -219,9 +223,11 @@ public class ServerToClientThread implements Runnable { } } catch (Exception e) { closeSocket(); + GameState.setPlayerHasLeftFlag(true); return; } } + GameState.setPlayerHasLeftFlag(true); logger.warn("Closed serverToClientThread" + thread, 1); } @@ -253,6 +259,10 @@ public class ServerToClientThread implements Runnable { } } + public Boolean isSocketOpen() { + return !socket.isClosed(); + } + private int readByte() throws Exception { int currentByte = -1; try { diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index d70ff09e..89715852 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -253,7 +253,7 @@ public class ClientYacht extends Observable { public void updateLocation(double lat, double lng, double heading, double velocity) { setLocation(lat, lng); this.heading = heading; -// this.currentVelocity = velocity; + this.currentVelocity = velocity; updateVelocityProperty(velocity); for (YachtLocationListener yll : locationListeners) { yll.notifyLocation(this, lat, lng, heading, sailIn, velocity); @@ -284,4 +284,8 @@ public class ClientYacht extends Observable { listener.notifyRounding(this, legNumber); } } + + public Double getCurrentVelocity() { + return currentVelocity; + } } diff --git a/src/main/java/seng302/utilities/Sounds.java b/src/main/java/seng302/utilities/Sounds.java index b0bd2209..944fa93f 100644 --- a/src/main/java/seng302/utilities/Sounds.java +++ b/src/main/java/seng302/utilities/Sounds.java @@ -26,7 +26,9 @@ public class Sounds { } } - public static void setMutes() { + + + static void setMutes() { if (soundPlayer != null) { soundPlayer.setMute(soundEffectsMuted); } @@ -49,14 +51,14 @@ public class Sounds { toggleMuteMusic(); } - public static void toggleMuteMusic() { + static void toggleMuteMusic() { musicMuted = !musicMuted; if (musicPlayer != null) { musicPlayer.setMute(musicMuted); } } - public static void toggleMuteEffects() { + static void toggleMuteEffects() { soundEffectsMuted = !soundEffectsMuted; if (soundPlayer != null) { soundPlayer.setMute(soundEffectsMuted); @@ -188,5 +190,4 @@ public class Sounds { } } - } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 32f65871..39f2df17 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -44,7 +44,6 @@ import seng302.utilities.XMLGenerator; import seng302.utilities.XMLParser; import seng302.visualiser.controllers.FinishScreenViewController; import seng302.visualiser.controllers.LobbyController; -import seng302.visualiser.controllers.LobbyController_old; import seng302.visualiser.controllers.RaceViewController; import seng302.visualiser.controllers.ViewManager; @@ -201,23 +200,6 @@ public class GameClient { socketThread.addStreamObserver(this::parsePackets); } - /** - * Loads a view of the lobby into the clients pane - * - * @return the lobby controller. - */ - private LobbyController_old loadLobby() { - FXMLLoader fxmlLoader = new FXMLLoader( - GameClient.class.getResource("/views/LobbyView.fxml")); - try { - holderPane.getChildren().clear(); - holderPane.getChildren().add(fxmlLoader.load()); - } catch (IOException e) { - e.printStackTrace(); - } - return fxmlLoader.getController(); - } - private void loadRaceView() { FXMLLoader fxmlLoader = loadFXMLToHolder("/views/RaceView.fxml"); holderPane.getScene().setOnKeyPressed(this::keyPressed); diff --git a/src/main/java/seng302/visualiser/controllers/CustomizationController_old.java b/src/main/java/seng302/visualiser/controllers/CustomizationController_old.java deleted file mode 100644 index b8f0b146..00000000 --- a/src/main/java/seng302/visualiser/controllers/CustomizationController_old.java +++ /dev/null @@ -1,76 +0,0 @@ -package seng302.visualiser.controllers; - -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.ColorPicker; -import javafx.scene.control.TextField; -import javafx.scene.paint.Color; -import javafx.stage.Stage; -import seng302.gameServer.messages.CustomizeRequestType; -import seng302.utilities.Sounds; -import seng302.visualiser.ClientToServerThread; - -public class CustomizationController_old { - - @FXML - private TextField nameField; - - @FXML - private ColorPicker boatColorPicker; - - @FXML - private Button customizeSubmit; - - private LobbyController_old lc; - private ClientToServerThread socketThread; - private Stage windowStage; - - public void initialize() { - - } - - public void setServerThread(ClientToServerThread ctsThread) { - this.socketThread = ctsThread; - } - - @FXML - public void submitCustomization() { - Sounds.playButtonClick(); -// System.out.println("Attempting to send"); - socketThread.sendCustomizationRequest(CustomizeRequestType.NAME, nameField.getText().getBytes()); - // TODO: 16/08/17 ajm412: Turn colors into byte array. - Color color = boatColorPicker.getValue(); - - short red = (short) (color.getRed() * 255); - short green = (short) (color.getGreen() * 255); - short blue = (short) (color.getBlue() * 255); - - byte[] colorArray = new byte[3]; - - colorArray[0] = (byte) red; - colorArray[1] = (byte) green; - colorArray[2] = (byte) blue; - - socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray); - lc.setPlayersColor(color); - windowStage.close(); - } - - public void setLobbyController(LobbyController_old lc) { - this.lc = lc; - } - - public void setStage(Stage stage) { - this.windowStage = stage; - } - - public void setPlayerName(String name) { - this.nameField.setText(name); - } - - public void setPlayerColor(Color playerColor) { - this.boatColorPicker.setValue(playerColor); - } - - -} diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java index 7608b252..9beb14f5 100644 --- a/src/main/java/seng302/visualiser/controllers/LobbyController.java +++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java @@ -31,6 +31,7 @@ import seng302.model.stream.xml.parser.RaceXMLData; import seng302.utilities.Sounds; import seng302.visualiser.GameView; import seng302.visualiser.controllers.cells.PlayerCell; +import seng302.visualiser.controllers.dialogs.BoatCustomizeController; public class LobbyController implements Initializable { @@ -51,7 +52,6 @@ public class LobbyController implements Initializable { private Pane serverMap; //---------FXML END---------// - private List lobbyListeners = new ArrayList<>(); private RaceState raceState; private JFXDialog customizationDialog; public Color playersColor; @@ -93,8 +93,8 @@ public class LobbyController implements Initializable { Integer playerId = ViewManager.getInstance().getGameClient().getServerThread().getClientId(); String name = ViewManager.getInstance().getGameClient().getPlayerNames().get(playerId - 1); - Color playerColor = Colors.getColor( playerId - 1); - customizationDialog = ViewManager.getInstance().loadCustomizationDialog(serverListMainStackPane, this, playerColor, name); + playersColor = Colors.getColor(playerId - 1); + customizationDialog = createCustomizeDialog(); customizeButton.setOnMouseReleased(event -> { Sounds.playButtonClick(); @@ -109,6 +109,32 @@ public class LobbyController implements Initializable { initMapPreview(); } + private JFXDialog createCustomizeDialog() { + // TODO: 12/09/17 ajm412: Why is this here? is there no better way we can do this? Ideally inside the LobbyController. + FXMLLoader dialog = new FXMLLoader( + getClass().getResource("/views/dialogs/BoatCustomizeDialog.fxml")); + + JFXDialog customizationDialog = null; + + try { + customizationDialog = new JFXDialog(serverListMainStackPane, dialog.load(), + JFXDialog.DialogTransition.CENTER); + + } catch (IOException e) { + e.printStackTrace(); + } + + BoatCustomizeController controller = dialog.getController(); + + controller.setParentController(this); + controller.setPlayerColor(this.playersColor); + + return customizationDialog; + } + + /** + * + */ private void refreshMapView(){ RaceXMLData raceData = ViewManager.getInstance().getGameClient().getCourseData(); List border = raceData.getCourseLimit(); @@ -122,12 +148,8 @@ public class LobbyController implements Initializable { gameView.updateCourse(marks, corners); } - private void getPlayerColors() { - - } - /** - * + * Initializes a top down preview of the race course map. */ private void initMapPreview() { gameView = new GameView(); @@ -163,7 +185,7 @@ public class LobbyController implements Initializable { } /** - * + * Refreshes the list of players and their boats, as a series of VBox PlayerCell objects. */ private void refreshPlayerList() { playerListVBox.getChildren().clear(); @@ -192,17 +214,12 @@ public class LobbyController implements Initializable { } } - /** - * - */ private void leaveLobby() { + ViewManager.getInstance().getGameClient().stopGame(); ViewManager.getInstance().goToStartView(); } - /** - * - */ public void disableReadyButton() { this.beginRaceButton.setDisable(true); this.beginRaceButton.setText("Waiting for host..."); diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController_old.java b/src/main/java/seng302/visualiser/controllers/LobbyController_old.java deleted file mode 100644 index 20f16801..00000000 --- a/src/main/java/seng302/visualiser/controllers/LobbyController_old.java +++ /dev/null @@ -1,249 +0,0 @@ -package seng302.visualiser.controllers; - -import com.sun.media.jfxmedia.logging.Logger; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javafx.application.Platform; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.TextArea; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.paint.Color; -import javafx.scene.text.Text; -import javafx.stage.Stage; -import seng302.gameServer.GameStages; -import seng302.gameServer.GameState; -import seng302.model.Colors; -import seng302.model.RaceState; -import seng302.visualiser.ClientToServerThread; - -/** - * A class describing the actions of the lobby screen - * Created by wmu16 on 10/07/17. - */ -public class LobbyController_old { - - public enum CloseStatus { - LEAVE, - READY - } - - @FunctionalInterface - public interface LobbyCloseListener { - void notify(CloseStatus exitCause); - } - - @FXML - private Text lobbyIpText; - @FXML - private Button readyButton; - @FXML - private Button customizeButton; - @FXML - private TextArea playerOneTxt; - @FXML - private TextArea playerTwoTxt; - @FXML - private TextArea playerThreeTxt; - @FXML - private TextArea playerFourTxt; - @FXML - private TextArea playerFiveTxt; - @FXML - private TextArea playerSixTxt; - @FXML - private TextArea playerSevenTxt; - @FXML - private TextArea playerEightTxt; - @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; - @FXML - private Text timeUntilStart; - @FXML - private Text courseNameText; - - private List imageViews = new ArrayList<>(); - private List