mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Began fixing bugs with caused by asynchronous listener calls.
#bug
This commit is contained in:
@@ -17,7 +17,9 @@ public class App extends Application {
|
||||
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml"));
|
||||
primaryStage.setTitle("RaceVision");
|
||||
primaryStage.setScene(new Scene(root, 1530, 960));
|
||||
Scene scene = new Scene(root, 1530, 960);
|
||||
scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
primaryStage.setScene(scene);
|
||||
// primaryStage.setMaxWidth(1530);
|
||||
// primaryStage.setMaxHeight(960);
|
||||
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
@@ -27,11 +29,11 @@ public class App extends Application {
|
||||
primaryStage.setOnCloseRequest(e -> {
|
||||
// ClientPacketParser.appClose();
|
||||
StreamReceiver.noMoreBytes();
|
||||
ClientPacketParser.appClose();
|
||||
// ClientPacketParser.appClose();
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
ClientState.primaryStage = primaryStage;
|
||||
// ClientState.primaryStage = primaryStage;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,77 +1,77 @@
|
||||
package seng302.client;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import seng302.model.Yacht;
|
||||
import javafx.stage.Stage;
|
||||
import seng302.models.Yacht;
|
||||
|
||||
/**
|
||||
* Used by the client to store static variables to be used in game.
|
||||
*/
|
||||
public class ClientState {
|
||||
|
||||
// private static String hostIp = "";
|
||||
// private static Boolean isHost = false;
|
||||
// private static Boolean raceStarted = false;
|
||||
// private static Boolean connectedToHost = false;
|
||||
// private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
|
||||
// private static Boolean dirtyState = true;
|
||||
// private static String clientSourceId = "";
|
||||
//package seng302.client;
|
||||
//
|
||||
// public static String getHostIp() {
|
||||
// return hostIp;
|
||||
// }
|
||||
//import java.util.Map;
|
||||
//import java.util.concurrent.ConcurrentHashMap;
|
||||
//import seng302.model.Yacht;
|
||||
//import javafx.stage.Stage;
|
||||
//import seng302.models.Yacht;
|
||||
//
|
||||
// public static void setHostIp(String hostIp) {
|
||||
// ClientState.hostIp = hostIp;
|
||||
// }
|
||||
///**
|
||||
// * Used by the client to store static variables to be used in game.
|
||||
// */
|
||||
//public class ClientState {
|
||||
//
|
||||
// public static Boolean isHost() {
|
||||
// return isHost;
|
||||
// }
|
||||
//
|
||||
// public static void setHost(Boolean isHost) {
|
||||
// ClientState.isHost = isHost;
|
||||
// }
|
||||
//
|
||||
// public static Boolean isRaceStarted() {
|
||||
// return raceStarted;
|
||||
// }
|
||||
//
|
||||
// public static void setRaceStarted(Boolean raceStarted) {
|
||||
// ClientState.raceStarted = raceStarted;
|
||||
// }
|
||||
//
|
||||
// public static Boolean isConnectedToHost() {
|
||||
// return connectedToHost;
|
||||
// }
|
||||
//
|
||||
// public static void setConnectedToHost(Boolean connectedToHost) {
|
||||
// ClientState.connectedToHost = connectedToHost;
|
||||
// }
|
||||
//
|
||||
// public static Map<Integer, Yacht> getBoats() {
|
||||
// return boats;
|
||||
// }
|
||||
//
|
||||
// public static Boolean isDirtyState() {
|
||||
// return dirtyState;
|
||||
// }
|
||||
//
|
||||
// public static void setDirtyState(Boolean dirtyState) {
|
||||
// ClientState.dirtyState = dirtyState;
|
||||
// }
|
||||
//
|
||||
// public static String getClientSourceId() {
|
||||
// return clientSourceId;
|
||||
// }
|
||||
//
|
||||
// public static void setClientSourceId(String clientSourceId) {
|
||||
// ClientState.clientSourceId = clientSourceId;
|
||||
// }
|
||||
//
|
||||
// public static void setBoats(Map<Integer, Yacht> boats) {
|
||||
// ClientState.boats = boats;
|
||||
// }
|
||||
}
|
||||
//// private static String hostIp = "";
|
||||
//// private static Boolean isHost = false;
|
||||
//// private static Boolean raceStarted = false;
|
||||
//// private static Boolean connectedToHost = false;
|
||||
//// private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
|
||||
//// private static Boolean dirtyState = true;
|
||||
//// private static String clientSourceId = "";
|
||||
////
|
||||
//// public static String getHostIp() {
|
||||
//// return hostIp;
|
||||
//// }
|
||||
////
|
||||
//// public static void setHostIp(String hostIp) {
|
||||
//// ClientState.hostIp = hostIp;
|
||||
//// }
|
||||
////
|
||||
//// public static Boolean isHost() {
|
||||
//// return isHost;
|
||||
//// }
|
||||
////
|
||||
//// public static void setHost(Boolean isHost) {
|
||||
//// ClientState.isHost = isHost;
|
||||
//// }
|
||||
////
|
||||
//// public static Boolean isRaceStarted() {
|
||||
//// return raceStarted;
|
||||
//// }
|
||||
////
|
||||
//// public static void setRaceStarted(Boolean raceStarted) {
|
||||
//// ClientState.raceStarted = raceStarted;
|
||||
//// }
|
||||
////
|
||||
//// public static Boolean isConnectedToHost() {
|
||||
//// return connectedToHost;
|
||||
//// }
|
||||
////
|
||||
//// public static void setConnectedToHost(Boolean connectedToHost) {
|
||||
//// ClientState.connectedToHost = connectedToHost;
|
||||
//// }
|
||||
////
|
||||
//// public static Map<Integer, Yacht> getBoats() {
|
||||
//// return boats;
|
||||
//// }
|
||||
////
|
||||
//// public static Boolean isDirtyState() {
|
||||
//// return dirtyState;
|
||||
//// }
|
||||
////
|
||||
//// public static void setDirtyState(Boolean dirtyState) {
|
||||
//// ClientState.dirtyState = dirtyState;
|
||||
//// }
|
||||
////
|
||||
//// public static String getClientSourceId() {
|
||||
//// return clientSourceId;
|
||||
//// }
|
||||
////
|
||||
//// public static void setClientSourceId(String clientSourceId) {
|
||||
//// ClientState.clientSourceId = clientSourceId;
|
||||
//// }
|
||||
////
|
||||
//// public static void setBoats(Map<Integer, Yacht> boats) {
|
||||
//// ClientState.boats = boats;
|
||||
//// }
|
||||
//}
|
||||
|
||||
@@ -1,235 +1,235 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
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.ListView;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.text.Text;
|
||||
import seng302.client.ClientState;
|
||||
import seng302.client.ClientStateQueryingRunnable;
|
||||
import seng302.gameServer.GameStages;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.gameServer.MainServerThread;
|
||||
|
||||
/**
|
||||
* A class describing the actions of the lobby screen
|
||||
* Created by wmu16 on 10/07/17.
|
||||
*/
|
||||
public class LobbyController implements Initializable, Observer{
|
||||
@FXML
|
||||
private GridPane lobbyScreen;
|
||||
@FXML
|
||||
private Text lobbyIpText;
|
||||
@FXML
|
||||
private Button readyButton;
|
||||
@FXML
|
||||
private ListView firstListView;
|
||||
@FXML
|
||||
private ListView secondListView;
|
||||
@FXML
|
||||
private ListView thirdListView;
|
||||
@FXML
|
||||
private ListView fourthListView;
|
||||
@FXML
|
||||
private ListView fifthListView;
|
||||
@FXML
|
||||
private ListView sixthListView;
|
||||
@FXML
|
||||
private ListView seventhListView;
|
||||
@FXML
|
||||
private ListView eighthListView;
|
||||
@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;
|
||||
|
||||
private static List<ObservableList<String>> competitors = new ArrayList<>();
|
||||
private static ObservableList<String> firstCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> secondCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> thirdCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> fourthCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> fifthCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> sixthCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
|
||||
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
||||
private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
||||
private static List<ImageView> imageViews;
|
||||
private static List<ListView> listViews;
|
||||
|
||||
private int MAX_NUM_PLAYERS = 8;
|
||||
|
||||
private Boolean switchedPane = false;
|
||||
private MainServerThread mainServerThread;
|
||||
private Controller controller;
|
||||
|
||||
private void setContentPane(String jfxUrl) {
|
||||
try {
|
||||
AnchorPane contentPane = (AnchorPane) lobbyScreen.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) {
|
||||
System.out.println("[Controller] FXML load exception");
|
||||
} catch (IOException e) {
|
||||
System.out.println("[Controller] IO exception");
|
||||
} catch (NullPointerException e) {
|
||||
// System.out.println("[Controller] Null Pointer Exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
if (ClientState.isHost()) {
|
||||
lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
|
||||
readyButton.setDisable(false);
|
||||
}
|
||||
else {
|
||||
lobbyIpText.setText("Connected to IP: " + ClientState.getHostIp());
|
||||
readyButton.setDisable(true);
|
||||
}
|
||||
|
||||
// put all javafx objects in lists, so we can iterate though conveniently
|
||||
imageViews = new ArrayList<>();
|
||||
Collections.addAll(imageViews, firstImageView, secondImageView, thirdImageView, fourthImageView,
|
||||
fifthImageView, sixthImageView, seventhImageView, eighthImageView);
|
||||
listViews = new ArrayList<>();
|
||||
Collections.addAll(listViews, firstListView, secondListView, thirdListView, fourthListView, fifthListView,
|
||||
sixthListView, seventhListView, eighthListView);
|
||||
competitors = new ArrayList<>();
|
||||
Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
|
||||
fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
|
||||
|
||||
initialiseListView();
|
||||
initialiseImageView(); // parrot gif init
|
||||
|
||||
// set up client state query thread, so that when it receives the race-started packet
|
||||
// it can switch to the race view
|
||||
ClientStateQueryingRunnable clientStateQueryingRunnable = new ClientStateQueryingRunnable();
|
||||
clientStateQueryingRunnable.addObserver(this);
|
||||
Thread clientStateQueryingThread = new Thread(clientStateQueryingRunnable, "Client State querying thread");
|
||||
clientStateQueryingThread.setDaemon(true);
|
||||
clientStateQueryingThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Observers "ClientStateQueryingRunnable".
|
||||
* When the clients state has been marked to "race start", the querying thread
|
||||
* will notify this lobby to change the view
|
||||
* @param o
|
||||
* @param arg
|
||||
*/
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (arg.equals("game started") && !switchedPane) {
|
||||
switchToRaceView();
|
||||
}
|
||||
if (arg.equals(("update players"))) {
|
||||
initialiseListView();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all ListViews and ImageViews according to the current competitors
|
||||
*/
|
||||
private void initialiseListView() {
|
||||
listViews.forEach(listView -> listView.getItems().clear());
|
||||
imageViews.forEach(gif -> gif.setVisible(false));
|
||||
competitors.forEach(ol -> ol.removeAll());
|
||||
|
||||
List<Integer> ids = new ArrayList<>(ClientState.getBoats().keySet());
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
competitors.get(i).add(ClientState.getBoats().get(ids.get(i)).getBoatName());
|
||||
listViews.get(i).setItems(competitors.get(i));
|
||||
imageViews.get(i).setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads preset images into imageViews
|
||||
*/
|
||||
private void initialiseImageView() {
|
||||
for (int i = 0; i < MAX_NUM_PLAYERS; i++) {
|
||||
imageViews.get(i).setImage(new Image(getClass().getResourceAsStream("/pics/sail.png")));
|
||||
}
|
||||
// Image image1 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// firstImageView.setImage(image1);
|
||||
// Image image2 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// secondImageView.setImage(image2);
|
||||
// Image image3 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// thirdImageView.setImage(image3);
|
||||
// Image image4 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// fourthImageView.setImage(image4);
|
||||
// Image image5 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// fifthImageView.setImage(image5);
|
||||
// Image image6 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// sixthImageView.setImage(image6);
|
||||
// Image image7 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// seventhImageView.setImage(image7);
|
||||
// Image image8 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
// eighthImageView.setImage(image8);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void leaveLobbyButtonPressed() {
|
||||
if (ClientState.isHost()) {
|
||||
GameState.setCurrentStage(GameStages.CANCELLED);
|
||||
mainServerThread.terminate();
|
||||
}
|
||||
ClientState.setConnectedToHost(false);
|
||||
controller.setUpStartScreen();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void readyButtonPressed() {
|
||||
GameState.setCurrentStage(GameStages.RACING);
|
||||
mainServerThread.startGame();
|
||||
}
|
||||
|
||||
|
||||
private void switchToRaceView() {
|
||||
if (!switchedPane) {
|
||||
switchedPane = true;
|
||||
setContentPane("/views/RaceView.fxml");
|
||||
}
|
||||
}
|
||||
|
||||
public void setMainServerThread(MainServerThread mainServerThread) {
|
||||
this.mainServerThread = mainServerThread;
|
||||
}
|
||||
|
||||
public void setController(Controller controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
}
|
||||
//package seng302.controllers;
|
||||
//
|
||||
//import java.io.IOException;
|
||||
//import java.net.URL;
|
||||
//import java.util.*;
|
||||
//
|
||||
//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.ListView;
|
||||
//import javafx.scene.image.Image;
|
||||
//import javafx.scene.image.ImageView;
|
||||
//import javafx.scene.layout.AnchorPane;
|
||||
//import javafx.scene.layout.GridPane;
|
||||
//import javafx.scene.layout.Pane;
|
||||
//import javafx.scene.text.Text;
|
||||
//import seng302.client.ClientState;
|
||||
//import seng302.client.ClientStateQueryingRunnable;
|
||||
//import seng302.gameServer.GameStages;
|
||||
//import seng302.gameServer.GameState;
|
||||
//import seng302.gameServer.MainServerThread;
|
||||
//
|
||||
///**
|
||||
// * A class describing the actions of the lobby screen
|
||||
// * Created by wmu16 on 10/07/17.
|
||||
// */
|
||||
//public class LobbyController implements Initializable, Observer{
|
||||
// @FXML
|
||||
// private GridPane lobbyScreen;
|
||||
// @FXML
|
||||
// private Text lobbyIpText;
|
||||
// @FXML
|
||||
// private Button readyButton;
|
||||
// @FXML
|
||||
// private ListView firstListView;
|
||||
// @FXML
|
||||
// private ListView secondListView;
|
||||
// @FXML
|
||||
// private ListView thirdListView;
|
||||
// @FXML
|
||||
// private ListView fourthListView;
|
||||
// @FXML
|
||||
// private ListView fifthListView;
|
||||
// @FXML
|
||||
// private ListView sixthListView;
|
||||
// @FXML
|
||||
// private ListView seventhListView;
|
||||
// @FXML
|
||||
// private ListView eighthListView;
|
||||
// @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;
|
||||
//
|
||||
// private static List<ObservableList<String>> competitors = new ArrayList<>();
|
||||
// private static ObservableList<String> firstCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> secondCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> thirdCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> fourthCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> fifthCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> sixthCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> seventhCompetitor = FXCollections.observableArrayList();
|
||||
// private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
||||
// private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
||||
// private static List<ImageView> imageViews;
|
||||
// private static List<ListView> listViews;
|
||||
//
|
||||
// private int MAX_NUM_PLAYERS = 8;
|
||||
//
|
||||
// private Boolean switchedPane = false;
|
||||
// private MainServerThread mainServerThread;
|
||||
// private Controller controller;
|
||||
//
|
||||
// private void setContentPane(String jfxUrl) {
|
||||
// try {
|
||||
// AnchorPane contentPane = (AnchorPane) lobbyScreen.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) {
|
||||
// System.out.println("[Controller] FXML load exception");
|
||||
// } catch (IOException e) {
|
||||
// System.out.println("[Controller] IO exception");
|
||||
// } catch (NullPointerException e) {
|
||||
//// System.out.println("[Controller] Null Pointer Exception");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void initialize(URL location, ResourceBundle resources) {
|
||||
// if (ClientState.isHost()) {
|
||||
// lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
|
||||
// readyButton.setDisable(false);
|
||||
// }
|
||||
// else {
|
||||
// lobbyIpText.setText("Connected to IP: " + ClientState.getHostIp());
|
||||
// readyButton.setDisable(true);
|
||||
// }
|
||||
//
|
||||
// // put all javafx objects in lists, so we can iterate though conveniently
|
||||
// imageViews = new ArrayList<>();
|
||||
// Collections.addAll(imageViews, firstImageView, secondImageView, thirdImageView, fourthImageView,
|
||||
// fifthImageView, sixthImageView, seventhImageView, eighthImageView);
|
||||
// listViews = new ArrayList<>();
|
||||
// Collections.addAll(listViews, firstListView, secondListView, thirdListView, fourthListView, fifthListView,
|
||||
// sixthListView, seventhListView, eighthListView);
|
||||
// competitors = new ArrayList<>();
|
||||
// Collections.addAll(competitors, firstCompetitor, secondCompetitor, thirdCompetitor,
|
||||
// fourthCompetitor, fifthCompetitor, sixthCompetitor, seventhCompetitor, eighthCompetitor);
|
||||
//
|
||||
// initialiseListView();
|
||||
// initialiseImageView(); // parrot gif init
|
||||
//
|
||||
// // set up client state query thread, so that when it receives the race-started packet
|
||||
// // it can switch to the race view
|
||||
// ClientStateQueryingRunnable clientStateQueryingRunnable = new ClientStateQueryingRunnable();
|
||||
// clientStateQueryingRunnable.addObserver(this);
|
||||
// Thread clientStateQueryingThread = new Thread(clientStateQueryingRunnable, "Client State querying thread");
|
||||
// clientStateQueryingThread.setDaemon(true);
|
||||
// clientStateQueryingThread.start();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Observers "ClientStateQueryingRunnable".
|
||||
// * When the clients state has been marked to "race start", the querying thread
|
||||
// * will notify this lobby to change the view
|
||||
// * @param o
|
||||
// * @param arg
|
||||
// */
|
||||
// @Override
|
||||
// public void update(Observable o, Object arg) {
|
||||
// Platform.runLater(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// if (arg.equals("game started") && !switchedPane) {
|
||||
// switchToRaceView();
|
||||
// }
|
||||
// if (arg.equals(("update players"))) {
|
||||
// initialiseListView();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Reset all ListViews and ImageViews according to the current competitors
|
||||
// */
|
||||
// private void initialiseListView() {
|
||||
// listViews.forEach(listView -> listView.getItems().clear());
|
||||
// imageViews.forEach(gif -> gif.setVisible(false));
|
||||
// competitors.forEach(ol -> ol.removeAll());
|
||||
//
|
||||
// List<Integer> ids = new ArrayList<>(ClientState.getBoats().keySet());
|
||||
// for (int i = 0; i < ids.size(); i++) {
|
||||
// competitors.get(i).add(ClientState.getBoats().get(ids.get(i)).getBoatName());
|
||||
// listViews.get(i).setItems(competitors.get(i));
|
||||
// imageViews.get(i).setVisible(true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Loads preset images into imageViews
|
||||
// */
|
||||
// private void initialiseImageView() {
|
||||
// for (int i = 0; i < MAX_NUM_PLAYERS; i++) {
|
||||
// imageViews.get(i).setImage(new Image(getClass().getResourceAsStream("/pics/sail.png")));
|
||||
// }
|
||||
//// Image image1 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// firstImageView.setImage(image1);
|
||||
//// Image image2 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// secondImageView.setImage(image2);
|
||||
//// Image image3 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// thirdImageView.setImage(image3);
|
||||
//// Image image4 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// fourthImageView.setImage(image4);
|
||||
//// Image image5 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// fifthImageView.setImage(image5);
|
||||
//// Image image6 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// sixthImageView.setImage(image6);
|
||||
//// Image image7 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// seventhImageView.setImage(image7);
|
||||
//// Image image8 = new Image(getClass().getResourceAsStream("/pics/sail.png"));
|
||||
//// eighthImageView.setImage(image8);
|
||||
// }
|
||||
//
|
||||
// @FXML
|
||||
// public void leaveLobbyButtonPressed() {
|
||||
// if (ClientState.isHost()) {
|
||||
// GameState.setCurrentStage(GameStages.CANCELLED);
|
||||
// mainServerThread.terminate();
|
||||
// }
|
||||
// ClientState.setConnectedToHost(false);
|
||||
// controller.setUpStartScreen();
|
||||
// }
|
||||
//
|
||||
// @FXML
|
||||
// public void readyButtonPressed() {
|
||||
// GameState.setCurrentStage(GameStages.RACING);
|
||||
// mainServerThread.startGame();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private void switchToRaceView() {
|
||||
// if (!switchedPane) {
|
||||
// switchedPane = true;
|
||||
// setContentPane("/views/RaceView.fxml");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void setMainServerThread(MainServerThread mainServerThread) {
|
||||
// this.mainServerThread = mainServerThread;
|
||||
// }
|
||||
//
|
||||
// public void setController(Controller controller) {
|
||||
// this.controller = controller;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import seng302.model.Player;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.server.messages.BoatActionType;
|
||||
|
||||
/**
|
||||
@@ -26,6 +27,7 @@ public class GameState implements Runnable {
|
||||
private static Map<Integer, Yacht> yachts;
|
||||
private static Boolean isRaceStarted;
|
||||
private static GameStages currentStage;
|
||||
private static long startTime;
|
||||
|
||||
// TODO: 26/07/17 cir27 - Super hackish fix until something more permanent can be made.
|
||||
private static ObservableList<String> observablePlayers = FXCollections.observableArrayList();
|
||||
@@ -170,7 +172,6 @@ public class GameState implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a new ID based off the size of current players + 1
|
||||
* @return a playerID to be allocated to a new connetion
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Stack;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import seng302.model.Player;
|
||||
import seng302.server.messages.Heartbeat;
|
||||
import seng302.server.messages.Message;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Send Heartbeat messages to connected player at a specified interval
|
||||
* Will call .clientDisconnected on the delegate when a heartbeat message
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Observable;
|
||||
import seng302.client.ClientPacketParser;
|
||||
import seng302.models.Player;
|
||||
import seng302.models.stream.PacketBufferDelegate;
|
||||
import seng302.models.stream.packets.StreamPacket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Observable;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.logging.Logger;
|
||||
import seng302.model.Player;
|
||||
|
||||
/**
|
||||
* A class describing the overall server, which creates and collects server threads for each client
|
||||
|
||||
@@ -3,7 +3,6 @@ package seng302.gameServer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -15,7 +14,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.CRC32;
|
||||
@@ -26,13 +24,12 @@ 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.model.stream.xml.generator.XMLGenerator;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
import seng302.server.messages.BoatActionType;
|
||||
import seng302.server.messages.BoatLocationMessage;
|
||||
import seng302.server.messages.BoatStatus;
|
||||
import seng302.server.messages.BoatSubMessage;
|
||||
import seng302.server.messages.Message;
|
||||
|
||||
import seng302.server.messages.RaceStatus;
|
||||
import seng302.server.messages.RaceStatusMessage;
|
||||
import seng302.server.messages.RaceType;
|
||||
@@ -270,6 +267,7 @@ public class ServerToClientThread implements Runnable, Observer {
|
||||
currentByte = is.read();
|
||||
crcBuffer.write(currentByte);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
serverLog("Socket read failed", 1);
|
||||
}
|
||||
if (currentByte == -1) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package seng302.model;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Stores the data for the cornering of a mark.
|
||||
*/
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
package seng302.model;
|
||||
|
||||
import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongWrapper;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.paint.Color;
|
||||
import seng302.model.mark.Mark;
|
||||
import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import javafx.scene.paint.Color;
|
||||
import seng302.client.ClientPacketParser;
|
||||
import seng302.controllers.RaceViewController;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.GeoPoint;
|
||||
|
||||
/**
|
||||
@@ -32,6 +29,11 @@ public class Yacht {
|
||||
void notifyLocation(Yacht yacht, double lat, double lon, double heading, double velocity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface YachtPositionListener {
|
||||
void notifyPosition(int position);
|
||||
}
|
||||
|
||||
//BOTH AFAIK
|
||||
private String boatType;
|
||||
private Integer sourceId;
|
||||
@@ -137,7 +139,7 @@ public class Yacht {
|
||||
Double windSpeedKnots = GameState.getWindSpeedKnots();
|
||||
Double trueWindAngle = Math.abs(GameState.getWindDirection() - heading);
|
||||
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, trueWindAngle);
|
||||
Double maxBoatSpeed = boatSpeedInKnots / ClientPacketParser.MS_TO_KNOTS * 1000;
|
||||
Double maxBoatSpeed = boatSpeedInKnots / 1.943844492 * 1000;
|
||||
if (sailIn && velocity <= maxBoatSpeed && maxBoatSpeed != 0d) {
|
||||
|
||||
if (velocity < maxBoatSpeed) {
|
||||
@@ -159,30 +161,22 @@ public class Yacht {
|
||||
velocity = 0d;
|
||||
}
|
||||
}
|
||||
if (sailIn) {
|
||||
Double secondsElapsed = timeInterval / 1000000.0;
|
||||
Double windSpeedKnots = GameState.getWindSpeedKnots();
|
||||
Double trueWindAngle = Math.abs(GameState.getWindDirection() - heading);
|
||||
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, trueWindAngle);
|
||||
velocity = boatSpeedInKnots / 1.943844492 * 1000; // TODO: 26/07/17 cir27 - Remove magic number
|
||||
Double metersCovered = velocity * secondsElapsed;
|
||||
location = getGeoCoordinate(location, heading, metersCovered);
|
||||
} else {
|
||||
velocity = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if (sailIn) {
|
||||
// Double secondsElapsed = timeInterval / 1000000.0;
|
||||
// Double windSpeedKnots = GameState.getWindSpeedKnots();
|
||||
// Double trueWindAngle = Math.abs(GameState.getWindDirection() - heading);
|
||||
// Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, trueWindAngle);
|
||||
// velocity = boatSpeedInKnots / 1.943844492 * 1000; // TODO: 26/07/17 cir27 - Remove magic number
|
||||
// Double metersCovered = velocity * secondsElapsed;
|
||||
// location = getGeoCoordinate(location, heading, metersCovered);
|
||||
// } else {
|
||||
// velocity = 0d;
|
||||
// }
|
||||
Double metersCovered = velocity * secondsElapsed;
|
||||
location = getGeoCoordinate(location, heading, metersCovered);
|
||||
}
|
||||
|
||||
|
||||
public Double getHeading() {
|
||||
return heading;
|
||||
}
|
||||
|
||||
public void adjustHeading(Double amount) {
|
||||
Double newVal = heading + amount;
|
||||
lastHeading = heading;
|
||||
@@ -501,4 +495,8 @@ public class Yacht {
|
||||
public void addLocationListener (YachtLocationListener listener) {
|
||||
locationListeners.add(listener);
|
||||
}
|
||||
|
||||
public void addPositionListener (YachtPositionListener listener) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package seng302.model.stream;
|
||||
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
|
||||
public interface PacketBufferDelegate {
|
||||
boolean addToBuffer(StreamPacket streamPacket);
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package seng302.model.stream;
|
||||
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
|
||||
|
||||
public class StreamReceiver extends Thread {
|
||||
private InputStream inputStream;
|
||||
private OutputStream outputStream;
|
||||
private Socket host;
|
||||
private ByteArrayOutputStream crcBuffer;
|
||||
private Thread t;
|
||||
private String threadName;
|
||||
public static PriorityBlockingQueue<StreamPacket> packetBuffer;
|
||||
private static boolean moreBytes;
|
||||
|
||||
public StreamReceiver(String hostAddress, int hostPort, String threadName) {
|
||||
this.threadName = threadName;
|
||||
this.setDaemon(true);
|
||||
try {
|
||||
host = new Socket(hostAddress, hostPort);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void run(){
|
||||
PriorityBlockingQueue<StreamPacket> pq = new PriorityBlockingQueue<>(256, new Comparator<StreamPacket>() {
|
||||
@Override
|
||||
public int compare(StreamPacket s1, StreamPacket s2) {
|
||||
return (int) (s1.getTimeStamp() - s2.getTimeStamp());
|
||||
}
|
||||
});
|
||||
packetBuffer = pq;
|
||||
connect();
|
||||
}
|
||||
|
||||
public void start () {
|
||||
if (t == null) {
|
||||
t = new Thread (this, threadName);
|
||||
t.start ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public StreamReceiver(Socket host, PriorityBlockingQueue packetBuffer){
|
||||
this.host=host;
|
||||
this.packetBuffer = packetBuffer;
|
||||
}
|
||||
|
||||
|
||||
public void connect(){
|
||||
|
||||
// int sync1;
|
||||
// int sync2;
|
||||
// moreBytes = true;
|
||||
// while(moreBytes) {
|
||||
// try {
|
||||
// crcBuffer = new ByteArrayOutputStream();
|
||||
// sync1 = readByte();
|
||||
// sync2 = readByte();
|
||||
// //checking if it is the start of the packet
|
||||
// if(sync1 == 0x47 && sync2 == 0x83) {
|
||||
// int type = readByte();
|
||||
// //No. of milliseconds since Jan 1st 1970
|
||||
// long timeStamp = bytesToLong(getBytes(6));
|
||||
// skipBytes(4);
|
||||
// long payloadLength = bytesToLong(getBytes(2));
|
||||
// byte[] payload = getBytes((int) payloadLength);
|
||||
// Checksum checksum = new CRC32();
|
||||
// checksum.update(crcBuffer.toByteArray(), 0, crcBuffer.size());
|
||||
// long computedCrc = checksum.getValue();
|
||||
// long packetCrc = bytesToLong(getBytes(4));
|
||||
// if (computedCrc == packetCrc) {
|
||||
// packetBuffer.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
// } else {
|
||||
// System.err.println("Packet has been dropped");
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// moreBytes = false;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private int readByte() throws Exception {
|
||||
int currentByte = -1;
|
||||
try {
|
||||
currentByte = inputStream.read();
|
||||
crcBuffer.write(currentByte);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (currentByte == -1){
|
||||
throw new Exception();
|
||||
}
|
||||
return currentByte;
|
||||
}
|
||||
|
||||
private byte[] getBytes(int n) throws Exception{
|
||||
byte[] bytes = new byte[n];
|
||||
for (int i = 0; i < n; i++){
|
||||
bytes[i] = (byte) readByte();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private void skipBytes(long n) throws Exception{
|
||||
for (int i=0; i < n; i++){
|
||||
readByte();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
StreamReceiver sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1");
|
||||
//StreamReceiver sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread2");
|
||||
sr.start();
|
||||
|
||||
}
|
||||
|
||||
public static void noMoreBytes(){
|
||||
moreBytes = false;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public class MarkRoundingData {
|
||||
private int roundingSide;
|
||||
private long timeStamp;
|
||||
|
||||
MarkRoundingData(int boatId, int markId, int roundingSide, long timeStamp) {
|
||||
public MarkRoundingData(int boatId, int markId, int roundingSide, long timeStamp) {
|
||||
this.boatId = boatId;
|
||||
this.markId = markId;
|
||||
this.roundingSide = roundingSide;
|
||||
|
||||
@@ -14,7 +14,7 @@ public class PositionUpdateData {
|
||||
private double heading;
|
||||
private double groundSpeed;
|
||||
|
||||
PositionUpdateData(int deviceId, DeviceType type, double lat, double lon,
|
||||
public PositionUpdateData(int deviceId, DeviceType type, double lat, double lon,
|
||||
double heading, double groundSpeed) {
|
||||
this.deviceId = deviceId;
|
||||
this.type = type;
|
||||
|
||||
@@ -10,7 +10,7 @@ public class RaceStartData {
|
||||
private int notificationType;
|
||||
private long timeStamp;
|
||||
|
||||
RaceStartData (long raceId, long raceStartTime, int notificationType, long timeStamp) {
|
||||
public RaceStartData (long raceId, long raceStartTime, int notificationType, long timeStamp) {
|
||||
this.raceId = raceId;
|
||||
this.raceStartTime = raceStartTime;
|
||||
this.notificationType = notificationType;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class RaceStatusData {
|
||||
private long expectedStartTime;
|
||||
private List<long[]> boatData = new ArrayList<>();
|
||||
|
||||
RaceStatusData(
|
||||
public RaceStatusData(
|
||||
long windDir, long rawWindSpeed, int raceStatus, long currentTime, long expectedStartTime) {
|
||||
|
||||
windDirection = windDir / WIND_DIR_FACTOR;
|
||||
@@ -29,8 +29,8 @@ public class RaceStatusData {
|
||||
this.expectedStartTime = expectedStartTime;
|
||||
}
|
||||
|
||||
void addBoatData (long boatID, long estTimeToNextMark, long estTimeToFinish, int leg) {
|
||||
boatData.add(new long[] {boatID, estTimeToNextMark, estTimeToFinish, leg});
|
||||
public void addBoatData (long boatID, long estTimeToNextMark, long estTimeToFinish, int leg, int boatStatus) {
|
||||
boatData.add(new long[] {boatID, estTimeToNextMark, estTimeToFinish, leg, boatStatus});
|
||||
}
|
||||
|
||||
public double getWindDirection() {
|
||||
|
||||
@@ -18,7 +18,7 @@ public class RaceXMLData {
|
||||
private List<Limit> courseLimit;
|
||||
private Map<Integer, Mark> individualMarks;
|
||||
|
||||
RaceXMLData(List<Integer> participants, List<Mark> compoundMarks, List<Corner> markSequence,
|
||||
public RaceXMLData(List<Integer> participants, List<Mark> compoundMarks, List<Corner> markSequence,
|
||||
List<Limit> courseLimit) {
|
||||
this.participants = participants;
|
||||
this.markSequence = markSequence;
|
||||
|
||||
@@ -12,7 +12,7 @@ public class RegattaXMLData {
|
||||
private Double centralLng;
|
||||
private Integer utcOffset;
|
||||
|
||||
RegattaXMLData (Integer regattaID, String regattaName, String courseName,
|
||||
public RegattaXMLData (Integer regattaID, String regattaName, String courseName,
|
||||
Double centralLat, Double centralLng, Integer utcOffset) {
|
||||
this.regattaID = regattaID;
|
||||
this.regattaName = regattaName;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Created by kre39 on 12/07/17.
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BoatLocationMessage extends Message {
|
||||
private final int MESSAGE_SIZE = 56;
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Header {
|
||||
// From API spec
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Heartbeat extends Message {
|
||||
private final int MESSAGE_SIZE = 4;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class MarkRoundingMessage extends Message{
|
||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||
private final int MESSAGE_SIZE = 21;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class RaceStartStatusMessage extends Message {
|
||||
private final int MESSAGE_SIZE = 20;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class XMLMessage extends Message{
|
||||
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
|
||||
private final int MESSAGE_VERSION = 1; //Always set to 1
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package seng302.server.simulator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import seng302.server.simulator.mark.Corner;
|
||||
import seng302.server.simulator.mark.Mark;
|
||||
import seng302.server.simulator.parsers.RaceParser;
|
||||
import seng302.utilities.GeoPoint;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Simulator extends Observable implements Runnable {
|
||||
|
||||
private List<Corner> course;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package seng302.server.simulator.parsers;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package seng302.server.simulator.parsers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -9,11 +13,6 @@ import seng302.server.simulator.mark.Corner;
|
||||
import seng302.server.simulator.mark.Mark;
|
||||
import seng302.server.simulator.mark.RoundingType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Parses the race xml file to get course details
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package seng302.server.simulator.parsers;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package seng302.server.simulator.parsers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -7,9 +9,6 @@ import org.w3c.dom.NodeList;
|
||||
import seng302.server.simulator.Boat;
|
||||
import seng302.server.simulator.mark.Corner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Parses the race xml file to get course details
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
|
||||
+14
-8
@@ -1,6 +1,5 @@
|
||||
package seng302.model.stream.parser;
|
||||
package seng302.utilities;
|
||||
|
||||
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -14,6 +13,11 @@ import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
import seng302.model.stream.parser.PositionUpdateData;
|
||||
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
||||
import seng302.model.stream.parser.RaceStartData;
|
||||
import seng302.model.stream.parser.RaceStatusData;
|
||||
|
||||
/**
|
||||
* StreamParser is a utilities class for taking byte data, formatted according to the AC35
|
||||
@@ -87,22 +91,24 @@ public class StreamParser {
|
||||
//
|
||||
int noBoats = payload[22];
|
||||
int raceType = payload[23];
|
||||
long boatID, estTimeAtNextMark, estTimeAtFinish;
|
||||
int leg, boatStatus;
|
||||
for (int i = 0; i < noBoats; i++) {
|
||||
long boatID = bytesToLong(
|
||||
boatID = bytesToLong(
|
||||
Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
|
||||
// boat.setBoatStatus((int) payload[28 + (i * 20)]);
|
||||
boatStatus = (int) payload[28 + (i * 20)];
|
||||
|
||||
// setBoatLegPosition(boat, (int) payload[29 + (i * 20)]);
|
||||
// boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
|
||||
// boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
|
||||
Long estTimeAtNextMark = bytesToLong(
|
||||
estTimeAtNextMark = bytesToLong(
|
||||
Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20)));
|
||||
// boat.setEstimateTimeTillNextMark(estTimeAtNextMark);
|
||||
Long estTimeAtFinish = bytesToLong(
|
||||
estTimeAtFinish = bytesToLong(
|
||||
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
|
||||
int leg = (int) payload[29 + (i * 20)];
|
||||
leg = (int) payload[29 + (i * 20)];
|
||||
// boat.setEstimateTimeAtFinish(estTimeAtFinish);
|
||||
data.addBoatData(boatID, estTimeAtNextMark, estTimeAtFinish, leg);
|
||||
data.addBoatData(boatID, estTimeAtNextMark, estTimeAtFinish, leg, boatStatus);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
+7
-3
@@ -1,12 +1,16 @@
|
||||
package seng302.model.stream.xml.generator;
|
||||
package seng302.utilities;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import seng302.model.stream.xml.generator.Race;
|
||||
import seng302.model.stream.xml.generator.Regatta;
|
||||
import seng302.server.messages.XMLMessageSubType;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* An XML generator to generate the Race, Boat, and Regatta XML dynamically
|
||||
*/
|
||||
+5
-2
@@ -1,4 +1,5 @@
|
||||
package seng302.model.stream.xml.parser;
|
||||
package seng302.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -7,13 +8,15 @@ import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.Corner;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.GateMark;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.mark.MarkType;
|
||||
import seng302.model.mark.SingleMark;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
|
||||
/**
|
||||
* Utilities for parsing XML documents
|
||||
@@ -1,11 +0,0 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
|
||||
/**
|
||||
* Functional interface for receiving packets from client socket.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ClientSocketListener {
|
||||
void newPacket(StreamPacket packet);
|
||||
}
|
||||
@@ -5,14 +5,16 @@ 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.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.time.LocalDateTime;
|
||||
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 seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.server.messages.BoatActionMessage;
|
||||
import seng302.server.messages.Message;
|
||||
@@ -22,6 +24,21 @@ import seng302.server.messages.Message;
|
||||
* its own thread.
|
||||
*/
|
||||
public class ClientToServerThread implements Runnable {
|
||||
|
||||
/**
|
||||
* Functional interface for receiving packets from client socket.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ClientSocketListener {
|
||||
void newPacket();
|
||||
}
|
||||
|
||||
private class ByteReadException extends Exception {
|
||||
private ByteReadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int LOG_LEVEL = 1;
|
||||
|
||||
private Queue<StreamPacket> streamPackets = new ConcurrentLinkedQueue<>();
|
||||
@@ -34,8 +51,9 @@ public class ClientToServerThread implements Runnable {
|
||||
|
||||
private int clientId;
|
||||
|
||||
private Boolean updateClient = true;
|
||||
// private Boolean updateClient = true;
|
||||
private ByteArrayOutputStream crcBuffer;
|
||||
private boolean socketOpen = true;
|
||||
|
||||
/**
|
||||
* Constructor for ClientToServerThread which takes in ipAddress and portNumber and attempts to
|
||||
@@ -53,7 +71,6 @@ public class ClientToServerThread implements Runnable {
|
||||
socket = new Socket(ipAddress, portNumber);
|
||||
is = socket.getInputStream();
|
||||
os = socket.getOutputStream();
|
||||
|
||||
Integer allocatedID = threeWayHandshake();
|
||||
if (allocatedID != null) {
|
||||
clientId = allocatedID;
|
||||
@@ -90,8 +107,19 @@ public class ClientToServerThread implements Runnable {
|
||||
int sync1;
|
||||
int sync2;
|
||||
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
|
||||
while(true) { /**REMOVED SOMETHING HERE ClientState.isConnectedToHost() */
|
||||
while(socketOpen) { /**REMOVED SOMETHING HERE ClientState.isConnectedToHost() */
|
||||
System.out.println("socket.isConnected() = " + socket.isConnected());
|
||||
try {
|
||||
//Perform a write if it is time to as delegated by the MainServerThread
|
||||
// if (updateClient) {
|
||||
// // TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream
|
||||
//// try {
|
||||
//// GameState.outputState(os);
|
||||
//// } catch (IOException e) {
|
||||
//// System.out.println("IO error in server thread upon writing to output stream");
|
||||
//// }
|
||||
// updateClient = false;
|
||||
// }
|
||||
crcBuffer = new ByteArrayOutputStream();
|
||||
sync1 = readByte();
|
||||
sync2 = readByte();
|
||||
@@ -109,29 +137,33 @@ public class ClientToServerThread implements Runnable {
|
||||
long packetCrc = Message.bytesToLong(getBytes(4));
|
||||
if (computedCrc == packetCrc) {
|
||||
// streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
for (ClientSocketListener csl : listeners)
|
||||
csl.newPacket(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
// for (ClientSocketListener csl : listeners)
|
||||
// csl.newPacket(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
if (streamPackets.size() > 0) {
|
||||
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
} else {
|
||||
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
for (ClientSocketListener csl : listeners)
|
||||
csl.newPacket();
|
||||
}
|
||||
} else {
|
||||
clientLog("Packet has been dropped", 1);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (ByteReadException e) {
|
||||
closeSocket();
|
||||
Platform.runLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setHeaderText("Host has disconnected");
|
||||
alert.setContentText("Cannot find Server");
|
||||
alert.showAndWait();
|
||||
}
|
||||
});
|
||||
clientLog("Disconnected from server", 1);
|
||||
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;
|
||||
}
|
||||
}
|
||||
// closeSocket();
|
||||
// clientLog("Disconnected from server", 0);
|
||||
closeSocket();
|
||||
clientLog("Closed connection to Server", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +179,6 @@ public class ClientToServerThread implements Runnable {
|
||||
ourSourceID = is.read();
|
||||
} catch (IOException e) {
|
||||
clientLog("Three way handshake failed", 1);
|
||||
|
||||
}
|
||||
if (ourSourceID != null) {
|
||||
try {
|
||||
@@ -174,7 +205,7 @@ public class ClientToServerThread implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
public void closeSocket() {
|
||||
private void closeSocket() {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
@@ -182,6 +213,14 @@ public class ClientToServerThread implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public void setSocketToClose () {
|
||||
socketOpen = false;
|
||||
}
|
||||
|
||||
public Queue<StreamPacket> getPacketQueue () {
|
||||
return streamPackets;
|
||||
}
|
||||
|
||||
public void addStreamObserver (ClientSocketListener streamListener) {
|
||||
listeners.add(streamListener);
|
||||
}
|
||||
@@ -190,7 +229,7 @@ public class ClientToServerThread implements Runnable {
|
||||
listeners.remove(streamListener);
|
||||
}
|
||||
|
||||
private int readByte() throws Exception {
|
||||
private int readByte() throws ByteReadException {
|
||||
int currentByte = -1;
|
||||
try {
|
||||
currentByte = is.read();
|
||||
@@ -199,12 +238,12 @@ public class ClientToServerThread implements Runnable {
|
||||
clientLog("Read byte failed", 1);
|
||||
}
|
||||
if (currentByte == -1) {
|
||||
throw new Exception();
|
||||
throw new ByteReadException("InputStream reach end of stream");
|
||||
}
|
||||
return currentByte;
|
||||
}
|
||||
|
||||
private byte[] getBytes(int n) throws Exception {
|
||||
private byte[] getBytes(int n) throws ByteReadException {
|
||||
byte[] bytes = new byte[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
bytes[i] = (byte) readByte();
|
||||
@@ -212,7 +251,7 @@ public class ClientToServerThread implements Runnable {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private void skipBytes(long n) throws Exception {
|
||||
private void skipBytes(long n) throws ByteReadException {
|
||||
for (int i = 0; i < n; i++) {
|
||||
readByte();
|
||||
}
|
||||
|
||||
@@ -3,29 +3,28 @@ package seng302.visualiser;
|
||||
import java.io.IOException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.gameServer.MainServerThread;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
import seng302.model.stream.parser.RaceStatusData;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.parser.StreamParser;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.model.stream.xml.parser.XMLParser;
|
||||
import seng302.model.stream.parser.PositionUpdateData;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.visualiser.ClientToServerThread;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
import seng302.model.stream.parser.PositionUpdateData;
|
||||
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
||||
import seng302.model.stream.parser.RaceStatusData;
|
||||
import seng302.utilities.StreamParser;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.utilities.XMLParser;
|
||||
import seng302.visualiser.controllers.LobbyController;
|
||||
import seng302.visualiser.controllers.LobbyController.CloseStatus;
|
||||
import seng302.visualiser.controllers.RaceViewController;
|
||||
@@ -61,9 +60,10 @@ public class GameClient {
|
||||
}
|
||||
LobbyController lobbyController = loadLobby("/views/LobbyView.fxml");
|
||||
lobbyController.setPlayerListSource(lobbyList);
|
||||
lobbyController.disableReadyButton();
|
||||
lobbyController.setTitle("Connected to host - IP : " + ipAddress + " Port : " + portNumber);
|
||||
lobbyController.addCloseListener((exitCause) -> this.loadStartScreen());
|
||||
socketThread.addStreamObserver(this::parsePacket);
|
||||
socketThread.addStreamObserver(this::parsePackets);
|
||||
}
|
||||
|
||||
public void runAsHost (String ipAddress, Integer portNumber) {
|
||||
@@ -74,13 +74,13 @@ public class GameClient {
|
||||
ioe.printStackTrace();
|
||||
System.out.println("Unable to make local connection to host...");
|
||||
}
|
||||
LobbyController lobbyController = loadLobby("/views/HostLobbyView.fxml");
|
||||
socketThread.addStreamObserver(this::parsePackets);
|
||||
LobbyController lobbyController = loadLobby("/views/LobbyView.fxml");
|
||||
lobbyController.setPlayerListSource(GameState.getObservablePlayers());
|
||||
lobbyController.setTitle("Hosting Lobby - IP : " + ipAddress + " Port : " + portNumber);
|
||||
lobbyController.addCloseListener(exitCause -> {
|
||||
if (exitCause == CloseStatus.READY) {
|
||||
server.startGame();
|
||||
socketThread.addStreamObserver(this::parsePacket);
|
||||
} else if (exitCause == CloseStatus.LEAVE) {
|
||||
loadStartScreen();
|
||||
}
|
||||
@@ -88,11 +88,11 @@ public class GameClient {
|
||||
}
|
||||
|
||||
private void loadStartScreen () {
|
||||
socketThread.closeSocket();
|
||||
socketThread.setSocketToClose();
|
||||
socketThread = null;
|
||||
if (server != null) {
|
||||
// TODO: 26/07/17 cir27 - handle disconnecting
|
||||
server.shutDown();
|
||||
// server.shutDown();
|
||||
server = null;
|
||||
}
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/StartScreenView.fxml"));
|
||||
@@ -125,68 +125,78 @@ public class GameClient {
|
||||
// if (courseData.getParticipants().contains(id))
|
||||
// racingBoats.put(id, boat);
|
||||
// });
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/RaceView.fxml"));
|
||||
raceView = fxmlLoader.getController();
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(RaceViewController.class.getResource("/views/RaceView.fxml"));
|
||||
// raceView = fxmlLoader.getController();
|
||||
try {
|
||||
holderPane.getChildren().add(fxmlLoader.load());
|
||||
Node node = fxmlLoader.load();
|
||||
Platform.runLater(() -> {
|
||||
holderPane.getChildren().clear();
|
||||
holderPane.getChildren().add(node);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
raceView = fxmlLoader.getController();
|
||||
raceView.loadRace(allBoatsMap, courseData, raceState);
|
||||
}
|
||||
|
||||
private void parsePacket(StreamPacket packet) {
|
||||
switch (packet.getType()) {
|
||||
case RACE_STATUS:
|
||||
processRaceStatusUpdate(StreamParser.extractRaceStatus(packet));
|
||||
break;
|
||||
private void parsePackets() {
|
||||
while (socketThread.getPacketQueue().peek() != null) {
|
||||
StreamPacket packet = socketThread.getPacketQueue().poll();
|
||||
switch (packet.getType()) {
|
||||
case RACE_STATUS:
|
||||
processRaceStatusUpdate(StreamParser.extractRaceStatus(packet));
|
||||
startRaceIfAllDataReceived();
|
||||
break;
|
||||
|
||||
case REGATTA_XML:
|
||||
System.out.println("REGATTA XML");
|
||||
regattaData = XMLParser.parseRegatta(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
raceState.setTimeZone(
|
||||
TimeZone.getTimeZone(
|
||||
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(regattaData.getUtcOffset()))
|
||||
)
|
||||
);
|
||||
startRaceIfAllDataReceived();
|
||||
break;
|
||||
case REGATTA_XML:
|
||||
System.out.println("REGATTA XML");
|
||||
regattaData = XMLParser.parseRegatta(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
raceState.setTimeZone(
|
||||
TimeZone.getTimeZone(
|
||||
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(regattaData.getUtcOffset()))
|
||||
)
|
||||
);
|
||||
// startRaceIfAllDataReceived();
|
||||
break;
|
||||
|
||||
case RACE_XML:
|
||||
System.out.println("RACE XML");
|
||||
courseData = XMLParser.parseRace(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
if (raceView != null) {
|
||||
raceView.updateRaceData(courseData);
|
||||
}
|
||||
startRaceIfAllDataReceived();
|
||||
break;
|
||||
case RACE_XML:
|
||||
System.out.println("RACE XML");
|
||||
courseData = XMLParser.parseRace(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
if (raceView != null) {
|
||||
raceView.updateRaceData(courseData);
|
||||
}
|
||||
// startRaceIfAllDataReceived();
|
||||
break;
|
||||
|
||||
case BOAT_XML:
|
||||
System.out.println("BOAT XML");
|
||||
allBoatsMap = XMLParser.parseBoats(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
lobbyList.clear();
|
||||
allBoatsMap.forEach((id, boat) -> lobbyList.add(id.toString() + boat.getBoatName()));
|
||||
allBoatsMap.forEach((i, b) -> System.out.println(b.getBoatName()));
|
||||
startRaceIfAllDataReceived();
|
||||
break;
|
||||
case BOAT_XML:
|
||||
System.out.println("BOAT XML");
|
||||
allBoatsMap = XMLParser.parseBoats(
|
||||
StreamParser.extractXmlMessage(packet)
|
||||
);
|
||||
lobbyList.clear();
|
||||
allBoatsMap
|
||||
.forEach((id, boat) -> lobbyList.add(id.toString() + boat.getBoatName()));
|
||||
allBoatsMap.forEach((i, b) -> System.out.println(b.getBoatName()));
|
||||
// startRaceIfAllDataReceived();
|
||||
break;
|
||||
|
||||
case RACE_START_STATUS:
|
||||
raceState.updateState(StreamParser.extractRaceStartStatus(packet));
|
||||
break;
|
||||
case RACE_START_STATUS:
|
||||
raceState.updateState(StreamParser.extractRaceStartStatus(packet));
|
||||
break;
|
||||
|
||||
case BOAT_LOCATION:
|
||||
updatePosition(StreamParser.extractBoatLocation(packet));
|
||||
break;
|
||||
case BOAT_LOCATION:
|
||||
updatePosition(StreamParser.extractBoatLocation(packet));
|
||||
break;
|
||||
|
||||
case MARK_ROUNDING:
|
||||
updateMarkRounding(StreamParser.extractMarkRounding(packet));
|
||||
break;
|
||||
case MARK_ROUNDING:
|
||||
updateMarkRounding(StreamParser.extractMarkRounding(packet));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +253,7 @@ public class GameClient {
|
||||
yacht.setEstimateTimeAtFinish(boatData[2]);
|
||||
int legNumber = (int) boatData[3];
|
||||
yacht.setLegNumber(legNumber);
|
||||
yacht.setBoatStatus((int) boatData[4]);
|
||||
if (legNumber != yacht.getLegNumber()) {
|
||||
int placing = 1;
|
||||
for (Yacht otherYacht : allBoatsMap.values()) {
|
||||
@@ -257,7 +268,7 @@ public class GameClient {
|
||||
}
|
||||
|
||||
private void close () {
|
||||
socketThread.closeSocket();
|
||||
socketThread.setSocketToClose();
|
||||
}
|
||||
|
||||
// /** Handle the key-pressed event from the text field. */
|
||||
|
||||
@@ -22,20 +22,18 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
import seng302.model.Limit;
|
||||
import seng302.visualiser.fxObjects.AnnotationBox;
|
||||
import seng302.visualiser.fxObjects.BoatObject;
|
||||
import seng302.visualiser.fxObjects.MarkObject;
|
||||
import seng302.model.Colors;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.map.Boundary;
|
||||
import seng302.model.map.CanvasMap;
|
||||
import seng302.model.mark.GateMark;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.mark.MarkType;
|
||||
import seng302.model.mark.SingleMark;
|
||||
import seng302.utilities.GeoPoint;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.AnnotationBox;
|
||||
import seng302.visualiser.fxObjects.BoatObject;
|
||||
import seng302.visualiser.fxObjects.MarkObject;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 20/07/17.
|
||||
@@ -45,11 +43,11 @@ public class GameView extends Pane {
|
||||
private ObservableList<Node> gameObjects;
|
||||
private ImageView mapImage;
|
||||
|
||||
private final int BUFFER_SIZE = 50;
|
||||
private final int PANEL_WIDTH = 1260; // it should be 1280 but, minors 40 to cancel the bias.
|
||||
private final int PANEL_HEIGHT = 960;
|
||||
private final int CANVAS_WIDTH = 1100;
|
||||
private final int CANVAS_HEIGHT = 920;
|
||||
private double bufferSize = 50;
|
||||
private double panelWidth = 1260; // it should be 1280 but, minors 40 to cancel the bias.
|
||||
private double panelHeight = 960;
|
||||
private double canvasWidth = 1100;
|
||||
private double canvasHeight = 920;
|
||||
private boolean horizontalInversion = false;
|
||||
|
||||
private double distanceScaleFactor;
|
||||
@@ -63,13 +61,14 @@ public class GameView extends Pane {
|
||||
private double metersPerPixelX;
|
||||
private double metersPerPixelY;
|
||||
|
||||
private Map<SingleMark, MarkObject> markObjects = new HashMap<>();
|
||||
private Map<Yacht, BoatObject> boatObjects = new HashMap<>();
|
||||
private List<AnnotationBox> annotations = new ArrayList<>();
|
||||
|
||||
private Text fpsDisplay = new Text();
|
||||
|
||||
private Polygon raceBorder = new Polygon();
|
||||
/* Note that if either of these is null then values for it have not been added and the other
|
||||
should be used as the limits of the map. */
|
||||
private Polygon raceBorder;
|
||||
private Map<SingleMark, MarkObject> markObjects = new HashMap<>();
|
||||
|
||||
//FRAME RATE
|
||||
private Double frameRate = 60.0;
|
||||
@@ -205,9 +204,13 @@ public class GameView extends Pane {
|
||||
* in a compound mark etc..
|
||||
*/
|
||||
public void updateBorder(List<Limit> border) {
|
||||
raceBorder.setStroke(new Color(0.0f, 0.0f, 0.74509807f, 1));
|
||||
raceBorder.setStrokeWidth(3);
|
||||
raceBorder.setFill(new Color(0,0,0,0));
|
||||
if (raceBorder == null) {
|
||||
raceBorder = new Polygon();
|
||||
raceBorder.setStroke(new Color(0.0f, 0.0f, 0.74509807f, 1));
|
||||
raceBorder.setStrokeWidth(3);
|
||||
raceBorder.setFill(new Color(0,0,0,0));
|
||||
findCanvasScaling();
|
||||
}
|
||||
List<Double> boundaryPoints = new ArrayList<>();
|
||||
for (Limit limit : border) {
|
||||
Point2D location = findScaledXY(limit.getLat(), limit.getLng());
|
||||
@@ -393,24 +396,24 @@ public class GameView extends Pane {
|
||||
|
||||
if (scaleDirection == ScaleDirection.HORIZONTAL) {
|
||||
referenceAngle = Math.abs(Mark.calculateHeadingRad(referencePoint, minLonPoint));
|
||||
referencePointX = BUFFER_SIZE + distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint);
|
||||
referencePointX = bufferSize + distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint);
|
||||
|
||||
referenceAngle = Math.abs(Mark.calculateHeadingRad(referencePoint, maxLatPoint));
|
||||
referencePointY = canvasHeight - (BUFFER_SIZE + BUFFER_SIZE);
|
||||
referencePointY = canvasHeight - (bufferSize + bufferSize);
|
||||
referencePointY -= distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint);
|
||||
referencePointY = referencePointY / 2;
|
||||
referencePointY += BUFFER_SIZE;
|
||||
referencePointY += bufferSize;
|
||||
referencePointY += distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint);
|
||||
} else {
|
||||
referencePointY = canvasHeight - BUFFER_SIZE;
|
||||
referencePointY = canvasHeight - bufferSize;
|
||||
|
||||
referenceAngle = Math.abs(Mark.calculateHeadingRad(referencePoint, minLonPoint));
|
||||
referencePointX = BUFFER_SIZE;
|
||||
referencePointX = bufferSize;
|
||||
referencePointX += distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint);
|
||||
referencePointX += ((canvasWidth - (BUFFER_SIZE + BUFFER_SIZE)) - (minLonToMaxLon * distanceScaleFactor)) / 2;
|
||||
referencePointX += ((canvasWidth - (bufferSize + bufferSize)) - (minLonToMaxLon * distanceScaleFactor)) / 2;
|
||||
}
|
||||
if(horizontalInversion) {
|
||||
referencePointX = canvasWidth - BUFFER_SIZE - (referencePointX - BUFFER_SIZE);
|
||||
referencePointX = canvasWidth - bufferSize - (referencePointX - bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,10 +437,10 @@ public class GameView extends Pane {
|
||||
double horiDistance =
|
||||
Math.cos(horiAngle) * Mark.calculateDistance(minLonPoint, maxLonPoint);
|
||||
|
||||
double vertScale = (canvasHeight - (BUFFER_SIZE + BUFFER_SIZE)) / vertDistance;
|
||||
double vertScale = (canvasHeight - (bufferSize + bufferSize)) / vertDistance;
|
||||
|
||||
if ((horiDistance * vertScale) > (canvasWidth - (BUFFER_SIZE + BUFFER_SIZE))) {
|
||||
distanceScaleFactor = (canvasWidth - (BUFFER_SIZE + BUFFER_SIZE)) / horiDistance;
|
||||
if ((horiDistance * vertScale) > (canvasWidth - (bufferSize + bufferSize))) {
|
||||
distanceScaleFactor = (canvasWidth - (bufferSize + bufferSize)) / horiDistance;
|
||||
scaleDirection = ScaleDirection.HORIZONTAL;
|
||||
} else {
|
||||
distanceScaleFactor = vertScale;
|
||||
@@ -479,7 +482,7 @@ public class GameView extends Pane {
|
||||
yAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||
}
|
||||
if(horizontalInversion) {
|
||||
xAxisLocation = canvasWidth - BUFFER_SIZE - (xAxisLocation - BUFFER_SIZE);
|
||||
xAxisLocation = canvasWidth - bufferSize - (xAxisLocation - bufferSize);
|
||||
}
|
||||
return new Point2D(xAxisLocation, yAxisLocation);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.stream.parser.StreamParser;
|
||||
|
||||
public class FinishScreenViewController implements Initializable {
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ package seng302.visualiser.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
@@ -11,7 +12,6 @@ import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
@@ -36,9 +36,6 @@ public class LobbyController implements Initializable {
|
||||
void notify(CloseStatus exitCause);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private ListView<String> competitorsListView;
|
||||
|
||||
@FXML
|
||||
private GridPane lobbyScreen;
|
||||
@FXML
|
||||
@@ -259,10 +256,13 @@ public class LobbyController implements Initializable {
|
||||
@FXML
|
||||
public void leaveLobbyButtonPressed() {
|
||||
// TODO: 10/07/17 wmu16 - Finish function!
|
||||
setContentPane("/views/StartScreenView.fxml");
|
||||
// setContentPane("/views/StartScreenView.fxml");
|
||||
GameState.setCurrentStage(GameStages.CANCELLED);
|
||||
// TODO: 20/07/17 wmu16 - Implement some way of terminating the game
|
||||
// ClientState.setConnectedToHost(false);
|
||||
for (LobbyCloseListener readyListener : lobbyListeners)
|
||||
readyListener.notify(CloseStatus.LEAVE);
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -309,11 +309,15 @@ public class LobbyController implements Initializable {
|
||||
}
|
||||
|
||||
public void setPlayerListSource (ObservableList<String> players) {
|
||||
if (competitorsListView != null)
|
||||
competitorsListView.setItems(players);
|
||||
if (firstListView != null) {
|
||||
// if (competitorsListView != null)
|
||||
// competitorsListView.setItems(players);
|
||||
// if (firstListView != null) {
|
||||
firstListView.setItems(players);
|
||||
firstImageView.setVisible(false);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public void disableReadyButton () {
|
||||
readyButton.setDisable(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package seng302.visualiser.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
@@ -9,7 +15,6 @@ import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Scene;
|
||||
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
@@ -30,7 +35,9 @@ import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import seng302.model.Corner;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.visualiser.GameView;
|
||||
import seng302.visualiser.controllers.annotations.Annotation;
|
||||
@@ -38,11 +45,6 @@ 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.model.*;
|
||||
import seng302.model.mark.Mark;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Controller class that manages the display of a race
|
||||
@@ -92,6 +94,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
raceSparkLine.getYAxis().setAutoRanging(false);
|
||||
sparklineYAxis.setTickMarkVisible(false);
|
||||
|
||||
positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
|
||||
selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView());
|
||||
}
|
||||
|
||||
@@ -189,11 +193,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
annotationSlider.setValue(2);
|
||||
annotationSlider.valueProperty().addListener((obs, oldVal, newVal) ->
|
||||
setAnnotations((int) annotationSlider.getValue())
|
||||
);
|
||||
annotationSlider.setValue(2);
|
||||
}
|
||||
|
||||
|
||||
@@ -368,14 +371,15 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
*/
|
||||
private void updateOrder() {
|
||||
positionVbox.getChildren().clear();
|
||||
positionVbox.getChildren().removeAll();
|
||||
positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
// positionVbox.getChildren().removeAll();
|
||||
// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||
|
||||
// list of racing yacht id
|
||||
List<Yacht> sorted = new ArrayList<>(participants.values());
|
||||
sorted.sort(Comparator.comparingInt(Yacht::getPositionInteger));
|
||||
|
||||
for (Yacht yacht : sorted) {
|
||||
// System.out.println("yacht == null " + String.valueOf(yacht == null));
|
||||
if (yacht.getBoatStatus() == 3) { // 3 is finish status
|
||||
Text textToAdd = new Text(yacht.getPositionInteger() + ". " +
|
||||
yacht.getShortName() + " (Finished)");
|
||||
@@ -389,6 +393,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
textToAdd.setStyle("");
|
||||
positionVbox.getChildren().add(textToAdd);
|
||||
}
|
||||
// System.out.println("finished a loop :))))))))))))");
|
||||
}
|
||||
// participants.forEach((id, yacht) ->{
|
||||
// Text textToAdd = new Text(yacht.getPosition() + ". " +
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
package seng302.visualiser.controllers;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.client.ClientState;
|
||||
import seng302.visualiser.ClientToServerThread;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.gameServer.MainServerThread;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import seng302.visualiser.GameClient;
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -1,5 +1,7 @@
|
||||
package seng302.visualiser.controllers.annotations;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
@@ -7,8 +9,7 @@ import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.net.URL;;
|
||||
import java.util.ResourceBundle;
|
||||
;
|
||||
|
||||
public class ImportantAnnotationController implements Initializable {
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package seng302.visualiser.fxObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.CacheHint;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import seng302.model.Yacht;
|
||||
|
||||
/**
|
||||
* BoatGroup is a javafx group that by default contains a graphical objects for representing a 2
|
||||
@@ -64,52 +62,49 @@ public class BoatObject extends Group {
|
||||
* polygon.
|
||||
*/
|
||||
public BoatObject(double... points) {
|
||||
public BoatGroup(Yacht boat, Color color, double... points) {
|
||||
this.colour = colour;
|
||||
destinationSet = false;
|
||||
this.boat = boat;
|
||||
initChildren(color, points);
|
||||
initChildren(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the javafx objects that will be the in the group by default.
|
||||
*
|
||||
* @param color The colour of the boat polygon and the trailing line.
|
||||
* @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat
|
||||
* polygon.
|
||||
*/
|
||||
private void initChildren(Color color, double... points) {
|
||||
this.color = color;
|
||||
private void initChildren(double... points) {
|
||||
// this.colour = color;
|
||||
boatPoly = new Polygon(points);
|
||||
boatPoly.setFill(colour);
|
||||
boatPoly.setFill(this.color);
|
||||
boatPoly.setFill(this.colour);
|
||||
boatPoly.setOnMouseEntered(event -> {
|
||||
boatPoly.setFill(Color.FLORALWHITE);
|
||||
boatPoly.setStroke(Color.RED);
|
||||
});
|
||||
boatPoly.setOnMouseExited(event -> {
|
||||
boatPoly.setFill(colour);
|
||||
boatPoly.setFill(this.color);
|
||||
boatPoly.setFill(this.colour);
|
||||
boatPoly.setStroke(Color.BLACK);
|
||||
});
|
||||
boatPoly.setOnMouseClicked(event -> setIsSelected(!isSelected));
|
||||
boatPoly.setCache(true);
|
||||
boatPoly.setCacheHint(CacheHint.SPEED);
|
||||
|
||||
annotationBox = new AnnotationBox();
|
||||
annotationBox.setFill(colour);
|
||||
boatAnnotations = new BoatAnnotations(boat, this.color);
|
||||
// annotationBox = new AnnotationBox();
|
||||
// annotationBox.setFill(colour);
|
||||
|
||||
leftLayLine = new Line();
|
||||
rightLayline = new Line();
|
||||
|
||||
wake = new Wake(0, -BOAT_HEIGHT);
|
||||
super.getChildren().addAll(boatPoly, annotationBox);
|
||||
super.getChildren().addAll(boatPoly);//, annotationBox);
|
||||
}
|
||||
|
||||
public void setFill (Paint value) {
|
||||
this.colour = value;
|
||||
boatPoly.setFill(colour);
|
||||
annotationBox.setFill(colour);
|
||||
// annotationBox.setFill(colour);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,14 +202,14 @@ public class BoatObject extends Group {
|
||||
wake.setRotation(rotation, groundSpeed);
|
||||
// yacht.setVelocity(groundSpeed);
|
||||
lastTimeValid = timeValid;
|
||||
boat.setVelocity(groundSpeed);
|
||||
// boat.setVelocity(groundSpeed);
|
||||
isStopped = false;
|
||||
lastRotation = rotation;
|
||||
boatAnnotations.update();
|
||||
// boatAnnotations.update();
|
||||
|
||||
distanceTravelled += Math.sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
if (distanceTravelled > 10 && isPlayer) {
|
||||
if (distanceTravelled > 10){// && isPlayer) {
|
||||
distanceTravelled = 0d;
|
||||
|
||||
if (lastPoint != null) {
|
||||
@@ -225,7 +220,7 @@ public class BoatObject extends Group {
|
||||
boatPoly.getLayoutY()
|
||||
);
|
||||
l.getStrokeDashArray().setAll(3d, 7d);
|
||||
l.setStroke(boat.getColour());
|
||||
l.setStroke(this.colour);
|
||||
l.setCache(true);
|
||||
l.setCacheHint(CacheHint.SPEED);
|
||||
lineGroup.getChildren().add(l);
|
||||
@@ -280,8 +275,7 @@ public class BoatObject extends Group {
|
||||
|
||||
public void setVisibility (boolean teamName, boolean velocity, boolean estTime, boolean legTime,
|
||||
boolean trail, boolean wake) {
|
||||
public void setVisibility (boolean teamName, boolean velocity, boolean estTime, boolean legTime, boolean trail, boolean wake) {
|
||||
boatAnnotations.setVisible(teamName, velocity, estTime, legTime);
|
||||
// boatAnnotations.setVisible(teamName, velocity, estTime, legTime);
|
||||
this.wake.setVisible(wake);
|
||||
this.lineGroup.setVisible(trail);
|
||||
}
|
||||
@@ -336,23 +330,18 @@ public class BoatObject extends Group {
|
||||
return isStopped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return boat.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this boat to appear highlighted
|
||||
*/
|
||||
public void setAsPlayer() {
|
||||
boatPoly.getPoints().setAll(
|
||||
-BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
|
||||
0.0, -BOAT_HEIGHT / 1.75,
|
||||
BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
|
||||
);
|
||||
boatPoly.setStroke(Color.BLACK);
|
||||
boatPoly.setStrokeWidth(3);
|
||||
boatAnnotations.setAsPlayer();
|
||||
isPlayer = true;
|
||||
// boatPoly.getPoints().setAll(
|
||||
// -BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
|
||||
// 0.0, -BOAT_HEIGHT / 1.75,
|
||||
// BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
|
||||
// );
|
||||
// boatPoly.setStroke(Color.BLACK);
|
||||
// boatPoly.setStrokeWidth(3);
|
||||
// boatAnnotations.setAsPlayer();
|
||||
// isPlayer = true;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package seng302.model.map;
|
||||
package seng302.visualiser.map;
|
||||
|
||||
/**
|
||||
* The Boundary class represents a rectangle territorial boundary on a map. It
|
||||
@@ -7,11 +7,11 @@ package seng302.model.map;
|
||||
*
|
||||
* Created by Haoming on 10/5/17
|
||||
*/
|
||||
public class Boundary {
|
||||
class Boundary {
|
||||
|
||||
private double northLat, eastLng, southLat, westLng;
|
||||
|
||||
public Boundary(double northLat, double eastLng, double southLat, double westLng) {
|
||||
Boundary(double northLat, double eastLng, double southLat, double westLng) {
|
||||
this.northLat = northLat;
|
||||
this.eastLng = eastLng;
|
||||
this.southLat = southLat;
|
||||
+5
-8
@@ -1,13 +1,10 @@
|
||||
package seng302.model.map;
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.image.Image;
|
||||
import seng302.utilities.GeoPoint;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import java.lang.Math;
|
||||
import seng302.utilities.GeoPoint;
|
||||
|
||||
/**
|
||||
* CanvasMap retrieves a map image with given geo boundary from Google Map server.
|
||||
@@ -25,12 +22,12 @@ public class CanvasMap {
|
||||
|
||||
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
||||
|
||||
public CanvasMap(Boundary boundary) {
|
||||
CanvasMap(Boundary boundary) {
|
||||
this.boundary = boundary;
|
||||
calculateOptimalMapSize();
|
||||
}
|
||||
|
||||
public Image getMapImage() {
|
||||
Image getMapImage() {
|
||||
try {
|
||||
URL url = new URL(getRequest());
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package seng302.model.map;
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
import seng302.utilities.GeoPoint;
|
||||
@@ -28,7 +28,7 @@ public class MercatorProjection {
|
||||
* @param geo GeoPoint (lat, lng) location to be projected
|
||||
* @return the projection Point2D (x, y) on planar
|
||||
*/
|
||||
public static Point2D toMapPoint(GeoPoint geo) {
|
||||
static Point2D toMapPoint(GeoPoint geo) {
|
||||
double x, y;
|
||||
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
|
||||
x = (origin.getX() + geo.getLng() * pixelsPerLngDegree);
|
||||
+3
-4
@@ -1,13 +1,12 @@
|
||||
package seng302.model.map;
|
||||
package seng302.visualiser.map;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class TestMapController implements Initializable{
|
||||
|
||||
@FXML
|
||||
@@ -1,11 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<GridPane fx:id="finishScreenGridPane" maxHeight="837.0" maxWidth="837.0" minHeight="837.0" minWidth="837.0" nodeOrientation="LEFT_TO_RIGHT" prefHeight="837.0" prefWidth="837.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.FinishScreenViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<GridPane fx:id="lobbyScreen" nodeOrientation="LEFT_TO_RIGHT" prefHeight="533.0" prefWidth="802.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<GridPane fx:id="lobbyScreen" nodeOrientation="LEFT_TO_RIGHT" prefHeight="960.0" prefWidth="1530.0" style="-fx-background-color: #2C2c36;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.chart.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<?import javafx.scene.chart.CategoryAxis?>
|
||||
<?import javafx.scene.chart.LineChart?>
|
||||
<?import javafx.scene.chart.NumberAxis?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<GridPane prefHeight="960.0" prefWidth="1530.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints maxWidth="246.0" minWidth="246.0" prefWidth="246.0" />
|
||||
@@ -55,7 +65,7 @@
|
||||
<Label layoutX="10.0" layoutY="499.0" text="Annotations" textFill="WHITE" />
|
||||
<Button fx:id="selectAnnotationBtn" focusTraversable="false" layoutX="35.0" layoutY="578.0" mnemonicParsing="false" prefHeight="18.0" prefWidth="170.0" styleClass="blue-ui-btn" text="Select Annotations" textFill="WHITE" />
|
||||
<Text fill="WHITE" layoutX="11.0" layoutY="649.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Boat Selection" />
|
||||
<ComboBox fx:id="boatSelectionComboBox" focusTraversable="false" layoutX="37.0" layoutY="664.0" prefHeight="25.0" prefWidth="170.0" promptText="Select Boat" styleClass="combo-box-base" />
|
||||
<ComboBox fx:id="yachtSelectionComboBox" focusTraversable="false" layoutX="37.0" layoutY="664.0" prefHeight="25.0" prefWidth="170.0" promptText="Select Yacht" styleClass="combo-box-base" />
|
||||
<LineChart fx:id="raceSparkLine" layoutX="-1.0" layoutY="719.0" legendVisible="false" prefHeight="277.0" prefWidth="246.0" title="Boat Positions">
|
||||
<xAxis>
|
||||
<CategoryAxis label="Leg Number" side="BOTTOM" styleClass="spark-line-xaxis" />
|
||||
@@ -66,7 +76,7 @@
|
||||
</LineChart>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane fx:id="contentAnchorPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" style="-fx-background-color: skyblue;" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2147483647" GridPane.valignment="TOP">
|
||||
<AnchorPane fx:id="contentAnchorPane" style="-fx-background-color: skyblue;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2147483647" GridPane.valignment="TOP">
|
||||
|
||||
</AnchorPane>
|
||||
</children>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<AnchorPane fx:id="holder" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="960.0" prefWidth="1530.0" style="-fx-background-color: #2C2c36;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.StartScreenController">
|
||||
<children>
|
||||
<GridPane fx:id="startScreen2" layoutX="365.0" layoutY="285.0" nodeOrientation="LEFT_TO_RIGHT" prefWidth="800.0" style="-fx-background-color: #2C2c36;">
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.canvas.*?>
|
||||
|
||||
|
||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="960.0" prefWidth="1280.0" style="-fx-background-color: #ddd;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.model.map.TestMapController">
|
||||
<?import javafx.scene.canvas.Canvas?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="960.0" prefWidth="1280.0" style="-fx-background-color: #ddd;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.map.TestMapController">
|
||||
<children>
|
||||
<Canvas fx:id="mapCanvas" height="960.0" width="1280.0" />
|
||||
</children>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<AnchorPane fx:id="annotationSelectWindow" maxHeight="270.0" maxWidth="469.0" minHeight="270.0" minWidth="469.0" prefHeight="270.0" prefWidth="469.0" styleClass="background-blue" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Text fill="WHITE" layoutX="26.0" layoutY="52.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Select important annotations">
|
||||
|
||||
Reference in New Issue
Block a user