mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Lobby view will switch to race view when received race status packet with race start type.
Ready button can only be pressed by host. Once pressed, it will send out race status packet with race start to all clients. #story[1055]
This commit is contained in:
@@ -215,6 +215,11 @@ public class ClientPacketParser {
|
|||||||
clientBoat.setEstimateTimeAtNextMark(estTimeAtNextMark);
|
clientBoat.setEstimateTimeAtNextMark(estTimeAtNextMark);
|
||||||
clientBoat.setEstimateTimeAtFinish(estTimeAtFinish);
|
clientBoat.setEstimateTimeAtFinish(estTimeAtFinish);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3 is race started
|
||||||
|
if (raceStatus == 3) {
|
||||||
|
ClientState.setRaceStarted(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
|
private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ public class ClientStateQueryingRunnable extends Observable implements Runnable
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(!terminate) {
|
while(!terminate) {
|
||||||
// if (ClientState.isRaceStarted() && ClientState.isConnectedToHost()) {
|
|
||||||
// setChanged();
|
|
||||||
// notifyObservers();
|
|
||||||
// }
|
|
||||||
// Sleeping the thread so it will respond to the if statement below
|
// Sleeping the thread so it will respond to the if statement below
|
||||||
// if you know a better fix, pls tell me :) -ryan
|
// if you know a better fix, pls tell me :) -ryan
|
||||||
try {
|
try {
|
||||||
@@ -26,9 +22,16 @@ public class ClientStateQueryingRunnable extends Observable implements Runnable
|
|||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ClientState.isRaceStarted() && ClientState.isConnectedToHost()) {
|
||||||
|
setChanged();
|
||||||
|
notifyObservers("game started");
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
if (ClientState.isDirtyState()) {
|
if (ClientState.isDirtyState()) {
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers();
|
notifyObservers("update players");
|
||||||
ClientState.setDirtyState(false);
|
ClientState.setDirtyState(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,11 +95,9 @@ public class ClientToServerThread implements Runnable {
|
|||||||
// TODO: 17/07/17 wmu16 - Fix this or maybe we dont need to go through the main server at all!?!?
|
// TODO: 17/07/17 wmu16 - Fix this or maybe we dont need to go through the main server at all!?!?
|
||||||
// packetBufferDelegate.addToBuffer(new StreamPacket(type, payloadLength, timeStamp, payload));
|
// packetBufferDelegate.addToBuffer(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Packet has been dropped");
|
clientLog("Packet has been dropped", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
closeSocket();
|
closeSocket();
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import javafx.collections.ObservableList;
|
|||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
@@ -29,19 +30,20 @@ import seng302.client.ClientState;
|
|||||||
import seng302.client.ClientStateQueryingRunnable;
|
import seng302.client.ClientStateQueryingRunnable;
|
||||||
import seng302.gameServer.GameStages;
|
import seng302.gameServer.GameStages;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
|
import seng302.gameServer.MainServerThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing the actions of the lobby screen
|
* A class describing the actions of the lobby screen
|
||||||
* Created by wmu16 on 10/07/17.
|
* Created by wmu16 on 10/07/17.
|
||||||
*/
|
*/
|
||||||
public class LobbyController implements Initializable, Observer{
|
public class LobbyController implements Initializable, Observer{
|
||||||
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private GridPane lobbyScreen;
|
private GridPane lobbyScreen;
|
||||||
@FXML
|
@FXML
|
||||||
private Text lobbyIpText;
|
private Text lobbyIpText;
|
||||||
@FXML
|
@FXML
|
||||||
|
private Button readyButton;
|
||||||
|
@FXML
|
||||||
private ListView firstListView;
|
private ListView firstListView;
|
||||||
@FXML
|
@FXML
|
||||||
private ListView secondListView;
|
private ListView secondListView;
|
||||||
@@ -85,6 +87,9 @@ public class LobbyController implements Initializable, Observer{
|
|||||||
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
private static ObservableList<String> eighthCompetitor = FXCollections.observableArrayList();
|
||||||
private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
private ClientStateQueryingRunnable clientStateQueryingRunnable;
|
||||||
|
|
||||||
|
private Boolean switchedPane = false;
|
||||||
|
private MainServerThread mainServerThread;
|
||||||
|
|
||||||
private void setContentPane(String jfxUrl) {
|
private void setContentPane(String jfxUrl) {
|
||||||
try {
|
try {
|
||||||
AnchorPane contentPane = (AnchorPane) lobbyScreen.getParent();
|
AnchorPane contentPane = (AnchorPane) lobbyScreen.getParent();
|
||||||
@@ -102,10 +107,14 @@ public class LobbyController implements Initializable, Observer{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
if (ClientState.isHost())
|
if (ClientState.isHost()) {
|
||||||
lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
|
lobbyIpText.setText("Lobby Host IP: " + ClientState.getHostIp());
|
||||||
else
|
readyButton.setDisable(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
lobbyIpText.setText("Connected to IP: ");
|
lobbyIpText.setText("Connected to IP: ");
|
||||||
|
readyButton.setDisable(true);
|
||||||
|
}
|
||||||
initialiseListView();
|
initialiseListView();
|
||||||
// initialiseLobbyControllerThread();
|
// initialiseLobbyControllerThread();
|
||||||
// initialiseImageView(); // parrot gif init
|
// initialiseImageView(); // parrot gif init
|
||||||
@@ -124,9 +133,12 @@ public class LobbyController implements Initializable, Observer{
|
|||||||
Platform.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// switchToRaceView();
|
if (arg.equals("game started") && !switchedPane) {
|
||||||
|
switchToRaceView();
|
||||||
|
}
|
||||||
|
if (arg.equals(("update players"))) {
|
||||||
initialiseListView();
|
initialiseListView();
|
||||||
// clientStateQueryingRunnable.terminate();
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -163,8 +175,6 @@ public class LobbyController implements Initializable, Observer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
firstListView.setItems(firstCompetitor);
|
firstListView.setItems(firstCompetitor);
|
||||||
secondListView.setItems(secondCompetitor);
|
secondListView.setItems(secondCompetitor);
|
||||||
thirdListView.setItems(thirdCompetitor);
|
thirdListView.setItems(thirdCompetitor);
|
||||||
@@ -220,11 +230,19 @@ public class LobbyController implements Initializable, Observer{
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void readyButtonPressed() {
|
public void readyButtonPressed() {
|
||||||
setContentPane("/views/RaceView.fxml");
|
// setContentPane("/views/RaceView.fxml");
|
||||||
GameState.setCurrentStage(GameStages.RACING);
|
GameState.setCurrentStage(GameStages.RACING);
|
||||||
|
mainServerThread.startGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void switchToRaceView() {
|
private void switchToRaceView() {
|
||||||
|
if (!switchedPane) {
|
||||||
|
switchedPane = true;
|
||||||
setContentPane("/views/RaceView.fxml");
|
setContentPane("/views/RaceView.fxml");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainServerThread(MainServerThread mainServerThread) {
|
||||||
|
this.mainServerThread = mainServerThread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,14 +72,15 @@ public class StartScreenController {
|
|||||||
String ipAddress = InetAddress.getLocalHost().getHostAddress();
|
String ipAddress = InetAddress.getLocalHost().getHostAddress();
|
||||||
// get the lobby controller so that we can pass the game server thread to it
|
// get the lobby controller so that we can pass the game server thread to it
|
||||||
new GameState(getLocalHostIp());
|
new GameState(getLocalHostIp());
|
||||||
new MainServerThread();
|
MainServerThread mainServerThread = new MainServerThread();
|
||||||
ClientState.setHost(true);
|
ClientState.setHost(true);
|
||||||
// host will connect and handshake to itself after setting up the server
|
// host will connect and handshake to itself after setting up the server
|
||||||
// TODO: 24/07/17 wmu16 - Make port number some static global type constant?
|
// TODO: 24/07/17 wmu16 - Make port number some static global type constant?
|
||||||
ClientToServerThread clientToServerThread = new ClientToServerThread(ClientState.getHostIp(), 4942);
|
ClientToServerThread clientToServerThread = new ClientToServerThread(ClientState.getHostIp(), 4942);
|
||||||
ClientState.setConnectedToHost(true);
|
ClientState.setConnectedToHost(true);
|
||||||
controller.setClientToServerThread(clientToServerThread);
|
controller.setClientToServerThread(clientToServerThread);
|
||||||
setContentPane("/views/LobbyView.fxml");
|
LobbyController lobbyController = (LobbyController) setContentPane("/views/LobbyView.fxml");
|
||||||
|
lobbyController.setMainServerThread(mainServerThread);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Alert alert = new Alert(AlertType.ERROR);
|
Alert alert = new Alert(AlertType.ERROR);
|
||||||
alert.setHeaderText("Cannot host");
|
alert.setHeaderText("Cannot host");
|
||||||
|
|||||||
@@ -1,372 +0,0 @@
|
|||||||
package seng302.gameServer;
|
|
||||||
|
|
||||||
import seng302.models.Player;
|
|
||||||
import seng302.models.Yacht;
|
|
||||||
import seng302.server.messages.*;
|
|
||||||
import seng302.server.simulator.Boat;
|
|
||||||
import seng302.server.simulator.Simulator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.SocketOption;
|
|
||||||
import java.net.SocketOptions;
|
|
||||||
import java.nio.channels.ServerSocketChannel;
|
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class GameServerThread implements Runnable, Observer, ClientConnectionDelegate{
|
|
||||||
|
|
||||||
private static final Integer MAX_NUM_PLAYERS = 10;
|
|
||||||
public static final int PORT_NUMBER = 4942;
|
|
||||||
|
|
||||||
private Boolean hosting = true;
|
|
||||||
|
|
||||||
private ServerSocketChannel server;
|
|
||||||
private long startTime;
|
|
||||||
private short seqNum;
|
|
||||||
|
|
||||||
private final int RACE_STATUS_PERIOD = 1000/2;
|
|
||||||
private final int RACE_START_STATUS_PERIOD = 1000;
|
|
||||||
private final int BOAT_LOCATION_PERIOD = 1000/5;
|
|
||||||
private final int TIME_TILL_RACE_START = 20*1000;
|
|
||||||
private static final int LOG_LEVEL = 1;
|
|
||||||
|
|
||||||
public GameServerThread(String threadName){
|
|
||||||
Thread runner = new Thread(this, threadName);
|
|
||||||
runner.setDaemon(true);
|
|
||||||
seqNum = 0;
|
|
||||||
|
|
||||||
runner.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverLog(String message, int logLevel){
|
|
||||||
if(logLevel <= LOG_LEVEL){
|
|
||||||
System.out.println("[SERVER] " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns an XML Message from the file specified
|
|
||||||
* @param fileName The source XML file
|
|
||||||
* @param type The XML Message type
|
|
||||||
* @return The XML Message
|
|
||||||
*/
|
|
||||||
private Message getXmlMessage(String fileName, XMLMessageSubType type){
|
|
||||||
String fileContents = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
InputStream thisStream = this.getClass().getResourceAsStream(fileName);
|
|
||||||
fileContents = new String(org.apache.commons.io.IOUtils.toByteArray(thisStream));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NullPointerException e){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContents != null){
|
|
||||||
return new XMLMessage(fileContents, type, seqNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Get a race status message for the current race
|
|
||||||
*/
|
|
||||||
private Message getRaceStatusMessage(){
|
|
||||||
|
|
||||||
List<BoatSubMessage> boatSubMessages = new ArrayList<>();
|
|
||||||
BoatStatus boatStatus;
|
|
||||||
RaceStatus raceStatus;
|
|
||||||
boolean thereAreBoatsNotFinished = false;
|
|
||||||
|
|
||||||
for (Player player : GameState.getPlayers()){
|
|
||||||
Yacht y = player.getYacht();
|
|
||||||
|
|
||||||
if (GameState.getCurrentStage() == GameStages.PRE_RACE){
|
|
||||||
boatStatus = BoatStatus.PRESTART;
|
|
||||||
thereAreBoatsNotFinished = true;
|
|
||||||
}
|
|
||||||
else if(false){ //@TODO if boat has finished
|
|
||||||
boatStatus = BoatStatus.FINISHED;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
boatStatus = BoatStatus.PRESTART;
|
|
||||||
thereAreBoatsNotFinished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), boatStatus, y.getLastMarkRounded().getId(), 0, 0, 1234l, 1234l);
|
|
||||||
boatSubMessages.add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thereAreBoatsNotFinished){
|
|
||||||
if (GameState.getCurrentStage() == GameStages.RACING){
|
|
||||||
raceStatus = RaceStatus.STARTED;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
long timeDifference = startTime - currentTime;
|
|
||||||
|
|
||||||
if (timeDifference > 60*3){
|
|
||||||
raceStatus = RaceStatus.PRESTART;
|
|
||||||
}
|
|
||||||
else if (timeDifference > 60){
|
|
||||||
raceStatus = RaceStatus.WARNING;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
raceStatus = RaceStatus.PREPARATORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
raceStatus = RaceStatus.TERMINATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RaceStatusMessage(1, raceStatus, startTime, WindDirection.SOUTH,
|
|
||||||
100, GameState.getPlayers().size(), RaceType.MATCH_RACE, 1, boatSubMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sending race start status messages until race starts
|
|
||||||
*/
|
|
||||||
private void startSendingRaceStartStatusMessages(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Message raceStartStatusMessage = new RaceStartStatusMessage(seqNum, startTime , 1,
|
|
||||||
RaceStartNotificationType.SET_RACE_START_TIME);
|
|
||||||
try {
|
|
||||||
if (startTime < System.currentTimeMillis() && GameState.getCurrentStage() != GameStages.RACING){
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
broadcast(raceStartStatusMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, RACE_START_STATUS_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sending race start status messages until race starts
|
|
||||||
*/
|
|
||||||
private void startSendingRaceStatusMessages(){
|
|
||||||
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Message raceStatusMessage = getRaceStatusMessage();
|
|
||||||
try {
|
|
||||||
broadcast(raceStatusMessage);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, RACE_STATUS_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the race, boat, and regatta XML files to the client
|
|
||||||
*/
|
|
||||||
private void sendXml(){
|
|
||||||
try{
|
|
||||||
Message raceData = getXmlMessage("/server_config/race.xml", XMLMessageSubType.RACE);
|
|
||||||
Message boatData = getXmlMessage("/server_config/boats.xml", XMLMessageSubType.BOAT);
|
|
||||||
Message regatta = getXmlMessage("/server_config/regatta.xml", XMLMessageSubType.REGATTA);
|
|
||||||
|
|
||||||
if (raceData != null){
|
|
||||||
broadcast(raceData);
|
|
||||||
}
|
|
||||||
if (boatData != null){
|
|
||||||
broadcast(boatData);
|
|
||||||
}
|
|
||||||
if (regatta != null){
|
|
||||||
broadcast(regatta);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
serverLog("Couldn't send an XML Message: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the post-start race course information
|
|
||||||
*/
|
|
||||||
private void sendPostStartCourseXml(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Message raceData = getXmlMessage("/server_config/courseLimits.xml", XMLMessageSubType.RACE);
|
|
||||||
if (raceData != null) {
|
|
||||||
broadcast(raceData);
|
|
||||||
}
|
|
||||||
}catch (IOException e) {
|
|
||||||
serverLog("Couldn't send an XML Message: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},1000);
|
|
||||||
//Delays the new course xml data for 25 seconds so the boats are able to pass the starting line
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
ServerListenThread serverListenThread;
|
|
||||||
HeartbeatThread heartbeatThread;
|
|
||||||
Boolean serverIsSendingMessages = false;
|
|
||||||
|
|
||||||
try{
|
|
||||||
server = ServerSocketChannel.open();
|
|
||||||
server.socket().bind(new InetSocketAddress("localhost", PORT_NUMBER));
|
|
||||||
|
|
||||||
// serverListenThread = new ServerListenThread(server, this);
|
|
||||||
heartbeatThread = new HeartbeatThread(this);
|
|
||||||
|
|
||||||
heartbeatThread.start();
|
|
||||||
// serverListenThread.start();
|
|
||||||
}
|
|
||||||
catch (IOException e){
|
|
||||||
serverLog("Failed to bind socket: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (hosting) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GameState.getCurrentStage() == GameStages.RACING && !serverIsSendingMessages) {
|
|
||||||
serverLog("Race Started", 0);
|
|
||||||
|
|
||||||
sendXml();
|
|
||||||
startSendingRaceStartStatusMessages();
|
|
||||||
//startSendingRaceStatusMessages();
|
|
||||||
sendPostStartCourseXml();
|
|
||||||
serverIsSendingMessages = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (GameState.getCurrentStage() == GameStages.FINISHED) {
|
|
||||||
serverLog("Race Finished", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
startTime = System.currentTimeMillis() + TIME_TILL_RACE_START;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Start sending static boat position updates when race has finished
|
|
||||||
// */
|
|
||||||
// private void startSendingRaceFinishedBoatPositions(){
|
|
||||||
// Timer t = new Timer();
|
|
||||||
// t.schedule(new TimerTask() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
// try {
|
|
||||||
// for (Boat b : raceSimulator.getBoats()){
|
|
||||||
// Message m = new BoatLocationMessage(b.getSourceID(), seqNum, b.getLat(),
|
|
||||||
// b.getLng(), b.getLastPassedCorner().getBearingToNextCorner(),
|
|
||||||
// ((long) 0));
|
|
||||||
//
|
|
||||||
// server.send(m);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }, 0, BOAT_LOCATION_PERIOD);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A client has tried to connect to the server
|
|
||||||
* @param player The player that connected
|
|
||||||
*/
|
|
||||||
public void clientConnected(Player player) {
|
|
||||||
if (GameState.getPlayers().size() < MAX_NUM_PLAYERS && GameState.getCurrentStage() == GameStages.LOBBYING) {
|
|
||||||
serverLog("Player Connected", 0);
|
|
||||||
GameState.addPlayer(player);
|
|
||||||
sendXml();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clientConnected(ServerToClientThread serverToClientThread) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A player has left the game, remove the player from the GameState
|
|
||||||
* @param player The player that left
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void clientDisconnected(Player player) {
|
|
||||||
serverLog("Player disconnected", 0);
|
|
||||||
GameState.removePlayer(player);
|
|
||||||
sendXml();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void broadcast(Message message) throws IOException{
|
|
||||||
for(Player player : GameState.getPlayers()) {
|
|
||||||
//heh
|
|
||||||
player.getSocket().getOutputStream().write(message.getBuffer());
|
|
||||||
}
|
|
||||||
seqNum++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a boat location message when they are updated by the simulator
|
|
||||||
* @param o .
|
|
||||||
* @param arg .
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void update(Observable o, Object arg) {
|
|
||||||
/* Only send if server started
|
|
||||||
// TODO: I don't understand why i need to check server is null or not ... confused - haoming 2/5/17
|
|
||||||
if(server == null || !server.isStarted()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int numOfBoatsFinished = 0;
|
|
||||||
for (Boat boat : (List<Boat>) arg){
|
|
||||||
try {
|
|
||||||
if (boat.isFinished()) {
|
|
||||||
numOfBoatsFinished ++;
|
|
||||||
if (!boatsFinished.get(boat.getSourceID())) {
|
|
||||||
boatsFinished.put(boat.getSourceID(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message m = new BoatLocationMessage(boat.getSourceID(), 1, boat.getLat(),
|
|
||||||
boat.getLng(), boat.getLastPassedCorner().getBearingToNextCorner(),
|
|
||||||
((long) boat.getSpeed()));
|
|
||||||
broadcast(m);
|
|
||||||
} catch (IOException e) {
|
|
||||||
serverLog("Couldn't send a boat status message", 3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (NullPointerException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (numOfBoatsFinished == ((List<Boat>) arg).size()) {
|
|
||||||
// startSendingRaceFinishedBoatPositions();
|
|
||||||
// }
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
public void terminateGame() {
|
|
||||||
try {
|
|
||||||
//TODO: for now, I just close the socket, but i think we should terminate the whole thread instead. -hyi25 13 July
|
|
||||||
server.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -99,9 +99,6 @@ public class MainServerThread extends Observable implements Runnable, PacketBuff
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void updateClients() {
|
public void updateClients() {
|
||||||
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||||
serverToClientThread.updateClient();
|
serverToClientThread.updateClient();
|
||||||
@@ -146,4 +143,9 @@ public class MainServerThread extends Observable implements Runnable, PacketBuff
|
|||||||
// sendXml();
|
// sendXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startGame() {
|
||||||
|
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
|
||||||
|
serverToClientThread.sendRaceStatusMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -23,12 +24,18 @@ import seng302.models.xml.Regatta;
|
|||||||
import seng302.models.xml.XMLGenerator;
|
import seng302.models.xml.XMLGenerator;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.server.messages.BoatActionType;
|
||||||
import seng302.server.messages.BoatLocationMessage;
|
import seng302.server.messages.BoatLocationMessage;
|
||||||
|
import seng302.server.messages.BoatStatus;
|
||||||
|
import seng302.server.messages.BoatSubMessage;
|
||||||
import seng302.server.messages.Message;
|
import seng302.server.messages.Message;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
|
import seng302.server.messages.RaceStatus;
|
||||||
|
import seng302.server.messages.RaceStatusMessage;
|
||||||
|
import seng302.server.messages.RaceType;
|
||||||
|
import seng302.server.messages.WindDirection;
|
||||||
import seng302.server.messages.XMLMessage;
|
import seng302.server.messages.XMLMessage;
|
||||||
import seng302.server.messages.XMLMessageSubType;
|
import seng302.server.messages.XMLMessageSubType;
|
||||||
import seng302.server.messages.XMLMessage;
|
import seng302.server.messages.XMLMessage;
|
||||||
@@ -172,6 +179,8 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
|
// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
|
||||||
// sendMessage(message);
|
// sendMessage(message);
|
||||||
// System.out.println("[server] send message 4 " + message);
|
// System.out.println("[server] send message 4 " + message);
|
||||||
|
// sendMessage(getRaceStatusMessage());
|
||||||
|
// System.out.println("sent race status");
|
||||||
//-------
|
//-------
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
@@ -215,7 +224,7 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Packet has been dropped");
|
serverLog("Packet has been dropped", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -359,10 +368,42 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Thread getThread() {
|
public Thread getThread() {
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendRaceStatusMessage(){
|
||||||
|
// variables taken from GameServerThread
|
||||||
|
int TIME_TILL_RACE_START = 20*1000;
|
||||||
|
long startTime = System.currentTimeMillis() + TIME_TILL_RACE_START;
|
||||||
|
|
||||||
|
List<BoatSubMessage> boatSubMessages = new ArrayList<>();
|
||||||
|
BoatStatus boatStatus;
|
||||||
|
RaceStatus raceStatus;
|
||||||
|
|
||||||
|
for (Player player : GameState.getPlayers()){
|
||||||
|
Yacht y = player.getYacht();
|
||||||
|
|
||||||
|
if (GameState.getCurrentStage() == GameStages.PRE_RACE){
|
||||||
|
boatStatus = BoatStatus.PRESTART;
|
||||||
|
}
|
||||||
|
else if(GameState.getCurrentStage() == GameStages.RACING){
|
||||||
|
boatStatus = BoatStatus.RACING;
|
||||||
|
} else {
|
||||||
|
boatStatus = BoatStatus.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), boatStatus, 0, 0, 0, 1234l, 1234l);
|
||||||
|
boatSubMessages.add(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameState.getCurrentStage() == GameStages.RACING){
|
||||||
|
raceStatus = RaceStatus.STARTED;
|
||||||
|
} else {
|
||||||
|
raceStatus = RaceStatus.WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(new RaceStatusMessage(1, raceStatus, startTime, WindDirection.SOUTH,
|
||||||
|
100, GameState.getPlayers().size(), RaceType.MATCH_RACE, 1, boatSubMessages));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Button focusTraversable="false" mnemonicParsing="false" onAction="#readyButtonPressed" prefWidth="101.0" text="Ready" GridPane.halignment="CENTER" />
|
<Button fx:id="readyButton" focusTraversable="false" mnemonicParsing="false" onAction="#readyButtonPressed" prefWidth="101.0" text="Ready" GridPane.halignment="CENTER" />
|
||||||
<Button focusTraversable="false" mnemonicParsing="false" onAction="#leaveLobbyButtonPressed" text="Leave Lobby" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
|
<Button focusTraversable="false" mnemonicParsing="false" onAction="#leaveLobbyButtonPressed" text="Leave Lobby" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user