From 5b6b0a99788a02fd6a91ea260507f3da9a400b02 Mon Sep 17 00:00:00 2001 From: hba56 Date: Tue, 29 Aug 2017 12:57:19 +1200 Subject: [PATCH 01/46] added the new program for holding known games #stroy[1188] --- matchBrowser/pom.xml | 82 +++++++++++++++++++ matchBrowser/src/main/java/app/Main.java | 7 ++ .../src/main/java/model/MatchTable.java | 34 ++++++++ .../src/main/java/model/TableKey.java | 30 +++++++ .../java/networkInterface/InInterface.java | 46 +++++++++++ .../java/networkInterface/OutInterface.java | 7 ++ .../src/test/java/model/MatchTableTest.java | 27 ++++++ 7 files changed, 233 insertions(+) create mode 100644 matchBrowser/pom.xml create mode 100644 matchBrowser/src/main/java/app/Main.java create mode 100644 matchBrowser/src/main/java/model/MatchTable.java create mode 100644 matchBrowser/src/main/java/model/TableKey.java create mode 100644 matchBrowser/src/main/java/networkInterface/InInterface.java create mode 100644 matchBrowser/src/main/java/networkInterface/OutInterface.java create mode 100644 matchBrowser/src/test/java/model/MatchTableTest.java diff --git a/matchBrowser/pom.xml b/matchBrowser/pom.xml new file mode 100644 index 00000000..fb8cabe9 --- /dev/null +++ b/matchBrowser/pom.xml @@ -0,0 +1,82 @@ + + + + team-7 + seng302 + 2.0 + + 4.0.0 + + + jar + matchBrowser + matchBrowser + 2.0 + + + + junit + junit + 4.12 + test + + + + + org.mockito + mockito-all + 1.9.5 + + + + org.testng + testng + 6.11 + test + + + + + 1.8 + 1.8 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + + + app.Main + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + package + + shade + + + + + + + + \ No newline at end of file diff --git a/matchBrowser/src/main/java/app/Main.java b/matchBrowser/src/main/java/app/Main.java new file mode 100644 index 00000000..e189c052 --- /dev/null +++ b/matchBrowser/src/main/java/app/Main.java @@ -0,0 +1,7 @@ +package app; + +/** + * Used when starting the matchmaking browser + */ +public class Main { +} diff --git a/matchBrowser/src/main/java/model/MatchTable.java b/matchBrowser/src/main/java/model/MatchTable.java new file mode 100644 index 00000000..d2798939 --- /dev/null +++ b/matchBrowser/src/main/java/model/MatchTable.java @@ -0,0 +1,34 @@ +package model; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Holds a table object that stores current games + */ +public class MatchTable { + private HashMap matchTable; + + public MatchTable() { + this.matchTable = new HashMap(); + } + + public void addEntry(ArrayList newEntry) { + //create a key from the ip and port + TableKey entryKey = new TableKey((String) newEntry.get(0), (Integer) newEntry.get(1)); + + //get the rest of the entry and use it as the value + List entryItems = new ArrayList(); + for(int i = 2; i getMatchTable() { + return matchTable; + } +} diff --git a/matchBrowser/src/main/java/model/TableKey.java b/matchBrowser/src/main/java/model/TableKey.java new file mode 100644 index 00000000..6b803fd9 --- /dev/null +++ b/matchBrowser/src/main/java/model/TableKey.java @@ -0,0 +1,30 @@ +package model; + +/** + * Used to create a key made of an ip and port. + */ +public class TableKey { + + private final String ip; + private final int port; + + public TableKey(String ip, int port) { + this.ip = ip; + this.port = port; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TableKey)) return false; + TableKey key = (TableKey) o; + return ip == key.ip && port == key.port; + } + + @Override + public int hashCode() { + int result = port; + result = 31 * result + ip.hashCode(); + return result; + } +} diff --git a/matchBrowser/src/main/java/networkInterface/InInterface.java b/matchBrowser/src/main/java/networkInterface/InInterface.java new file mode 100644 index 00000000..5d729e08 --- /dev/null +++ b/matchBrowser/src/main/java/networkInterface/InInterface.java @@ -0,0 +1,46 @@ +package networkInterface; + +import java.io.*; +import java.net.*; + +/** + * Holds the output for the network for + */ +public class InInterface { + private DatagramSocket serverSocket; + private byte[] receiveData = new byte[1024]; + private byte[] sendData = new byte[1024]; + + public InInterface(){ + try { + this.serverSocket = new DatagramSocket(3779); + + this.run(); + } catch (IOException e) { + System.err.println("Error listening on port: " + this.serverSocket.getLocalPort() + "."); + System.exit(-1); + } + + } + + private void run() throws IOException{ + while(true) { + DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); + serverSocket.receive(receivePacket); + + //decode and update table + + //client ip and port + InetAddress IPAddress = receivePacket.getAddress(); + int port = receivePacket.getPort(); + + + +// String capitalizedSentence = sentence.toUpperCase(); +// sendData = capitalizedSentence.getBytes(); +// DatagramPacket sendPacket = +// new DatagramPacket(sendData, sendData.length, IPAddress, port); +// serverSocket.send(sendPacket); + } + } +} diff --git a/matchBrowser/src/main/java/networkInterface/OutInterface.java b/matchBrowser/src/main/java/networkInterface/OutInterface.java new file mode 100644 index 00000000..18746004 --- /dev/null +++ b/matchBrowser/src/main/java/networkInterface/OutInterface.java @@ -0,0 +1,7 @@ +package networkInterface; + +/** + * Holds the connection to the network for output + */ +public class OutInterface { +} diff --git a/matchBrowser/src/test/java/model/MatchTableTest.java b/matchBrowser/src/test/java/model/MatchTableTest.java new file mode 100644 index 00000000..6c16cd9e --- /dev/null +++ b/matchBrowser/src/test/java/model/MatchTableTest.java @@ -0,0 +1,27 @@ +package model; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +public class MatchTableTest { + private MatchTable testTable; + + @Before + public void setUp() { + testTable = new MatchTable(); + } + + @Test + public void testTable() { + ArrayList entry = new ArrayList(Arrays.asList("127.0.0.1", 4942, 1, 1, 2, 6, 1)); + + testTable.addEntry(entry); + + assertEquals(testTable.getMatchTable().get(new TableKey("127.0.0.1", 4942)), Arrays.asList(1, 1, 2, 6, 1)); + } +} From cb8e81a7b21f26db913aaee651b1b01b299798f9 Mon Sep 17 00:00:00 2001 From: hba56 Date: Tue, 29 Aug 2017 14:38:42 +1200 Subject: [PATCH 02/46] encoders and decoders for the host game message with datatype and test #story[1188] --- .../HostGameMessageDecoder.java | 63 +++++++++++++++ .../HostGameMessageEncoder.java | 54 +++++++++++++ .../network/Messages/Enums/MessageType.java | 2 + .../main/java/network/Messages/HostGame.java | 79 +++++++++++++++++++ .../HostGameMessageDecoderTest.java | 36 +++++++++ 5 files changed, 234 insertions(+) create mode 100644 racevisionGame/src/main/java/network/MessageDecoders/HostGameMessageDecoder.java create mode 100644 racevisionGame/src/main/java/network/MessageEncoders/HostGameMessageEncoder.java create mode 100644 racevisionGame/src/main/java/network/Messages/HostGame.java create mode 100644 racevisionGame/src/test/java/network/MessageDecoders/HostGameMessageDecoderTest.java diff --git a/racevisionGame/src/main/java/network/MessageDecoders/HostGameMessageDecoder.java b/racevisionGame/src/main/java/network/MessageDecoders/HostGameMessageDecoder.java new file mode 100644 index 00000000..3991b83e --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageDecoders/HostGameMessageDecoder.java @@ -0,0 +1,63 @@ +package network.MessageDecoders; + +import network.Exceptions.InvalidMessageException; +import network.Messages.AC35Data; +import network.Messages.CourseWinds; +import network.Messages.Enums.RaceStatusEnum; +import network.Messages.HostGame; +import network.Messages.RaceStatus; + +import java.util.Arrays; + +import static network.Utils.ByteConverter.bytesToInt; + +public class HostGameMessageDecoder implements MessageDecoder { + + /** + * The encoded message. + */ + private byte[] encodedMessage; + + /** + * The decoded message. + */ + private HostGame message; + + /** + * Constructor + */ + public HostGameMessageDecoder() { + } + + @Override + public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException { + this.encodedMessage = encodedMessage; + + try{ + byte ipPart1 = encodedMessage[0]; + byte ipPart2 = encodedMessage[1]; + byte ipPart3 = encodedMessage[2]; + byte ipPart4 = encodedMessage[3]; + String ipString = ipPart1 + "." + ipPart2 + "." + ipPart3 + "." + ipPart4; +// System.out.println(ipString); + int port = bytesToInt(Arrays.copyOfRange(encodedMessage, 4, 8)); + byte map = encodedMessage[8]; + byte speed = encodedMessage[9]; + byte status = encodedMessage[10]; + byte requiredNumPlayers = encodedMessage[11]; + byte currentNumPlayers = encodedMessage[12]; + + + message = new HostGame(ipString, port, map, + speed, RaceStatusEnum.fromByte(status), + requiredNumPlayers, currentNumPlayers); + + return message; + + } catch (Exception e) { + throw new InvalidMessageException("Could not decode Host game message.", e); + } + } + + +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/HostGameMessageEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/HostGameMessageEncoder.java new file mode 100644 index 00000000..0a5c9a08 --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/HostGameMessageEncoder.java @@ -0,0 +1,54 @@ +package network.MessageEncoders; + +import network.Exceptions.InvalidMessageException; +import network.Messages.AC35Data; +import network.Messages.HostGame; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.List; + +import static network.Utils.ByteConverter.intToBytes; + + +public class HostGameMessageEncoder implements MessageEncoder{ + + /** + * Constructor + */ + public HostGameMessageEncoder() { + } + + @Override + public byte[] encode(AC35Data message) throws InvalidMessageException { + try{ + //Downcast + HostGame hostGame = (HostGame) message; + + ByteBuffer hostGameMessage = ByteBuffer.allocate(14); + + ByteBuffer ipBytes = ByteBuffer.allocate(4); + String ip = hostGame.getIp(); + String[] ipValues = ip.split("\\."); + for(String value:ipValues){ + ipBytes.put(intToBytes(Integer.parseInt(value), 1)[0]); + } + byte raceStatus = hostGame.getStatus().getValue(); + + hostGameMessage.put(ipBytes.array()); + hostGameMessage.put(intToBytes(hostGame.getPort())); + hostGameMessage.put(hostGame.getMap()); + hostGameMessage.put(hostGame.getSpeed()); + hostGameMessage.put(raceStatus); + hostGameMessage.put(hostGame.getRequiredNumPlayers()); + hostGameMessage.put(hostGame.getCurrentNumPlayers()); + + +// System.out.println(hostGameMessage.array()[4]); + return hostGameMessage.array(); + + } catch (Exception e) { + throw new InvalidMessageException("Could not encode Host game message.", e); + } + } +} diff --git a/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java b/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java index aed5d70a..e6cabbe0 100644 --- a/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java +++ b/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java @@ -39,6 +39,8 @@ public enum MessageType { */ ASSIGN_PLAYER_BOAT(121), + HOST_GAME(108), + NOTAMESSAGE(0); diff --git a/racevisionGame/src/main/java/network/Messages/HostGame.java b/racevisionGame/src/main/java/network/Messages/HostGame.java new file mode 100644 index 00000000..d03292fe --- /dev/null +++ b/racevisionGame/src/main/java/network/Messages/HostGame.java @@ -0,0 +1,79 @@ +package network.Messages; + + +import network.Messages.Enums.MessageType; +import network.Messages.Enums.RaceStatusEnum; + +public class HostGame extends AC35Data { + + private String ip; + private int port; + private byte map; + private byte speed; + private RaceStatusEnum status; + private byte requiredNumPlayers; + private byte currentNumPlayers; + + public HostGame(String ip, int port, byte map, byte speed, + RaceStatusEnum status, byte requiredNumPlayers, + byte currentNumPlayers) { + super(MessageType.HOST_GAME); + this.ip = ip; + this.port = port; + this.map = map; + this.speed = speed; + this.status = status; + this.requiredNumPlayers = requiredNumPlayers; + this.currentNumPlayers = currentNumPlayers; + + } + + /** + * @return the ip of host + */ + public String getIp() { + return ip; + } + + /** + * @return the port of host + */ + public int getPort() { + return port; + } + + /** + * @return the map index + */ + public byte getMap() { + return map; + } + + /** + * @return the speed value of game + */ + public byte getSpeed() { + return speed; + } + + /** + * @return the status of race + */ + public RaceStatusEnum getStatus() { + return status; + } + + /** + * @return required number of players + */ + public byte getRequiredNumPlayers() { + return requiredNumPlayers; + } + + /** + * @return current number of players + */ + public byte getCurrentNumPlayers() { + return currentNumPlayers; + } +} diff --git a/racevisionGame/src/test/java/network/MessageDecoders/HostGameMessageDecoderTest.java b/racevisionGame/src/test/java/network/MessageDecoders/HostGameMessageDecoderTest.java new file mode 100644 index 00000000..2d73241d --- /dev/null +++ b/racevisionGame/src/test/java/network/MessageDecoders/HostGameMessageDecoderTest.java @@ -0,0 +1,36 @@ +package network.MessageDecoders; + +import network.MessageEncoders.HostGameMessageEncoder; +import network.Messages.AC35Data; +import network.Messages.Enums.RaceStatusEnum; +import network.Messages.HostGame; +import org.junit.Assert; +import org.junit.Test; + +public class HostGameMessageDecoderTest { + + @Test + public void hostGameMessageDecoderTest() throws Exception { + HostGame testHost = new HostGame("127.0.0.1", 3779, (byte) 1, (byte) 2, RaceStatusEnum.PRESTART, (byte) 6, (byte) 2); + + + HostGameMessageEncoder encoder = new HostGameMessageEncoder(); + + byte[] encodedMessage = encoder.encode(testHost); + + HostGameMessageDecoder decoder = new HostGameMessageDecoder(); + + HostGame decodedTest = (HostGame) decoder.decode(encodedMessage); + + compareHostGameMessage(testHost, decodedTest); + } + + public static void compareHostGameMessage(HostGame original, HostGame decoded) { + Assert.assertEquals(original.getIp(), decoded.getIp()); + Assert.assertEquals(original.getPort(), decoded.getPort()); + Assert.assertEquals(original.getSpeed(), decoded.getSpeed()); + Assert.assertEquals(original.getStatus(), decoded.getStatus()); + Assert.assertEquals(original.getRequiredNumPlayers(), decoded.getRequiredNumPlayers()); + Assert.assertEquals(original.getCurrentNumPlayers(), decoded.getCurrentNumPlayers()); + } +} From ca0a3f2a8b3d1c9b7fbe1d9f0c9a475081c09017 Mon Sep 17 00:00:00 2001 From: hba56 Date: Tue, 29 Aug 2017 15:28:03 +1200 Subject: [PATCH 03/46] encoders and decoders for the hosted games request message with datatype and test #story[1188] --- .../HostedGamesRequestDecoder.java | 34 ++++++++++++++ .../HostedGamesRequestEncoder.java | 44 +++++++++++++++++++ .../network/Messages/Enums/MessageType.java | 2 + .../network/Messages/HostGamesRequest.java | 22 ++++++++++ .../HostedGamesRequestDecoderTest.java | 38 ++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 racevisionGame/src/main/java/network/MessageDecoders/HostedGamesRequestDecoder.java create mode 100644 racevisionGame/src/main/java/network/MessageEncoders/HostedGamesRequestEncoder.java create mode 100644 racevisionGame/src/main/java/network/Messages/HostGamesRequest.java create mode 100644 racevisionGame/src/test/java/network/MessageDecoders/HostedGamesRequestDecoderTest.java diff --git a/racevisionGame/src/main/java/network/MessageDecoders/HostedGamesRequestDecoder.java b/racevisionGame/src/main/java/network/MessageDecoders/HostedGamesRequestDecoder.java new file mode 100644 index 00000000..95f5cf5c --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageDecoders/HostedGamesRequestDecoder.java @@ -0,0 +1,34 @@ +package network.MessageDecoders; + +import network.Exceptions.InvalidMessageException; +import network.Messages.AC35Data; +import network.Messages.HostGame; +import network.Messages.HostGamesRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static network.Utils.ByteConverter.bytesToInt; + +public class HostedGamesRequestDecoder implements MessageDecoder{ + @Override + public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException { + try{ + int numberOfGames = bytesToInt(Arrays.copyOfRange(encodedMessage, 0, 4)); + + HostGameMessageDecoder lineDecoder = new HostGameMessageDecoder(); + List knownGames = new ArrayList<>(); + int byteIndex = 4; + for (int i = 0; i < numberOfGames; i++){ + knownGames.add((HostGame) lineDecoder.decode(Arrays.copyOfRange(encodedMessage, byteIndex, byteIndex+14))); + byteIndex += 14; + } + + return new HostGamesRequest(knownGames); + + } catch (Exception e) { + throw new InvalidMessageException("Could not decode Host game message.", e); + } + } +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/HostedGamesRequestEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/HostedGamesRequestEncoder.java new file mode 100644 index 00000000..4b4b52d1 --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/HostedGamesRequestEncoder.java @@ -0,0 +1,44 @@ +package network.MessageEncoders; + +import network.Exceptions.InvalidMessageException; +import network.Messages.AC35Data; +import network.Messages.HostGame; +import network.Messages.HostGamesRequest; + +import java.nio.ByteBuffer; +import java.util.List; + +import static network.Utils.ByteConverter.intToBytes; + +public class HostedGamesRequestEncoder implements MessageEncoder{ + + /** + * Constructor + */ + public HostedGamesRequestEncoder() { + } + + @Override + public byte[] encode(AC35Data message) throws InvalidMessageException { + try{ + //Downcast + HostGamesRequest hostGamesRequest = (HostGamesRequest) message; + + int numGames = hostGamesRequest.getKnownGames().size(); + + ByteBuffer hostedGamesRequestMessage = ByteBuffer.allocate(4+14*numGames); + + hostedGamesRequestMessage.put(intToBytes(numGames)); + + HostGameMessageEncoder lineEncoder = new HostGameMessageEncoder(); + for (HostGame line: hostGamesRequest.getKnownGames()) { + hostedGamesRequestMessage.put(lineEncoder.encode(line)); + } + + return hostedGamesRequestMessage.array(); + + }catch(Exception e){ + throw new InvalidMessageException("Could not encode Host game message.", e); + } + } +} diff --git a/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java b/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java index e6cabbe0..0941fd08 100644 --- a/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java +++ b/racevisionGame/src/main/java/network/Messages/Enums/MessageType.java @@ -41,6 +41,8 @@ public enum MessageType { HOST_GAME(108), + HOSTED_GAMES_REQUEST(109), + NOTAMESSAGE(0); diff --git a/racevisionGame/src/main/java/network/Messages/HostGamesRequest.java b/racevisionGame/src/main/java/network/Messages/HostGamesRequest.java new file mode 100644 index 00000000..4ecfc2d2 --- /dev/null +++ b/racevisionGame/src/main/java/network/Messages/HostGamesRequest.java @@ -0,0 +1,22 @@ +package network.Messages; + +import network.Messages.Enums.MessageType; + +import java.util.List; + +public class HostGamesRequest extends AC35Data{ + + private List knownGames; + + /** + * Constructor + */ + public HostGamesRequest(List knownGames) { + super(MessageType.HOSTED_GAMES_REQUEST); + this.knownGames = knownGames; + } + + public List getKnownGames() { + return knownGames; + } +} diff --git a/racevisionGame/src/test/java/network/MessageDecoders/HostedGamesRequestDecoderTest.java b/racevisionGame/src/test/java/network/MessageDecoders/HostedGamesRequestDecoderTest.java new file mode 100644 index 00000000..7567fe23 --- /dev/null +++ b/racevisionGame/src/test/java/network/MessageDecoders/HostedGamesRequestDecoderTest.java @@ -0,0 +1,38 @@ +package network.MessageDecoders; + + +import network.MessageEncoders.HostGameMessageEncoder; +import network.MessageEncoders.HostedGamesRequestEncoder; +import network.Messages.Enums.RaceStatusEnum; +import network.Messages.HostGame; +import network.Messages.HostGamesRequest; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +public class HostedGamesRequestDecoderTest { + @Test + public void hostGamesRequestMessageDecoderTest() throws Exception { + HostGame testHostGame1 = new HostGame("127.0.0.1", 3779, (byte) 1, (byte) 2, RaceStatusEnum.PRESTART, (byte) 6, (byte) 2); + HostGame testHostGame2 = new HostGame("127.0.0.1", 3780, (byte) 1, (byte) 2, RaceStatusEnum.PRESTART, (byte) 6, (byte) 2); + + List knownGames = Arrays.asList(testHostGame1, testHostGame2); + + HostedGamesRequestEncoder encoder = new HostedGamesRequestEncoder(); + + byte[] encodedMessage = encoder.encode(new HostGamesRequest(knownGames)); + + HostedGamesRequestDecoder decoder = new HostedGamesRequestDecoder(); + + HostGamesRequest decodedTest = (HostGamesRequest) decoder.decode(encodedMessage); + + compareHostGamesRequestMessage(knownGames, decodedTest.getKnownGames()); + } + + public static void compareHostGamesRequestMessage(List original, List decoded) { + Assert.assertEquals(original.get(0).getIp(), decoded.get(0).getIp()); + Assert.assertEquals(original.get(1).getPort(), decoded.get(1).getPort()); + } +} From 88782182d7b7b373a188e13e26e732b81ae5d7dc Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 30 Aug 2017 11:39:41 +1200 Subject: [PATCH 04/46] Player panes and spectator list now call method on click. Will later be used for players to choose whether they want to play or spectate. #story[1188] --- .../visualiser/Controllers/HostController.java | 8 ++++++++ .../resources/visualiser/scenes/hostlobby.fxml | 14 +++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 22c76426..9f96ad55 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -119,4 +119,12 @@ public class HostController extends Controller { System.out.println("Should start the race. This button is only visible for the host"); } + public void joinSpecPressed(){ + System.out.println("Spectator list pressed. Joining spectators"); + } + + public void joinRacePressed(){ + System.out.println("Empty race user pane pressed. Joining racers"); + } + } diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml index aed6664b..443aa548 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml @@ -44,7 +44,7 @@ - + @@ -60,7 +60,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -92,7 +92,7 @@ - + @@ -108,7 +108,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -164,7 +164,7 @@ - + From d2f0c1105a5cd6db1632d824f578b38a770d72e0 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 30 Aug 2017 11:52:45 +1200 Subject: [PATCH 05/46] Merged 3d branch. Added 3d item to one of the player pane. #story[1188] --- .../main/java/visualiser/Controllers/HostController.java | 7 ++++++- .../src/main/resources/visualiser/scenes/hostlobby.fxml | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 53be0471..2d9605e4 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -7,6 +7,7 @@ import javafx.scene.control.SplitPane; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import mock.app.Event; import mock.exceptions.EventConstructionException; import visualiser.model.View3D; @@ -49,6 +50,9 @@ public class HostController extends Controller { @FXML GridPane playerContainer; + @FXML + private Pane playerPane; + private Event game; private View3D fancyStuff; @@ -56,7 +60,8 @@ public class HostController extends Controller { @Override public void initialize(URL location, ResourceBundle resources) { fancyStuff = new View3D(); - playerContainer.add(fancyStuff, 0,0); + playerPane.getChildren().add(fancyStuff); + //playerContainer.add(fancyStuff, 0,0); fancyStuff.spinBox(); } diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml index 77e0ad15..045ff98d 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml @@ -46,7 +46,7 @@ - + From 028428da2c60c8dd4dc8b9f251374955eb713519 Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 30 Aug 2017 12:04:17 +1200 Subject: [PATCH 06/46] Fixed fxml issues due to merge. Added pane centering for panes. #story[1188] --- .../visualiser/Controllers/HostController.java | 10 +++++++++- .../resources/visualiser/scenes/hostlobby.fxml | 15 ++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 2d9605e4..506e6c15 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -53,6 +53,9 @@ public class HostController extends Controller { @FXML private Pane playerPane; + @FXML + private Pane playerPane4; + private Event game; private View3D fancyStuff; @@ -60,8 +63,13 @@ public class HostController extends Controller { @Override public void initialize(URL location, ResourceBundle resources) { fancyStuff = new View3D(); - playerPane.getChildren().add(fancyStuff); + playerPane4.getChildren().add(fancyStuff); + + //centering the 3d object + fancyStuff.layoutXProperty().bind(playerPane4.widthProperty().subtract(fancyStuff.widthProperty()).divide(2)); + fancyStuff.layoutYProperty().bind(playerPane4.heightProperty().subtract(fancyStuff.heightProperty()).divide(2)); //playerContainer.add(fancyStuff, 0,0); + fancyStuff.spinBox(); } diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml index 045ff98d..24aedebc 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml @@ -94,7 +94,7 @@ - + @@ -145,7 +145,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml index ab14abaf..901cd255 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml @@ -1,44 +1,40 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - diff --git a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml index 7aff44c0..f6ebbab4 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml @@ -7,8 +7,9 @@ - + + From ddc3a6ae4759d494c308081d6cebe9078fabe508 Mon Sep 17 00:00:00 2001 From: hba56 Date: Sat, 9 Sep 2017 16:26:17 +1200 Subject: [PATCH 20/46] boxes in lobby are now boats --- .../src/main/java/shared/model/Constants.java | 2 +- .../Controllers/InGameLobbyController.java | 14 +- .../main/java/visualiser/layout/View3D.java | 259 +++++++++++++++++- 3 files changed, 269 insertions(+), 6 deletions(-) diff --git a/racevisionGame/src/main/java/shared/model/Constants.java b/racevisionGame/src/main/java/shared/model/Constants.java index 18a2aaed..54a4e264 100644 --- a/racevisionGame/src/main/java/shared/model/Constants.java +++ b/racevisionGame/src/main/java/shared/model/Constants.java @@ -46,7 +46,7 @@ public class Constants { * The race preparatory time, in milliseconds. 1 minute. */ // public static final long RacePreparatoryTime = 60 * 1000; - public static final long RacePreparatoryTime = 3 * 1000; + public static final long RacePreparatoryTime = 1* 60 * 1000; diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index 9f152728..e2f0f787 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -1,5 +1,6 @@ package visualiser.Controllers; +import com.interactivemesh.jfx.importer.stl.StlMeshImporter; import javafx.animation.AnimationTimer; import javafx.application.Platform; import javafx.collections.FXCollections; @@ -12,6 +13,7 @@ import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.shape.Box; +import javafx.scene.shape.MeshView; import mock.app.Event; import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RequestToJoinEnum; @@ -78,6 +80,8 @@ public class InGameLobbyController extends Controller { private ObservableList subjects = FXCollections.observableArrayList(); + private StlMeshImporter importer; + @Override public void initialize(URL location, ResourceBundle resources) { allPlayerLabels = new ArrayList(Arrays.asList(playerLabel, playerLabel2, @@ -85,6 +89,10 @@ public class InGameLobbyController extends Controller { playerLabel4, playerLabel5, playerLabel6)); + + URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl"); + importer = new StlMeshImporter(); + importer.read(asset); } private void populatePlayers(ListChangeListener.Change change){ @@ -98,10 +106,12 @@ public class InGameLobbyController extends Controller { for (VisualiserBoat boat :this.visualiserRaceEvent.getVisualiserRaceState().getBoats()) { View3D playerBoatToSet = new View3D(); playerBoatToSet.setItems(subjects); + playerContainer.add(playerBoatToSet, (count % 3) , row); playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10)); - Subject3D subject = new Subject3D(new Box()); + MeshView mesh = new MeshView(importer.getImport()); + Subject3D subject = new Subject3D(mesh); subjects.add(subject); playerBoatToSet.setDistance(50); @@ -113,7 +123,7 @@ public class InGameLobbyController extends Controller { AnimationTimer rotate = new AnimationTimer() { @Override public void handle(long now) { - subject.setHeading(subject.getHeading() + 0.1); + subject.setHeading(subject.getHeading().getAngle() + 0.1); } }; rotate.start(); diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index e7635498..6b5db309 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -1,7 +1,260 @@ package visualiser.layout; +import javafx.beans.value.ChangeListener; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.scene.Group; +import javafx.scene.PerspectiveCamera; +import javafx.scene.SubScene; +import javafx.scene.input.PickResult; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Shape3D; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; + +import java.util.HashMap; +import java.util.Map; + /** - * Created by hba56 on 9/09/17. + * Control for rendering 3D objects visible through a PerspectiveCamera. Implements Adapter Pattern to + * interface with camera, and allows clients to add shapes to the scene. All scenes contain sea plane and + * sky box, whose textures are set with special methods. */ -public class View3D { -} +public class View3D extends Pane { + /** + * Container for group and camera + */ + private SubScene scene; + /** + * Observable list of renderable items + */ + private ObservableList items; + /** + * Map for selecting Subject3D from Shape3D + */ + private Map selectionMap; + /** + * Subject tracked by camera + */ + private Subject3D target; + /** + * Rendering container for shapes + */ + private Group world; + /** + * Near limit of view frustum + */ + private double nearClip; + /** + * Far limit of view frustum + */ + private double farClip; + /** + * Camera origin + */ + private Translate pivot; + /** + * Distance of camera from pivot point + */ + private Translate distance; + /** + * Angle along ground between z-axis and camera + */ + private Rotate yaw; + /** + * Angle between ground plane and camera direction + */ + private Rotate pitch; + /** + * Single listener for subject heading changes + */ + private ChangeListener pivotHeading = (o, prev, curr) -> yaw.setAngle((double)curr); + /** + * Single listener for subject position (x) changes + */ + private ChangeListener pivotX = (o, prev, curr) -> pivot.setX((double)curr); + /** + * Single listener for subject position (y) changes + */ + private ChangeListener pivotY = (o, prev, curr) -> pivot.setY((double)curr); + /** + * Single listener for subject position (z) changes + */ + private ChangeListener pivotZ = (o, prev, curr) -> pivot.setZ((double)curr); + /** + * Distance to switch from third person to bird's eye + */ + private double THIRD_PERSON_LIMIT = 100; + + /** + * Default constructor for View3D. Sets up Scene and PerspectiveCamera. + */ + public View3D() { + this.world = new Group(); + this.selectionMap = new HashMap<>(); + this.target = null; + this.scene = new SubScene(world, 300, 300); + + scene.widthProperty().bind(this.widthProperty()); + scene.heightProperty().bind(this.heightProperty()); + scene.setFill(new Color(0.2, 0.6, 1, 1)); + + scene.setCamera(buildCamera()); + + this.getChildren().add(scene); + } + + /** + * Sets up camera view frustum and binds transformations + * @return perspective camera + */ + private PerspectiveCamera buildCamera() { + PerspectiveCamera camera = new PerspectiveCamera(true); + + // Set up view frustum + nearClip = 0.1; + farClip = 3000.0; + camera.setNearClip(nearClip); + camera.setFarClip(farClip); + + // Set up transformations + pivot = new Translate(); + distance = new Translate(); + yaw = new Rotate(0, Rotate.Y_AXIS); + pitch = new Rotate(0, Rotate.X_AXIS); + camera.getTransforms().addAll(pivot, yaw, pitch, distance); + + return camera; + } + + /** + * Provide the list of subjects to be automatically added or removed from the view as the list + * changes. + * @param items list managed by client + */ + public void setItems(ObservableList items) { + this.items = items; + this.items.addListener((ListChangeListener) c -> { + while(c.next()) { + if (c.wasRemoved() || c.wasAdded()) { + for (Subject3D shape : c.getRemoved()) { + world.getChildren().remove(shape.getMesh()); + selectionMap.remove(shape.getMesh()); + } + for (Subject3D shape : c.getAddedSubList()) { + world.getChildren().add(shape.getMesh()); + selectionMap.put(shape.getMesh(), shape); + } + } + } + }); + } + + /** + * Intercept mouse clicks on subjects in view. The applied listener cannot be removed. + */ + public void enableTracking() { + scene.setOnMousePressed(e -> { + PickResult result = e.getPickResult(); + if(result != null && result.getIntersectedNode() != null && result.getIntersectedNode() instanceof Shape3D) { + trackSubject(selectionMap.get(result.getIntersectedNode())); + } + }); + } + + /** + * Stop camera from following the last selected subject + */ + private void untrackSubject() { + if(target != null) { + target.getPosition().xProperty().removeListener(pivotX); + target.getPosition().yProperty().removeListener(pivotY); + target.getPosition().zProperty().removeListener(pivotZ); + target.getHeading().angleProperty().removeListener(pivotHeading); + } + } + + /** + * Set camera to follow the selected subject + * @param subject to track + */ + private void trackSubject(Subject3D subject) { + untrackSubject(); + target = subject; + + updatePivot(target.getPosition()); + setYaw(target.getHeading().getAngle()); + + target.getPosition().xProperty().addListener(pivotX); + target.getPosition().yProperty().addListener(pivotY); + target.getPosition().zProperty().addListener(pivotZ); + target.getHeading().angleProperty().addListener(pivotHeading); + + this.setDistance(THIRD_PERSON_LIMIT); + this.setPitch(20); + } + + public void setNearClip(double nearClip) { + this.nearClip = nearClip; + } + + public void setFarClip(double farClip) { + this.farClip = farClip; + } + + /** + * Sets the coordinates of the camera pivot once. + * @param pivot source of coordinates + */ + public void updatePivot(Translate pivot) { + this.pivot.setX(pivot.getX()); + this.pivot.setY(pivot.getY()); + this.pivot.setZ(pivot.getZ()); + } + + /** + * Set distance of camera from pivot + * @param distance in units + */ + public void setDistance(double distance) { + this.distance.setZ(-distance); + } + + /** + * Adds delta to current distance and changes camera mode if applicable. + * Third person limit specifies the distance at which a third person camera + * switches to bird's-eye, remaining focused on the same position. + * @param delta amount to change distance by + */ + public void updateDistance(double delta) { + double distance = -this.distance.getZ() + delta; + + if(distance <= 0) { + this.setDistance(0); + } else if(distance > THIRD_PERSON_LIMIT) { + untrackSubject(); + this.setYaw(0); + this.setPitch(60); + this.setDistance(distance); + } else { + this.setDistance(distance); + } + } + + /** + * Set angle of camera from z-axis along ground + * @param yaw in degrees + */ + public void setYaw(double yaw) { + this.yaw.setAngle(yaw); + } + + /** + * Set elevation of camera + * @param pitch in degrees + */ + public void setPitch(double pitch) { + this.pitch.setAngle(-pitch); + } +} \ No newline at end of file From d92410b9b4560db786fc0f86e40a2633f821a164 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 11 Sep 2017 18:14:26 +1200 Subject: [PATCH 21/46] Fixed XML Issue where sometimes the last boat would not display itself #story[1188] --- racevisionGame/src/main/java/mock/app/MockOutput.java | 2 -- racevisionGame/src/main/java/mock/model/MockRace.java | 1 + racevisionGame/src/main/java/mock/model/RaceServer.java | 9 +++++++++ .../src/main/java/network/Messages/LatestMessages.java | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/racevisionGame/src/main/java/mock/app/MockOutput.java b/racevisionGame/src/main/java/mock/app/MockOutput.java index 023235cc..198dcc3f 100644 --- a/racevisionGame/src/main/java/mock/app/MockOutput.java +++ b/racevisionGame/src/main/java/mock/app/MockOutput.java @@ -60,7 +60,6 @@ public class MockOutput implements RunnableWithFramePeriod { try { Thread.sleep(500); - } catch (InterruptedException e) { //If we get interrupted, exit the function. Logger.getGlobal().log(Level.WARNING, "MockOutput.run().sleep(waitForXMLs) was interrupted on thread: " + Thread.currentThread(), e); @@ -72,7 +71,6 @@ public class MockOutput implements RunnableWithFramePeriod { } } - long previousFrameTime = System.currentTimeMillis(); diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index a9f11770..05444f6f 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -126,6 +126,7 @@ public class MockRace extends RaceState { this.boats.add(mockBoat); getRaceDataSource().incrementSequenceNumber(); + } /** diff --git a/racevisionGame/src/main/java/mock/model/RaceServer.java b/racevisionGame/src/main/java/mock/model/RaceServer.java index b7ccef12..31c9aea0 100644 --- a/racevisionGame/src/main/java/mock/model/RaceServer.java +++ b/racevisionGame/src/main/java/mock/model/RaceServer.java @@ -21,6 +21,8 @@ import java.util.logging.Logger; * Created by connortaylorbrown on 2/08/17. */ public class RaceServer { + private static RaceServer server;//this is for updating xml files as I cannot find an elegant way to do this and since it is near the end of the sprint we shouldn't be doing large scale refactors + private MockRace race; private LatestMessages latestMessages; @@ -47,6 +49,7 @@ public class RaceServer { public RaceServer(MockRace race, LatestMessages latestMessages) { + server = this; this.race = race; this.latestMessages = latestMessages; } @@ -73,6 +76,12 @@ public class RaceServer { } + public static void staticUpdateXML(){ + if (server != null){ + server.updateXMLFiles(); + } + } + /** * Checks if the race/boat/regatta data sources have changed, and if they have, update their xml representations. */ diff --git a/racevisionGame/src/main/java/network/Messages/LatestMessages.java b/racevisionGame/src/main/java/network/Messages/LatestMessages.java index c16d722f..ba6cc45c 100644 --- a/racevisionGame/src/main/java/network/Messages/LatestMessages.java +++ b/racevisionGame/src/main/java/network/Messages/LatestMessages.java @@ -1,5 +1,6 @@ package network.Messages; +import mock.model.RaceServer; import network.Messages.Enums.XMLMessageType; import java.util.*; @@ -152,6 +153,7 @@ public class LatestMessages extends Observable { return false; } else { + RaceServer.staticUpdateXML(); return true; } From df04cdf87ccb807b54f9598486951318f9483a1c Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 11 Sep 2017 19:54:43 +1200 Subject: [PATCH 22/46] Boats are now visualy removed when they leave the lobby. --- .../Controllers/InGameLobbyController.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index e2f0f787..7cc40eeb 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -8,6 +8,7 @@ import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.geometry.Insets; +import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; @@ -95,12 +96,28 @@ public class InGameLobbyController extends Controller { importer.read(asset); } + private void resetLobby(){ + int count = 0; + for (Label label: allPlayerLabels){ + label.setText("Player " + count + 1); + count ++; + } + List nodeCopy = new ArrayList(playerContainer.getChildren()); + for (Node node: nodeCopy){ + if (node instanceof View3D){ + playerContainer.getChildren().remove(node); + } + } + } + private void populatePlayers(ListChangeListener.Change change){ + Platform.runLater( () -> { while (change.next()){ - if (change.wasAdded()){ + if (change.wasAdded() || change.wasRemoved() || change.wasUpdated() || change.wasPermutated()){ try{ + resetLobby(); int count = 0; int row = 0; for (VisualiserBoat boat :this.visualiserRaceEvent.getVisualiserRaceState().getBoats()) { From 54a9140f31cb495aa01a4211333482f728e02d28 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 11 Sep 2017 20:29:15 +1200 Subject: [PATCH 23/46] lobby listener is added and removed so that the program doesn't drasticaly slow down when the lobby is connected to multiple times #story[1188] --- .../Controllers/InGameLobbyController.java | 107 ++++++++++-------- 1 file changed, 61 insertions(+), 46 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index 7cc40eeb..5e9c8792 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -83,6 +83,8 @@ public class InGameLobbyController extends Controller { private StlMeshImporter importer; + private PopulatePlayers lobbyUpdateListener; + @Override public void initialize(URL location, ResourceBundle resources) { allPlayerLabels = new ArrayList(Arrays.asList(playerLabel, playerLabel2, @@ -94,6 +96,8 @@ public class InGameLobbyController extends Controller { URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl"); importer = new StlMeshImporter(); importer.read(asset); + lobbyUpdateListener = new PopulatePlayers(); + } private void resetLobby(){ @@ -110,56 +114,69 @@ public class InGameLobbyController extends Controller { } } - private void populatePlayers(ListChangeListener.Change change){ + public class PopulatePlayers implements ListChangeListener { + + @Override + public void onChanged(Change change) { - Platform.runLater( - () -> { - while (change.next()){ - if (change.wasAdded() || change.wasRemoved() || change.wasUpdated() || change.wasPermutated()){ - try{ - resetLobby(); - int count = 0; - int row = 0; - for (VisualiserBoat boat :this.visualiserRaceEvent.getVisualiserRaceState().getBoats()) { - View3D playerBoatToSet = new View3D(); - playerBoatToSet.setItems(subjects); - - playerContainer.add(playerBoatToSet, (count % 3) , row); - playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10)); - - MeshView mesh = new MeshView(importer.getImport()); - Subject3D subject = new Subject3D(mesh); - subjects.add(subject); - - playerBoatToSet.setDistance(50); - playerBoatToSet.setYaw(45); - playerBoatToSet.setPitch(20); - - - - AnimationTimer rotate = new AnimationTimer() { - @Override - public void handle(long now) { - subject.setHeading(subject.getHeading().getAngle() + 0.1); + Platform.runLater( + () -> { + if (visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum() != RaceStatusEnum.PRESTART){ + return; + } + while (change.next()){ + if (change.wasAdded() || change.wasRemoved() || change.wasUpdated() || change.wasPermutated()){ + if (visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum() != RaceStatusEnum.PRESTART){ + return; + } + try{ + resetLobby(); + int count = 0; + int row = 0; + for (VisualiserBoat boat :visualiserRaceEvent.getVisualiserRaceState().getBoats()) { + View3D playerBoatToSet = new View3D(); + playerBoatToSet.setItems(subjects); + + playerContainer.add(playerBoatToSet, (count % 3) , row); + playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10)); + + MeshView mesh = new MeshView(importer.getImport()); + Subject3D subject = new Subject3D(mesh); + subjects.add(subject); + + playerBoatToSet.setDistance(50); + playerBoatToSet.setYaw(45); + playerBoatToSet.setPitch(20); + + + + AnimationTimer rotate = new AnimationTimer() { + @Override + public void handle(long now) { + subject.setHeading(subject.getHeading().getAngle() + 0.1); + } + }; + rotate.start(); + + allPlayerLabels.get(count).setText("Player: " + boat.getSourceID()); + allPlayerLabels.get(count).toFront(); + count += 1; + if (count > 2){ + row = 1; } - }; - rotate.start(); - - allPlayerLabels.get(count).setText("Player: " + boat.getSourceID()); - allPlayerLabels.get(count).toFront(); - count += 1; - if (count > 2){ - row = 1; } } - } - catch(ConcurrentModificationException e){ + catch(ConcurrentModificationException e){ + } } } } - } - ); + ); + } } + /* + private void populatePlayers(ListChangeListener.Change change){ + }*/ /** * Starts the race. @@ -220,7 +237,7 @@ public class InGameLobbyController extends Controller { //Hide this, and display the race controller. gameLobbyWrapper.setVisible(false); - + visualiserRaceEvent.getVisualiserRaceState().getBoats().removeListener(lobbyUpdateListener); parent.beginRace(visualiserRaceEvent, controllerClient, isHost); } @@ -239,9 +256,7 @@ public class InGameLobbyController extends Controller { this.controllerClient = visualiserRaceEvent.getControllerClient(); - this.visualiserRaceEvent.getVisualiserRaceState().getBoats().addListener((ListChangeListener) c ->{ - populatePlayers(c); - }); + this.visualiserRaceEvent.getVisualiserRaceState().getBoats().addListener(this.lobbyUpdateListener); gameLobbyWrapper.setVisible(true); From 2cda5ea70de24cf011b54e5ed5f0b89b642bad1e Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 11 Sep 2017 20:34:34 +1200 Subject: [PATCH 24/46] Lobby no longer glitches out when a person disconnects and reconnects without restarting the program #story[1188] --- .../visualiser/Controllers/InGameLobbyController.java | 1 + .../java/visualiser/model/VisualiserRaceEvent.java | 4 ++-- .../main/java/visualiser/network/ServerConnection.java | 10 +++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index 5e9c8792..b8108c18 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -277,6 +277,7 @@ public class InGameLobbyController extends Controller { alert.setHeaderText("You are about to quit the race"); Optional result = alert.showAndWait(); if(result.get() == ButtonType.OK){ + visualiserRaceEvent.terminate(); gameLobbyWrapper.setVisible(false); parent.enterTitle(); } diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceEvent.java b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceEvent.java index d5ab9b66..24da83f3 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceEvent.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceEvent.java @@ -112,8 +112,8 @@ public class VisualiserRaceEvent { * Terminates the server connection and race service. */ public void terminate() { - this.serverConnectionThread.interrupt(); - this.visualiserRaceServiceThread.interrupt(); + this.serverConnectionThread.interrupt(); + serverConnection.terminate(); } } diff --git a/racevisionGame/src/main/java/visualiser/network/ServerConnection.java b/racevisionGame/src/main/java/visualiser/network/ServerConnection.java index 5d6d8773..899cbc45 100644 --- a/racevisionGame/src/main/java/visualiser/network/ServerConnection.java +++ b/racevisionGame/src/main/java/visualiser/network/ServerConnection.java @@ -468,7 +468,15 @@ public class ServerConnection implements RunnableWithFramePeriod { this.visualiserRaceControllerThread.interrupt(); } - + if (this.socket != null) { + try { + this.socket.getInputStream().close(); + this.socket.getOutputStream().close(); + this.socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } //TODO input controller? From 33017984115299d642efa43534d761f094d04062 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Tue, 12 Sep 2017 21:35:10 +1200 Subject: [PATCH 25/46] Fixed boats not rotating in lobby #story[1188] --- .idea/copyright/profiles_settings.xml | 3 +++ .../visualiser/Controllers/InGameLobbyController.java | 9 +-------- 2 files changed, 4 insertions(+), 8 deletions(-) create mode 100644 .idea/copyright/profiles_settings.xml diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..e7bedf33 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index b8108c18..9140d1be 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -118,17 +118,10 @@ public class InGameLobbyController extends Controller { @Override public void onChanged(Change change) { - Platform.runLater( () -> { - if (visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum() != RaceStatusEnum.PRESTART){ - return; - } while (change.next()){ - if (change.wasAdded() || change.wasRemoved() || change.wasUpdated() || change.wasPermutated()){ - if (visualiserRaceEvent.getVisualiserRaceState().getRaceStatusEnum() != RaceStatusEnum.PRESTART){ - return; - } + if (change.wasAdded() || change.wasRemoved() || change.wasUpdated()){ try{ resetLobby(); int count = 0; From 4dcff5c0095548172c85b8504557596effdb3ec5 Mon Sep 17 00:00:00 2001 From: hba56 Date: Tue, 12 Sep 2017 21:55:23 +1200 Subject: [PATCH 26/46] SeaSurface files have been added to display the surface in the lobby. Surface is now drawn in the lobby --- .../Controllers/InGameLobbyController.java | 13 +- .../main/java/visualiser/layout/Plane3D.java | 125 ++++++++++++++++ .../java/visualiser/layout/SeaSurface.java | 135 ++++++++++++++++++ .../utils/PerlinNoiseGenerator.java | 88 ++++++++++++ 4 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/layout/Plane3D.java create mode 100644 racevisionGame/src/main/java/visualiser/layout/SeaSurface.java create mode 100644 racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java diff --git a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java index 9140d1be..a6442664 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/InGameLobbyController.java @@ -9,16 +9,18 @@ import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.geometry.Insets; import javafx.scene.Node; -import javafx.scene.control.*; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; -import javafx.scene.shape.Box; import javafx.scene.shape.MeshView; import mock.app.Event; import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RequestToJoinEnum; import visualiser.gameController.ControllerClient; +import visualiser.layout.SeaSurface; import visualiser.layout.Subject3D; import visualiser.layout.View3D; import visualiser.model.VisualiserBoat; @@ -101,10 +103,8 @@ public class InGameLobbyController extends Controller { } private void resetLobby(){ - int count = 0; for (Label label: allPlayerLabels){ - label.setText("Player " + count + 1); - count ++; + label.setText("No Player"); } List nodeCopy = new ArrayList(playerContainer.getChildren()); for (Node node: nodeCopy){ @@ -133,6 +133,9 @@ public class InGameLobbyController extends Controller { playerContainer.add(playerBoatToSet, (count % 3) , row); playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10)); + SeaSurface sea = new SeaSurface(750, 200, 250, 0, 210); + subjects.add(sea.getSurface()); + MeshView mesh = new MeshView(importer.getImport()); Subject3D subject = new Subject3D(mesh); subjects.add(subject); diff --git a/racevisionGame/src/main/java/visualiser/layout/Plane3D.java b/racevisionGame/src/main/java/visualiser/layout/Plane3D.java new file mode 100644 index 00000000..0952b61c --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/Plane3D.java @@ -0,0 +1,125 @@ +package visualiser.layout; + +import javafx.scene.shape.TriangleMesh; + +import java.util.ArrayList; +import java.util.List; + +/** + * 3D plane + */ +public class Plane3D extends TriangleMesh{ + + /** + * Length is up down, and width is left right. Drawn on the x-y plane with z kept at 0. + * @param width width of the plane + * @param length length of the plane + * @param subdivisionsWidth number of divisions along the width of the plane + * @param subdivisionsLength number of division along the length of the plane + */ + public Plane3D(float width, float length, int subdivisionsWidth, int subdivisionsLength){ + //add texture points and vertex points + float subWidth = width / (float) subdivisionsWidth; + float subLength = length / (float) subdivisionsLength; + + ArrayList pointsList = new ArrayList<>(); + ArrayList textureCoord = new ArrayList<>(); + float startW = -width/2; + float startL = -length/2; + + for (float l = 0; l <= length; l += subLength) { + for (float w = 0; w <= width; w += subWidth){ + //add points + pointsList.add(w + startW); + pointsList.add(l + startL); + pointsList.add(0f); + //addTexture coords + textureCoord.add(1 - w/width); + textureCoord.add(1 - l/length); + } + } + + this.getPoints().setAll(copyListToArray(pointsList)); + this.getTexCoords().setAll(copyListToArray(textureCoord)); + + //connect points to make faces + ArrayList faces = new ArrayList<>(); + + int listSize = pointsList.size()/3; + int divsInRow = subdivisionsWidth + 1; + for (int i = 0; i < listSize; i++){ + int row = i/divsInRow; + + if (row < 1){ + continue; + } + + boolean notFirstCol = (i) % divsInRow != 0; + boolean notLastCol = (i + 1) % divsInRow != 0; + if (notFirstCol){ + faces.add(i); + faces.add(i); +// printPointAtIndex(i); + faces.add(i - divsInRow); + faces.add(i - divsInRow); +// printPointAtIndex(i - divsInRow); + faces.add(i - 1); + faces.add(i - 1); +// printPointAtIndex(i-1); + } + if (notLastCol) { + faces.add(i - divsInRow + 1); + faces.add(i - divsInRow + 1); +// printPointAtIndex(i - divsInRow + 1); + faces.add(i - divsInRow); + faces.add(i - divsInRow); +// printPointAtIndex(i - divsInRow); + faces.add(i); + faces.add(i); +// printPointAtIndex(i); + } + + } + this.getFaces().setAll(copyListToIntArray(faces)); + } + + /** + * Testing function to see if the points are correct + * @param index index that the points correspond to (remember 3 is a point) + */ + private void printPointAtIndex(int index){ + int i = index * 3; + float x = this.getPoints().get(i); + float y = this.getPoints().get(i + 1); + float z = this.getPoints().get(i + 2); + System.out.println(String.format("Point at %d is x:%f, y:%f, z:%f", index, x, y, z)); + } + + /** + * copies the list to a float array because java List.toArray isn't working + * @param list list to copy + * @return array + */ + private static float[] copyListToArray(List list){ + float[] res = new float[list.size()]; + for (int i = 0; i < list.size(); i++){ + res[i] = list.get(i); + } + return res; + } + + /** + * copies the list to an integer array because java List.toArray isn't working + * @param list list to copy + * @return array + */ + private static int[] copyListToIntArray(List list){ + int[] res = new int[list.size()]; + for (int i = 0; i < list.size(); i++){ + res[i] = list.get(i); + } + return res; + } + + +} \ No newline at end of file diff --git a/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java new file mode 100644 index 00000000..fae9a7a9 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java @@ -0,0 +1,135 @@ +package visualiser.layout; + +import javafx.scene.image.Image; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.MeshView; +import visualiser.utils.PerlinNoiseGenerator; + +/** + * Creates a SeaSurface + */ +public class SeaSurface { + private float[][] noiseArray; + private Subject3D surface; + + /** + * Sea Surface Constructor + * @param size size of the sea surface (has to be square for simplicity's sake) + * @param freq frequency the perlin noise is to be generated at + * @param x offset that the sea should be set at position-wise + * @param z offset that the sea should be set at position-wise + */ + public SeaSurface(int size, double freq, double x, double y, double z){ + noiseArray = PerlinNoiseGenerator.createNoise(size, freq); + createSurface(); + surface.setZ(z); + surface.setY(y); + surface.setX(x); + } + + /** + * Creates the sea surface + */ + private void createSurface(){ + Image diffuseMap = createImage(noiseArray.length, noiseArray); + + PhongMaterial material = new PhongMaterial(); + material.setDiffuseMap(diffuseMap); + //material.setSpecularColor(Color.WHITE); + + Plane3D seaPlane = new Plane3D(noiseArray.length, noiseArray.length, 10, 10); + MeshView seaSurface = new MeshView(seaPlane); +// Box seaSurface = new Box(noiseArray.length, 0.1, noiseArray.length); + seaSurface.setMaterial(material); + seaSurface.setMouseTransparent(true); + seaSurface.toFront(); + //seaSurface.setRotationAxis(new Point3D(1, 0, 0)); + //seaSurface.setRotate(90); + + surface = new Subject3D(seaSurface); + } + + /** + * Create texture for uv mapping + * @param size size of the image to make + * @param noise array of noise + * @return image that is created + */ + private Image createImage(double size, float[][] noise) { + + int width = (int) size; + int height = (int) size; + + WritableImage wr = new WritableImage(width, height); + PixelWriter pw = wr.getPixelWriter(); + //interpolate colours based on noise + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + + float value = noise[x][y]; + + double gray = normalizeValue(value, -.5, .5, 0., 1.); + + gray = clamp(gray, 0, 1); + + //values to interpolate on + Color brightBlue = new Color(0.06, 0.5, .78, 1); + Color lightBlue = new Color(0.15, 0.68, .88, 1); + Color lighterBlue = new Color(0.28, 0.73, .91, 1); + + Color colour = Color.WHITE.interpolate(brightBlue, gray).interpolate(lighterBlue, gray).interpolate(lightBlue, gray); + + pw.setColor(x, y, colour); + + } + } + + return wr; + + } + + /** + * Nomalises the values so that the colours are correct + * @param value value to normalise + * @param min current min + * @param max current max + * @param newMin new min + * @param newMax new max + * @return returns normalised value + */ + private static double normalizeValue(double value, double min, double max, double newMin, double newMax) { + + return (value - min) * (newMax - newMin) / (max - min) + newMin; + + } + + /** + * clamps a value between a min and max + * @param value value to clamp + * @param min minimum value it can be + * @param max maximum value it can be + * @return result after clamp + */ + private static double clamp(double value, double min, double max) { + + if (Double.compare(value, min) < 0) + return min; + + if (Double.compare(value, max) > 0) + return max; + + return value; + } + + /** + * Get surface + * @return the surface so it can be drawn + */ + public Subject3D getSurface(){ + return surface; + } + +} \ No newline at end of file diff --git a/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java b/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java new file mode 100644 index 00000000..becf59a2 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java @@ -0,0 +1,88 @@ +package visualiser.utils; + +/** + * Perlin Noise Generator + */ +public class PerlinNoiseGenerator { + + + /** + * Create an array of the given size with values of perlin noise + * @param size size of array that you wish to create + * @param freq frequency that the noise is to be generated at. + * @return noise generated + */ + public static float[][] createNoise( int size, double freq) { + float[][] noiseArray = new float[(int) size][(int) size]; + + for (int x = 0; x < size; x++) { + for (int y = 0; y < size; y++) { + + double frequency = freq / (double) size; + + double noise = ImprovedNoise.noise(x * frequency, y * frequency, 0); + + noiseArray[x][y] = (float) noise; + } + } + + return noiseArray; + + } + + /** + * Perlin noise generator + * + * // JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN. + * // http://mrl.nyu.edu/~perlin/paper445.pdf + * // http://mrl.nyu.edu/~perlin/noise/ + */ + public final static class ImprovedNoise { + static public double noise(double x, double y, double z) { + int X = (int)Math.floor(x) & 255, // FIND UNIT CUBE THAT + Y = (int)Math.floor(y) & 255, // CONTAINS POINT. + Z = (int)Math.floor(z) & 255; + x -= Math.floor(x); // FIND RELATIVE X,Y,Z + y -= Math.floor(y); // OF POINT IN CUBE. + z -= Math.floor(z); + double u = fade(x), // COMPUTE FADE CURVES + v = fade(y), // FOR EACH OF X,Y,Z. + w = fade(z); + int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, // HASH COORDINATES OF + B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS, + + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD + grad(p[BA ], x-1, y , z )), // BLENDED + lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS + grad(p[BB ], x-1, y-1, z ))),// FROM 8 + lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS + grad(p[BA+1], x-1, y , z-1 )), // OF CUBE + lerp(u, grad(p[AB+1], x , y-1, z-1 ), + grad(p[BB+1], x-1, y-1, z-1 )))); + } + static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); } + static double lerp(double t, double a, double b) { return a + t * (b - a); } + static double grad(int hash, double x, double y, double z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + double u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. + v = h<4 ? y : h==12||h==14 ? x : z; + return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); + } + static final int p[] = new int[512], permutation[] = { 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 + }; + static { for (int i=0; i < 256 ; i++) p[256+i] = p[i] = permutation[i]; } + } + +} \ No newline at end of file From 3d588017605dea140304211f55b4e13524cc795c Mon Sep 17 00:00:00 2001 From: hba56 Date: Tue, 12 Sep 2017 22:02:51 +1200 Subject: [PATCH 27/46] matchbrowser now updates and flushes in a better time frame. 30s for flush as thats the time for match lobbys and 5s for update --- .../src/main/java/networkInterface/NetworkInterface.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java index b564f3df..241da0f4 100644 --- a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java +++ b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java @@ -2,19 +2,14 @@ package networkInterface; import model.ClientAddress; import model.MatchTable; -import model.TableKey; import network.BinaryMessageDecoder; -import network.BinaryMessageEncoder; import network.Exceptions.InvalidMessageException; import network.MessageDecoders.HostGameMessageDecoder; import network.MessageDecoders.HostedGamesRequestDecoder; -import network.MessageEncoders.HostGameMessageEncoder; import network.MessageEncoders.HostedGamesRequestEncoder; import network.Messages.Enums.MessageType; -import network.Messages.Enums.RaceStatusEnum; import network.Messages.HostGame; import network.Messages.HostGamesRequest; -import network.Messages.RaceStatus; import java.io.IOException; import java.net.DatagramPacket; @@ -46,8 +41,8 @@ public class NetworkInterface { this.groupPort = 4941; this.serverSocket = new DatagramSocket(3779); - startBroadcast(10000); - scheduleFlush(300000); + startBroadcast(5000); + scheduleFlush(30000); this.run(); } catch (IOException e) { System.err.println("Error listening on port: " + this.serverSocket.getLocalPort() + "."); From 4adcd6322cc266e494787f70076ebff308539581 Mon Sep 17 00:00:00 2001 From: hba56 Date: Wed, 13 Sep 2017 12:05:09 +1200 Subject: [PATCH 28/46] send out to every client --- .../networkInterface/NetworkInterface.java | 19 +++++++++++-------- .../Controllers/KeyBindingsController.java | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java index 241da0f4..431cdd84 100644 --- a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java +++ b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java @@ -66,14 +66,14 @@ public class NetworkInterface { if(game != null) { games.add(game); } - } - HostedGamesRequestEncoder encoder = new HostedGamesRequestEncoder(); - try { - byte[] message = encoder.encode(new HostGamesRequest(games)); - System.out.println(LocalDateTime.now() + ": Sending " + games.size() + " game/s"); - serverSocket.send(new DatagramPacket(message, message.length, groupAddress, groupPort)); - } catch (InvalidMessageException | IOException e) { - e.printStackTrace(); + HostedGamesRequestEncoder encoder = new HostedGamesRequestEncoder(); + try { + byte[] message = encoder.encode(new HostGamesRequest(games)); + System.out.println(LocalDateTime.now() + ": Sending " + games.size() + " game/s"); + serverSocket.send(new DatagramPacket(message, message.length, groupAddress, groupPort)); + } catch (InvalidMessageException | IOException e) { + e.printStackTrace(); + } } } }, period, period); @@ -97,6 +97,9 @@ public class NetworkInterface { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); + System.out.println(receivePacket.getAddress()); + System.out.println(this.clientsAddresses); + BinaryMessageDecoder messageDecoder = new BinaryMessageDecoder(receivePacket.getData()); switch (MessageType.fromByte(messageDecoder.getHeaderMessageType())){ case HOST_GAME: diff --git a/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java index 84d82e91..ba533551 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java @@ -188,6 +188,7 @@ public class KeyBindingsController { loadNotification("One or more key bindings are missing. " + "Failed to save.", true); } + ((Stage)btnCancel.getScene().getWindow()).close(); } /** From bed9f8b07a3f338f5cfc4e142133e4d00ab394df Mon Sep 17 00:00:00 2001 From: hba56 Date: Wed, 13 Sep 2017 12:19:33 +1200 Subject: [PATCH 29/46] send out to every client fix --- .../networkInterface/NetworkInterface.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java index 431cdd84..62327081 100644 --- a/matchBrowser/src/main/java/networkInterface/NetworkInterface.java +++ b/matchBrowser/src/main/java/networkInterface/NetworkInterface.java @@ -66,14 +66,17 @@ public class NetworkInterface { if(game != null) { games.add(game); } - HostedGamesRequestEncoder encoder = new HostedGamesRequestEncoder(); - try { - byte[] message = encoder.encode(new HostGamesRequest(games)); - System.out.println(LocalDateTime.now() + ": Sending " + games.size() + " game/s"); - serverSocket.send(new DatagramPacket(message, message.length, groupAddress, groupPort)); - } catch (InvalidMessageException | IOException e) { - e.printStackTrace(); + } + + HostedGamesRequestEncoder encoder = new HostedGamesRequestEncoder(); + try { + byte[] message = encoder.encode(new HostGamesRequest(games)); + System.out.println(LocalDateTime.now() + ": Sending " + games.size() + " game/s"); + for(ClientAddress address: clientsAddresses) { + serverSocket.send(new DatagramPacket(message, message.length, InetAddress.getByName(address.getIp()), groupPort)); } + } catch (InvalidMessageException | IOException e) { + e.printStackTrace(); } } }, period, period); @@ -97,8 +100,8 @@ public class NetworkInterface { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); - System.out.println(receivePacket.getAddress()); - System.out.println(this.clientsAddresses); +// System.out.println(receivePacket.getAddress()); +// System.out.println(this.clientsAddresses); BinaryMessageDecoder messageDecoder = new BinaryMessageDecoder(receivePacket.getData()); switch (MessageType.fromByte(messageDecoder.getHeaderMessageType())){ From 7cea1fb11c5d8bfe06d52e27faac56334343c01a Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 13 Sep 2017 12:20:42 +1200 Subject: [PATCH 30/46] Reworking fxml for lobby. --- .../visualiser/Controllers/RaceController.java | 2 +- .../visualiser/network/MatchBrowserInterface.java | 2 +- .../resources/visualiser/scenes/gameLobby.fxml | 4 ++-- settings/keyBindings.xml | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index f4eacb5e..47bae7e6 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -667,7 +667,7 @@ public class RaceController extends Controller { //Set next key to press as the zoom-out key searchMapForKey("Zoom Out"); //Update tutorial text - tutorialText.setText("Nice! You will also be able to zoom into boats and marks by clicking them. To zoom out press " + keyToPress + "."); + tutorialText.setText("Nice! You will also be able to zoom into boats and marks by clicking them. \nTo zoom out press " + keyToPress + "."); updateTutorialState(); break; case ZOOMOUT: diff --git a/racevisionGame/src/main/java/visualiser/network/MatchBrowserInterface.java b/racevisionGame/src/main/java/visualiser/network/MatchBrowserInterface.java index 85f22230..e6777c87 100644 --- a/racevisionGame/src/main/java/visualiser/network/MatchBrowserInterface.java +++ b/racevisionGame/src/main/java/visualiser/network/MatchBrowserInterface.java @@ -29,7 +29,7 @@ public class MatchBrowserInterface { public MatchBrowserInterface() { //TODO change to ip of cloud server hosting this try { - this.IPAddress = InetAddress.getByName("localhost"); + this.IPAddress = InetAddress.getByName("132.181.13.223"); } catch (UnknownHostException e) { e.printStackTrace(); } diff --git a/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml index 49b1bce3..920b83cf 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml @@ -20,9 +20,9 @@ - + - +