Moved networking code into the network module.

This commit is contained in:
fjc40
2017-04-27 20:28:07 +12:00
parent 06d786d581
commit 50cb31b85f
44 changed files with 139 additions and 0 deletions
@@ -0,0 +1,69 @@
package seng302.Networking;
import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.InputSource;
import seng302.Networking.MessageDecoders.XMLMessageDecoder;
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
import seng302.Networking.Utils.MessageType;
import java.io.*;
/**
* Created by hba56 on 21/04/17.
*/
public class BinaryMessageDecoderTest {
@Test
public void decodeTest(){
try{
StringBuilder xmlString;
BufferedReader br = new BufferedReader(new InputStreamReader(
this.getClass().getResourceAsStream(("../../raceXML/Regatta.xml"))));
String line;
xmlString = new StringBuilder();
while((line=br.readLine())!= null){
xmlString.append(line.trim());
}
long time = System.currentTimeMillis();
XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedMessage = testEncoder.encode();
BinaryMesageEncoder testMessage = new BinaryMesageEncoder(MessageType.XMLMESSAGE, time, 1, (short)encodedMessage.length, encodedMessage);
BinaryMessageDecoder testDecoder = new BinaryMessageDecoder(testMessage.getFullMessage());
testDecoder.decode();
//message length
Assert.assertEquals((short) encodedMessage.length,testDecoder.getMessageLength());
//time stamp
Assert.assertEquals(time,testDecoder.getTimeStamp());
//source ID
Assert.assertEquals((short) 1, testDecoder.getSourceID());
//message type
Assert.assertEquals(26, testDecoder.getMessageType());
XMLMessageDecoder decoderXML = new XMLMessageDecoder(testDecoder.getMessage());
decoderXML.decode();
//tests from seng302.Networking.MessageDecoders.XMLMessageDecoderTest to make sure the file is still good
Assert.assertEquals((byte)1, decoderXML.getMessageVersionNumber());
Assert.assertEquals((short)1, decoderXML.getAckNumber());
Assert.assertEquals(time, decoderXML.getTimeStamp());
Assert.assertEquals((byte)7, decoderXML.getXmlMsgSubType());
Assert.assertEquals((short)1, decoderXML.getSequenceNumber());
Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength());
Reader reader = decoderXML.getXmlMessageInputSource().getCharacterStream();
int c;
String contents = "";
while((c = reader.read()) != -1) {
contents += (char)c;
}
Assert.assertEquals(xmlString.toString(), contents);
}catch (IOException e){
System.out.println(e);
}
}
}
@@ -0,0 +1,165 @@
package seng302.Networking;
import org.junit.Test;
import seng302.Networking.Utils.ByteConverter;
import java.nio.ByteOrder;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Created by fwy13 on 25/04/17.
*/
public class ByteConverterTest {
@Test
public void testLargerIntToByte(){
int int1 = 1532158456; //100 in bytes
byte[] bytes1 = {(byte)0xF8, (byte)0xE1, 0x52, 0x5B};//this is in little endian
assertTrue(testArrayContents(ByteConverter.intToBytes(int1), bytes1));
byte[] bytes2 = {0x5B, 0x52, (byte)0xE1, (byte)0xF8};// this is big endian
assertTrue(testArrayContents(ByteConverter.intToBytes(int1, ByteConverter.IntegerSize, ByteOrder.BIG_ENDIAN), bytes2));
//test chopping
byte[] chopped1 = ByteConverter.intToBytes(int1, 3, ByteOrder.LITTLE_ENDIAN);
byte[] bytes3 = {(byte)0xF8, (byte)0xE1, 0x52};
assertTrue(testArrayContents(chopped1, bytes3));
byte[] chopped2 = ByteConverter.intToBytes(int1, 2, ByteOrder.LITTLE_ENDIAN);
byte[] bytes4 = {(byte)0xF8, (byte)0xE1};
assertTrue(testArrayContents(chopped2, bytes4));
byte[] chopped3 = ByteConverter.intToBytes(int1, 1, ByteOrder.LITTLE_ENDIAN);
byte[] bytes5 = {(byte)0xF8};
assertTrue(testArrayContents(chopped3, bytes5));
byte[] chopped4 = ByteConverter.intToBytes(int1, 3, ByteOrder.BIG_ENDIAN);
byte[] bytes6 = {0x52, (byte)0xE1, (byte)0xF8};
assertTrue(testArrayContents(chopped4, bytes6));
byte[] chopped5 = ByteConverter.intToBytes(int1, 2, ByteOrder.BIG_ENDIAN);
byte[] bytes7 = {(byte)0xE1, (byte)0xF8};
assertTrue(testArrayContents(chopped5, bytes7));
byte[] chopped6 = ByteConverter.intToBytes(int1, 1, ByteOrder.BIG_ENDIAN);
byte[] bytes8 = {(byte)0xF8};
assertTrue(testArrayContents(chopped6, bytes8));
}
@Test
public void testByteToInt(){
int int1 = 100; //100 in bytes
byte[] bytes1 = {100, 0, 0, 0};//this is in little endian
assertTrue(ByteConverter.bytesToInt(bytes1) == int1);
assertTrue(ByteConverter.bytesToInt(bytes1, ByteOrder.LITTLE_ENDIAN) == int1);
byte[] bytes2 = {0, 0, 0, 100};// this is big endian
assertTrue(ByteConverter.bytesToInt(bytes2, ByteOrder.BIG_ENDIAN) == int1);
//check single bytes to integers
assertTrue(ByteConverter.bytesToInt((byte)100) == int1);
}
@Test
public void testByteToLong(){
long lng1 = 15; //100 in bytes
byte[] bytes1 = {15, 0, 0, 0, 0, 0, 0, 0};//this is in little endian
assertTrue(ByteConverter.bytesToLong(bytes1) == lng1);
assertTrue(ByteConverter.bytesToLong(bytes1, ByteOrder.LITTLE_ENDIAN) == lng1);
byte[] bytes2 = {0, 0, 0, 0, 0, 0, 0, 15};// this is big endian
assertTrue(ByteConverter.bytesToLong(bytes2, ByteOrder.BIG_ENDIAN) == lng1);
//check single bytes to integers
assertTrue(ByteConverter.bytesToLong((byte)15) == lng1);
}
@Test
public void testByteToShort(){
short short1 = 20; //100 in bytes
byte[] bytes1 = {20, 0};//this is in little endian
assertTrue(ByteConverter.bytesToShort(bytes1) == short1);
assertTrue(ByteConverter.bytesToShort(bytes1, ByteOrder.LITTLE_ENDIAN) == short1);
byte[] bytes2 = {0, 20};// this is big endian
assertTrue(ByteConverter.bytesToShort(bytes2, ByteOrder.BIG_ENDIAN) == short1);
//check single bytes to integers
assertTrue(ByteConverter.bytesToShort((byte)20) == short1);
}
@Test
public void testByteToChar(){
char char1 = 20; //100 in bytes
byte[] bytes1 = {20, 0};//this is in little endian
assertTrue(ByteConverter.bytesToChar(bytes1) == char1);
assertTrue(ByteConverter.bytesToChar(bytes1, ByteOrder.LITTLE_ENDIAN) == char1);
byte[] bytes2 = {0, 20};// this is big endian
assertTrue(ByteConverter.bytesToChar(bytes2, ByteOrder.BIG_ENDIAN) == char1);
//check single bytes to integers
assertTrue(ByteConverter.bytesToChar((byte)20) == char1);
}
@Test
public void testIntToByte(){
int int1 = 100; //100 in bytes
byte[] bytes1 = {100, 0, 0, 0};//this is in little endian
assertTrue(testArrayContents(ByteConverter.intToBytes(int1), bytes1));
byte[] bytes2 = {0, 0, 0, 100};// this is big endian
assertTrue(testArrayContents(ByteConverter.intToBytes(int1, ByteConverter.IntegerSize, ByteOrder.BIG_ENDIAN), bytes2));
//test chopping
byte[] chopped1 = ByteConverter.intToBytes(int1, 3, ByteOrder.LITTLE_ENDIAN);
byte[] bytes3 = {100, 0, 0};
assertTrue(testArrayContents(chopped1, bytes3));
byte[] chopped2 = ByteConverter.intToBytes(int1, 2, ByteOrder.LITTLE_ENDIAN);
byte[] bytes4 = {100, 0};
assertTrue(testArrayContents(chopped2, bytes4));
byte[] chopped3 = ByteConverter.intToBytes(int1, 1, ByteOrder.LITTLE_ENDIAN);
byte[] bytes5 = {100};
assertTrue(testArrayContents(chopped3, bytes5));
byte[] chopped4 = ByteConverter.intToBytes(int1, 3, ByteOrder.BIG_ENDIAN);
byte[] bytes6 = {0, 0, 100};
assertTrue(testArrayContents(chopped4, bytes6));
byte[] chopped5 = ByteConverter.intToBytes(int1, 2, ByteOrder.BIG_ENDIAN);
byte[] bytes7 = {0, 100};
assertTrue(testArrayContents(chopped5, bytes7));
byte[] chopped6 = ByteConverter.intToBytes(int1, 1, ByteOrder.BIG_ENDIAN);
byte[] bytes8 = {100};
assertTrue(testArrayContents(chopped6, bytes8));
}
@Test
public void testLongToBytes(){
long lng1 = 15; //100 in bytes
byte[] bytes1 = {15, 0, 0, 0, 0, 0, 0, 0};//this is in little endian
assertTrue(testArrayContents(ByteConverter.longToBytes(lng1), bytes1));
byte[] bytes2 = {0, 0, 0, 0, 0, 0, 0, 15};// this is big endian
assertTrue(testArrayContents(ByteConverter.longToBytes(lng1, ByteConverter.LongSize, ByteOrder.BIG_ENDIAN), bytes2));
//test chopping
byte[] chopped1 = ByteConverter.longToBytes(lng1, 3, ByteOrder.LITTLE_ENDIAN);
byte[] bytes3 = {15, 0, 0};
assertTrue(testArrayContents(chopped1, bytes3));
byte[] chopped2 = ByteConverter.longToBytes(lng1, 2, ByteOrder.LITTLE_ENDIAN);
byte[] bytes4 = {15, 0};
assertTrue(testArrayContents(chopped2, bytes4));
byte[] chopped3 = ByteConverter.longToBytes(lng1, 1, ByteOrder.LITTLE_ENDIAN);
byte[] bytes5 = {15};
assertTrue(testArrayContents(chopped3, bytes5));
byte[] chopped4 = ByteConverter.longToBytes(lng1, 3, ByteOrder.BIG_ENDIAN);
byte[] bytes6 = {0, 0, 15};
assertTrue(testArrayContents(chopped4, bytes6));
byte[] chopped5 = ByteConverter.longToBytes(lng1, 2, ByteOrder.BIG_ENDIAN);
byte[] bytes7 = {0, 15};
assertTrue(testArrayContents(chopped5, bytes7));
byte[] chopped6 = ByteConverter.longToBytes(lng1, 1, ByteOrder.BIG_ENDIAN);
byte[] bytes8 = {15};
assertTrue(testArrayContents(chopped6, bytes8));
}
public boolean testArrayContents(byte[] bytes1, byte[] bytes2){
if (bytes1.length != bytes2.length){
return false;
}
for (int i = 0; i < bytes1.length; i++){
if (bytes1[i] != bytes2[i]){
return false;
}
}
return true;
}
}
@@ -0,0 +1,49 @@
package seng302.Networking.MessageDecoders;
import org.junit.Assert;
import org.junit.Test;
import seng302.Networking.Utils.BoatLocationMessage;
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
/**
* Created by hba56 on 23/04/17.
*/
public class BoatLocationDecoderTest {
@Test
public void getByteArrayTest(){
long time = System.currentTimeMillis();
BoatLocationMessage testMessage = new BoatLocationMessage(1, time, 2,
3, 1, 180, -180, 4, 5,
6, 7, 8, 9, 10, 11,
12, 13, 14 , 15,
16, 17, 18);
RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder();
byte [] testEncodedMessage = raceVisionByteEncoder.boatLocation(testMessage);
BoatLocationDecoder testDecoder = new BoatLocationDecoder(testEncodedMessage);
BoatLocationMessage decodedTest = testDecoder.getMessage();
Assert.assertEquals(testMessage.getMessageVersionNumber(), decodedTest.getMessageVersionNumber());
Assert.assertEquals(testMessage.getTime(), decodedTest.getTime());
Assert.assertEquals(testMessage.getSequenceNumber(), decodedTest.getSequenceNumber());
Assert.assertEquals(testMessage.getDeviceType(), decodedTest.getDeviceType());
Assert.assertEquals(testMessage.getLatitude(), decodedTest.getLatitude());
Assert.assertEquals(testMessage.getLongitude(), decodedTest.getLongitude());
Assert.assertEquals(testMessage.getAltitude(), decodedTest.getAltitude());
Assert.assertEquals(testMessage.getHeading(), decodedTest.getHeading());
Assert.assertEquals(testMessage.getPitch(), decodedTest.getPitch());
Assert.assertEquals(testMessage.getRoll(), decodedTest.getRoll());
Assert.assertEquals(testMessage.getBoatSpeed(), decodedTest.getBoatSpeed());
Assert.assertEquals(testMessage.getBoatCOG(), decodedTest.getBoatCOG());
Assert.assertEquals(testMessage.getBoatSOG(), decodedTest.getBoatSOG());
Assert.assertEquals(testMessage.getApparentWindSpeed(), decodedTest.getApparentWindSpeed());
Assert.assertEquals(testMessage.getTrueWindSpeed(), decodedTest.getTrueWindSpeed());
Assert.assertEquals(testMessage.getTrueWindDirection(), decodedTest.getTrueWindDirection());
Assert.assertEquals(testMessage.getTrueWindAngle(), decodedTest.getTrueWindAngle());
Assert.assertEquals(testMessage.getCurrentDrift(), decodedTest.getCurrentDrift());
Assert.assertEquals(testMessage.getCurrentSet(), decodedTest.getCurrentSet());
Assert.assertEquals(testMessage.getRudderAngle(), decodedTest.getRudderAngle());
}
}
@@ -0,0 +1,59 @@
package seng302.Networking.MessageDecoders;
import org.junit.Assert;
import org.junit.Test;
import seng302.Networking.Utils.CourseWind;
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
import java.util.ArrayList;
/**
* Created by hba56 on 23/04/17.
*/
public class CourseWindDecoderTest {
@Test
public void getByteArrayTest(){
long time = System.currentTimeMillis();
CourseWind testCourseWind1 = new CourseWind(1, time, 2,
3, 4, 5,
7, 6);
long time2 = System.currentTimeMillis();
CourseWind testCourseWind2 = new CourseWind(2, time2, 2,
3, 4, 5,
7, 6);
ArrayList<CourseWind> testCourseWinds = new ArrayList<CourseWind>();
testCourseWinds.add(testCourseWind1);
testCourseWinds.add(testCourseWind2);
RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder();
byte[] testEncodedCourseWind = raceVisionByteEncoder.courseWind((byte) 1, testCourseWinds);
CourseWindDecoder testDecoder = new CourseWindDecoder(testEncodedCourseWind);
ArrayList<CourseWind> testDecodedCourseWinds = testDecoder.getLoopMessages();
Assert.assertEquals(testCourseWinds.get(0).getID(), testDecodedCourseWinds.get(0).getID());
Assert.assertEquals(testCourseWinds.get(0).getTime(), testDecodedCourseWinds.get(0).getTime());
Assert.assertEquals(testCourseWinds.get(0).getRaceID(), testDecodedCourseWinds.get(0).getRaceID());
Assert.assertEquals(testCourseWinds.get(0).getWindDirection(), testDecodedCourseWinds.get(0).getWindDirection());
Assert.assertEquals(testCourseWinds.get(0).getWindSpeed(), testDecodedCourseWinds.get(0).getWindSpeed());
Assert.assertEquals(testCourseWinds.get(0).getBestUpwindAngle(), testDecodedCourseWinds.get(0).getBestUpwindAngle());
Assert.assertEquals(testCourseWinds.get(0).getBestDownwindAngle(), testDecodedCourseWinds.get(0).getBestDownwindAngle());
Assert.assertEquals(testCourseWinds.get(0).getFlags(), testDecodedCourseWinds.get(0).getFlags());
Assert.assertEquals(testCourseWinds.get(1).getID(), testDecodedCourseWinds.get(1).getID());
Assert.assertEquals(testCourseWinds.get(1).getTime(), testDecodedCourseWinds.get(1).getTime());
Assert.assertEquals(testCourseWinds.get(1).getRaceID(), testDecodedCourseWinds.get(1).getRaceID());
Assert.assertEquals(testCourseWinds.get(1).getWindDirection(), testDecodedCourseWinds.get(1).getWindDirection());
Assert.assertEquals(testCourseWinds.get(1).getWindSpeed(), testDecodedCourseWinds.get(1).getWindSpeed());
Assert.assertEquals(testCourseWinds.get(1).getBestUpwindAngle(), testDecodedCourseWinds.get(1).getBestUpwindAngle());
Assert.assertEquals(testCourseWinds.get(1).getBestDownwindAngle(), testDecodedCourseWinds.get(1).getBestDownwindAngle());
Assert.assertEquals(testCourseWinds.get(1).getFlags(), testDecodedCourseWinds.get(1).getFlags());
}
}
@@ -0,0 +1,30 @@
package seng302.Networking.MessageDecoders;
import org.junit.Assert;
import org.junit.Test;
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
/**
* Created by hba56 on 23/04/17.
*/
public class RaceStartStatusDecoderTest {
@Test
public void getByteArrayTest(){
long time = System.currentTimeMillis();
RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder();
long time2 = System.currentTimeMillis();
byte[] encodedRaceStartStatus = raceVisionByteEncoder.raceStartStatus(time, (short)1,
time2, 2, (char)3);
RaceStartStatusDecoder testDecoder = new RaceStartStatusDecoder(encodedRaceStartStatus);
Assert.assertEquals(0b1, testDecoder.getMessageVersion());
Assert.assertEquals(time, testDecoder.getTime());
Assert.assertEquals(1, testDecoder.getAck());
Assert.assertEquals(time2, testDecoder.getStartTime());
Assert.assertEquals(2, testDecoder.getRaceID());
Assert.assertEquals((char)3, testDecoder.getNotification());
}
}
@@ -0,0 +1,49 @@
package seng302.Networking.MessageDecoders;
import javafx.scene.paint.Color;
import org.junit.Assert;
import org.junit.Test;
import seng302.Model.BoatInRace;
import seng302.Model.Leg;
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
import java.util.ArrayList;
/**
* Created by hba56 on 23/04/17.
*/
public class RaceStatusDecoderTest {
@Test
public void getByteArrayTest(){
long time = System.currentTimeMillis();
BoatInRace boat1 = new BoatInRace("Test", 1, Color.ALICEBLUE, "tt");
Leg testLeg = new Leg("test leg", 1);
boat1.setCurrentLeg(testLeg);
BoatInRace boat2 = new BoatInRace("Test2", 1, Color.ALICEBLUE, "tt");
boat2.setCurrentLeg(testLeg);
ArrayList boats = new ArrayList();
boats.add(boat1);
boats.add(boat2);
long time2 = System.currentTimeMillis();
RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder();
byte[] encodedRaceStatus = raceVisionByteEncoder.raceStatus(time, 1, 2, time2,
(short)2, (short)3,4, boats);
RaceStatusDecoder decoderTest = new RaceStatusDecoder(encodedRaceStatus);
Assert.assertEquals(0b10, decoderTest.getVersionNum());
Assert.assertEquals(time, decoderTest.getTime());
Assert.assertEquals(1, decoderTest.getRace());
Assert.assertEquals(2, decoderTest.getRaceState());
Assert.assertEquals(time2, decoderTest.getStartTime());
Assert.assertEquals(2, decoderTest.getRaceWindDir());
Assert.assertEquals((short)3, decoderTest.getRaceWindSpeed());
Assert.assertEquals(0, decoderTest.getBoats().get(0).getBoatStatus());
Assert.assertEquals(0, decoderTest.getBoats().get(0).getLegNumber());
Assert.assertEquals(0, decoderTest.getBoats().get(0).getNumPenaltiesAwarded());
}
}
@@ -0,0 +1,55 @@
package seng302.Networking.MessageDecoders;
import org.junit.Assert;
import org.junit.Test;
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
/**
* Created by hba56 on 20/04/17.
*/
public class XMLMessageDecoderTest {
@Test
public void getByteArrayTest(){
try{
StringBuilder xmlString;
BufferedReader br = new BufferedReader(new InputStreamReader(
this.getClass().getResourceAsStream(("../../../raceXML/Regatta.xml"))));
String line;
xmlString = new StringBuilder();
while((line=br.readLine())!= null){
xmlString.append(line.trim());
}
long time = System.currentTimeMillis();
XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedXML = testEncoder.encode();
XMLMessageDecoder decoderXML = new XMLMessageDecoder(encodedXML);
decoderXML.decode();
Assert.assertEquals((byte)1, decoderXML.getMessageVersionNumber());
Assert.assertEquals((short)1, decoderXML.getAckNumber());
Assert.assertEquals(time, decoderXML.getTimeStamp());
Assert.assertEquals((byte)7, decoderXML.getXmlMsgSubType());
Assert.assertEquals((short)1, decoderXML.getSequenceNumber());
Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength());
Reader reader = decoderXML.getXmlMessageInputSource().getCharacterStream();
int c;
String contents = "";
while((c = reader.read()) != -1) {
contents += (char)c;
}
Assert.assertEquals(xmlString.toString(), contents);
}catch (IOException e){
System.out.println(e);
}
}
}
@@ -0,0 +1,55 @@
package seng302.Networking;
import org.junit.Assert;
import org.junit.Test;
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
import java.io.*;
/**
* Created by hba56 on 19/04/17.
*/
public class XMLMessageEncoderTest {
@Test
public void getByteArrayTest(){
StringBuilder xmlString;
try{
BufferedReader br = new BufferedReader(new InputStreamReader(
this.getClass().getResourceAsStream(("../../raceXML/Regatta.xml"))));
String line;
xmlString = new StringBuilder();
while((line=br.readLine())!= null){
xmlString.append(line.trim());
}
XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)xmlString.length(), xmlString.toString());
byte[] encodedXML = testEncoder.encode();
//1 + 2 + 6 + 1 + 2 + 2 + 374
Assert.assertEquals(388, encodedXML.length);
}catch (IOException e){
System.out.println(e);
}
}
@Test
public void getByteArrayNullTest(){
StringBuilder xmlString;
try{
BufferedReader br = new BufferedReader(new InputStreamReader(
this.getClass().getResourceAsStream(("../../raceXML/Regatta.xml"))));
String line;
xmlString = new StringBuilder();
while((line=br.readLine())!= null){
xmlString.append(line.trim());
}
XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)1, xmlString.toString());
byte[] encodedXML = testEncoder.encode();
Assert.assertEquals(null, encodedXML);
}catch (IOException e){
System.out.println(e);
}
}
}
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RegattaConfig>
<RegattaID>1</RegattaID>
<RegattaName>Seng302 Mock Test</RegattaName>
<CourseName>Bermuda AC35</CourseName>
<CentralLatitude>-32.296577</CentralLatitude>
<CentralLongitude>64.854304</CentralLongitude>
<CentralAltitude>0.00</CentralAltitude>
<UtcOffset>-4</UtcOffset>
<MagneticVariation>-14.78</MagneticVariation>
</RegattaConfig>