diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 4050a08f..c97b5be7 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -35,51 +35,7 @@ public class App extends Application { } public static void main(String[] args) { - StreamReceiver sr = null; - - new ServerThread("Racevision Test Server"); - - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - if (args.length == 1 && args[0].equals("-standalone")) { - return; - } - - if (args.length == 3 && args[0].equals("-server")) { - - sr = new StreamReceiver(args[1], Integer.valueOf(args[2]), "RaceStream"); - - } else if (args.length == 2 && args[0].equals("-server")) { - switch (args[1]) { - case "internal": - sr = new StreamReceiver("localhost", 4949, "RaceStream"); - break; - case "staffserver": - sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); - break; - case "official": - sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); - break; - } - } - //Change the StreamReceiver in this else block to change the default data source. - else{ -// sr = new StreamReceiver("localhost", 4949, "RaceStream"); -// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); - sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream"); -// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); - } - -// sr.start(); -// StreamParser streamParser = new StreamParser("StreamParser"); -// streamParser.start(); - launch(args); - } } diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index 893ab467..73b3766b 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -33,7 +33,7 @@ public class Controller implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - setContentPane("/views/StartScreen2View.fxml"); + setContentPane("/views/StartScreenView.fxml"); StreamParser.boatLocations.clear(); } } diff --git a/src/main/java/seng302/controllers/LobbyController.java b/src/main/java/seng302/controllers/LobbyController.java index 965d7703..eb0a5979 100644 --- a/src/main/java/seng302/controllers/LobbyController.java +++ b/src/main/java/seng302/controllers/LobbyController.java @@ -52,7 +52,7 @@ public class LobbyController { @FXML public void leaveLobbyButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function! - setContentPane("/views/StartScreen2View.fxml"); + setContentPane("/views/StartScreenView.fxml"); System.out.println("Leaving lobby!"); } diff --git a/src/main/java/seng302/controllers/StartScreen2Controller.java b/src/main/java/seng302/controllers/StartScreen2Controller.java deleted file mode 100644 index 974d18fe..00000000 --- a/src/main/java/seng302/controllers/StartScreen2Controller.java +++ /dev/null @@ -1,73 +0,0 @@ -package seng302.controllers; - -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.control.TextField; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Pane; -import seng302.gameServer.GameServerThread; -import seng302.gameServer.GameState; -import seng302.models.stream.StreamReceiver; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * A Class describing the actions of the start screen controller - * Created by wmu16 on 10/07/17. - */ -public class StartScreen2Controller { - - @FXML - private TextField ipTextField; - @FXML - private GridPane startScreen2; - - - private void setContentPane(String jfxUrl) { - try { - AnchorPane contentPane = (AnchorPane) startScreen2.getParent(); - contentPane.getChildren().removeAll(); - contentPane.getChildren().clear(); - contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - contentPane.getChildren() - .addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); - } catch (javafx.fxml.LoadException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - /** - * 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 - * Switches to the lobby screen - */ - @FXML - public void hostButtonPressed() { - try { - String ipAddress = InetAddress.getLocalHost().getHostAddress(); - new GameState(ipAddress); - GameServerThread gameServerThread = new GameServerThread("Game Server"); - setContentPane("/views/LobbyView.fxml"); - } catch (UnknownHostException e) { - System.err.println("COULD NOT FIND YOUR IP ADDRESS!"); - e.printStackTrace(); - } - - } - - - @FXML - public void connectButtonPressed() { - // TODO: 10/07/17 wmu16 - Finish function - String ipAddress = ipTextField.getText().trim(); - StreamReceiver sr = new StreamReceiver(ipAddress, GameServerThread.PORT_NUMBER, "HostStream"); - sr.start(); - } -} diff --git a/src/main/java/seng302/controllers/StartScreenController.java b/src/main/java/seng302/controllers/StartScreenController.java index 931874d5..8c8ef772 100644 --- a/src/main/java/seng302/controllers/StartScreenController.java +++ b/src/main/java/seng302/controllers/StartScreenController.java @@ -1,64 +1,39 @@ package seng302.controllers; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.ResourceBundle; -import java.util.Timer; -import java.util.TimerTask; -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.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; -import javafx.scene.paint.Color; -import seng302.models.Yacht; -import seng302.models.stream.StreamParser; -import seng302.models.stream.XMLParser.RaceXMLObject.Participant; +import seng302.gameServer.GameServerThread; +import seng302.gameServer.GameState; +import seng302.models.stream.StreamReceiver; -public class StartScreenController implements Initializable { +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * A Class describing the actions of the start screen controller + * Created by wmu16 on 10/07/17. + */ +public class StartScreenController { @FXML - private GridPane gridPane; + private TextField ipTextField; @FXML - private Label timeTillLive; - @FXML - private Button streamButton; - @FXML - private Button switchToRaceViewButton; - @FXML - private TableView teamList; - @FXML - private TableColumn boatNameCol; - @FXML - private TableColumn shortNameCol; - @FXML - private TableColumn countryCol; - @FXML - private TableColumn posCol; - @FXML - private Label realTime; + private GridPane startScreen2; - private boolean switchedToRaceView = false; private void setContentPane(String jfxUrl) { try { - // get the main controller anchor pane (MainView.fxml) - AnchorPane contentPane = (AnchorPane) gridPane.getParent(); + AnchorPane contentPane = (AnchorPane) startScreen2.getParent(); contentPane.getChildren().removeAll(); contentPane.getChildren().clear(); contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); contentPane.getChildren() - .addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); + .addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); } catch (javafx.fxml.LoadException e) { e.printStackTrace(); } catch (IOException e) { @@ -66,126 +41,34 @@ public class StartScreenController implements Initializable { } } - @Override - public void initialize(URL location, ResourceBundle resources) { - gridPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - teamList.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - } /** - * Running a timer to update the livestream status on welcome screen. Update interval is 1 - * second. + * 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 + * Switches to the lobby screen */ - public void startStream() { - // reset boolean for switch to race view - switchedToRaceView = false; - - if (StreamParser.isStreamStatus()) { - streamButton.setVisible(false); - realTime.setVisible(true); - timeTillLive.setVisible(true); - timeTillLive.setTextFill(Color.GREEN); - timeTillLive.setText("Connecting..."); - Timer timer = new Timer(); - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - Platform.runLater(() -> { - if (StreamParser.isRaceStarted()) { - if (!switchedToRaceView) { - switchToRaceView(); - } - timer.cancel(); - } - if (StreamParser.isRaceFinished()) { - realTime.setText(StreamParser.getCurrentTimeString()); - timeTillLive.setTextFill(Color.RED); - timeTillLive.setText("Race finished! Waiting for new race..."); - switchToRaceViewButton.setDisable(true); - } else if (StreamParser.getTimeSinceStart() > 0) { - realTime.setText(StreamParser.getCurrentTimeString()); - updateTeamList(); - timeTillLive.setTextFill(Color.RED); - switchToRaceViewButton.setDisable(false); - String timerMinute = Long - .toString(StreamParser.getTimeSinceStart() / 60); - String timerSecond = Long - .toString(StreamParser.getTimeSinceStart() % 60); - if (timerSecond.length() == 1) { - timerSecond = "0" + timerSecond; - } - String timerString = "-" + timerMinute + ":" + timerSecond; - timeTillLive.setText(timerString); - } else { - realTime.setText(StreamParser.getCurrentTimeString()); - updateTeamList(); - timeTillLive.setTextFill(Color.BLACK); - switchToRaceViewButton.setDisable(false); - String timerMinute = Long - .toString(-1 * StreamParser.getTimeSinceStart() / 60); - String timerSecond = Long - .toString(-1 * StreamParser.getTimeSinceStart() % 60); - if (timerSecond.length() == 1) { - timerSecond = "0" + timerSecond; - } - String timerString = timerMinute + ":" + timerSecond; - timeTillLive.setText(timerString); - } - }); - } - }, 0, 1000); - } else { - timeTillLive.setText("Stream not available."); - timeTillLive.setTextFill(Color.RED); + @FXML + public void hostButtonPressed() { + try { + String ipAddress = InetAddress.getLocalHost().getHostAddress(); + new GameState(ipAddress); + new GameServerThread("Game Server"); + System.out.println("Server thread started"); + setContentPane("/views/LobbyView.fxml"); + } catch (UnknownHostException e) { + System.err.println("COULD NOT FIND YOUR IP ADDRESS!"); + e.printStackTrace(); } + } - public void switchToRaceView() { - StreamParser.boatLocations.clear(); - switchedToRaceView = true; - setContentPane("/views/RaceView.fxml"); - } - private void updateTeamList() { - ObservableList data = FXCollections.observableArrayList(); - - teamList.setItems(data); - - boatNameCol.setCellValueFactory( - new PropertyValueFactory<>("boatName") - ); - shortNameCol.setCellValueFactory( - new PropertyValueFactory<>("shortName") - ); - countryCol.setCellValueFactory( - new PropertyValueFactory<>("country") - ); - posCol.setCellValueFactory( - new PropertyValueFactory<>("position") - ); - - // check if the boat is racing - ArrayList participants = StreamParser.getXmlObject().getRaceXML() - .getParticipants(); - ArrayList participantIDs = new ArrayList<>(); - for (Participant p : participants) { - participantIDs.add(p.getsourceID()); - } - - // add boats to the start screen list - if (StreamParser.isRaceStarted()) { // if race is started, use StreamParser.getBoatsPos() - for (Yacht boat : StreamParser.getBoatsPos().values()) { - if (participantIDs.contains(boat.getSourceID())) { - data.add(boat); - } - } - } else { // else use StreamParser.getBoats() - for (Yacht boat : StreamParser.getBoats().values()) { - if (participantIDs.contains(boat.getSourceID())) { - data.add(boat); - } - } - } - teamList.refresh(); + @FXML + public void connectButtonPressed() { + // TODO: 10/07/17 wmu16 - Finish function + String ipAddress = ipTextField.getText().trim(); + StreamReceiver sr = new StreamReceiver(ipAddress, GameServerThread.PORT_NUMBER, "HostStream"); + sr.start(); } } diff --git a/src/main/java/seng302/gameServer/GameServerThread.java b/src/main/java/seng302/gameServer/GameServerThread.java index 3f204e84..100e9791 100644 --- a/src/main/java/seng302/gameServer/GameServerThread.java +++ b/src/main/java/seng302/gameServer/GameServerThread.java @@ -141,6 +141,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel Message heartbeat = new Heartbeat(seqNum); try { + System.out.println("Sending heartbeat"); broadcast(heartbeat); } catch (IOException e) { e.printStackTrace(); @@ -163,6 +164,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel if (startTime < System.currentTimeMillis() && GameState.getCurrentStage() != GameStages.RACING){ } else{ + System.out.println("Sending race start status"); broadcast(raceStartStatusMessage); } @@ -202,12 +204,15 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel Message regatta = getXmlMessage("/server_config/regatta.xml", XMLMessageSubType.REGATTA); if (raceData != null){ + System.out.println("Sending RaceXML"); broadcast(raceData); } if (boatData != null){ + System.out.println("Sending boatsXML"); broadcast(boatData); } if (regatta != null){ + System.out.println("Sending regattaXML"); broadcast(regatta); } } catch (IOException e) { @@ -226,6 +231,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel try { Message raceData = getXmlMessage("/server_config/courseLimits.xml", XMLMessageSubType.RACE); if (raceData != null) { + System.out.println("Sending courseLimitsXML"); broadcast(raceData); } }catch (IOException e) { @@ -242,37 +248,47 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel try{ server = ServerSocketChannel.open(); server.socket().bind(new InetSocketAddress("localhost", PORT_NUMBER)); - serverListenThread = new ServerListenThread(server, this); - serverListenThread.start(); +// serverListenThread = new ServerListenThread(server, this); +// serverListenThread.start(); } catch (IOException e){ serverLog("Failed to bind socket: " + e.getMessage(), 0); } - while (hosting) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (GameState.getCurrentStage() == GameStages.RACING) { - System.out.println("Racing"); - //startSendingHeartbeats(); - sendXml(); - //startSendingRaceStartStatusMessages(); - //startSendingRaceStatusMessages(); - //sendPostStartCourseXml(); - } + acceptConnection(); + acceptConnection(); +// acceptConnection(); - else if (GameState.getCurrentStage() == GameStages.FINISHED) { - - } - - startTime = System.currentTimeMillis() + TIME_TILL_RACE_START; + for (Player player : GameState.getPlayers()) { + System.out.println(player); } + +// while (hosting) { +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// if (GameState.getCurrentStage() == GameStages.RACING) { +// System.out.println("Racing"); +// //startSendingHeartbeats(); +// sendXml(); +// //startSendingRaceStartStatusMessages(); +// //startSendingRaceStatusMessages(); +// //sendPostStartCourseXml(); +// } +// +// else if (GameState.getCurrentStage() == GameStages.FINISHED) { +// +// } +// +// startTime = System.currentTimeMillis() + TIME_TILL_RACE_START; +// } + startSendingHeartbeats(); - sendXml(); +// sendXml(); startSendingRaceStartStatusMessages(); //startSendingRaceStatusMessages(); sendPostStartCourseXml(); @@ -303,6 +319,21 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel // } + /** + * Listens for a connection and upon finding one, creates a Player object and adds it to the universal GameState + */ + private void acceptConnection() { + try { + SocketChannel thisClient = server.accept(); + if (thisClient.socket() != null){ + Player thisPlayer = new Player(thisClient); + GameState.addPlayer(thisPlayer); + } + } catch (IOException e) { + e.getMessage(); + } + } + void unicast(Message message, SocketChannel client) throws IOException { message.send(client); // TODO: 11/07/17 Do we incement seqNum for individual messages? @@ -311,6 +342,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel void broadcast(Message message) throws IOException{ for(Player player : GameState.getPlayers()) { + System.out.println("Sending message seqNo[" + seqNum + "] to Player: " + player.toString()); message.send(player.getSocketChannel()); } seqNum++; // TODO: 11/07/17 Do we increment seqNum for every message or for the one message to everyone diff --git a/src/main/java/seng302/models/Player.java b/src/main/java/seng302/models/Player.java index ceae4029..55897cd8 100644 --- a/src/main/java/seng302/models/Player.java +++ b/src/main/java/seng302/models/Player.java @@ -2,6 +2,7 @@ package seng302.models; import javafx.scene.paint.Color; +import java.io.IOException; import java.nio.channels.SocketChannel; /** @@ -36,4 +37,16 @@ public class Player { public Yacht getYacht() { return yacht; } + + @Override + public String toString() { + String playerAddress = null; + try { + playerAddress = socketChannel.getRemoteAddress().toString(); + } catch (IOException e) { + e.printStackTrace(); + } + + return playerAddress; + } } diff --git a/src/main/resources/views/StartScreen2View.fxml b/src/main/resources/views/StartScreen2View.fxml deleted file mode 100644 index 435001ee..00000000 --- a/src/main/resources/views/StartScreen2View.fxml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -