mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Upon hosting, and then creating a new instance and connecting to that IP, button transmissions work and print out on server!! :D
Took the send method out of the Message class as it didnt make sense to have it there. This meant taking it out of all subclasses too tags: #story[1055] pair[wmu16, zyt10]
This commit is contained in:
@@ -8,7 +8,6 @@ import javafx.stage.Stage;
|
|||||||
import seng302.models.PolarTable;
|
import seng302.models.PolarTable;
|
||||||
import seng302.models.stream.StreamParser;
|
import seng302.models.stream.StreamParser;
|
||||||
import seng302.models.stream.StreamReceiver;
|
import seng302.models.stream.StreamReceiver;
|
||||||
import seng302.server.ServerThread;
|
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package seng302.client;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
import java.util.zip.Checksum;
|
||||||
|
|
||||||
|
import seng302.models.stream.StreamParser;
|
||||||
|
import seng302.models.stream.packets.StreamPacket;
|
||||||
|
import seng302.server.messages.BoatActionMessage;
|
||||||
|
import seng302.server.messages.BoatActionType;
|
||||||
|
import seng302.server.messages.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kre39 on 13/07/17.
|
||||||
|
*/
|
||||||
|
public class ClientToServerThread extends Thread {
|
||||||
|
private Socket socket;
|
||||||
|
private InputStream is;
|
||||||
|
private OutputStream os;
|
||||||
|
private final int PORT_NUMBER = 0;
|
||||||
|
private static final int LOG_LEVEL = 1;
|
||||||
|
|
||||||
|
private Boolean updateClient = true;
|
||||||
|
private ByteArrayOutputStream crcBuffer;
|
||||||
|
|
||||||
|
public ClientToServerThread(String ipAddress, Integer portNumber){
|
||||||
|
try {
|
||||||
|
socket = new Socket(ipAddress, portNumber);
|
||||||
|
is = socket.getInputStream();
|
||||||
|
os = socket.getOutputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serverLog(String message, int logLevel){
|
||||||
|
if(logLevel <= LOG_LEVEL){
|
||||||
|
System.out.println("[SERVER] " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
int sync1;
|
||||||
|
int sync2;
|
||||||
|
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
//Perform a write if it is time to as delegated by the MainServerThread
|
||||||
|
if (updateClient) {
|
||||||
|
// TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream
|
||||||
|
// try {
|
||||||
|
// GameState.outputState(os);
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// System.out.println("IO error in server thread upon writing to output stream");
|
||||||
|
// }
|
||||||
|
updateClient = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
crcBuffer = new ByteArrayOutputStream();
|
||||||
|
sync1 = readByte();
|
||||||
|
sync2 = readByte();
|
||||||
|
//checking if it is the start of the packet
|
||||||
|
if(sync1 == 0x47 && sync2 == 0x83) {
|
||||||
|
int type = readByte();
|
||||||
|
//No. of milliseconds since Jan 1st 1970
|
||||||
|
long timeStamp = Message.bytesToLong(getBytes(6));
|
||||||
|
skipBytes(4);
|
||||||
|
long payloadLength = Message.bytesToLong(getBytes(2));
|
||||||
|
byte[] payload = getBytes((int) payloadLength);
|
||||||
|
Checksum checksum = new CRC32();
|
||||||
|
checksum.update(crcBuffer.toByteArray(), 0, crcBuffer.size());
|
||||||
|
long computedCrc = checksum.getValue();
|
||||||
|
long packetCrc = Message.bytesToLong(getBytes(4));
|
||||||
|
if (computedCrc == packetCrc) {
|
||||||
|
StreamParser.parsePacket(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
|
// TODO: 17/07/17 wmu16 - Fix this or maybe we dont need to go through the main server at all!?!?
|
||||||
|
// packetBufferDelegate.addToBuffer(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
|
} else {
|
||||||
|
System.err.println("Packet has been dropped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
closeSocket();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the post-start race course information
|
||||||
|
*/
|
||||||
|
public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
|
||||||
|
try {
|
||||||
|
os.write(boatActionMessage.getBuffer());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void closeSocket() {
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("IO error in server thread upon trying to close socket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int readByte() throws Exception {
|
||||||
|
int currentByte = -1;
|
||||||
|
try {
|
||||||
|
currentByte = is.read();
|
||||||
|
crcBuffer.write(currentByte);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (currentByte == -1){
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
return currentByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getBytes(int n) throws Exception{
|
||||||
|
byte[] bytes = new byte[n];
|
||||||
|
for (int i = 0; i < n; i++){
|
||||||
|
bytes[i] = (byte) readByte();
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipBytes(long n) throws Exception{
|
||||||
|
for (int i=0; i < n; i++){
|
||||||
|
readByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package seng302.client;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import seng302.server.StreamingServerSocket;
|
|
||||||
import seng302.server.messages.BoatActionMessage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by kre39 on 13/07/17.
|
|
||||||
*/
|
|
||||||
public class ClientTransmitterThread implements Runnable {
|
|
||||||
private StreamingServerSocket server;
|
|
||||||
private final int PORT_NUMBER = 0;
|
|
||||||
private static final int LOG_LEVEL = 1;
|
|
||||||
|
|
||||||
public ClientTransmitterThread(String threadName){
|
|
||||||
Thread runner = new Thread(this, threadName);
|
|
||||||
runner.setDaemon(true);
|
|
||||||
runner.start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serverLog(String message, int logLevel){
|
|
||||||
if(logLevel <= LOG_LEVEL){
|
|
||||||
System.out.println("[SERVER] " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try{
|
|
||||||
// Needs to connect to the server: Currently no server is being connect so the boat action keys are not being sent
|
|
||||||
server = new StreamingServerSocket(PORT_NUMBER);
|
|
||||||
}
|
|
||||||
catch (IOException e){
|
|
||||||
serverLog("Failed to bind socket: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for client to connect
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the post-start race course information
|
|
||||||
*/
|
|
||||||
public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
|
|
||||||
try {
|
|
||||||
server.send(boatActionMessage);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,9 +9,8 @@ import javafx.fxml.Initializable;
|
|||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.Pane;
|
|
||||||
import seng302.models.stream.StreamParser;
|
import seng302.models.stream.StreamParser;
|
||||||
import seng302.client.ClientTransmitterThread;
|
import seng302.client.ClientToServerThread;
|
||||||
import seng302.server.messages.BoatActionMessage;
|
import seng302.server.messages.BoatActionMessage;
|
||||||
import seng302.server.messages.BoatActionType;
|
import seng302.server.messages.BoatActionType;
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ public class Controller implements Initializable {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private AnchorPane contentPane;
|
private AnchorPane contentPane;
|
||||||
private ClientTransmitterThread clientTransmitterThread;
|
private ClientToServerThread clientToServerThread;
|
||||||
|
|
||||||
private Object setContentPane(String jfxUrl) {
|
private Object setContentPane(String jfxUrl) {
|
||||||
try {
|
try {
|
||||||
@@ -52,19 +51,19 @@ public class Controller implements Initializable {
|
|||||||
switch (e.getCode()){
|
switch (e.getCode()){
|
||||||
case SPACE: // align with vmg
|
case SPACE: // align with vmg
|
||||||
boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
|
boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
|
||||||
clientTransmitterThread.sendBoatActionMessage(boatActionMessage);
|
clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||||
break;
|
break;
|
||||||
case PAGE_UP: // upwind
|
case PAGE_UP: // upwind
|
||||||
boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
|
boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
|
||||||
clientTransmitterThread.sendBoatActionMessage(boatActionMessage);
|
clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||||
break;
|
break;
|
||||||
case PAGE_DOWN: // downwind
|
case PAGE_DOWN: // downwind
|
||||||
boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
|
boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
|
||||||
clientTransmitterThread.sendBoatActionMessage(boatActionMessage);
|
clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||||
break;
|
break;
|
||||||
case ENTER: // tack/gybe
|
case ENTER: // tack/gybe
|
||||||
boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
|
boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
|
||||||
clientTransmitterThread.sendBoatActionMessage(boatActionMessage);
|
clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||||
break;
|
break;
|
||||||
//TODO Allow a zoom in and zoom out methods
|
//TODO Allow a zoom in and zoom out methods
|
||||||
case Z: // zoom in
|
case Z: // zoom in
|
||||||
@@ -81,12 +80,12 @@ public class Controller implements Initializable {
|
|||||||
//TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
|
//TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
|
||||||
case SHIFT: // sails in/sails out
|
case SHIFT: // sails in/sails out
|
||||||
BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
|
BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
|
||||||
clientTransmitterThread.sendBoatActionMessage(boatActionMessage);
|
clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientTransmitterThread(ClientTransmitterThread ctt) {
|
public void setClientToServerThread(ClientToServerThread ctt) {
|
||||||
clientTransmitterThread = ctt;
|
clientToServerThread = ctt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import javafx.scene.control.TextField;
|
|||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import seng302.client.ClientTransmitterThread;
|
import seng302.client.ClientToServerThread;
|
||||||
import seng302.gameServer.GameServerThread;
|
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
import seng302.gameServerWithThreading.MainServerThread;
|
import seng302.gameServerWithThreading.MainServerThread;
|
||||||
import seng302.models.stream.StreamReceiver;
|
import seng302.models.stream.StreamReceiver;
|
||||||
@@ -81,17 +80,13 @@ public class StartScreenController {
|
|||||||
public void connectButtonPressed() {
|
public void connectButtonPressed() {
|
||||||
// TODO: 10/07/17 wmu16 - Finish function
|
// TODO: 10/07/17 wmu16 - Finish function
|
||||||
String ipAddress = ipTextField.getText().trim().toLowerCase();
|
String ipAddress = ipTextField.getText().trim().toLowerCase();
|
||||||
//startClientTransmitterThread();
|
ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, 4950);
|
||||||
StreamReceiver sr = new StreamReceiver(ipAddress, 4950, "HostStream");
|
controller.setClientToServerThread(clientToServerThread);
|
||||||
sr.start();
|
clientToServerThread.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setController(Controller controller) {
|
public void setController(Controller controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startClientTransmitterThread() {
|
|
||||||
this.controller.setClientTransmitterThread(new ClientTransmitterThread("RaceVision Test Client Transmitter"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,14 +306,11 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel
|
|||||||
sendXml();
|
sendXml();
|
||||||
}
|
}
|
||||||
|
|
||||||
void unicast(Message message, SocketChannel client) throws IOException {
|
|
||||||
message.send(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void broadcast(Message message) throws IOException{
|
void broadcast(Message message) throws IOException{
|
||||||
for(Player player : GameState.getPlayers()) {
|
for(Player player : GameState.getPlayers()) {
|
||||||
//System.out.println("Sending message seqNo[" + seqNum + "] to Player: " + player.toString());
|
//heh
|
||||||
message.send(player.getSocketChannel());
|
player.getSocketChannel().socket().getOutputStream().write(message.getBuffer());
|
||||||
}
|
}
|
||||||
seqNum++;
|
seqNum++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,12 @@ public class HeartbeatThread extends Thread{
|
|||||||
if (!player.getSocketChannel().isConnected()){
|
if (!player.getSocketChannel().isConnected()){
|
||||||
playerLostConnection(player);
|
playerLostConnection(player);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
try {
|
// try {
|
||||||
heartbeat.send(player.getSocketChannel());
|
// player.getSocketChannel().socket().getOutputStream().write(heartbeat.getBuffer());
|
||||||
} catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
playerLostConnection(player);
|
// playerLostConnection(player);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDelegate();
|
updateDelegate();
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateClients();
|
updateClients();
|
||||||
|
|
||||||
while (!packetBuffer.isEmpty()){
|
while (!packetBuffer.isEmpty()){
|
||||||
System.out.println("WHATUPPP");
|
System.out.println("WHATUPPP");
|
||||||
|
|||||||
@@ -35,19 +35,18 @@ public class ServerToClientThread extends Thread {
|
|||||||
|
|
||||||
public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) {
|
public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.packetBufferDelegate = packetBufferDelegate;
|
|
||||||
GameState.addPlayer(new Player(socket.getChannel()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try {
|
try {
|
||||||
is = socket.getInputStream();
|
is = socket.getInputStream();
|
||||||
os = socket.getOutputStream();
|
os = socket.getOutputStream();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("IO error in server thread upon grabbing streams");
|
System.out.println("IO error in server thread upon grabbing streams");
|
||||||
}
|
}
|
||||||
|
this.packetBufferDelegate = packetBufferDelegate;
|
||||||
|
// threeWayHandshake();
|
||||||
|
GameState.addPlayer(new Player(socket.getChannel()));
|
||||||
|
}
|
||||||
|
|
||||||
// threeWayHandshake();
|
public void run() {
|
||||||
|
|
||||||
int sync1;
|
int sync1;
|
||||||
int sync2;
|
int sync2;
|
||||||
|
|||||||
@@ -108,9 +108,6 @@ public class StreamParser{
|
|||||||
break;
|
break;
|
||||||
case BOAT_ACTION:
|
case BOAT_ACTION:
|
||||||
extractBoatAction(packet);
|
extractBoatAction(packet);
|
||||||
default:
|
|
||||||
//TODO: Haoming added something dumb here.
|
|
||||||
System.out.println(packet);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
|
|||||||
@@ -63,18 +63,6 @@ public class StreamReceiver extends Thread {
|
|||||||
|
|
||||||
|
|
||||||
public void connect(){
|
public void connect(){
|
||||||
try {
|
|
||||||
inputStream = host.getInputStream();
|
|
||||||
outputStream = host.getOutputStream();
|
|
||||||
BoatActionMessage thisMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
|
|
||||||
ByteBuffer thisBBMessage = thisMessage.stealBuffer();
|
|
||||||
byte[] calumsBuffer = thisBBMessage.array();
|
|
||||||
outputStream.write(thisBBMessage.array());
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// int sync1;
|
// int sync1;
|
||||||
// int sync2;
|
// int sync2;
|
||||||
|
|||||||
@@ -1,332 +0,0 @@
|
|||||||
package seng302.server;
|
|
||||||
|
|
||||||
import seng302.server.messages.*;
|
|
||||||
import seng302.server.simulator.Boat;
|
|
||||||
import seng302.server.simulator.Simulator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class ServerThread implements Runnable, Observer {
|
|
||||||
private StreamingServerSocket server;
|
|
||||||
private long startTime;
|
|
||||||
private boolean raceStarted = false;
|
|
||||||
private Map<Integer,Boolean> boatsFinished = new HashMap<>();
|
|
||||||
private List<Boat> boats;
|
|
||||||
private Simulator raceSimulator;
|
|
||||||
private boolean sendingRaceFinishedLocationMessages = true;
|
|
||||||
|
|
||||||
private final int HEARTBEAT_PERIOD = 5000;
|
|
||||||
private final int RACE_STATUS_PERIOD = 1000/2;
|
|
||||||
private final int RACE_START_STATUS_PERIOD = 1000;
|
|
||||||
private final int BOAT_LOCATION_PERIOD = 1000/5;
|
|
||||||
private final int PORT_NUMBER = 4949;
|
|
||||||
private final int TIME_TILL_RACE_START = 20*1000;
|
|
||||||
private static final int LOG_LEVEL = 1;
|
|
||||||
|
|
||||||
public ServerThread(String threadName){
|
|
||||||
Thread runner = new Thread(this, threadName);
|
|
||||||
runner.setDaemon(true);
|
|
||||||
|
|
||||||
raceSimulator = new Simulator(BOAT_LOCATION_PERIOD);
|
|
||||||
raceSimulator.addObserver(this);
|
|
||||||
// run race simulator, so it can send boats' static location.
|
|
||||||
Thread raceSimulatorThread = new Thread(raceSimulator, "Race Simulator");
|
|
||||||
|
|
||||||
boats = raceSimulator.getBoats();
|
|
||||||
|
|
||||||
for (Boat b : boats){
|
|
||||||
boatsFinished.put(b.getSourceID(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
runner.start();
|
|
||||||
raceSimulatorThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serverLog(String message, int logLevel){
|
|
||||||
if(logLevel <= LOG_LEVEL){
|
|
||||||
System.out.println("[SERVER] " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns an XML Message from the file specified
|
|
||||||
* @param fileName The source XML file
|
|
||||||
* @param type The XML Message type
|
|
||||||
* @return The XML Message
|
|
||||||
*/
|
|
||||||
private Message getXmlMessage(String fileName, XMLMessageSubType type){
|
|
||||||
String fileContents = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
InputStream thisStream = this.getClass().getResourceAsStream(fileName);
|
|
||||||
fileContents = new String(org.apache.commons.io.IOUtils.toByteArray(thisStream));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NullPointerException e){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileContents != null){
|
|
||||||
return new XMLMessage(fileContents, type, server.getSequenceNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Get a race status message for the current race
|
|
||||||
*/
|
|
||||||
private Message getRaceStatusMessage(){
|
|
||||||
List<BoatSubMessage> boatSubMessages = new ArrayList<>();
|
|
||||||
BoatStatus boatStatus;
|
|
||||||
RaceStatus raceStatus;
|
|
||||||
boolean thereAreBoatsNotFinished = false;
|
|
||||||
|
|
||||||
for (Boat b : boats){
|
|
||||||
if (!raceStarted){
|
|
||||||
boatStatus = BoatStatus.PRESTART;
|
|
||||||
thereAreBoatsNotFinished = true;
|
|
||||||
}
|
|
||||||
else if(boatsFinished.get(b.getSourceID())){
|
|
||||||
boatStatus = BoatStatus.FINISHED;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
boatStatus = BoatStatus.PRESTART;
|
|
||||||
thereAreBoatsNotFinished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoatSubMessage m = new BoatSubMessage(b.getSourceID(), boatStatus, b.getLastPassedCorner().getSeqID(), 0, 0, b.getEstimatedTimeTillFinish(), b.getEstimatedTimeTillFinish());
|
|
||||||
boatSubMessages.add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thereAreBoatsNotFinished){
|
|
||||||
if (raceStarted){
|
|
||||||
raceStatus = RaceStatus.STARTED;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
long timeDifference = startTime - currentTime;
|
|
||||||
|
|
||||||
if (timeDifference > 60*3){
|
|
||||||
raceStatus = RaceStatus.PRESTART;
|
|
||||||
}
|
|
||||||
else if (timeDifference > 60){
|
|
||||||
raceStatus = RaceStatus.WARNING;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
raceStatus = RaceStatus.PREPARATORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
raceStatus = RaceStatus.TERMINATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RaceStatusMessage(1, raceStatus, startTime, WindDirection.SOUTH,
|
|
||||||
100, boats.size(), RaceType.MATCH_RACE, 1, boatSubMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an instance of the race simulator
|
|
||||||
*/
|
|
||||||
private void startRaceSim(){
|
|
||||||
// set race started to true, so the simulator will start moving boats
|
|
||||||
raceSimulator.setRaceStarted(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts sending heartbeat messages to the client
|
|
||||||
*/
|
|
||||||
private void startSendingHeartbeats() {
|
|
||||||
Timer t = new Timer();
|
|
||||||
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Message heartbeat = new Heartbeat(server.getSequenceNumber());
|
|
||||||
|
|
||||||
try {
|
|
||||||
server.send(heartbeat);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, HEARTBEAT_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sending race start status messages until race starts
|
|
||||||
*/
|
|
||||||
private void startSendingRaceStartStatusMessages(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Message raceStartStatusMessage = new RaceStartStatusMessage(server.getSequenceNumber(), startTime , 1,
|
|
||||||
RaceStartNotificationType.SET_RACE_START_TIME);
|
|
||||||
try {
|
|
||||||
if (startTime < System.currentTimeMillis() && !raceStarted){
|
|
||||||
startRaceSim();
|
|
||||||
raceStarted = true;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
server.send(raceStartStatusMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, RACE_START_STATUS_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sending race start status messages until race starts
|
|
||||||
*/
|
|
||||||
private void startSendingRaceStatusMessages(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Message raceStatusMessage = getRaceStatusMessage();
|
|
||||||
try {
|
|
||||||
server.send(raceStatusMessage);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, RACE_STATUS_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends the race, boat, and regatta XML files to the client
|
|
||||||
*/
|
|
||||||
private void sendXml(){
|
|
||||||
try{
|
|
||||||
Message raceData = getXmlMessage("/server_config/race.xml", XMLMessageSubType.RACE);
|
|
||||||
Message boatData = getXmlMessage("/server_config/boats.xml", XMLMessageSubType.BOAT);
|
|
||||||
Message regatta = getXmlMessage("/server_config/regatta.xml", XMLMessageSubType.REGATTA);
|
|
||||||
|
|
||||||
if (raceData != null){
|
|
||||||
server.send(raceData);
|
|
||||||
}
|
|
||||||
if (boatData != null){
|
|
||||||
server.send(boatData);
|
|
||||||
}
|
|
||||||
if (regatta != null){
|
|
||||||
server.send(regatta);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
serverLog("Couldn't send an XML Message: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the post-start race course information
|
|
||||||
*/
|
|
||||||
private void sendPostStartCourseXml(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Message raceData = getXmlMessage("/server_config/courseLimits.xml", XMLMessageSubType.RACE);
|
|
||||||
if (raceData != null) {
|
|
||||||
server.send(raceData);
|
|
||||||
}
|
|
||||||
}catch (IOException e) {
|
|
||||||
serverLog("Couldn't send an XML Message: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},25000);
|
|
||||||
//Delays the new course xml data for 25 seconds so the boats are able to pass the starting line
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try{
|
|
||||||
server = new StreamingServerSocket(PORT_NUMBER);
|
|
||||||
}
|
|
||||||
catch (IOException e){
|
|
||||||
serverLog("Failed to bind socket: " + e.getMessage(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for client to connect
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
startTime = System.currentTimeMillis() + TIME_TILL_RACE_START;
|
|
||||||
|
|
||||||
startSendingHeartbeats();
|
|
||||||
sendXml();
|
|
||||||
startSendingRaceStartStatusMessages();
|
|
||||||
startSendingRaceStatusMessages();
|
|
||||||
sendPostStartCourseXml();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start sending static boat position updates when race has finished
|
|
||||||
*/
|
|
||||||
private void startSendingRaceFinishedBoatPositions(){
|
|
||||||
Timer t = new Timer();
|
|
||||||
t.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
for (Boat b : raceSimulator.getBoats()){
|
|
||||||
Message m = new BoatLocationMessage(b.getSourceID(), server.getSequenceNumber(), b.getLat(),
|
|
||||||
b.getLng(), b.getLastPassedCorner().getBearingToNextCorner(),
|
|
||||||
((long) 0));
|
|
||||||
|
|
||||||
server.send(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, BOAT_LOCATION_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a boat location message when they are updated by the simulator
|
|
||||||
* @param o .
|
|
||||||
* @param arg .
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void update(Observable o, Object arg) {
|
|
||||||
// Only send if server started
|
|
||||||
// TODO: I don't understand why i need to check server is null or not ... confused - haoming 2/5/17
|
|
||||||
if(server == null || !server.isStarted()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int numOfBoatsFinished = 0;
|
|
||||||
for (Boat boat : (List<Boat>) arg){
|
|
||||||
try {
|
|
||||||
if (boat.isFinished()) {
|
|
||||||
numOfBoatsFinished ++;
|
|
||||||
if (!boatsFinished.get(boat.getSourceID())) {
|
|
||||||
boatsFinished.put(boat.getSourceID(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message m = new BoatLocationMessage(boat.getSourceID(), 1, boat.getLat(),
|
|
||||||
boat.getLng(), boat.getLastPassedCorner().getBearingToNextCorner(),
|
|
||||||
((long) boat.getSpeed()));
|
|
||||||
server.send(m);
|
|
||||||
} catch (IOException e) {
|
|
||||||
serverLog("Couldn't send a boat status message", 3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (NullPointerException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numOfBoatsFinished == ((List<Boat>) arg).size()) {
|
|
||||||
startSendingRaceFinishedBoatPositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package seng302.server;
|
|
||||||
|
|
||||||
import seng302.server.messages.Message;
|
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.ServerSocketChannel;
|
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class StreamingServerSocket {
|
|
||||||
private ServerSocketChannel socket;
|
|
||||||
private SocketChannel client;
|
|
||||||
private short seqNum;
|
|
||||||
private boolean isServerStarted;
|
|
||||||
|
|
||||||
public StreamingServerSocket(int port) throws IOException{
|
|
||||||
socket = ServerSocketChannel.open();
|
|
||||||
socket.socket().bind(new InetSocketAddress("localhost", port));
|
|
||||||
//socket.setSoTimeout(10000);
|
|
||||||
seqNum = 0;
|
|
||||||
isServerStarted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(){
|
|
||||||
try {
|
|
||||||
client = socket.accept();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.getMessage();
|
|
||||||
}
|
|
||||||
if (client.socket() == null){
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
isServerStarted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(Message message) throws IOException{
|
|
||||||
if (client == null){
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
message.send(client);
|
|
||||||
seqNum++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getSequenceNumber(){
|
|
||||||
return seqNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStarted(){
|
|
||||||
return isServerStarted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by kre39 on 12/07/17.
|
* Created by kre39 on 12/07/17.
|
||||||
@@ -15,6 +15,12 @@ public class BoatActionMessage extends Message{
|
|||||||
public BoatActionMessage(BoatActionType actionType) {
|
public BoatActionMessage(BoatActionType actionType) {
|
||||||
this.actionType = actionType;
|
this.actionType = actionType;
|
||||||
setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id
|
setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
// Write message fields
|
||||||
|
putInt((int) BoatActionType.getBoatPacketType(actionType), 1);
|
||||||
|
writeCRC();
|
||||||
|
rewind();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,30 +29,4 @@ public class BoatActionMessage extends Message{
|
|||||||
return MESSAGE_SIZE;
|
return MESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send this message as a stream of bytes
|
|
||||||
* @param outputStream The output stream to send the message
|
|
||||||
*/
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
System.out.println("[CLIENT] Sending boat action type: " + actionType.toString());
|
|
||||||
allocateBuffer();
|
|
||||||
writeHeaderToBuffer();
|
|
||||||
// Write message fields
|
|
||||||
putInt((int) BoatActionType.getBoatPacketType(actionType), 1);
|
|
||||||
writeCRC();
|
|
||||||
rewind();
|
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ByteBuffer stealBuffer() {
|
|
||||||
allocateBuffer();
|
|
||||||
writeHeaderToBuffer();
|
|
||||||
// Write message fields
|
|
||||||
putInt((int) BoatActionType.getBoatPacketType(actionType), 1);
|
|
||||||
writeCRC();
|
|
||||||
rewind();
|
|
||||||
return getBuffer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
|
|
||||||
public class BoatLocationMessage extends Message {
|
public class BoatLocationMessage extends Message {
|
||||||
private final int MESSAGE_SIZE = 56;
|
private final int MESSAGE_SIZE = 56;
|
||||||
@@ -65,6 +64,36 @@ public class BoatLocationMessage extends Message {
|
|||||||
this.rudderAngle = 0;
|
this.rudderAngle = 0;
|
||||||
|
|
||||||
setHeader(new Header(MessageType.BOAT_LOCATION, 1, (short) getSize()));
|
setHeader(new Header(MessageType.BOAT_LOCATION, 1, (short) getSize()));
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
long headingToSend = (long)((heading/360.0) * 65535.0);
|
||||||
|
|
||||||
|
putByte((byte) messageVersionNumber);
|
||||||
|
putInt(time, 6);
|
||||||
|
putInt((int) sourceId, 4);
|
||||||
|
putUnsignedInt((int) sequenceNum, 4);
|
||||||
|
putByte((byte) deviceType.getCode());
|
||||||
|
putInt((int) latLonToBinaryPackedLong(latitude), 4);
|
||||||
|
putInt((int) latLonToBinaryPackedLong(longitude), 4);
|
||||||
|
putInt((int) altitude, 4);
|
||||||
|
putInt(headingToSend, 2);
|
||||||
|
putInt((int) pitch, 2);
|
||||||
|
putInt((int) roll, 2);
|
||||||
|
putInt((int) boatSpeed, 2);
|
||||||
|
putUnsignedInt((int) COG, 2);
|
||||||
|
putUnsignedInt((int) SOG, 2);
|
||||||
|
putUnsignedInt((int) apparentWindSpeed, 2);
|
||||||
|
putInt((int) apparentWindAngle, 2);
|
||||||
|
putUnsignedInt((int) trueWindSpeed, 2);
|
||||||
|
putUnsignedInt((int) trueWindDirection, 2);
|
||||||
|
putInt((int) trueWindAngle, 2);
|
||||||
|
putUnsignedInt((int) currentDrift, 2);
|
||||||
|
putUnsignedInt((int) currentSet, 2);
|
||||||
|
putInt((int) rudderAngle, 2);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,41 +154,4 @@ public class BoatLocationMessage extends Message {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
return MESSAGE_SIZE;
|
return MESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(SocketChannel outputStream) throws IOException{
|
|
||||||
allocateBuffer();
|
|
||||||
writeHeaderToBuffer();
|
|
||||||
|
|
||||||
long headingToSend = (long)((heading/360.0) * 65535.0);
|
|
||||||
|
|
||||||
putByte((byte) messageVersionNumber);
|
|
||||||
putInt(time, 6);
|
|
||||||
putInt((int) sourceId, 4);
|
|
||||||
putUnsignedInt((int) sequenceNum, 4);
|
|
||||||
putByte((byte) deviceType.getCode());
|
|
||||||
putInt((int) latLonToBinaryPackedLong(latitude), 4);
|
|
||||||
putInt((int) latLonToBinaryPackedLong(longitude), 4);
|
|
||||||
putInt((int) altitude, 4);
|
|
||||||
putInt(headingToSend, 2);
|
|
||||||
putInt((int) pitch, 2);
|
|
||||||
putInt((int) roll, 2);
|
|
||||||
putInt((int) boatSpeed, 2);
|
|
||||||
putUnsignedInt((int) COG, 2);
|
|
||||||
putUnsignedInt((int) SOG, 2);
|
|
||||||
putUnsignedInt((int) apparentWindSpeed, 2);
|
|
||||||
putInt((int) apparentWindAngle, 2);
|
|
||||||
putUnsignedInt((int) trueWindSpeed, 2);
|
|
||||||
putUnsignedInt((int) trueWindDirection, 2);
|
|
||||||
putInt((int) trueWindAngle, 2);
|
|
||||||
putUnsignedInt((int) currentDrift, 2);
|
|
||||||
putUnsignedInt((int) currentSet, 2);
|
|
||||||
putInt((int) rudderAngle, 2);
|
|
||||||
|
|
||||||
writeCRC();
|
|
||||||
rewind();
|
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,16 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
import java.util.zip.CRC32;
|
|
||||||
|
|
||||||
public class Heartbeat extends Message {
|
public class Heartbeat extends Message {
|
||||||
private final int MESSAGE_SIZE = 4;
|
private final int MESSAGE_SIZE = 4;
|
||||||
private int seqNo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Heartbeat from the AC35 Streaming data spec
|
* Heartbeat from the AC35 Streaming data spec
|
||||||
* @param seqNo Increment every time a message is sent
|
* @param seqNo Increment every time a message is sent
|
||||||
*/
|
*/
|
||||||
public Heartbeat(int seqNo){
|
public Heartbeat(int seqNo){
|
||||||
this.seqNo = seqNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSize() {
|
|
||||||
return MESSAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
setHeader(new Header(MessageType.HEARTBEAT, 0x01, (short) getSize()));
|
setHeader(new Header(MessageType.HEARTBEAT, 0x01, (short) getSize()));
|
||||||
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
@@ -36,7 +20,11 @@ public class Heartbeat extends Message {
|
|||||||
|
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.Channels;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
|
|
||||||
public class MarkRoundingMessage extends Message{
|
public class MarkRoundingMessage extends Message{
|
||||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||||
@@ -33,15 +30,6 @@ public class MarkRoundingMessage extends Message{
|
|||||||
this.markId = markId;
|
this.markId = markId;
|
||||||
|
|
||||||
setHeader(new Header(MessageType.MARK_ROUNDING, 1, (short) getSize()));
|
setHeader(new Header(MessageType.MARK_ROUNDING, 1, (short) getSize()));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSize() {
|
|
||||||
return MESSAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
@@ -56,7 +44,10 @@ public class MarkRoundingMessage extends Message{
|
|||||||
|
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
}
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
@@ -33,11 +33,6 @@ public abstract class Message {
|
|||||||
*/
|
*/
|
||||||
public abstract int getSize();
|
public abstract int getSize();
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the message as through the outputStream
|
|
||||||
*/
|
|
||||||
public abstract void send(SocketChannel outputStream) throws IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate byte buffer to correct size
|
* Allocate byte buffer to correct size
|
||||||
*/
|
*/
|
||||||
@@ -162,10 +157,10 @@ public abstract class Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current buffer
|
* @return The current buffer as a byte array
|
||||||
*/
|
*/
|
||||||
public ByteBuffer getBuffer(){
|
public byte[] getBuffer(){
|
||||||
return buffer;
|
return buffer.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.Channels;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
|
|
||||||
public class RaceStartStatusMessage extends Message {
|
public class RaceStartStatusMessage extends Message {
|
||||||
private final int MESSAGE_SIZE = 20;
|
private final int MESSAGE_SIZE = 20;
|
||||||
@@ -32,15 +29,6 @@ public class RaceStartStatusMessage extends Message {
|
|||||||
this.raceId = raceId;
|
this.raceId = raceId;
|
||||||
|
|
||||||
setHeader(new Header(MessageType.RACE_START_STATUS, 1, (short) getSize()));
|
setHeader(new Header(MessageType.RACE_START_STATUS, 1, (short) getSize()));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSize() {
|
|
||||||
return MESSAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
@@ -53,16 +41,11 @@ public class RaceStartStatusMessage extends Message {
|
|||||||
|
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
if (outputStream == null){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
outputStream.write(getBuffer());
|
|
||||||
}
|
|
||||||
catch (IOException e){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.io.OutputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
@@ -47,22 +47,6 @@ public class RaceStatusMessage extends Message{
|
|||||||
crc = new CRC32();
|
crc = new CRC32();
|
||||||
|
|
||||||
setHeader(new Header(MESSAGE_TYPE, (int) sourceId, (short) getSize()));
|
setHeader(new Header(MESSAGE_TYPE, (int) sourceId, (short) getSize()));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the size of this message in bytes
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getSize() {
|
|
||||||
return MESSAGE_BASE_SIZE + (20 * ((int) numBoatsInRace));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send this message as a stream of bytes
|
|
||||||
* @param outputStream The output stream to send the message
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
@@ -82,7 +66,14 @@ public class RaceStatusMessage extends Message{
|
|||||||
|
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the size of this message in bytes
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_BASE_SIZE + (20 * ((int) numBoatsInRace));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
package seng302.server.messages;
|
package seng302.server.messages;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.SocketChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
import java.util.zip.CRC32;
|
|
||||||
|
|
||||||
public class XMLMessage extends Message{
|
public class XMLMessage extends Message{
|
||||||
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
|
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
|
||||||
@@ -35,20 +30,6 @@ public class XMLMessage extends Message{
|
|||||||
sequence = sequenceNum;
|
sequence = sequenceNum;
|
||||||
|
|
||||||
setHeader(new Header(MESSAGE_TYPE, 0x01, (short) getSize()));
|
setHeader(new Header(MESSAGE_TYPE, 0x01, (short) getSize()));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The length of this message
|
|
||||||
*/
|
|
||||||
public int getSize(){
|
|
||||||
return MESSAGE_SIZE + content.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send this message as a stream of bytes
|
|
||||||
* @param outputStream The output stream to send the message
|
|
||||||
*/
|
|
||||||
public void send(SocketChannel outputStream) throws IOException {
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
@@ -63,7 +44,12 @@ public class XMLMessage extends Message{
|
|||||||
|
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
}
|
||||||
|
|
||||||
outputStream.write(getBuffer());
|
/**
|
||||||
|
* @return The length of this message
|
||||||
|
*/
|
||||||
|
public int getSize(){
|
||||||
|
return MESSAGE_SIZE + content.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user