mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Implemented new client - server handshake protocol
- Implemented new packet types - Changed server & client logic to use new protocol Tags: #story[1124] (Issue 39)
This commit is contained in:
@@ -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.concurrent.ConcurrentLinkedQueue;
|
||||
@@ -15,9 +16,12 @@ import java.util.zip.Checksum;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.gameServer.server.messages.*;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.gameServer.server.messages.BoatActionMessage;
|
||||
import seng302.gameServer.server.messages.Message;
|
||||
|
||||
/**
|
||||
* A class describing a single connection to a Server for the purposes of sending and receiving on
|
||||
@@ -48,8 +52,9 @@ public class ClientToServerThread implements Runnable {
|
||||
private Socket socket;
|
||||
private InputStream is;
|
||||
private OutputStream os;
|
||||
private Logger logger = LoggerFactory.getLogger(ClientToServerThread.class);
|
||||
|
||||
private int clientId;
|
||||
private int clientId = -1;
|
||||
|
||||
// private Boolean updateClient = true;
|
||||
private ByteArrayOutputStream crcBuffer;
|
||||
@@ -71,15 +76,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();
|
||||
@@ -128,9 +126,15 @@ 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);
|
||||
@@ -155,36 +159,60 @@ 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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send the post-start race course information
|
||||
* @param boatActionMessage The message to send
|
||||
*/
|
||||
public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
|
||||
if (clientId == -1) return;
|
||||
|
||||
try {
|
||||
os.write(boatActionMessage.getBuffer());
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -62,6 +62,7 @@ public class GameClient {
|
||||
ioe.printStackTrace();
|
||||
System.out.println("Unable to connect to host...");
|
||||
}
|
||||
|
||||
socketThread.addStreamObserver(this::parsePackets);
|
||||
LobbyController lobbyController = loadLobby();
|
||||
lobbyController.setPlayerListSource(clientLobbyList);
|
||||
|
||||
Reference in New Issue
Block a user