diff --git a/racevisionGame/src/main/java/network/MessageEncoders/BoatActionEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/BoatActionEncoder.java new file mode 100644 index 00000000..ba5ce901 --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/BoatActionEncoder.java @@ -0,0 +1,40 @@ +package network.MessageEncoders; + + +import network.Messages.AC35Data; +import network.Messages.BoatAction; + +import java.nio.ByteBuffer; + +import static network.Utils.ByteConverter.intToBytes; + +/** + * This encoder can encode a {@link BoatAction} message. + */ +public class BoatActionEncoder implements MessageEncoder { + + + /** + * Constructor. + */ + public BoatActionEncoder() { + } + + + @Override + public byte[] encode(AC35Data message) { + + //Downcast. + BoatAction boatAction = (BoatAction) message; + + //Message is 1 byte. + ByteBuffer boatActionMessage = ByteBuffer.allocate(1); + + boatActionMessage.put(intToBytes(boatAction.getBoatAction(), 1)); + + byte [] result = boatActionMessage.array(); + + return result; + + } +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java b/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java index 620107fa..ebb7814a 100644 --- a/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java +++ b/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java @@ -33,6 +33,8 @@ public class EncoderFactory { case JOIN_ACCEPTANCE: return new JoinAcceptanceEncoder(); + case BOATACTION: return new BoatActionEncoder(); + default: throw new InvalidMessageTypeException("Unrecognised message type: " + type); } diff --git a/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java index 78498457..e3269fba 100644 --- a/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java +++ b/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java @@ -341,12 +341,6 @@ public class RaceVisionByteEncoder { return result.array(); } - public static byte[] boatActionMessage(BoatAction boatAction){ - ByteBuffer boatActionMessage = ByteBuffer.allocate(1); - boatActionMessage.put(intToBytes(boatAction.getBoatAction(), 1)); - byte [] result = boatActionMessage.array(); - return result; - } /** diff --git a/racevisionGame/src/main/java/network/Messages/Enums/BoatActionEnum.java b/racevisionGame/src/main/java/network/Messages/Enums/BoatActionEnum.java index 84f6e0fd..372349f7 100644 --- a/racevisionGame/src/main/java/network/Messages/Enums/BoatActionEnum.java +++ b/racevisionGame/src/main/java/network/Messages/Enums/BoatActionEnum.java @@ -8,6 +8,10 @@ import java.util.Map; */ public enum BoatActionEnum { NOT_A_STATUS(-1), + + /** + * Autopilot = auto VMG. + */ AUTO_PILOT(1), SAILS_IN(2), SAILS_OUT(3), @@ -68,4 +72,4 @@ public enum BoatActionEnum { } } -} \ No newline at end of file +} diff --git a/racevisionGame/src/main/java/visualiser/gameController/ControllerClient.java b/racevisionGame/src/main/java/visualiser/gameController/ControllerClient.java index a0f1af75..6c49cd69 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/ControllerClient.java +++ b/racevisionGame/src/main/java/visualiser/gameController/ControllerClient.java @@ -1,6 +1,7 @@ package visualiser.gameController; import network.BinaryMessageEncoder; +import network.Exceptions.InvalidMessageException; import network.MessageEncoders.RaceVisionByteEncoder; import network.Messages.BoatAction; import network.Messages.Enums.BoatActionEnum; @@ -12,6 +13,8 @@ import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.nio.ByteBuffer; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Basic service for sending key presses to game server @@ -50,18 +53,20 @@ public class ControllerClient { BoatActionEnum protocolCode = key.getProtocolCode(); if(protocolCode != BoatActionEnum.NOT_A_STATUS) { - byte[] bytes = new byte[4]; - ByteBuffer.wrap(bytes).putInt(protocolCode.getValue()); - BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(bytes[3]); + BoatAction boatAction = new BoatAction(protocolCode); - BoatAction boatAction = new BoatAction(boatActionEnum); - - byte[] encodedBoatAction = RaceVisionByteEncoder.boatActionMessage(boatAction); + //Encode BoatAction. + byte[] encodedBoatAction = new byte[0]; + try { + encodedBoatAction = RaceVisionByteEncoder.encode(boatAction); + } catch (InvalidMessageException e) { + Logger.getGlobal().log(Level.WARNING, "Could not encode BoatAction: " + boatAction, e); + } BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0, (short) encodedBoatAction.length, encodedBoatAction); - System.out.println("Sending out key: " + boatActionEnum); + System.out.println("Sending out key: " + protocolCode); outputStream.write(binaryMessage.getFullMessage()); } } diff --git a/racevisionGame/src/test/java/network/MessageDecoders/BoatActionDecoderTest.java b/racevisionGame/src/test/java/network/MessageDecoders/BoatActionDecoderTest.java new file mode 100644 index 00000000..1a16f669 --- /dev/null +++ b/racevisionGame/src/test/java/network/MessageDecoders/BoatActionDecoderTest.java @@ -0,0 +1,109 @@ +package network.MessageDecoders; + +import network.Exceptions.InvalidMessageException; +import network.MessageEncoders.RaceVisionByteEncoder; +import network.Messages.BoatAction; +import network.Messages.Enums.BoatActionEnum; +import network.Messages.Enums.RequestToJoinEnum; +import network.Messages.RequestToJoin; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + + +/** + * Test for the BoatAction encoder and decoder + */ +public class BoatActionDecoderTest { + + + /** + * Encodes and decodes a given message. + * @param message Message to encode/decode. + * @return The decoded message. + */ + private BoatAction encodeDecodeMessage(BoatAction message) throws InvalidMessageException { + + //Encode. + byte [] testEncodedMessage = RaceVisionByteEncoder.encode(message); + + //Decode. + BoatActionDecoder testDecoder = new BoatActionDecoder(testEncodedMessage); + BoatActionEnum decodedBoatAction = testDecoder.getBoatAction(); + + BoatAction decodedMessage = new BoatAction(decodedBoatAction); + + return decodedMessage; + } + + + /** + * Tests if a specific boat action type message can be encoded and decoded correctly. + * @param type The type of boat action. + */ + private void boatActionTypeTest(BoatActionEnum type) throws Exception { + + //Prepare message. + BoatAction beforeMessage = new BoatAction(type); + + + //Encode/decode it. + BoatAction afterMessage = encodeDecodeMessage(beforeMessage); + + + //Compare. + assertEquals(beforeMessage.getBoatAction(), afterMessage.getBoatAction()); + + } + + + /** + * Tests if an autopilot message can be encoded and decoded correctly. + */ + @Test + public void autoPilotTest() throws Exception { + boatActionTypeTest(BoatActionEnum.AUTO_PILOT); + } + + /** + * Tests if a sails in message can be encoded and decoded correctly. + */ + @Test + public void sailsInTest() throws Exception { + boatActionTypeTest(BoatActionEnum.SAILS_IN); + } + + /** + * Tests if a sails out message can be encoded and decoded correctly. + */ + @Test + public void sailsOutTest() throws Exception { + boatActionTypeTest(BoatActionEnum.SAILS_OUT); + } + + /** + * Tests if a tack/gybe message can be encoded and decoded correctly. + */ + @Test + public void tackGybeTest() throws Exception { + boatActionTypeTest(BoatActionEnum.TACK_GYBE); + } + + /** + * Tests if an upwind message can be encoded and decoded correctly. + */ + @Test + public void upwindTest() throws Exception { + boatActionTypeTest(BoatActionEnum.UPWIND); + } + + /** + * Tests if a downwind message can be encoded and decoded correctly. + */ + @Test + public void downwindTest() throws Exception { + boatActionTypeTest(BoatActionEnum.DOWNWIND); + } + + +}