Merge remote-tracking branch 'origin/issue38_irregular_key_event_packets' into issue38_irregular_key_event_packets

This commit is contained in:
Zhi You Tan
2017-08-14 11:02:19 +12:00
29 changed files with 1008 additions and 563 deletions
@@ -7,6 +7,7 @@ import java.io.OutputStream;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
@@ -17,9 +18,16 @@ import java.util.zip.Checksum;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import seng302.gameServer.server.messages.BoatActionMessage;
import javafx.scene.control.ButtonType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.server.messages.BoatAction;
import seng302.gameServer.server.messages.BoatActionMessage;
import seng302.gameServer.server.messages.ClientType;
import seng302.gameServer.server.messages.Message;
import seng302.gameServer.server.messages.RegistrationRequestMessage;
import seng302.gameServer.server.messages.RegistrationResponseStatus;
import seng302.model.stream.packets.PacketType;
import seng302.model.stream.packets.StreamPacket;
/**
@@ -51,6 +59,8 @@ public class ClientToServerThread implements Runnable {
private Socket socket;
private InputStream is;
private Logger logger = LoggerFactory.getLogger(ClientToServerThread.class);
//Output stream
private OutputStream os;
private Timer upWindPacketTimer = new Timer();
@@ -58,7 +68,9 @@ public class ClientToServerThread implements Runnable {
private boolean upwindTimerFlag = false, downwindTimerFlag = false;
static public final int PACKET_SENDING_INTERVAL_MS = 100;
private int clientId;
private int clientId = -1;
// private Boolean updateClient = true;
private ByteArrayOutputStream crcBuffer;
private boolean socketOpen = true;
@@ -78,15 +90,8 @@ public class ClientToServerThread implements Runnable {
socket = new Socket(ipAddress, portNumber);
is = socket.getInputStream();
os = socket.getOutputStream();
Integer allocatedID = threeWayHandshake();
if (allocatedID != null) {
clientId = allocatedID;
clientLog("Successful handshake. Allocated ID: " + clientId, 1);
} else {
clientLog("Unsuccessful handshake", 1);
closeSocket();
return;
}
sendRegistrationRequest();
thread = new Thread(this);
thread.start();
@@ -135,15 +140,22 @@ public class ClientToServerThread implements Runnable {
if (streamPackets.size() > 0) {
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
} else {
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
for (ClientSocketListener csl : listeners)
csl.newPacket();
if (PacketType.RACE_REGISTRATION_RESPONSE == PacketType.assignPacketType(type, payload)){
processRegistrationResponse(new StreamPacket(type, payloadLength, timeStamp, payload));
}
else {
if (clientId == -1) continue; // Do not continue if not registered
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
for (ClientSocketListener csl : listeners)
csl.newPacket();
}
}
} else {
clientLog("Packet has been dropped", 1);
}
}
} catch (ByteReadException e) {
e.printStackTrace();
closeSocket();
if (Platform.isFxApplicationThread()) {
Platform.runLater(() -> {
@@ -163,30 +175,52 @@ public class ClientToServerThread implements Runnable {
/**
* Listens for an allocated sourceID and returns it to the server
*
* @return the sourceID allocated to us by the server
* Sends a request to the server asking for a source ID
*/
private Integer threeWayHandshake() {
Integer ourSourceID = null;
while (true) {
try {
ourSourceID = is.read();
} catch (IOException e) {
clientLog("Three way handshake failed", 1);
}
if (ourSourceID != null) {
try {
os.write(ourSourceID);
return ourSourceID;
} catch (IOException e) {
clientLog("Three way handshake failed", 1);
return null;
}
}
private void sendRegistrationRequest() {
RegistrationRequestMessage requestMessage = new RegistrationRequestMessage(ClientType.PLAYER);
try {
os.write(requestMessage.getBuffer());
} catch (IOException e) {
logger.error("Could not send registration request. Exiting");
System.exit(1);
}
}
/**
* Accepts a response to the registration request message, and updates the client OR quits
* @param packet The registration requests packet
*/
private void processRegistrationResponse(StreamPacket packet){
int sourceId = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 0, 3));
int statusCode = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 4,5));
RegistrationResponseStatus status = RegistrationResponseStatus.getResponseStatus(statusCode);
if (status.equals(RegistrationResponseStatus.SUCCESS_PLAYING)){
clientId = sourceId;
return;
}
logger.error("Server Denied Connection, Exiting");
final String alertErrorText;
if (status.equals(RegistrationResponseStatus.FAILURE_FULL)){
alertErrorText = "Server is full";
}
else{
alertErrorText = "Could not connect to server";
}
Platform.runLater(() -> {
new Alert(AlertType.ERROR, alertErrorText, ButtonType.OK).showAndWait();
System.exit(1);
});
}
/**
* Sends packets for the given boat action. Special cases are: \n
* - DOWNWIND = Packets are sent every ClientToServerThread.PACKET_SENDING_INTERVAL_MS
@@ -254,10 +288,12 @@ public class ClientToServerThread implements Runnable {
* @param message The given message type.
*/
private void sendBoatAction(BoatActionMessage message) {
try {
os.write(message.getBuffer());
} catch (IOException e) {
clientLog("Could not write to server", 1);
if (clientId != -1) {
try {
os.write(message.getBuffer());
} catch (IOException e) {
clientLog("Could not write to server", 1);
}
}
}
@@ -30,7 +30,8 @@ import seng302.visualiser.controllers.LobbyController.CloseStatus;
import seng302.visualiser.controllers.RaceViewController;
/**
* Created by cir27 on 20/07/17.
* This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated
* with a JavaFX Pane to insert itself into.
*/
public class GameClient {
@@ -47,10 +48,20 @@ public class GameClient {
private ObservableList<String> clientLobbyList = FXCollections.observableArrayList();
/**
* Create an instance of the game client. Does not do anything until run with runAsClient()
* runAsHost().
* @param holder The JavaFX Pane that the visual elements for the race will be inserted into.
*/
public GameClient(Pane holder) {
this.holderPane = holder;
}
/**
* Connect to a game at the given address and starts the visualiser.
* @param ipAddress IP to connect to.
* @param portNumber Port to connect to.
*/
public void runAsClient(String ipAddress, Integer portNumber) {
try {
socketThread = new ClientToServerThread(ipAddress, portNumber);
@@ -58,6 +69,7 @@ public class GameClient {
ioe.printStackTrace();
System.out.println("Unable to connect to host...");
}
socketThread.addStreamObserver(this::parsePackets);
LobbyController lobbyController = loadLobby();
lobbyController.setPlayerListSource(clientLobbyList);
@@ -66,6 +78,11 @@ public class GameClient {
lobbyController.addCloseListener((exitCause) -> this.loadStartScreen());
}
/**
* Connect to a game as the host at the given address and starts the visualiser.
* @param ipAddress IP to connect to.
* @param portNumber Port to connect to.
*/
public void runAsHost(String ipAddress, Integer portNumber) {
server = new MainServerThread();
try {
@@ -89,10 +106,8 @@ public class GameClient {
private void loadStartScreen() {
socketThread.setSocketToClose();
socketThread = null;
if (server != null) {
// TODO: 26/07/17 cir27 - handle disconnecting
// server.shutDown();
server.terminate();
server = null;
}
FXMLLoader fxmlLoader = new FXMLLoader(
@@ -174,9 +189,9 @@ public class GameClient {
StreamParser.extractXmlMessage(packet)
);
clientLobbyList.clear();
allBoatsMap.forEach((id, boat) -> {
clientLobbyList.add(id + " " + boat.getBoatName());
});
allBoatsMap.forEach((id, boat) ->
clientLobbyList.add(id + " " + boat.getBoatName())
);
break;
case RACE_START_STATUS:
@@ -312,7 +312,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
updateRaceTime();
updateWindDirection();
updateOrder();
updateSparkLine();
// updateSparkLine();
}
}, 0, 1000);
}