diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 57e27ed8..c4538078 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -86,9 +86,6 @@ public class App extends Application { primaryStage.show(); primaryStage.setOnCloseRequest(e -> { -// ClientPacketParser.appClose(); -// ClientPacketParser.appClose(); - try { ServerAdvertiser.getInstance().unregister(); @@ -108,8 +105,6 @@ public class App extends Application { parseArgs(args); } catch (ParseException e) { logger.error("Could not parse command line arguments"); - } catch (IOException e) { - e.printStackTrace(); } launch(args); diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 8c6b7274..03956ae0 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -16,6 +16,7 @@ import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; import seng302.gameServer.GameState; import seng302.gameServer.MainServerThread; +import seng302.gameServer.ServerDescription; import seng302.gameServer.messages.BoatAction; import seng302.gameServer.messages.BoatStatus; import seng302.model.ClientYacht; @@ -34,6 +35,7 @@ import seng302.visualiser.controllers.FinishScreenViewController; import seng302.visualiser.controllers.LobbyController_old; import seng302.visualiser.controllers.LobbyController_old.CloseStatus; import seng302.visualiser.controllers.RaceViewController; +import seng302.visualiser.controllers.ViewManager; /** * This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated @@ -72,30 +74,43 @@ public class GameClient { public void runAsClient(String ipAddress, Integer portNumber) { try { startClientToServerThread(ipAddress, portNumber); - socketThread.addDisconnectionListener((cause) -> { - showConnectionError(cause); - Platform.runLater(this::loadStartScreen); - }); + +// socketThread.addDisconnectionListener((cause) -> { +// showConnectionError(cause); +// Platform.runLater(this::loadStartScreen); +// }); + + socketThread.addStreamObserver(this::parsePackets); - LobbyController_old lobbyController = loadLobby(); - lobbyController.setSocketThread(socketThread); - lobbyController.setPlayerID(socketThread.getClientId()); - lobbyController.setPlayerListSource(clientLobbyList); - lobbyController.disableReadyButton(); + + ViewManager.getInstance().setPlayerList(clientLobbyList); + if (regattaData != null){ - lobbyController.setTitle(regattaData.getRegattaName()); - lobbyController.setCourseName(regattaData.getCourseName()); + ViewManager.getInstance().setProperty("serverName", regattaData.getRegattaName()); + ViewManager.getInstance().setProperty("mapName", regattaData.getCourseName()); } else{ - lobbyController.setTitle(ipAddress); - lobbyController.setCourseName(""); + ViewManager.getInstance().setProperty("serverName", ipAddress); + ViewManager.getInstance().setProperty("mapName", ""); } - lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); - this.lobbyController = lobbyController; + + // TODO disable ready button; + + + //LobbyController_old lobbyController = loadLobby(); + //lobbyController.setSocketThread(socketThread); + //lobbyController.setPlayerID(socketThread.getClientId()); + //lobbyController.setPlayerListSource(clientLobbyList); + //lobbyController.disableReadyButton(); + + + +// lobbyController.addCloseListener((exitCause) -> this.loadStartScreen()); +// this.lobbyController = lobbyController; } catch (IOException ioe) { showConnectionError("Unable to find server"); - Platform.runLater(this::loadStartScreen); + //Platform.runLater(this::loadStartScreen); } } @@ -104,41 +119,32 @@ public class GameClient { * @param ipAddress IP to connect to. * @param portNumber Port to connect to. */ - public void runAsHost(String ipAddress, Integer portNumber) { + public ServerDescription runAsHost(String ipAddress, Integer portNumber) { server = new MainServerThread(); - try { - startClientToServerThread(ipAddress, portNumber); - socketThread.addDisconnectionListener((cause) -> { - Platform.runLater(this::loadStartScreen); - }); - LobbyController_old 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(""); - } - 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) { + try { + startClientToServerThread(ipAddress, 4942); + } catch (IOException e) { showConnectionError("Cannot connect to server as host"); - Platform.runLater(this::loadStartScreen); } + + String serverName = ""; + String courseName = ""; + + while (regattaData == null){ + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + ViewManager.getInstance().setPlayerList(clientLobbyList); + + serverName = regattaData.getRegattaName(); + courseName = regattaData.getCourseName(); + + return new ServerDescription(serverName, courseName, 0, ipAddress, 4942); } private void loadStartScreen() { diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java index 6cd9a2e2..45792694 100644 --- a/src/main/java/seng302/visualiser/controllers/LobbyController.java +++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java @@ -3,16 +3,24 @@ package seng302.visualiser.controllers; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXDialog; import com.jfoenix.controls.JFXDialog.DialogTransition; + import java.io.IOException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.ResourceBundle; + import javafx.application.Platform; +import javafx.collections.ListChangeListener; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; +import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; +import seng302.gameServer.GameStages; +import seng302.gameServer.GameState; public class LobbyController implements Initializable { @@ -23,41 +31,43 @@ public class LobbyController implements Initializable { private ScrollPane playerListScrollpane; @FXML - private JFXButton customizeButton; + private JFXButton customizeButton, leaveLobbyButton; @FXML private StackPane serverListMainStackPane; + @FXML + private Label serverName; + + @FXML + private Label mapName; + + private List lobbyListeners = new ArrayList<>(); + @Override public void initialize(URL location, ResourceBundle resources) { + + leaveLobbyButton.setOnMouseReleased(event -> leaveLobby()); + Platform.runLater(() -> { - Integer max = 6; - for (int i = 0; i < max; i++) { - VBox pane = null; - FXMLLoader loader = new FXMLLoader( - getClass().getResource("/views/cells/PlayerCell.fxml")); + serverName.setText(ViewManager.getInstance().getProperty("serverName")); + mapName.setText(ViewManager.getInstance().getProperty("mapName")); - loader.setController(new PlayerCell("Player " + i)); + ViewManager.getInstance().getPlayerList().addListener((ListChangeListener) c -> { + Platform.runLater(this::refreshPlayerList); + }); - try { - pane = loader.load(); - } catch (IOException e) { - e.printStackTrace(); - } - - playerListVBox.getChildren().add(pane); - } + ViewManager.getInstance().getPlayerList().setAll(ViewManager.getInstance().getPlayerList().sorted()); }); - Platform.runLater(() -> { FXMLLoader dialogContent = new FXMLLoader(getClass().getResource( - "/views/dialogs/BoatCustomizeDialog.fxml")); + "/views/dialogs/BoatCustomizeDialog.fxml")); try { JFXDialog dialog = new JFXDialog(serverListMainStackPane, dialogContent.load(), - DialogTransition.CENTER); + DialogTransition.CENTER); customizeButton.setOnAction(action -> dialog.show()); } catch (IOException e) { e.printStackTrace(); @@ -65,4 +75,35 @@ public class LobbyController implements Initializable { }); } + + private void refreshPlayerList() { + playerListVBox.getChildren().clear(); + + for (String player : ViewManager.getInstance().getPlayerList()) { + VBox pane = null; + + FXMLLoader loader = new FXMLLoader( + getClass().getResource("/views/cells/PlayerCell.fxml")); + + loader.setController(new PlayerCell(player)); + + try { + pane = loader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + playerListVBox.getChildren().add(pane); + } + } + + public void leaveLobby() { + // TODO: 10/07/17 wmu16 - Finish function! + GameState.setCurrentStage(GameStages.CANCELLED); +// for (LobbyController_old.LobbyCloseListener readyListener : lobbyListeners) +// readyListener.notify(LobbyController_old.CloseStatus.LEAVE); + + //TODO close threads and figure out what the above lines do; + ViewManager.getInstance().goToStartView(); + } } diff --git a/src/main/java/seng302/visualiser/controllers/ServerCell.java b/src/main/java/seng302/visualiser/controllers/ServerCell.java index c423a0ac..7ba0a5d2 100644 --- a/src/main/java/seng302/visualiser/controllers/ServerCell.java +++ b/src/main/java/seng302/visualiser/controllers/ServerCell.java @@ -5,6 +5,8 @@ import com.jfoenix.controls.JFXDecorator; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; + +import com.jfoenix.controls.JFXTextField; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; @@ -13,58 +15,59 @@ import javafx.scene.control.Label; import javafx.scene.effect.DropShadow; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; +import seng302.gameServer.ServerDescription; public class ServerCell implements Initializable { - @FXML - private Label serverName; - + //--------FXML BEGIN--------// + //Layout @FXML private GridPane serverListCell; + //Server Information + @FXML + private Label serverName; + @FXML + private Label mapName; + @FXML + private Label serverPlayerCount; + //Server Connection @FXML private JFXButton serverConnButton; + //---------FXML END---------// private String name; + private String mapNameString; + + private Integer currPlayerCount; + + private String hostName; + private Integer portNumber; - public ServerCell(String name) { - this.name = name; + public ServerCell(ServerDescription server) { + this.name = server.getName(); + this.currPlayerCount = server.spacesLeft(); + this.mapNameString = server.getMapName(); + + this.hostName = server.getAddress(); + this.portNumber = server.portNumber(); } public void initialize(URL location, ResourceBundle resources) { serverName.setText(name); + serverPlayerCount.setText(Integer.toString(currPlayerCount)); - DropShadow dropShadow = new DropShadow(); - dropShadow.setRadius(10.0); - dropShadow.setOffsetX(3.0); - dropShadow.setOffsetY(4.0); - dropShadow.setColor(Color.color(0, 0, 0, 0.1)); - serverListCell.setEffect(dropShadow); - - DropShadow dropShadow2 = new DropShadow(); - dropShadow2.setRadius(10.0); - dropShadow2.setOffsetX(5.0); - dropShadow2.setOffsetY(6.0); - dropShadow2.setColor(Color.color(0, 0, 0, 0.3)); - - serverListCell.setOnMouseEntered(event -> { - serverListCell.setEffect(dropShadow2); - }); - - serverListCell.setOnMouseExited(event -> { - serverListCell.setEffect(dropShadow); - }); + serverConnButton.setOnMouseReleased(event -> joinServer()); } - public void createServer() { - JFXDecorator decorator = (JFXDecorator) serverConnButton.getScene().getRoot(); + public void joinServer() { + // TODO: 7/09/17 ajm412: Connect to a server here with the values stored in the hostName/portNumber variables. System.out.println("Connecting to " + serverName.getText()); - FXMLLoader fxmlLoader = new FXMLLoader(); try { Parent root = FXMLLoader.load(StartScreenController.class.getResource("/views/LobbyView.fxml")); - decorator.setContent(root); + ViewManager.getInstance().setScene(root); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/seng302/visualiser/controllers/ServerCreationController.java b/src/main/java/seng302/visualiser/controllers/ServerCreationController.java index 805237e1..5a24f422 100644 --- a/src/main/java/seng302/visualiser/controllers/ServerCreationController.java +++ b/src/main/java/seng302/visualiser/controllers/ServerCreationController.java @@ -6,48 +6,48 @@ import com.jfoenix.controls.JFXSlider; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; + +import com.jfoenix.controls.JFXTextField; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; +import seng302.gameServer.ServerDescription; public class ServerCreationController implements Initializable { + //--------FXML BEGIN--------// @FXML - private JFXButton submitBtn; + private JFXTextField serverName; @FXML private JFXSlider maxPlayers; - @FXML private Label maxPlayersLabel; - public ServerCreationController() { - - } - + @FXML + private JFXButton submitBtn; + //---------FXML END---------// public void initialize(URL location, ResourceBundle resources) { updateMaxPlayerLabel(); maxPlayers.valueProperty().addListener((observable, oldValue, newValue) -> { updateMaxPlayerLabel(); }); + + submitBtn.setOnMouseReleased(event -> createServer()); } public void createServer() { - System.out.println(submitBtn.getScene().getRoot()); - JFXDecorator decorator = (JFXDecorator) submitBtn.getScene().getRoot(); - System.out.println(decorator.getChildren()); - StackPane stackPane = (StackPane) decorator.getChildren().get(1); - - FXMLLoader fxmlLoader = new FXMLLoader(); - try { - Parent root = FXMLLoader.load(StartScreenController.class.getResource("/views/LobbyView.fxml")); + ServerDescription serverDescription = ViewManager.getInstance().getGameClient().runAsHost("localhost", 4941); - ViewManager.getInstance().getGameClient().runAsHost("localhost", 4941); + ViewManager.getInstance().setProperty("serverName", serverDescription.getName()); + ViewManager.getInstance().setProperty("mapName", serverDescription.getMapName()); + + Parent root = FXMLLoader.load(StartScreenController.class.getResource("/views/LobbyView.fxml")); ViewManager.getInstance().setScene(root); } catch (IOException e) { diff --git a/src/main/java/seng302/visualiser/controllers/ServerListController.java b/src/main/java/seng302/visualiser/controllers/ServerListController.java index 8cc8877f..70578076 100644 --- a/src/main/java/seng302/visualiser/controllers/ServerListController.java +++ b/src/main/java/seng302/visualiser/controllers/ServerListController.java @@ -5,7 +5,9 @@ import com.jfoenix.controls.JFXDialog; import com.jfoenix.controls.JFXDialog.DialogTransition; import java.io.IOException; import java.net.URL; +import java.util.List; import java.util.ResourceBundle; +import com.jfoenix.controls.JFXTextField; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; @@ -13,42 +15,49 @@ import javafx.fxml.Initializable; import javafx.scene.control.ScrollPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import seng302.gameServer.ServerDescription; +import seng302.visualiser.ServerListener; +import seng302.visualiser.ServerListenerDelegate; -public class ServerListController implements Initializable { +public class ServerListController implements Initializable, ServerListenerDelegate { + //--------FXML BEGIN--------// + // Layout Related @FXML private VBox serverListVBox; @FXML private ScrollPane serverListScrollPane; @FXML private StackPane serverListMainStackPane; + + // Host Button @FXML private JFXButton serverListHostButton; - private void refreshServerList(){ + //Direct Connect + @FXML + private JFXButton connectButton; + @FXML + private JFXTextField serverHostName; + @FXML + private JFXTextField serverPortNumber; + //---------FXML END---------// - } + private Logger logger = LoggerFactory.getLogger(ServerListController.class); public void initialize(URL location, ResourceBundle resources) { serverListVBox.minWidthProperty().bind(serverListScrollPane.widthProperty()); -// for (int i = 0; i < 20; i++) { -// VBox pane = null; -// -// FXMLLoader loader = new FXMLLoader( -// getClass().getResource("/views/cells/ServerCell.fxml")); -// -// loader.setController(new ServerCell("Server " + i)); -// -// try { -// pane = loader.load(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// -// serverListVBox.getChildren().add(pane); -// } + connectButton.setOnMouseReleased(event -> goToDirectConnectLobby()); + + try { + ServerListener.getInstance().setDelegate(this); + } catch (IOException e) { + logger.warn("Could not start Server Listener Delegate"); + } Platform.runLater(() -> { FXMLLoader dialogContent = new FXMLLoader(getClass().getResource( @@ -59,8 +68,49 @@ public class ServerListController implements Initializable { DialogTransition.CENTER); serverListHostButton.setOnAction(action -> dialog.show()); } catch (IOException e) { - e.printStackTrace(); + logger.warn("Could not create Server Creation Dialog."); } }); } + + private void goToDirectConnectLobby() { + // TODO: 7/09/17 ajm412: Implement ability to connect to a lobby. + serverHostName.setText("Invalid Host Name or Port Number"); + serverPortNumber.setText(""); + } + + @Override + public void serverRemoved(List servers) { + Platform.runLater(() -> refreshServers(servers)); + } + + @Override + public void serverDetected(ServerDescription serverDescription, List servers) { + Platform.runLater(() -> refreshServers(servers)); + } + + private void refreshServers(List servers) { + // TODO: 7/09/17 ajm412: Add some way to force a refresh. + // TODO: 7/09/17 ajm412: Add something for No Servers Found. + serverListVBox.getChildren().clear(); + + // Populate the server list with a series of server cell objects. + for (ServerDescription server : servers){ + VBox pane = null; + + FXMLLoader loader = new FXMLLoader( + getClass().getResource("/views/cells/ServerCell.fxml")); + + loader.setController(new ServerCell(server)); + + try { + pane = loader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + serverListVBox.getChildren().add(pane); + } + + } } diff --git a/src/main/java/seng302/visualiser/controllers/StartScreenController.java b/src/main/java/seng302/visualiser/controllers/StartScreenController.java index af1f4c3c..c9190226 100644 --- a/src/main/java/seng302/visualiser/controllers/StartScreenController.java +++ b/src/main/java/seng302/visualiser/controllers/StartScreenController.java @@ -36,7 +36,7 @@ import java.util.Enumeration; import java.util.List; import java.util.ResourceBundle; -public class StartScreenController implements Initializable { +public class StartScreenController implements Initializable{ @FXML private Label headText; @@ -47,38 +47,8 @@ public class StartScreenController implements Initializable { private Node serverList; private Logger logger = LoggerFactory.getLogger(StartScreenController.class); - public void initialize(URL url, ResourceBundle resourceBundle) { -// gameClient = new GameClient(holder); - try { - ServerListener.getInstance().setDelegate(this); - } catch (IOException e) { - e.printStackTrace(); - } - - joinLobbyButton.setOnAction(event -> joinLobbyClicked()); - } -// -// /** -// * 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; -// } + private List servers; private void setInitialDropShadow(){ DropShadow dropShadow = new DropShadow(); @@ -114,5 +84,8 @@ public class StartScreenController implements Initializable { setInitialDropShadow(); preloadServerListView(); + + } + } diff --git a/src/main/java/seng302/visualiser/controllers/ViewManager.java b/src/main/java/seng302/visualiser/controllers/ViewManager.java index e569b1c9..3f1e49f7 100644 --- a/src/main/java/seng302/visualiser/controllers/ViewManager.java +++ b/src/main/java/seng302/visualiser/controllers/ViewManager.java @@ -1,16 +1,25 @@ package seng302.visualiser.controllers; import com.jfoenix.controls.JFXDecorator; +import javafx.collections.ObservableList; +import javafx.fxml.FXMLLoader; import javafx.scene.Node; +import javafx.scene.Parent; import seng302.visualiser.GameClient; +import java.io.IOException; +import java.util.HashMap; + public class ViewManager { private static ViewManager instance; private GameClient gameClient; private JFXDecorator decorator; + private HashMap props; //TODO is this the best way to do this?? + private ObservableList playerList; private ViewManager(){ + props = new HashMap<>(); gameClient = new GameClient(decorator); } @@ -34,8 +43,33 @@ public class ViewManager { decorator.setContent(scene); } + public void goToStartView() { + try { + Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml")); + this.setScene(root); + } catch (IOException e) { + e.printStackTrace(); + } + + } + public GameClient getGameClient(){ return gameClient; } + public String getProperty(String key){ + return props.get(key); + } + + public void setProperty(String key, String val){ + props.put(key, val); + } + + public void setPlayerList(ObservableList playerList) { + this.playerList = playerList; + } + + public ObservableList getPlayerList(){ + return playerList; + } } diff --git a/src/main/resources/css/ServerCell.css b/src/main/resources/css/ServerCell.css index 54f1ba0e..8fe51c19 100644 --- a/src/main/resources/css/ServerCell.css +++ b/src/main/resources/css/ServerCell.css @@ -1,5 +1,10 @@ #serverListCell { -fx-background-color: -fx-pp-front-color; + -fx-effect: -fx-pp-dropshadow-light; +} + +#serverListCell:hover { + -fx-effect: -fx-pp-dropshadow-dark; } #serverCellVBox { diff --git a/src/main/resources/css/master.css b/src/main/resources/css/master.css index 9ce21498..69c596e6 100644 --- a/src/main/resources/css/master.css +++ b/src/main/resources/css/master.css @@ -10,6 +10,9 @@ -fx-pp-background-color: transparent; -fx-pp-front-color: #fff; -fx-font-family: "Baloo Tammudu"; + + -fx-pp-dropshadow-light: dropshadow(gaussian, rgba(0, 0, 0, 0.1), 10.0, 0.2, 3, 4); + -fx-pp-dropshadow-dark: dropshadow(gaussian, rgba(0, 0, 0, 0.3), 10.0, 0.2, 5, 6); } .jfx-text-field { diff --git a/src/main/resources/views/LobbyView.fxml b/src/main/resources/views/LobbyView.fxml index 6fe65212..15fdd2e7 100644 --- a/src/main/resources/views/LobbyView.fxml +++ b/src/main/resources/views/LobbyView.fxml @@ -33,7 +33,7 @@ - - +