mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Yacht now extends observable and can notify server to client thread to broadcast message.
#story[1124]
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user