mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Merge remote-tracking branch 'origin/develop' into Story80_BoatCustomization
# Conflicts: # src/main/java/seng302/gameServer/GameState.java # src/main/java/seng302/gameServer/ServerPacketParser.java # src/main/java/seng302/gameServer/ServerToClientThread.java # src/main/java/seng302/gameServer/messages/ChatterMessage.java # src/main/java/seng302/gameServer/messages/MarkRoundingMessage.java # src/main/java/seng302/model/ServerYacht.java # src/main/java/seng302/visualiser/ClientToServerThread.java # src/main/java/seng302/visualiser/GameClient.java # src/main/java/seng302/visualiser/GameView.java
This commit is contained in:
@@ -104,7 +104,6 @@ public class GameState implements Runnable {
|
||||
|
||||
resetStartTime();
|
||||
|
||||
new Thread(this).start(); //Run the auto updates on the game state
|
||||
new Thread(this, "GameState").start(); //Run the auto updates on the game state
|
||||
|
||||
marks = new MarkOrder().getAllMarks();
|
||||
@@ -186,6 +185,14 @@ public class GameState implements Runnable {
|
||||
return windDirection;
|
||||
}
|
||||
|
||||
public static void setWindDirection(Double newWindDirection) {
|
||||
windDirection = newWindDirection;
|
||||
}
|
||||
|
||||
public static void setWindSpeed(Double newWindSpeed) {
|
||||
windSpeed = newWindSpeed;
|
||||
}
|
||||
|
||||
public static Double getWindSpeedMMS() {
|
||||
return windSpeed;
|
||||
}
|
||||
@@ -256,7 +263,6 @@ public class GameState implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called periodically in this GameState thread to update the GameState values
|
||||
*/
|
||||
@@ -277,6 +283,8 @@ public class GameState implements Runnable {
|
||||
checkForLegProgression(yacht);
|
||||
raceFinished = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (raceFinished) {
|
||||
@@ -335,17 +343,20 @@ public class GameState implements Runnable {
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId())
|
||||
);
|
||||
} else if (checkBoundaryCollision(serverYacht)) {
|
||||
serverYacht.setLocation(
|
||||
calculateBounceBack(serverYacht, serverYacht.getLocation(),
|
||||
BOUNCE_DISTANCE_YACHT)
|
||||
);
|
||||
serverYacht.setCurrentVelocity(
|
||||
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
|
||||
);
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId())
|
||||
);
|
||||
}
|
||||
else{
|
||||
if (checkBoundaryCollision(serverYacht)) {
|
||||
serverYacht.setLocation(
|
||||
calculateBounceBack(serverYacht, serverYacht.getLocation(),
|
||||
BOUNCE_DISTANCE_YACHT)
|
||||
);
|
||||
serverYacht.setCurrentVelocity(
|
||||
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
|
||||
);
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,7 +420,7 @@ public class GameState implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/** lobbyController.setPlayerListSource(clientLobbyList);
|
||||
* 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
|
||||
*
|
||||
@@ -432,6 +443,7 @@ public class GameState implements Runnable {
|
||||
}
|
||||
|
||||
if (hasProgressed) {
|
||||
yacht.incrementLegNumber();
|
||||
sendMarkRoundingMessage(yacht);
|
||||
logMarkRounding(yacht);
|
||||
yacht.setHasPassedLine(false);
|
||||
@@ -654,7 +666,7 @@ 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,
|
||||
roundingMark.getSourceID());
|
||||
currentMarkSeqID + 1);
|
||||
|
||||
notifyMessageListeners(markRoundingMessage);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import seng302.gameServer.messages.Message;
|
||||
* Will call .clientDisconnected on the delegate when a heartbeat message
|
||||
* cannot be sent to a player
|
||||
*/
|
||||
public class HeartbeatThread extends Thread{
|
||||
public class HeartbeatThread implements Runnable {
|
||||
private final int HEARTBEAT_PERIOD = 200;
|
||||
private ClientConnectionDelegate delegate;
|
||||
private Integer seqNum;
|
||||
@@ -23,6 +23,9 @@ public class HeartbeatThread extends Thread{
|
||||
this.delegate = delegate;
|
||||
seqNum = 0;
|
||||
disconnectedPlayers = new Stack<>();
|
||||
|
||||
Thread thread = new Thread(this, "HeartBeat");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.net.ServerSocket;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import seng302.gameServer.messages.BoatSubMessage;
|
||||
@@ -20,7 +21,6 @@ import seng302.model.PolarTable;
|
||||
import seng302.model.ServerYacht;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.GameClient;
|
||||
|
||||
/**
|
||||
* A class describing the overall server, which creates and collects server threads for each client
|
||||
@@ -29,12 +29,17 @@ import seng302.visualiser.GameClient;
|
||||
public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
|
||||
private static final int PORT = 4942;
|
||||
private static final Integer CLIENT_UPDATES_PER_SECOND = 10;
|
||||
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;
|
||||
@@ -42,8 +47,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
private ServerSocket serverSocket = null;
|
||||
private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>();
|
||||
|
||||
private GameClient gameClient;
|
||||
|
||||
public MainServerThread() {
|
||||
new GameState("localhost");
|
||||
try {
|
||||
@@ -55,19 +58,15 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
GameState.addMarkPassListener(this::broadcastMessage);
|
||||
terminated = false;
|
||||
thread = new Thread(this, "MainServer");
|
||||
startUpdatingWind();
|
||||
thread.start();
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
ServerListenThread serverListenThread;
|
||||
HeartbeatThread heartbeatThread;
|
||||
|
||||
serverListenThread = new ServerListenThread(serverSocket, this);
|
||||
heartbeatThread = new HeartbeatThread(this);
|
||||
|
||||
heartbeatThread.start();
|
||||
serverListenThread.start();
|
||||
new HeartbeatThread(this);
|
||||
new ServerListenThread(serverSocket, this);
|
||||
|
||||
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
|
||||
while (!terminated) {
|
||||
@@ -121,6 +120,45 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateWind(){
|
||||
Integer direction = GameState.getWindDirection().intValue();
|
||||
Integer windSpeed = GameState.getWindSpeedMMS().intValue();
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
if (Math.floorMod(random.nextInt(), 2) == 0){
|
||||
direction += random.nextInt(4);
|
||||
windSpeed += random.nextInt(100) + 500;
|
||||
}
|
||||
else{
|
||||
direction -= random.nextInt(4);
|
||||
windSpeed -= random.nextInt(100) + 500;
|
||||
}
|
||||
|
||||
direction = Math.floorMod(direction, 360);
|
||||
|
||||
if (windSpeed > MAX_WIND_SPEED){
|
||||
windSpeed -= random.nextInt(1000);
|
||||
}
|
||||
|
||||
if (windSpeed <= MIN_WIND_SPEED){
|
||||
windSpeed += random.nextInt(1000);
|
||||
}
|
||||
|
||||
GameState.setWindSpeed(Double.valueOf(windSpeed));
|
||||
GameState.setWindDirection(direction.doubleValue());
|
||||
}
|
||||
|
||||
private static void startUpdatingWind(){
|
||||
Timer timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateWind();
|
||||
}
|
||||
}, 0, 500);
|
||||
}
|
||||
|
||||
|
||||
static void serverLog(String message, int logLevel) {
|
||||
if (logLevel <= LOG_LEVEL) {
|
||||
@@ -202,7 +240,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
|
||||
for (Player player : GameState.getPlayers()) {
|
||||
ServerYacht y = player.getYacht();
|
||||
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(), 0,
|
||||
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(),
|
||||
y.getLegNumber(),
|
||||
0, 0, 1234L,
|
||||
1234L);
|
||||
boatSubMessages.add(m);
|
||||
@@ -236,25 +275,17 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass GameClient to main server thread so it can access the properties inside.
|
||||
*
|
||||
* @param gameClient gameClient
|
||||
*/
|
||||
public void setGameClient(GameClient gameClient) {
|
||||
this.gameClient = gameClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise boats to specific spaced out geopoints behind starting line.
|
||||
*/
|
||||
private void initialiseBoatPositions() {
|
||||
// Getting the start line compound marks
|
||||
CompoundMark cm = gameClient.getCourseData().getCompoundMarks().get(1);
|
||||
GeoPoint startMark1 = new GeoPoint(cm.getMarks().get(0).getLat(),
|
||||
cm.getMarks().get(0).getLng());
|
||||
GeoPoint startMark2 = new GeoPoint(cm.getMarks().get(1).getLat(),
|
||||
cm.getMarks().get(1).getLng());
|
||||
// if (gameClient== null) {
|
||||
// return;
|
||||
// }
|
||||
CompoundMark cm = GameState.getMarkOrder().getMarkOrder().get(0);
|
||||
GeoPoint startMark1 = cm.getSubMark(1);
|
||||
GeoPoint startMark2 = cm.getSubMark(2);
|
||||
|
||||
// Calculating midpoint
|
||||
Double perpendicularAngle = GeoUtility.getBearing(startMark1, startMark2);
|
||||
|
||||
@@ -8,13 +8,16 @@ import java.net.Socket;
|
||||
* A class for a thread to listen to connections
|
||||
* Created by wmu16 on 11/07/17.
|
||||
*/
|
||||
public class ServerListenThread extends Thread{
|
||||
public class ServerListenThread implements Runnable {
|
||||
private ServerSocket serverSocket;
|
||||
private ClientConnectionDelegate delegate;
|
||||
|
||||
public ServerListenThread(ServerSocket serverSocket, ClientConnectionDelegate delegate){
|
||||
this.serverSocket = serverSocket;
|
||||
this.delegate = delegate;
|
||||
|
||||
Thread thread = new Thread(this, "ServerListen");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ import seng302.gameServer.messages.RegistrationResponseStatus;
|
||||
import seng302.gameServer.messages.XMLMessage;
|
||||
import seng302.gameServer.messages.XMLMessageSubType;
|
||||
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||
import seng302.model.Player;
|
||||
import seng302.model.ServerYacht;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
@@ -37,6 +38,19 @@ 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 seng302.gameServer.messages.BoatAction;
|
||||
import seng302.gameServer.messages.BoatLocationMessage;
|
||||
import seng302.gameServer.messages.BoatSubMessage;
|
||||
import seng302.gameServer.messages.ClientType;
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.gameServer.messages.RaceStatus;
|
||||
import seng302.gameServer.messages.RaceStatusMessage;
|
||||
import seng302.gameServer.messages.RaceType;
|
||||
import seng302.gameServer.messages.RegistrationResponseMessage;
|
||||
import seng302.gameServer.messages.RegistrationResponseStatus;
|
||||
import seng302.gameServer.messages.XMLMessage;
|
||||
import seng302.gameServer.messages.XMLMessageSubType;
|
||||
import seng302.model.ServerYacht;
|
||||
|
||||
/**
|
||||
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
||||
@@ -186,6 +200,7 @@ public class ServerToClientThread implements Runnable, Observer {
|
||||
long computedCrc = checksum.getValue();
|
||||
long packetCrc = Message.bytesToLong(getBytes(4));
|
||||
if (computedCrc == packetCrc) {
|
||||
//System.out.println("RECEIVED A PACKET");
|
||||
switch (PacketType.assignPacketType(type, payload)) {
|
||||
case BOAT_ACTION:
|
||||
BoatAction actionType = ServerPacketParser
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package seng302.gameServer.messages;
|
||||
|
||||
|
||||
/**
|
||||
* Created by kre39 on 20/07/17.
|
||||
*/
|
||||
public class ChatterMessage extends Message {
|
||||
|
||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package seng302.gameServer.messages;
|
||||
|
||||
public class MarkRoundingMessage extends Message{
|
||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||
private final int MESSAGE_SIZE = 21;
|
||||
|
||||
private long time;
|
||||
private long ackNumber;
|
||||
private long raceId;
|
||||
private long sourceId;
|
||||
private RoundingBoatStatus boatStatus;
|
||||
private RoundingSide roundingSide;
|
||||
private long markId;
|
||||
|
||||
|
||||
/**
|
||||
* This message is sent when a boat passes a mark, start line, or finish line
|
||||
* The purpose of this is to record the time when yachts cross marks
|
||||
* @param ackNumber ackNumber
|
||||
* @param raceId raceId
|
||||
* @param sourceId boatSourceId
|
||||
* @param roundingBoatStatus roundingBoatStatus
|
||||
* @param roundingSide roundingSide
|
||||
* @param markId markId
|
||||
*/
|
||||
public MarkRoundingMessage(int ackNumber, int raceId, int sourceId, RoundingBoatStatus roundingBoatStatus,
|
||||
RoundingSide roundingSide, MarkType markType, int markId) {
|
||||
this.time = System.currentTimeMillis();
|
||||
this.ackNumber = ackNumber;
|
||||
this.raceId = raceId;
|
||||
this.sourceId = sourceId;
|
||||
this.boatStatus = roundingBoatStatus;
|
||||
this.roundingSide = roundingSide;
|
||||
this.markId = markId;
|
||||
|
||||
setHeader(new Header(MessageType.MARK_ROUNDING, 1, (short) getSize()));
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
putByte((byte) MESSAGE_VERSION_NUMBER);
|
||||
putInt((int) time, 6);
|
||||
putInt((int) ackNumber, 2);
|
||||
putInt((int) raceId, 4);
|
||||
putInt((int) sourceId, 4);
|
||||
putByte((byte) boatStatus.getCode());
|
||||
putByte((byte) roundingSide.getCode());
|
||||
putByte((byte) markType.getCode());
|
||||
putByte((byte) markId);
|
||||
|
||||
writeCRC();
|
||||
rewind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return MESSAGE_SIZE;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class RaceStatusMessage extends Message{
|
||||
this.raceId = raceId;
|
||||
this.raceStatus = raceStatus;
|
||||
this.expectedStartTime = expectedStartTime;
|
||||
this.raceWindDirection = raceWindDirection * windDirFactor;
|
||||
this.raceWindDirection = raceWindDirection * windDirFactor+100.0;
|
||||
this.windSpeed = windSpeed;
|
||||
this.numBoatsInRace = numBoatsInRace;
|
||||
this.raceType = raceType;
|
||||
|
||||
Reference in New Issue
Block a user