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;
import seng302.gameServer.server.messages.*;
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;
import java.io.*;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.time.LocalDateTime;
@@ -22,6 +18,26 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.zip.CRC32;
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
@@ -99,6 +115,7 @@ public class ServerToClientThread implements Runnable, Observer {
"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.addPlayer(new Player(socket, yacht));
}
@@ -112,8 +129,12 @@ public class ServerToClientThread implements Runnable, Observer {
@Override
public void update(Observable o, Object arg) {
if (arg != null) {
sendMessage((Message) arg);
} else {
sendSetupMessages();
}
}
private void completeRegistration(ClientType clientType) throws IOException {
// Fail if not a player
+53 -24
View File
@@ -5,6 +5,8 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.ReadOnlyLongProperty;
@@ -13,20 +15,24 @@ import javafx.scene.paint.Color;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Mark;
import seng302.utilities.GeoUtility;
/**
* Yacht class for the racing boat.
*
* 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 not used anymore.
* 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
* not used anymore.
*/
public class Yacht {
public class Yacht extends Observable {
@FunctionalInterface
public interface YachtLocationListener {
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
}
/**
* 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
* of mark rounding
* Calculates the distance to the next mark (closest of the two if a gate mark). For purposes of
* mark rounding
*
* @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)
* 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
* 1 - Passing the start line
* 2 - Passing any in-race Gate
* 3 - Passing any in-race Mark
* 4 - Passing the finish line
* 4 Different cases of progression in the race 1 - Passing the start line 2 - Passing any
* in-race Gate 3 - Passing any in-race Mark 4 - Passing the finish line
*/
private void checkForLegProgression() {
CompoundMark currentMark = GameState.getMarkOrder().getCurrentMark(currentMarkSeqID);
@@ -202,6 +224,7 @@ public class Yacht {
if (crossedLine > 0) {
Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, nextMark.getMidPoint());
if (crossedLine == 2 && isClockwiseCross || crossedLine == 1 && !isClockwiseCross) {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++;
logMarkRounding(currentMark);
}
@@ -211,8 +234,7 @@ public class Yacht {
/**
* This algorithm checks for mark rounding. And increments the currentMarSeqID number attribute
* of the yacht if so.
* A visual representation of this algorithm can be seen on the Wiki under
* of the yacht if so. A visual representation of this algorithm can be seen on the Wiki under
* 'mark passing algorithm'
*/
private void checkMarkRounding(CompoundMark currentMark) {
@@ -275,6 +297,7 @@ public class Yacht {
if (prevMarkSide == nextMarkSide) {
checkMarkRounding(currentMark);
} else {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++;
logMarkRounding(currentMark);
}
@@ -295,6 +318,7 @@ public class Yacht {
if (crossedLine > 0) {
Boolean isClockwiseCross = GeoUtility.isClockwise(mark1, mark2, prevMark.getMidPoint());
if (crossedLine == 1 && isClockwiseCross || crossedLine == 2 && !isClockwiseCross) {
sendMarkRoundingMessage(currentMarkSeqID);
currentMarkSeqID++;
finishedRace = true;
logMarkRounding(currentMark);
@@ -306,8 +330,7 @@ public class Yacht {
/**
* Adjusts the heading of the boat by a given amount, while recording the boats
* last heading.
* Adjusts the heading of the boat by a given amount, while recording the boats last 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.
*
* @param thisHeading The heading to move the boat towards.
*/
private void setAutoPilot(Double thisHeading) {
@@ -441,9 +465,8 @@ public class Yacht {
}
/**
* Takes a given heading and rotates the boat towards that heading.
* This does not care about being upwind or downwind, just which direction will reach a given
* heading faster.
* Takes a given heading and rotates the boat towards that heading. This does not care about
* being upwind or downwind, just which direction will reach a given heading faster.
*
* @param newHeading The heading to turn the yacht towards.
*/
@@ -474,12 +497,16 @@ public class Yacht {
public Integer getSourceId() {
//@TODO Remove and merge with Creating Game Loop
if (sourceId == null) return 0;
if (sourceId == null) {
return 0;
}
return sourceId;
}
public String getHullID() {
if (hullID == null) return "";
if (hullID == null) {
return "";
}
return hullID;
}
@@ -492,7 +519,9 @@ public class Yacht {
}
public String getCountry() {
if (country == null) return "";
if (country == null) {
return "";
}
return country;
}
@@ -614,7 +643,7 @@ public class Yacht {
this.timeSinceLastMarkProperty.set(timeSinceLastMark);
}
public ReadOnlyLongProperty timeSinceLastMarkProperty () {
public ReadOnlyLongProperty timeSinceLastMarkProperty() {
return timeSinceLastMarkProperty.getReadOnlyProperty();
}
@@ -668,7 +697,7 @@ public class Yacht {
currentMarkSeqID));
}
public void addLocationListener (YachtLocationListener listener) {
public void addLocationListener(YachtLocationListener listener) {
locationListeners.add(listener);
}
}