mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Getting boat locations from race simulator & bug fixes
- Boat locations that are generated by the simulator are sent to the client as they happen - Fixed heading and lat/lon encoding - Fixed a bug where the header wasn't included in the sent byte stream - Fixed the format of data as it's sent to the client. - Data is now sent using a channel - Removed tests that don't work with channels Tags: #story[829]
This commit is contained in:
@@ -2,6 +2,9 @@ package seng302.server.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public class BoatLocationMessage extends Message {
|
||||
private final int MESSAGE_SIZE = 56;
|
||||
@@ -11,10 +14,10 @@ public class BoatLocationMessage extends Message {
|
||||
private long sourceId;
|
||||
private long sequenceNum;
|
||||
private DeviceType deviceType;
|
||||
private long latitude;
|
||||
private long longitude;
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private long altitude;
|
||||
private long heading;
|
||||
private Double heading;
|
||||
private long pitch;
|
||||
private long roll;
|
||||
private long boatSpeed;
|
||||
@@ -38,13 +41,13 @@ public class BoatLocationMessage extends Message {
|
||||
* @param heading The boats heading
|
||||
* @param boatSpeed The boats speed
|
||||
*/
|
||||
public BoatLocationMessage(int sourceId, int sequenceNum, long latitude, long longitude, long heading, long boatSpeed){
|
||||
public BoatLocationMessage(int sourceId, int sequenceNum, double latitude, double longitude, double heading, long boatSpeed){
|
||||
messageVersionNumber = 1;
|
||||
time = System.currentTimeMillis() / 1000L;
|
||||
this.sourceId = sourceId;
|
||||
this.sequenceNum = sequenceNum;
|
||||
this.deviceType = DeviceType.RACING_YACHT;
|
||||
this.latitude = -latitude;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.altitude = 0;
|
||||
this.heading = heading;
|
||||
@@ -126,19 +129,23 @@ public class BoatLocationMessage extends Message {
|
||||
|
||||
|
||||
@Override
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException{
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
heading = (heading + 180.0) % 360.0;
|
||||
|
||||
long headingToSend = (long)((heading/360.0)*65535.0);
|
||||
|
||||
putByte((byte) messageVersionNumber);
|
||||
putInt((int) time, 6);
|
||||
putInt(time, 6);
|
||||
putInt((int) sourceId, 4);
|
||||
putUnsignedInt((int) sequenceNum, 4);
|
||||
putByte((byte) deviceType.getCode());
|
||||
putInt((int) latitude, 4);
|
||||
putInt((int) longitude, 4);
|
||||
putInt((int) latLonToBinaryPackedLong(latitude), 4);
|
||||
putInt((int) latLonToBinaryPackedLong(longitude), 4);
|
||||
putInt((int) altitude, 4);
|
||||
putUnsignedInt((int) heading, 2);
|
||||
putInt(headingToSend, 2);
|
||||
putInt((int) pitch, 2);
|
||||
putInt((int) roll, 2);
|
||||
putUnsignedInt((int) boatSpeed, 2);
|
||||
@@ -153,12 +160,9 @@ public class BoatLocationMessage extends Message {
|
||||
putUnsignedInt((int) currentSet, 2);
|
||||
putInt((int) rudderAngle, 2);
|
||||
|
||||
|
||||
writeCRC();
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
System.out.print("");
|
||||
}
|
||||
rewind();
|
||||
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Header {
|
||||
// From API spec
|
||||
@@ -12,6 +15,8 @@ public class Header {
|
||||
private int sourceId;
|
||||
private short messageLength;
|
||||
private static final int MESSAGE_LEN = 15;
|
||||
private ByteBuffer buff;
|
||||
private int buffPos;
|
||||
|
||||
/**
|
||||
* Message Header from section 3.2 of the AC35 Streaming
|
||||
@@ -25,38 +30,34 @@ public class Header {
|
||||
this.sourceId = sourceId;
|
||||
this.messageLength = messageLength;
|
||||
timeStamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
buff = ByteBuffer.allocate(MESSAGE_LEN);
|
||||
buffPos = 0;
|
||||
}
|
||||
|
||||
private void putInBuffer(byte[] bytes, long val){
|
||||
byte[] tmp = bytes.clone();
|
||||
Message.reverse(tmp);
|
||||
|
||||
buff.put(tmp);
|
||||
buffPos += tmp.length;
|
||||
buff.position(buffPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a ByteBuffer containing the message header
|
||||
*/
|
||||
public ByteBuffer getByteBuffer(){
|
||||
ByteBuffer buff = ByteBuffer.allocate(15);
|
||||
putInBuffer(ByteBuffer.allocate(1).put((byte)syncByte1).array(), syncByte1);
|
||||
|
||||
// Sync Byte 1, 1 byte
|
||||
buff.put(ByteBuffer.allocate(1).put((byte)syncByte1).array());
|
||||
buff.position(1);
|
||||
putInBuffer(ByteBuffer.allocate(1).put((byte)syncByte2).array(), syncByte2);
|
||||
|
||||
// Sync Byte 2, 1 byte
|
||||
buff.put(ByteBuffer.allocate(1).put((byte)syncByte2).array());
|
||||
buff.position(2);
|
||||
putInBuffer(ByteBuffer.allocate(1).put((byte)messageType.getCode()).array(), messageType.getCode());
|
||||
|
||||
// Message Type, 1 byte
|
||||
buff.put(ByteBuffer.allocate(1).put((byte)messageType.getCode()).array());
|
||||
buff.position(3);
|
||||
putInBuffer(Message.intToByteArray(timeStamp, 6), timeStamp);
|
||||
|
||||
// Timestamp, 6 bytes
|
||||
int x = ((int) Integer.toUnsignedLong(6));
|
||||
buff.put(ByteBuffer.allocate(6).putInt(timeStamp).array());
|
||||
buff.position(9);
|
||||
putInBuffer(Message.intToByteArray(sourceId, 4), sourceId);
|
||||
|
||||
// Source ID, 4 bytes
|
||||
buff.put(ByteBuffer.allocate(4).putInt(sourceId).array());
|
||||
buff.position(13);
|
||||
|
||||
// Message Length, 2 bytes
|
||||
buff.put(ByteBuffer.allocate(2).putShort(messageLength).array());
|
||||
buff.position(15);
|
||||
putInBuffer(Message.intToByteArray(messageLength, 2), messageLength);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package seng302.server.messages;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
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 {
|
||||
@@ -23,7 +26,7 @@ public class Heartbeat extends Message {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException {
|
||||
setHeader(new Header(MessageType.HEARTBEAT, 0x01, (short) getSize()));
|
||||
|
||||
allocateBuffer();
|
||||
@@ -33,10 +36,6 @@ public class Heartbeat extends Message {
|
||||
|
||||
writeCRC();
|
||||
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package seng302.server.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public class MarkRoundingMessage extends Message{
|
||||
private final long MESSAGE_VERSION_NUMBER = 1;
|
||||
@@ -38,7 +41,7 @@ public class MarkRoundingMessage extends Message{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException {
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
@@ -53,10 +56,6 @@ public class MarkRoundingMessage extends Message{
|
||||
|
||||
writeCRC();
|
||||
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
public abstract class Message {
|
||||
@@ -33,13 +39,14 @@ public abstract class Message {
|
||||
/**
|
||||
* Send the message as through the outputStream
|
||||
*/
|
||||
public abstract void send(DataOutputStream outputStream);
|
||||
public abstract void send(SocketChannel outputStream) throws IOException;
|
||||
|
||||
/**
|
||||
* Allocate byte buffer to correct size
|
||||
*/
|
||||
void allocateBuffer(){
|
||||
buffer = ByteBuffer.allocate(Header.getSize() + getSize() + CRC_SIZE);
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
bufferPosition = 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +54,7 @@ public abstract class Message {
|
||||
* Write the set header to the byte buffer
|
||||
*/
|
||||
void writeHeaderToBuffer(){
|
||||
buffer.put(getHeader().getByteBuffer());
|
||||
buffer.put(getHeader().getByteBuffer().array());
|
||||
bufferPosition += Header.getSize();
|
||||
buffer.position(bufferPosition);
|
||||
}
|
||||
@@ -89,12 +96,15 @@ public abstract class Message {
|
||||
}
|
||||
else if (size < 4){
|
||||
// Use short
|
||||
buffer.put(ByteBuffer.allocate(size).putShort((short) (val & 0xffff)).array());
|
||||
byte[] tmp = Message.intToByteArray(val, size); //ByteBuffer.allocate(size).putShort((short) (val & 0xffff)).array();
|
||||
reverse(tmp);
|
||||
buffer.put(tmp);
|
||||
moveBufferPositionBy(size);
|
||||
}
|
||||
else{
|
||||
// Use int
|
||||
buffer.put(ByteBuffer.allocate(size).putInt((int) (val & 0xffffffffL)).array());
|
||||
byte[] tmp = Message.intToByteArray(val, size);
|
||||
reverse(tmp);
|
||||
moveBufferPositionBy(size);
|
||||
}
|
||||
}
|
||||
@@ -104,12 +114,16 @@ public abstract class Message {
|
||||
* @param val The integer value to add
|
||||
* @param size The size of the integer to be added to the buffer
|
||||
*/
|
||||
void putInt(int val, int size){
|
||||
void putInt(long val, int size){
|
||||
if (size < 4){
|
||||
buffer.put(ByteBuffer.allocate(size).putShort((short) val).array());
|
||||
byte[] tmp = Message.intToByteArray(val, size);
|
||||
reverse(tmp);
|
||||
buffer.put(tmp);
|
||||
}
|
||||
else{
|
||||
buffer.put(ByteBuffer.allocate(size).putInt((short) val).array());
|
||||
byte[] tmp = Message.intToByteArray(val, size);
|
||||
reverse(tmp);
|
||||
buffer.put(tmp);
|
||||
}
|
||||
moveBufferPositionBy(size);
|
||||
}
|
||||
@@ -141,7 +155,9 @@ public abstract class Message {
|
||||
crc = new CRC32();
|
||||
|
||||
buffer.position(0);
|
||||
crc.update(buffer.array());
|
||||
|
||||
byte[] data = Arrays.copyOfRange(buffer.array(), 0, buffer.array().length-CRC_SIZE);
|
||||
crc.update(data);
|
||||
buffer.position(bufferPosition);
|
||||
|
||||
putInt((int) crc.getValue(), CRC_SIZE);
|
||||
@@ -154,4 +170,42 @@ public abstract class Message {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewind the buffer to the beginning
|
||||
*/
|
||||
void rewind(){
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an integer to an array of bytes
|
||||
* @param val The value to add
|
||||
* @param len The width of the integer in the buffer
|
||||
* @return
|
||||
*/
|
||||
public static byte[] intToByteArray(long val, int len){
|
||||
int index = 0;
|
||||
byte[] data = new byte[len];
|
||||
|
||||
for (int i = 0; i < len; i++){
|
||||
data[len - index - 1] = (byte) ((val >>> (8 * index)));
|
||||
index++;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse an array of bytes
|
||||
* @param data The byte[] to reverse
|
||||
*/
|
||||
public static void reverse(byte[] data) {
|
||||
for (int left = 0, right = data.length - 1; left < right; left++, right--) {
|
||||
byte temp = data[left];
|
||||
data[left] = data[right];
|
||||
data[right] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ public enum MessageType {
|
||||
RACE_STATUS(12),
|
||||
DISPLAY_TEXT_MESSAGE(20),
|
||||
XML_MESSAGE(26),
|
||||
RACE_START_STATUS(27),
|
||||
RACE_START_STATUS(20),
|
||||
YACHT_EVENT_CODE(29),
|
||||
YACHT_ACTION_CODE(31),
|
||||
CHATTER_TEXT(36),
|
||||
|
||||
@@ -2,6 +2,9 @@ package seng302.server.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public class RaceStartStatusMessage extends Message {
|
||||
private final int MESSAGE_SIZE = 20;
|
||||
@@ -37,7 +40,7 @@ public class RaceStartStatusMessage extends Message {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException {
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
@@ -50,10 +53,6 @@ public class RaceStartStatusMessage extends Message {
|
||||
|
||||
writeCRC();
|
||||
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package seng302.server.messages;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.List;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
@@ -63,7 +66,7 @@ public class RaceStatusMessage extends Message{
|
||||
* @param outputStream The output stream to send the message
|
||||
*/
|
||||
@Override
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException {
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
@@ -83,11 +86,6 @@ public class RaceStatusMessage extends Message{
|
||||
|
||||
writeCRC();
|
||||
|
||||
// Send
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package seng302.server.messages;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
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{
|
||||
@@ -45,7 +48,7 @@ public class XMLMessage extends Message{
|
||||
* Send this message as a stream of bytes
|
||||
* @param outputStream The output stream to send the message
|
||||
*/
|
||||
public void send(DataOutputStream outputStream) {
|
||||
public void send(SocketChannel outputStream) throws IOException {
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
@@ -60,11 +63,6 @@ public class XMLMessage extends Message{
|
||||
|
||||
writeCRC();
|
||||
|
||||
// Send
|
||||
try {
|
||||
outputStream.write(getBuffer().array());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
outputStream.write(getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user