Yacht now extends observable and can notify server to client thread to broadcast message.

#story[1124]
This commit is contained in:
Haoming Yin
2017-08-14 10:48:11 +12:00
parent fda233f5ad
commit 028fc44dce
2 changed files with 87 additions and 37 deletions
@@ -1,16 +1,12 @@
package seng302.gameServer; package seng302.gameServer;
import seng302.gameServer.server.messages.*; import java.io.BufferedReader;
import seng302.model.Player; import java.io.ByteArrayOutputStream;
import seng302.model.Yacht; import java.io.IOException;
import seng302.model.stream.packets.PacketType; import java.io.InputStream;
import seng302.model.stream.packets.StreamPacket; import java.io.InputStreamReader;
import seng302.model.stream.xml.generator.Race; import java.io.OutputStream;
import seng302.model.stream.xml.generator.Regatta;
import seng302.utilities.XMLGenerator;
import java.io.*;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -22,6 +18,26 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import java.util.zip.Checksum; import java.util.zip.Checksum;
import seng302.gameServer.server.messages.BoatActionType;
import seng302.gameServer.server.messages.BoatLocationMessage;
import seng302.gameServer.server.messages.BoatStatus;
import seng302.gameServer.server.messages.BoatSubMessage;
import seng302.gameServer.server.messages.ClientType;
import seng302.gameServer.server.messages.Message;
import seng302.gameServer.server.messages.RaceStatus;
import seng302.gameServer.server.messages.RaceStatusMessage;
import seng302.gameServer.server.messages.RaceType;
import seng302.gameServer.server.messages.RegistrationResponseMessage;
import seng302.gameServer.server.messages.RegistrationResponseStatus;
import seng302.gameServer.server.messages.XMLMessage;
import seng302.gameServer.server.messages.XMLMessageSubType;
import seng302.model.Player;
import seng302.model.Yacht;
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.utilities.XMLGenerator;
/** /**
* A class describing a single connection to a Client for the purposes of sending and receiving on * A class describing a single connection to a Client for the purposes of sending and receiving on
@@ -99,6 +115,7 @@ public class ServerToClientThread implements Runnable, Observer {
"Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ" "Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
); );
yacht.addObserver(this); // TODO: yacht can notify mark rounding message hyi25 13/8/17
GameState.addYacht(sourceId, yacht); GameState.addYacht(sourceId, yacht);
GameState.addPlayer(new Player(socket, yacht)); GameState.addPlayer(new Player(socket, yacht));
} }
@@ -112,8 +129,12 @@ public class ServerToClientThread implements Runnable, Observer {
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
if (arg != null) {
sendMessage((Message) arg);
} else {
sendSetupMessages(); sendSetupMessages();
} }
}
private void completeRegistration(ClientType clientType) throws IOException { private void completeRegistration(ClientType clientType) throws IOException {
// Fail if not a player // Fail if not a player
+53 -24
View File
@@ -5,6 +5,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper; import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.ReadOnlyLongProperty; import javafx.beans.property.ReadOnlyLongProperty;
@@ -13,20 +15,24 @@ import javafx.scene.paint.Color;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.gameServer.server.messages.MarkRoundingMessage;
import seng302.gameServer.server.messages.Message;
import seng302.gameServer.server.messages.RoundingBoatStatus;
import seng302.gameServer.server.messages.RoundingSide;
import seng302.model.mark.CompoundMark; import seng302.model.mark.CompoundMark;
import seng302.model.mark.Mark; import seng302.model.mark.Mark;
import seng302.utilities.GeoUtility; import seng302.utilities.GeoUtility;
/** /**
* Yacht class for the racing boat. * Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
* * compared to the XMLParser boat class, also done outside Boat class because some old variables are
* Class created to store more variables (eg. boat statuses) compared to the XMLParser boat class, * not used anymore.
* also done outside Boat class because some old variables are not used anymore.
*/ */
public class Yacht { public class Yacht extends Observable {
@FunctionalInterface @FunctionalInterface
public interface YachtLocationListener { public interface YachtLocationListener {
void notifyLocation(Yacht yacht, double lat, double lon, double heading, double velocity); void notifyLocation(Yacht yacht, double lat, double lon, double heading, double velocity);
} }
@@ -145,10 +151,29 @@ public class Yacht {
// TODO: 3/08/17 wmu16 - Implement line cross check here // TODO: 3/08/17 wmu16 - Implement line cross check here
} }
/**
* Add ServerToClientThread as the observer, this observer pattern mainly server for the boat
* rounding package.
*/
@Override
public void addObserver(Observer o) {
super.addObserver(o);
}
private void sendMarkRoundingMessage(Integer passedMarkSeqID) {
// TODO: 13/8/17 figure out the rounding side, rounded mark source ID and boat status.
Message markRoundingMessage = new MarkRoundingMessage(0, 0,
getSourceId(), RoundingBoatStatus.RACING, RoundingSide.UNKNOWN,
GameState.getMarkOrder().getCurrentMark(passedMarkSeqID).getSubMark(1).getSourceID());
logger.debug("Sending mark rounding message...");
setChanged();
notifyObservers(markRoundingMessage);
}
/** /**
* Calculates the distance to the next mark (closest of the two if a gate mark). For purposes * Calculates the distance to the next mark (closest of the two if a gate mark). For purposes of
* of mark rounding * mark rounding
*
* @return A distance in metres. Returns -1 if there is no next mark * @return A distance in metres. Returns -1 if there is no next mark
* @throws IndexOutOfBoundsException If the next mark is null (ie the last mark in the race) * @throws IndexOutOfBoundsException If the next mark is null (ie the last mark in the race)
* Check first using {@link seng302.model.mark.MarkOrder#isLastMark(Integer)} * Check first using {@link seng302.model.mark.MarkOrder#isLastMark(Integer)}
@@ -169,11 +194,8 @@ public class Yacht {
/** /**
* 4 Different cases of progression in the race * 4 Different cases of progression in the race 1 - Passing the start line 2 - Passing any
* 1 - Passing the start line * in-race Gate 3 - Passing any in-race Mark 4 - Passing the finish line
* 2 - Passing any in-race Gate
* 3 - Passing any in-race Mark
* 4 - Passing the finish line
*/ */
private void checkForLegProgression() { private void checkForLegProgression() {
CompoundMark currentMark = GameState.getMarkOrder().getCurrentMark(currentMarkSeqID); CompoundMark currentMark = GameState.getMarkOrder().getCurrentMark(currentMarkSeqID);
@@ -202,6 +224,7 @@ public class Yacht {
if (crossedLine > 0) { if (crossedLine > 0) {
Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, nextMark.getMidPoint()); Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, nextMark.getMidPoint());
if (crossedLine == 2 && isClockwiseCross || crossedLine == 1 && !isClockwiseCross) { if (crossedLine == 2 && isClockwiseCross || crossedLine == 1 && !isClockwiseCross) {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++; currentMarkSeqID++;
logMarkRounding(currentMark); logMarkRounding(currentMark);
} }
@@ -211,8 +234,7 @@ public class Yacht {
/** /**
* This algorithm checks for mark rounding. And increments the currentMarSeqID number attribute * This algorithm checks for mark rounding. And increments the currentMarSeqID number attribute
* of the yacht if so. * of the yacht if so. A visual representation of this algorithm can be seen on the Wiki under
* A visual representation of this algorithm can be seen on the Wiki under
* 'mark passing algorithm' * 'mark passing algorithm'
*/ */
private void checkMarkRounding(CompoundMark currentMark) { private void checkMarkRounding(CompoundMark currentMark) {
@@ -275,6 +297,7 @@ public class Yacht {
if (prevMarkSide == nextMarkSide) { if (prevMarkSide == nextMarkSide) {
checkMarkRounding(currentMark); checkMarkRounding(currentMark);
} else { } else {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++; currentMarkSeqID++;
logMarkRounding(currentMark); logMarkRounding(currentMark);
} }
@@ -295,6 +318,7 @@ public class Yacht {
if (crossedLine > 0) { if (crossedLine > 0) {
Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, prevMark.getMidPoint()); Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, prevMark.getMidPoint());
if (crossedLine == 1 && isClockwiseCross || crossedLine == 2 && !isClockwiseCross) { if (crossedLine == 1 && isClockwiseCross || crossedLine == 2 && !isClockwiseCross) {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++; currentMarkSeqID++;
finishedRace = true; finishedRace = true;
logMarkRounding(currentMark); logMarkRounding(currentMark);
@@ -306,8 +330,7 @@ public class Yacht {
/** /**
* Adjusts the heading of the boat by a given amount, while recording the boats * Adjusts the heading of the boat by a given amount, while recording the boats last heading.
* last heading.
* *
* @param amount the amount by which to adjust the boat heading. * @param amount the amount by which to adjust the boat heading.
*/ */
@@ -333,6 +356,7 @@ public class Yacht {
/** /**
* Enables the boats auto pilot feature, which will move the boat towards a given heading. * Enables the boats auto pilot feature, which will move the boat towards a given heading.
*
* @param thisHeading The heading to move the boat towards. * @param thisHeading The heading to move the boat towards.
*/ */
private void setAutoPilot(Double thisHeading) { private void setAutoPilot(Double thisHeading) {
@@ -441,9 +465,8 @@ public class Yacht {
} }
/** /**
* Takes a given heading and rotates the boat towards that heading. * Takes a given heading and rotates the boat towards that heading. This does not care about
* This does not care about being upwind or downwind, just which direction will reach a given * being upwind or downwind, just which direction will reach a given heading faster.
* heading faster.
* *
* @param newHeading The heading to turn the yacht towards. * @param newHeading The heading to turn the yacht towards.
*/ */
@@ -474,12 +497,16 @@ public class Yacht {
public Integer getSourceId() { public Integer getSourceId() {
//@TODO Remove and merge with Creating Game Loop //@TODO Remove and merge with Creating Game Loop
if (sourceId == null) return 0; if (sourceId == null) {
return 0;
}
return sourceId; return sourceId;
} }
public String getHullID() { public String getHullID() {
if (hullID == null) return ""; if (hullID == null) {
return "";
}
return hullID; return hullID;
} }
@@ -492,7 +519,9 @@ public class Yacht {
} }
public String getCountry() { public String getCountry() {
if (country == null) return ""; if (country == null) {
return "";
}
return country; return country;
} }
@@ -614,7 +643,7 @@ public class Yacht {
this.timeSinceLastMarkProperty.set(timeSinceLastMark); this.timeSinceLastMarkProperty.set(timeSinceLastMark);
} }
public ReadOnlyLongProperty timeSinceLastMarkProperty () { public ReadOnlyLongProperty timeSinceLastMarkProperty() {
return timeSinceLastMarkProperty.getReadOnlyProperty(); return timeSinceLastMarkProperty.getReadOnlyProperty();
} }
@@ -668,7 +697,7 @@ public class Yacht {
currentMarkSeqID)); currentMarkSeqID));
} }
public void addLocationListener (YachtLocationListener listener) { public void addLocationListener(YachtLocationListener listener) {
locationListeners.add(listener); locationListeners.add(listener);
} }
} }