Merge remote-tracking branch 'origin/story1266_3d_model_factory' into NewUI_merge

# Conflicts:
#	pom.xml
#	src/main/java/seng302/App.java
#	src/main/java/seng302/gameServer/GameState.java
#	src/main/java/seng302/gameServer/MainServerThread.java
#	src/main/java/seng302/gameServer/ServerToClientThread.java
#	src/main/java/seng302/utilities/XMLGenerator.java
#	src/main/java/seng302/visualiser/GameClient.java
#	src/main/java/seng302/visualiser/controllers/RaceViewController.java
#	src/main/resources/views/RaceView.fxml
#	src/main/resources/views/StartScreenView.fxml
This commit is contained in:
Michael Rausch
2017-09-11 15:29:33 +12:00
130 changed files with 24554 additions and 331 deletions
+82 -17
View File
@@ -10,6 +10,8 @@ import seng302.model.*;
import seng302.model.mark.CompoundMark;
import seng302.model.mark.Mark;
import seng302.model.mark.MarkOrder;
import seng302.model.token.Token;
import seng302.model.token.TokenType;
import seng302.utilities.GeoUtility;
import seng302.utilities.XMLParser;
@@ -23,6 +25,7 @@ import java.util.*;
* Created by wmu16 on 10/07/17.
*/
public class GameState implements Runnable {
@FunctionalInterface
interface NewMessageListener {
@@ -31,13 +34,20 @@ public class GameState implements Runnable {
private Logger logger = LoggerFactory.getLogger(GameState.class);
static final int WARNING_TIME = 10 * -1000;
static final int PREPATORY_TIME = 5 * -1000;
private static final int TIME_TILL_START = 10 * 1000;
private static final Long POWERUP_TIMEOUT_MS = 10_000L;
private static final Integer STATE_UPDATES_PER_SECOND = 60;
public static Double ROUNDING_DISTANCE = 50d; // TODO: 14/08/17 wmu16 - Look into this value further
public static final Double MARK_COLLISION_DISTANCE = 15d;
private static Double ROUNDING_DISTANCE = 50d; // TODO: 14/08/17 wmu16 - Look into this value further
private static final Double MARK_COLLISION_DISTANCE = 15d;
public static final Double YACHT_COLLISION_DISTANCE = 25.0;
public static final Double BOUNCE_DISTANCE_MARK = 20.0;
private static final Double BOUNCE_DISTANCE_MARK = 20.0;
public static final Double BOUNCE_DISTANCE_YACHT = 30.0;
public static final Double COLLISION_VELOCITY_PENALTY = 0.3;
private static final Double COLLISION_VELOCITY_PENALTY = 0.3;
private static Long previousUpdateTime;
public static Double windDirection;
@@ -48,6 +58,7 @@ public class GameState implements Runnable {
private static String hostIpAddress;
private static List<Player> players;
private static Map<Integer, ServerYacht> yachts;
private static List<Token> tokens;
private static Boolean isRaceStarted;
private static GameStages currentStage;
private static MarkOrder markOrder;
@@ -76,6 +87,7 @@ public class GameState implements Runnable {
windSpeed = 10000d;
this.hostIpAddress = hostIpAddress;
yachts = new HashMap<>();
tokens = new ArrayList<>();
players = new ArrayList<>();
GameState.hostIpAddress = hostIpAddress;
customizationFlag = false;
@@ -122,6 +134,18 @@ public class GameState implements Runnable {
return players;
}
public static void addToken(Token token) {
tokens.add(token);
}
public static List<Token> getTokens() {
return tokens;
}
public static void clearTokens() {
tokens.clear();
}
public static void addPlayer(Player player) {
players.add(player);
String playerText = player.getYacht().getSourceId() + " " + player.getYacht().getBoatName()
@@ -163,7 +187,7 @@ public class GameState implements Runnable {
}
public static void resetStartTime(){
startTime = System.currentTimeMillis() + MainServerThread.TIME_TILL_START;
startTime = System.currentTimeMillis() + TIME_TILL_START;
}
public static Double getWindDirection() {
@@ -261,10 +285,12 @@ public class GameState implements Runnable {
}
for (ServerYacht yacht : yachts.values()) {
updateVelocity(yacht);
checkPowerUpTimeout(yacht);
yacht.runAutoPilot();
yacht.updateLocation(timeInterval);
if (yacht.getBoatStatus() != BoatStatus.FINISHED) {
checkCollision(yacht);
checkTokenPickUp(yacht);
checkForLegProgression(yacht);
raceFinished = false;
}
@@ -275,6 +301,17 @@ public class GameState implements Runnable {
}
}
private void checkPowerUpTimeout(ServerYacht yacht) {
if (yacht.getPowerUp() != null) {
if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > POWERUP_TIMEOUT_MS) {
yacht.powerDown();
logger.debug("Yacht: " + yacht.getShortName() + " powered down!");
}
}
}
/**
* Check if the yacht has crossed the course limit
*
@@ -295,6 +332,26 @@ public class GameState implements Runnable {
return false;
}
/**
* Checks all tokens to see if a yacht has picked one up
*
* @param serverYacht The yacht to check for
*/
private void checkTokenPickUp(ServerYacht serverYacht) {
for (Token token : tokens) {
Double distance = GeoUtility.getDistance(token, serverYacht.getLocation());
if (distance < YACHT_COLLISION_DISTANCE) {
tokens.remove(token);
serverYacht.powerUp(token.getTokenType());
logger.debug("Yacht: " + serverYacht.getShortName() + " got powerup " + token
.getTokenType());
notifyMessageListeners(MessageFactory.getRaceXML());
break;
}
}
}
public static void checkCollision(ServerYacht serverYacht) {
ServerYacht collidedYacht = checkYachtCollision(serverYacht);
if (collidedYacht != null) {
@@ -346,25 +403,31 @@ public class GameState implements Runnable {
private void updateVelocity(ServerYacht yacht) {
Double velocity = yacht.getCurrentVelocity();
Double trueWindAngle = Math.abs(windDirection - yacht.getHeading());
Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle);
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots);
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * 4;
if (yacht.getPowerUp() != null) {
if (yacht.getPowerUp().equals(TokenType.BOOST)) {
maxBoatSpeed *= 2;
}
}
Double currentVelocity = yacht.getCurrentVelocity();
// TODO: 15/08/17 remove magic numbers from these equations.
if (yacht.getSailIn()) {
if (velocity < maxBoatSpeed - 500) {
if (currentVelocity < maxBoatSpeed - 500) {
yacht.changeVelocity(maxBoatSpeed / 100);
} else if (velocity > maxBoatSpeed + 500) {
yacht.changeVelocity(-velocity / 200);
} else if (currentVelocity > maxBoatSpeed + 500) {
yacht.changeVelocity(-currentVelocity / 200);
} else {
yacht.setCurrentVelocity(maxBoatSpeed);
}
} else {
if (velocity > 3000) {
yacht.changeVelocity(-velocity / 200);
} else if (velocity > 100) {
yacht.changeVelocity(-velocity / 50);
} else if (velocity <= 100) {
if (currentVelocity > 3000) {
yacht.changeVelocity(-currentVelocity / 200);
} else if (currentVelocity > 100) {
yacht.changeVelocity(-currentVelocity / 50);
} else if (currentVelocity <= 100) {
yacht.setCurrentVelocity(0d);
}
}
@@ -648,7 +711,8 @@ public class GameState implements Runnable {
// TODO: 13/8/17 figure out the rounding side, rounded mark source ID and boat status.
Message markRoundingMessage = new MarkRoundingMessage(0, 0,
sourceID, RoundingBoatStatus.RACING, roundingMark.getRoundingSide(), markType,
currentMarkSeqID + 1);
currentMark.getId());
// currentMarkSeqID + 1);
notifyMessageListeners(markRoundingMessage);
}
@@ -667,7 +731,7 @@ public class GameState implements Runnable {
}
public static void addMarkPassListener(NewMessageListener listener) {
public static void addMessageEventListener(NewMessageListener listener) {
markListeners.add(listener);
}
@@ -702,4 +766,5 @@ public class GameState implements Runnable {
public static void setMaxPlayers(Integer newMax){
maxPlayers = newMax;
}
}
@@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.*;
import seng302.model.GeoPoint;
import seng302.model.Player;
@@ -12,6 +14,8 @@ import seng302.model.PolarTable;
import seng302.model.ServerYacht;
import seng302.model.mark.CompoundMark;
import seng302.model.stream.xml.parser.RegattaXMLData;
import seng302.model.token.Token;
import seng302.model.token.TokenType;
import seng302.utilities.GeoUtility;
import seng302.utilities.XMLGenerator;
import seng302.utilities.XMLParser;
@@ -22,7 +26,6 @@ import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.net.ServerSocket;
import java.time.LocalDateTime;
import java.util.*;
/**
@@ -31,18 +34,14 @@ import java.util.*;
*/
public class MainServerThread implements Runnable, ClientConnectionDelegate {
private Logger logger = LoggerFactory.getLogger(MainServerThread.class);
private static final int PORT = 4942;
private static final Integer CLIENT_UPDATES_PER_SECOND = 60;
private static final int LOG_LEVEL = 1;
private static final int WARNING_TIME = 10 * -1000;
private static final int PREPATORY_TIME = 5 * -1000;
public static final int TIME_TILL_START = 10 * 1000;
private static final int MAX_WIND_SPEED = 12000;
private static final int MIN_WIND_SPEED = 8000;
public static int windSpeed = 1000;
private boolean terminated;
private Thread thread;
@@ -95,16 +94,18 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
serverLog("IO error in server thread handler upon trying to make new server socket", 0);
logger.trace("IO error in server thread handler upon trying to make new server socket",
0);
}
startAdvertisingServer();
PolarTable.parsePolarFile(getClass().getResourceAsStream("/config/acc_polars.csv"));
GameState.addMarkPassListener(this::broadcastMessage);
GameState.addMessageEventListener(this::broadcastMessage);
terminated = false;
thread = new Thread(this, "MainServer");
startUpdatingWind();
startSpawningTokens();
thread.start();
}
@@ -119,24 +120,22 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
try {
Thread.sleep(1000 / CLIENT_UPDATES_PER_SECOND);
} catch (InterruptedException e) {
serverLog("Interrupted exception in Main Server Thread thread sleep", 1);
logger.trace("Interrupted exception in Main Server Thread thread sleep", 1);
}
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState
.getCustomizationFlag()) {
// TODO: 16/08/17 ajm412: This can probably be done in a nicer way via those fancy functional interfaces.
for (ServerToClientThread thread : serverToClientThreads) {
thread.sendSetupMessages();
}
sendSetupMessages();
GameState.resetCustomizationFlag();
}
if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
updateClients();
sendBoatLocations();
}
//RACING
if (GameState.getCurrentStage() == GameStages.RACING) {
updateClients();
sendBoatLocations();
}
//FINISHED
@@ -157,12 +156,18 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
}
}
public void updateClients() {
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.sendBoatLocationPackets();
public void sendBoatLocations() {
for (ServerYacht serverYacht : GameState.getYachts().values()) {
broadcastMessage(MessageFactory.getBoatLocationMessage(serverYacht));
}
}
public void sendSetupMessages() {
broadcastMessage(MessageFactory.getRaceXML());
broadcastMessage(MessageFactory.getRegattaXML());
broadcastMessage(MessageFactory.getBoatXML());
}
private void broadcastMessage(Message message) {
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.sendMessage(message);
@@ -198,6 +203,25 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
GameState.setWindDirection(direction.doubleValue());
}
// TODO: 29/08/17 wmu16 - This should not be in one function (init and a scheduling update)
public void startGame() {
initialiseBoatPositions();
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
broadcastMessage(MessageFactory.getRaceStatusMessage());
if (GameState.getCurrentStage() == GameStages.PRE_RACE
|| GameState.getCurrentStage() == GameStages.LOBBYING) {
broadcastMessage(MessageFactory.getRaceStartStatusMessage());
}
}
}, 0, 500);
}
// TODO: 29/08/17 wmu16 - This sort of update should be in game state
private static void startUpdatingWind(){
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@@ -208,11 +232,41 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
}, 0, 500);
}
/**
* Start spawning coins every 60s after the first minute
*/
private void startSpawningTokens() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
spawnNewCoins();
broadcastMessage(MessageFactory.getRaceXML());
}
}, 0, 60000);
}
static void serverLog(String message, int logLevel) {
if (logLevel <= LOG_LEVEL) {
System.out.println(
"[SERVER " + LocalDateTime.now().toLocalTime().toString() + "] " + message);
/**
* Randomly select a subset of tokens from a pre defined superset
* Broadasts a new race status message to show this update
*/
private void spawnNewCoins() {
List<Token> allTokens = new ArrayList<>();
Token token1 = new Token(TokenType.BOOST, 57.66946, 11.83154);
Token token2 = new Token(TokenType.BOOST, 57.66877, 11.83382);
Token token3 = new Token(TokenType.BOOST, 57.66914, 11.83965);
Token token4 = new Token(TokenType.BOOST, 57.66684, 11.83214);
allTokens.add(token1);
allTokens.add(token2);
allTokens.add(token3);
allTokens.add(token4);
GameState.clearTokens();
Random random = new Random();
Collections.shuffle(allTokens);
for (int i = 0; i < random.nextInt(allTokens.size()); i++) {
GameState.addToken(allTokens.get(i));
}
}
@@ -223,13 +277,9 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
*/
@Override
public void clientConnected(ServerToClientThread serverToClientThread) {
serverLog("Player Connected From " + serverToClientThread.getThread().getName(), 0);
logger.debug("Player Connected From " + serverToClientThread.getThread().getName(), 0);
serverToClientThreads.add(serverToClientThread);
serverToClientThread.addConnectionListener(() -> {
for (ServerToClientThread thread : serverToClientThreads) {
thread.sendSetupMessages();
}
});
serverToClientThread.addConnectionListener(this::sendSetupMessages);
serverToClientThread.addDisconnectListener(this::clientDisconnected);
try {
@@ -246,12 +296,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
*/
@Override
public void clientDisconnected(Player player) {
// try {
// player.getSocket().close();
// } catch (Exception e) {
// serverLog("Cannot disconnect the socket for the disconnected player.", 0);
// }
serverLog("Player " + player.getYacht().getSourceId() + "'s socket disconnected", 0);
logger.debug("Player " + player.getYacht().getSourceId() + "'s socket disconnected", 0);
GameState.removeYacht(player.getYacht().getSourceId());
GameState.removePlayer(player);
ServerToClientThread closedConnection = null;
@@ -290,55 +335,15 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
if (GameState.getCurrentStage() == GameStages.PRE_RACE || GameState.getCurrentStage() == GameStages.LOBBYING) {
broadcastMessage(makeRaceStartMessage());
}
serverToClientThreads.remove(closedConnection);
closedConnection.terminate();
}
}, 0, 500);
}
private RaceStartStatusMessage makeRaceStartMessage() {
Long raceStartTime = GameState.getStartTime();
return new RaceStartStatusMessage(1, raceStartTime ,
1, RaceStartNotificationType.SET_RACE_START_TIME);
}
private RaceStatusMessage makeRaceStatusMessage() {
// variables taken from GameServerThread
List<BoatSubMessage> boatSubMessages = new ArrayList<>();
RaceStatus raceStatus;
for (Player player : GameState.getPlayers()) {
ServerYacht y = player.getYacht();
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(),
y.getLegNumber(),
0, 0, 1234L,
1234L);
boatSubMessages.add(m);
}
long timeTillStart = System.currentTimeMillis() - GameState.getStartTime();
if (GameState.getCurrentStage() == GameStages.LOBBYING) {
raceStatus = RaceStatus.PRESTART;
} else if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
raceStatus = RaceStatus.PRESTART;
if (timeTillStart > WARNING_TIME) {
raceStatus = RaceStatus.WARNING;
}
if (timeTillStart > PREPATORY_TIME) {
raceStatus = RaceStatus.PREPARATORY;
}
} else {
raceStatus = RaceStatus.STARTED;
if (GameState.getCurrentStage() != GameStages.RACING) {
sendSetupMessages();
}
return new RaceStatusMessage(1, raceStatus, GameState.getStartTime(),
GameState.getWindDirection(),
GameState.getWindSpeedMMS().longValue(), GameState.getPlayers().size(),
RaceType.MATCH_RACE, 1, boatSubMessages);
}
public void terminate() {
@@ -0,0 +1,136 @@
package seng302.gameServer;
import java.util.ArrayList;
import java.util.List;
import seng302.gameServer.messages.BoatLocationMessage;
import seng302.gameServer.messages.BoatSubMessage;
import seng302.gameServer.messages.RaceStartNotificationType;
import seng302.gameServer.messages.RaceStartStatusMessage;
import seng302.gameServer.messages.RaceStatus;
import seng302.gameServer.messages.RaceStatusMessage;
import seng302.gameServer.messages.RaceType;
import seng302.gameServer.messages.XMLMessage;
import seng302.gameServer.messages.XMLMessageSubType;
import seng302.model.Player;
import seng302.model.ServerYacht;
import seng302.model.stream.xml.generator.RaceXMLTemplate;
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
import seng302.model.token.Token;
import seng302.utilities.XMLGenerator;
/**
* A Class for interfacing between the data we have in the GameState to the messages we need to send
* through the MainServerThread.
*
* WARNING DO NOT USE THIS CLASS IF GAMESTATE HAS NOT BEEN INSTANTIATED. (Main Server has not started)
* // TODO: 29/08/17 wmu16 - Make GameState non static to fix this ¯\_(ツ)_/¯
* Created by wmu16 on 29/08/17.
*/
/*
Ideally this class would be created with an instance of the GameState (I tried implementing this for
a bit) but it was too difficult to properly make GameState non static without doing some proper
re working. To do later.
*/
public class MessageFactory {
private static XMLGenerator xmlGenerator = new XMLGenerator();
public static RaceStartStatusMessage getRaceStartStatusMessage() {
return new RaceStartStatusMessage(
1,
GameState.getStartTime(),
1,
RaceStartNotificationType.SET_RACE_START_TIME);
}
public static RaceStatusMessage getRaceStatusMessage() {
// variables taken from GameServerThread
List<BoatSubMessage> boatSubMessages = new ArrayList<>();
RaceStatus raceStatus;
for (Player player : GameState.getPlayers()) {
ServerYacht y = player.getYacht();
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(),
y.getLegNumber(),
0, 0, 1234L,
1234L);
boatSubMessages.add(m);
}
long timeTillStart = System.currentTimeMillis() - GameState.getStartTime();
if (GameState.getCurrentStage() == GameStages.LOBBYING) {
raceStatus = RaceStatus.PRESTART;
} else if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
raceStatus = RaceStatus.PRESTART;
if (timeTillStart > GameState.WARNING_TIME) {
raceStatus = RaceStatus.WARNING;
}
if (timeTillStart > GameState.PREPATORY_TIME) {
raceStatus = RaceStatus.PREPARATORY;
}
} else {
raceStatus = RaceStatus.STARTED;
}
return new RaceStatusMessage(1, raceStatus, GameState.getStartTime(),
GameState.getWindDirection(),
GameState.getWindSpeedMMS().longValue(), GameState.getPlayers().size(),
RaceType.MATCH_RACE, 1, boatSubMessages);
}
public static BoatLocationMessage getBoatLocationMessage(ServerYacht yacht) {
return new BoatLocationMessage(
yacht.getSourceId(),
0, // TODO: 29/08/17 wmu16 - Work out what to do with seqNo. Currently not used
yacht.getLocation().getLat(),
yacht.getLocation().getLng(),
yacht.getHeading(),
yacht.getCurrentVelocity().longValue());
}
public static XMLMessage getRaceXML() {
List<ServerYacht> yachts = new ArrayList<>(GameState.getYachts().values());
List<Token> tokens = GameState.getTokens();
RaceXMLTemplate raceXMLTemplate = new RaceXMLTemplate(yachts, tokens);
xmlGenerator.setRaceTemplate(raceXMLTemplate);
XMLMessage raceXMLMessage = new XMLMessage(
xmlGenerator.getRaceAsXml(),
XMLMessageSubType.RACE,
xmlGenerator.getRaceAsXml().length());
return raceXMLMessage;
}
public static XMLMessage getRegattaXML() {
//@TODO calculate lat/lng values
xmlGenerator.setRegattaTemplate(
new RegattaXMLTemplate(
"Party Parrot Test Server", "Bermuda Test Course",
57.6679590, 11.8503233)
);
return new XMLMessage(
xmlGenerator.getRegattaAsXml(),
XMLMessageSubType.REGATTA,
xmlGenerator.getRegattaAsXml().length());
}
public static XMLMessage getBoatXML() {
List<ServerYacht> yachts = new ArrayList<>(GameState.getYachts().values());
List<Token> tokens = GameState.getTokens();
RaceXMLTemplate raceXMLTemplate = new RaceXMLTemplate(yachts, tokens);
xmlGenerator.setRaceTemplate(raceXMLTemplate);
return new XMLMessage(
xmlGenerator.getBoatsAsXml(),
XMLMessageSubType.BOAT,
xmlGenerator.getBoatsAsXml().length());
}
}
@@ -4,6 +4,16 @@ package seng302.gameServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.*;
import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatLocationMessage;
import seng302.gameServer.messages.ClientType;
import seng302.gameServer.messages.CustomizeRequestType;
import seng302.gameServer.messages.Message;
import seng302.gameServer.messages.RegistrationResponseMessage;
import seng302.gameServer.messages.RegistrationResponseStatus;
import seng302.gameServer.messages.XMLMessage;
import seng302.gameServer.messages.XMLMessageSubType;
import seng302.gameServer.messages.YachtEventCodeMessage;
import seng302.model.Player;
import seng302.model.ServerYacht;
import seng302.model.stream.packets.PacketType;
@@ -19,13 +29,17 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import seng302.model.stream.xml.generator.RaceXMLTemplate;
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
import seng302.model.token.Token;
import seng302.utilities.XMLGenerator;
/**
* A class describing a single connection to a Client for the purposes of sending and receiving on
* its own thread. All server threads created and owned by the server thread handler which can
* trigger client updates on its threads Created by wmu16 on 13/07/17.
*/
public class ServerToClientThread implements Runnable, Observer {
public class ServerToClientThread implements Runnable {
/**
* Called to notify listeners when this thread receives a connection correctly.
@@ -57,7 +71,7 @@ public class ServerToClientThread implements Runnable, Observer {
private ClientType clientType;
private Boolean isRegistered = false;
private XMLGenerator xml;
private XMLGenerator xmlGenerator;
private List<ConnectionListener> connectionListeners = new ArrayList<>();
private DisconnectListener disconnectListener;
@@ -109,21 +123,11 @@ 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
player = new Player(socket, yacht);
GameState.addYacht(sourceId, yacht);
GameState.addPlayer(player);
}
@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
if (!clientType.equals(ClientType.PLAYER)){
@@ -293,23 +297,6 @@ public class ServerToClientThread implements Runnable, Observer {
return seqNo;
}
public void sendBoatLocationPackets() {
ArrayList<ServerYacht> yachts = new ArrayList<>(GameState.getYachts().values());
for (ServerYacht yacht : yachts) {
BoatLocationMessage boatLocationMessage =
new BoatLocationMessage(
yacht.getSourceId(),
getSeqNo(),
yacht.getLocation().getLat(),
yacht.getLocation().getLng(),
yacht.getHeading(),
yacht.getCurrentVelocity().longValue());
sendMessage(boatLocationMessage);
}
}
public Thread getThread() {
return thread;
}