diff --git a/src/main/java/seng302/server/ClientTransmitterThread.java b/src/main/java/seng302/client/ClientTransmitterThread.java similarity index 92% rename from src/main/java/seng302/server/ClientTransmitterThread.java rename to src/main/java/seng302/client/ClientTransmitterThread.java index 2d15b4d4..69face4d 100644 --- a/src/main/java/seng302/server/ClientTransmitterThread.java +++ b/src/main/java/seng302/client/ClientTransmitterThread.java @@ -1,6 +1,8 @@ -package seng302.server; +package seng302.client; import java.io.IOException; + +import seng302.server.StreamingServerSocket; import seng302.server.messages.BoatActionMessage; /** @@ -8,7 +10,7 @@ import seng302.server.messages.BoatActionMessage; */ public class ClientTransmitterThread implements Runnable { private StreamingServerSocket server; - private final int PORT_NUMBER = 4951; + private final int PORT_NUMBER = 0; private static final int LOG_LEVEL = 1; public ClientTransmitterThread(String threadName){ diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index e07a654c..edb847d0 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -6,11 +6,12 @@ import java.util.ResourceBundle; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; +import javafx.scene.Parent; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import seng302.models.stream.StreamParser; -import seng302.server.ClientTransmitterThread; +import seng302.client.ClientTransmitterThread; import seng302.server.messages.BoatActionMessage; import seng302.server.messages.BoatActionType; @@ -20,28 +21,29 @@ public class Controller implements Initializable { private AnchorPane contentPane; private ClientTransmitterThread clientTransmitterThread; - private void setContentPane(String jfxUrl) { + private Object setContentPane(String jfxUrl) { try { contentPane.getChildren().removeAll(); contentPane.getChildren().clear(); contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - contentPane.getChildren() - .addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); + FXMLLoader fxmlLoader = new FXMLLoader((getClass().getResource(jfxUrl))); + Parent view = fxmlLoader.load(); + contentPane.getChildren().addAll(view); + return fxmlLoader.getController(); } catch (javafx.fxml.LoadException e) { System.err.println(e.getCause()); } catch (IOException e) { System.err.println(e); } + return null; } @Override public void initialize(URL location, ResourceBundle resources) { contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - setContentPane("/views/StartScreenView.fxml"); + StartScreenController startScreenController = (StartScreenController) setContentPane("/views/StartScreenView.fxml"); + startScreenController.setController(this); StreamParser.boatLocations.clear(); - clientTransmitterThread = new ClientTransmitterThread("RaceVision Test Client Transmitter"); - - } /** Handle the key-pressed event from the text field. */ @@ -83,4 +85,8 @@ public class Controller implements Initializable { break; } } + + public void setClientTransmitterThread(ClientTransmitterThread ctt) { + clientTransmitterThread = ctt; + } } diff --git a/src/main/java/seng302/controllers/StartScreenController.java b/src/main/java/seng302/controllers/StartScreenController.java index 146498da..1b219e66 100644 --- a/src/main/java/seng302/controllers/StartScreenController.java +++ b/src/main/java/seng302/controllers/StartScreenController.java @@ -6,6 +6,7 @@ import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; +import seng302.client.ClientTransmitterThread; import seng302.gameServer.GameServerThread; import seng302.gameServer.GameState; import seng302.gameServerWithThreading.MainServerThread; @@ -26,6 +27,8 @@ public class StartScreenController { @FXML private GridPane startScreen2; + private Controller controller; + /** * Loads the fxml content into the parent pane * @param jfxUrl @@ -62,10 +65,10 @@ public class StartScreenController { String ipAddress = InetAddress.getLocalHost().getHostAddress(); new GameState(ipAddress); new MainServerThread().start(); +// new GameServerThread("Fuck you"); // get the lobby controller so that we can pass the game server thread to it setContentPane("/views/LobbyView.fxml"); - } catch (UnknownHostException e) { System.err.println("COULD NOT FIND YOUR IP ADDRESS!"); e.printStackTrace(); @@ -78,7 +81,17 @@ public class StartScreenController { public void connectButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function String ipAddress = ipTextField.getText().trim().toLowerCase(); + //startClientTransmitterThread(); StreamReceiver sr = new StreamReceiver(ipAddress, 4950, "HostStream"); sr.start(); + + } + + public void setController(Controller controller) { + this.controller = controller; + } + + public void startClientTransmitterThread() { + this.controller.setClientTransmitterThread(new ClientTransmitterThread("RaceVision Test Client Transmitter")); } } diff --git a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java index a312b122..a53f6e32 100644 --- a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java +++ b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java @@ -19,7 +19,7 @@ import java.util.concurrent.PriorityBlockingQueue; public class MainServerThread extends Thread implements PacketBufferDelegate{ private static final int PORT = 4950; - private static final Integer MAX_NUM_PLAYERS = 10; + private static final Integer MAX_NUM_PLAYERS = 1; private ServerSocket serverSocket = null; private Socket socket; @@ -72,9 +72,10 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{ } - updateClients(); +// updateClients(); while (!packetBuffer.isEmpty()){ + System.out.println("WHATUPPP"); try { StreamPacket packet = packetBuffer.take(); StreamParser.parsePacket(packet); @@ -84,6 +85,8 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{ } } + System.out.println("WHOOPSIES"); + // TODO: 14/07/17 wmu16 - Send out disconnect packet to clients try { @@ -102,6 +105,7 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{ @Override public boolean addToBuffer(StreamPacket streamPacket) { + System.out.println("HEY HI"); return packetBuffer.add(streamPacket); } } diff --git a/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java b/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java index 9d0d9d11..757dcab2 100644 --- a/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java +++ b/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java @@ -1,13 +1,13 @@ package seng302.gameServerWithThreading; +import seng302.gameServer.GameState; +import seng302.models.Player; import seng302.models.stream.PacketBufferDelegate; +import seng302.models.stream.StreamParser; import seng302.models.stream.packets.StreamPacket; import seng302.server.messages.Message; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.net.Socket; import java.util.zip.CRC32; import java.util.zip.Checksum; @@ -36,6 +36,7 @@ public class ServerToClientThread extends Thread { public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) { this.socket = socket; this.packetBufferDelegate = packetBufferDelegate; + GameState.addPlayer(new Player(socket.getChannel())); } public void run() { @@ -46,7 +47,7 @@ public class ServerToClientThread extends Thread { System.out.println("IO error in server thread upon grabbing streams"); } - threeWayHandshake(); +// threeWayHandshake(); int sync1; int sync2; @@ -63,6 +64,7 @@ public class ServerToClientThread extends Thread { // } updateClient = false; } + crcBuffer = new ByteArrayOutputStream(); sync1 = readByte(); sync2 = readByte(); @@ -79,7 +81,9 @@ public class ServerToClientThread extends Thread { long computedCrc = checksum.getValue(); long packetCrc = Message.bytesToLong(getBytes(4)); if (computedCrc == packetCrc) { - packetBufferDelegate.addToBuffer(new StreamPacket(type, payloadLength, timeStamp, payload)); + 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"); } diff --git a/src/main/java/seng302/models/stream/StreamParser.java b/src/main/java/seng302/models/stream/StreamParser.java index 2f908858..3c7b829c 100644 --- a/src/main/java/seng302/models/stream/StreamParser.java +++ b/src/main/java/seng302/models/stream/StreamParser.java @@ -106,6 +106,8 @@ public class StreamParser{ case AVG_WIND: extractAvgWind(packet); break; + case BOAT_ACTION: + extractBoatAction(packet); default: //TODO: Haoming added something dumb here. System.out.println(packet); @@ -490,6 +492,27 @@ public class StreamParser{ long speed4 = bytesToLong(Arrays.copyOfRange(payload, 21, 23)); } + + private static void extractBoatAction(StreamPacket packet) { + byte[] payload = packet.getPayload(); + int messageVersionNo = payload[0]; + long actionType = bytesToLong(Arrays.copyOfRange(payload, 0, 1)); + if (actionType == 1) { + System.out.println("VMG"); + } else if (actionType == 2) { + System.out.println("SAILS IN"); + } else if (actionType == 3) { + System.out.println("SAILS OUT"); + } else if (actionType == 4) { + System.out.println("TACK/GYBE"); + } else if (actionType == 5) { + System.out.println("UPWIND"); + } else if (actionType == 6) { + System.out.println("DOWNWIND"); + } + + } + /** * takes an array of up to 7 bytes and returns a positive * long constructed from the input bytes diff --git a/src/main/java/seng302/models/stream/StreamReceiver.java b/src/main/java/seng302/models/stream/StreamReceiver.java index b1ddb996..a08b7702 100644 --- a/src/main/java/seng302/models/stream/StreamReceiver.java +++ b/src/main/java/seng302/models/stream/StreamReceiver.java @@ -1,11 +1,15 @@ package seng302.models.stream; import seng302.models.stream.packets.StreamPacket; +import seng302.server.messages.BoatActionMessage; +import seng302.server.messages.BoatActionType; +import seng302.server.messages.Heartbeat; +import seng302.server.messages.Message; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.net.Socket; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; import java.util.Comparator; import java.util.concurrent.PriorityBlockingQueue; import java.util.zip.CRC32; @@ -13,9 +17,10 @@ import java.util.zip.Checksum; public class StreamReceiver extends Thread { - private InputStream stream; + private InputStream inputStream; + private OutputStream outputStream; private Socket host; - private ByteArrayOutputStream crcBuffer; + private ByteArrayOutputStream crcBuffer; private Thread t; private String threadName; public static PriorityBlockingQueue packetBuffer; @@ -59,48 +64,54 @@ public class StreamReceiver extends Thread { public void connect(){ try { - stream = host.getInputStream(); + 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 sync2; - moreBytes = true; - while(moreBytes) { - try { - 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 = bytesToLong(getBytes(6)); - skipBytes(4); - long payloadLength = 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 = bytesToLong(getBytes(4)); - if (computedCrc == packetCrc) { - packetBuffer.add(new StreamPacket(type, payloadLength, timeStamp, payload)); - } else { - System.err.println("Packet has been dropped"); - } - } - } catch (Exception e) { - moreBytes = false; - } - } +// int sync1; +// int sync2; +// moreBytes = true; +// while(moreBytes) { +// try { +// 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 = bytesToLong(getBytes(6)); +// skipBytes(4); +// long payloadLength = 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 = bytesToLong(getBytes(4)); +// if (computedCrc == packetCrc) { +// packetBuffer.add(new StreamPacket(type, payloadLength, timeStamp, payload)); +// } else { +// System.err.println("Packet has been dropped"); +// } +// } +// } catch (Exception e) { +// moreBytes = false; +// } +// } } private int readByte() throws Exception { int currentByte = -1; try { - currentByte = stream.read(); + currentByte = inputStream.read(); crcBuffer.write(currentByte); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/seng302/server/StreamingServerSocket.java b/src/main/java/seng302/server/StreamingServerSocket.java index e6a5d62e..9817f60b 100644 --- a/src/main/java/seng302/server/StreamingServerSocket.java +++ b/src/main/java/seng302/server/StreamingServerSocket.java @@ -13,13 +13,13 @@ import java.nio.channels.WritableByteChannel; import java.util.ArrayList; import java.util.List; -class StreamingServerSocket { +public class StreamingServerSocket { private ServerSocketChannel socket; private SocketChannel client; private short seqNum; private boolean isServerStarted; - StreamingServerSocket(int port) throws IOException{ + public StreamingServerSocket(int port) throws IOException{ socket = ServerSocketChannel.open(); socket.socket().bind(new InetSocketAddress("localhost", port)); //socket.setSoTimeout(10000); @@ -27,7 +27,7 @@ class StreamingServerSocket { isServerStarted = false; } - void start(){ + public void start(){ try { client = socket.accept(); } catch (IOException e) { @@ -41,7 +41,7 @@ class StreamingServerSocket { } } - void send(Message message) throws IOException{ + public void send(Message message) throws IOException{ if (client == null){ return; diff --git a/src/main/java/seng302/server/messages/BoatActionMessage.java b/src/main/java/seng302/server/messages/BoatActionMessage.java index 02aea27c..499f209e 100644 --- a/src/main/java/seng302/server/messages/BoatActionMessage.java +++ b/src/main/java/seng302/server/messages/BoatActionMessage.java @@ -1,6 +1,7 @@ package seng302.server.messages; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; /** @@ -27,7 +28,7 @@ public class BoatActionMessage extends Message{ * @param outputStream The output stream to send the message */ public void send(SocketChannel outputStream) throws IOException { - System.out.println("Sending boat action type: " + actionType.toString()); + System.out.println("[CLIENT] Sending boat action type: " + actionType.toString()); allocateBuffer(); writeHeaderToBuffer(); // Write message fields @@ -37,4 +38,15 @@ public class BoatActionMessage extends Message{ outputStream.write(getBuffer()); } + + + public ByteBuffer stealBuffer() { + allocateBuffer(); + writeHeaderToBuffer(); + // Write message fields + putInt((int) BoatActionType.getBoatPacketType(actionType), 1); + writeCRC(); + rewind(); + return getBuffer(); + } } diff --git a/src/main/java/seng302/server/messages/BoatActionType.java b/src/main/java/seng302/server/messages/BoatActionType.java index ab43eccf..e323b6fe 100644 --- a/src/main/java/seng302/server/messages/BoatActionType.java +++ b/src/main/java/seng302/server/messages/BoatActionType.java @@ -5,12 +5,22 @@ package seng302.server.messages; */ public enum BoatActionType { - VMG, - SAILS_IN, - SAILS_OUT, - TACK_GYBE, - UPWIND, - DOWNWIND; + VMG(1), + SAILS_IN(2), + SAILS_OUT(3), + TACK_GYBE(4), + UPWIND(5), + DOWNWIND(6); + + private int type; + + BoatActionType(int type){ + this.type = type; + } + + public int getType(){ + return this.type; + } public static Short getBoatPacketType(BoatActionType type){ switch (type){ diff --git a/src/main/java/seng302/server/messages/BoatLocationMessage.java b/src/main/java/seng302/server/messages/BoatLocationMessage.java index 5e605170..97d03465 100644 --- a/src/main/java/seng302/server/messages/BoatLocationMessage.java +++ b/src/main/java/seng302/server/messages/BoatLocationMessage.java @@ -1,6 +1,7 @@ package seng302.server.messages; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class BoatLocationMessage extends Message { diff --git a/src/main/resources/views/StartScreenView.fxml b/src/main/resources/views/StartScreenView.fxml index 3990611d..295faef8 100644 --- a/src/main/resources/views/StartScreenView.fxml +++ b/src/main/resources/views/StartScreenView.fxml @@ -34,7 +34,7 @@