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:
@@ -20,6 +20,7 @@ public class GameState implements Runnable {
|
|||||||
private Logger logger = LoggerFactory.getLogger(MarkOrder.class);
|
private Logger logger = LoggerFactory.getLogger(MarkOrder.class);
|
||||||
|
|
||||||
private static Integer STATE_UPDATES_PER_SECOND = 60;
|
private static Integer STATE_UPDATES_PER_SECOND = 60;
|
||||||
|
public static Integer MAX_PLAYERS = 8;
|
||||||
|
|
||||||
private static Long previousUpdateTime;
|
private static Long previousUpdateTime;
|
||||||
public static Double windDirection;
|
public static Double windDirection;
|
||||||
|
|||||||
@@ -1,37 +1,26 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import seng302.gameServer.server.messages.ClientType;
|
||||||
|
import seng302.gameServer.server.messages.Message;
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
import seng302.gameServer.server.messages.BoatActionType;
|
import seng302.gameServer.server.messages.BoatActionType;
|
||||||
|
|
||||||
|
|
||||||
public class ServerPacketParser {
|
public class ServerPacketParser {
|
||||||
|
|
||||||
|
|
||||||
public static BoatActionType extractBoatAction(StreamPacket packet) {
|
public static BoatActionType extractBoatAction(StreamPacket packet) {
|
||||||
byte[] payload = packet.getPayload();
|
byte[] payload = packet.getPayload();
|
||||||
int messageVersionNo = payload[0];
|
int messageVersionNo = payload[0];
|
||||||
long actionTypeValue = bytesToLong(Arrays.copyOfRange(payload, 0, 1));
|
long actionTypeValue = Message.bytesToLong(Arrays.copyOfRange(payload, 0, 1));
|
||||||
return BoatActionType.getType((int) actionTypeValue);
|
return BoatActionType.getType((int) actionTypeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static ClientType extractClientType(StreamPacket packet){
|
||||||
* takes an array of up to 7 bytes and returns a positive
|
byte[] payload = packet.getPayload();
|
||||||
* long constructed from the input bytes
|
long value = Message.bytesToLong(Arrays.copyOfRange(payload, 0, 1));
|
||||||
*
|
return ClientType.getClientType((int) value);
|
||||||
* @return a positive long if there is less than 7 bytes -1 otherwise
|
|
||||||
*/
|
|
||||||
private static long bytesToLong(byte[] bytes) {
|
|
||||||
long partialLong = 0;
|
|
||||||
int index = 0;
|
|
||||||
for (byte b : bytes) {
|
|
||||||
if (index > 6) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
partialLong = partialLong | (b & 0xFFL) << (index * 8);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
return partialLong;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
|
|
||||||
|
import seng302.gameServer.server.messages.*;
|
||||||
import seng302.model.Player;
|
import seng302.model.Player;
|
||||||
import seng302.model.Yacht;
|
import seng302.model.Yacht;
|
||||||
import seng302.model.stream.packets.PacketType;
|
import seng302.model.stream.packets.PacketType;
|
||||||
@@ -25,16 +27,6 @@ import seng302.model.stream.packets.StreamPacket;
|
|||||||
import seng302.model.stream.xml.generator.Race;
|
import seng302.model.stream.xml.generator.Race;
|
||||||
import seng302.model.stream.xml.generator.Regatta;
|
import seng302.model.stream.xml.generator.Regatta;
|
||||||
import seng302.utilities.XMLGenerator;
|
import seng302.utilities.XMLGenerator;
|
||||||
import seng302.gameServer.server.messages.BoatActionType;
|
|
||||||
import seng302.gameServer.server.messages.BoatLocationMessage;
|
|
||||||
import seng302.gameServer.server.messages.BoatStatus;
|
|
||||||
import seng302.gameServer.server.messages.BoatSubMessage;
|
|
||||||
import seng302.gameServer.server.messages.Message;
|
|
||||||
import seng302.gameServer.server.messages.RaceStatus;
|
|
||||||
import seng302.gameServer.server.messages.RaceStatusMessage;
|
|
||||||
import seng302.gameServer.server.messages.RaceType;
|
|
||||||
import seng302.gameServer.server.messages.XMLMessage;
|
|
||||||
import seng302.gameServer.server.messages.XMLMessageSubType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
||||||
@@ -62,10 +54,27 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
private Integer seqNo;
|
private Integer seqNo;
|
||||||
private Integer sourceId;
|
private Integer sourceId;
|
||||||
|
|
||||||
|
private ClientType clientType;
|
||||||
|
private Boolean isRegistered = false;
|
||||||
|
|
||||||
private XMLGenerator xml;
|
private XMLGenerator xml;
|
||||||
|
|
||||||
public ServerToClientThread(Socket socket) {
|
public ServerToClientThread(Socket socket) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
seqNo = 0;
|
||||||
|
|
||||||
|
try{
|
||||||
|
is = socket.getInputStream();
|
||||||
|
os = socket.getOutputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread = new Thread(this);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpYacht(){
|
||||||
BufferedReader fn;
|
BufferedReader fn;
|
||||||
String fName = "";
|
String fName = "";
|
||||||
BufferedReader ln;
|
BufferedReader ln;
|
||||||
@@ -94,25 +103,13 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
serverLog("IO error in server thread upon grabbing streams", 1);
|
serverLog("IO error in server thread upon grabbing streams", 1);
|
||||||
}
|
}
|
||||||
//Attempt threeway handshake with connection
|
|
||||||
sourceId = GameState.getUniquePlayerID();
|
|
||||||
if (threeWayHandshake(sourceId)) {
|
|
||||||
serverLog("Successful handshake. Client allocated id: " + sourceId, 0);
|
|
||||||
Yacht yacht = new Yacht(
|
Yacht yacht = new Yacht(
|
||||||
"Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
|
"Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
|
||||||
);
|
);
|
||||||
// Yacht yacht = new Yacht("Kappa", "Kap", new GeoPoint(57.6708220, 11.8321340), 90.0);
|
|
||||||
GameState.addYacht(sourceId, yacht);
|
GameState.addYacht(sourceId, yacht);
|
||||||
GameState.addPlayer(new Player(socket, yacht));
|
GameState.addPlayer(new Player(socket, yacht));
|
||||||
} else {
|
|
||||||
serverLog("Unsuccessful handshake. Connection rejected", 1);
|
|
||||||
closeSocket();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
seqNo = 0;
|
|
||||||
thread = new Thread(this);
|
|
||||||
thread.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serverLog(String message, int logLevel) {
|
static void serverLog(String message, int logLevel) {
|
||||||
@@ -127,11 +124,39 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
sendSetupMessages();
|
sendSetupMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void completeRegistration(ClientType clientType) throws IOException {
|
||||||
|
// Fail if not a player
|
||||||
|
if (!clientType.equals(ClientType.PLAYER)){
|
||||||
|
RegistrationResponseMessage responseMessage = new RegistrationResponseMessage(0, RegistrationResponseStatus.FAILURE_GENERAL);
|
||||||
|
os.write(responseMessage.getBuffer());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameState.getPlayers().size() >= GameState.MAX_PLAYERS){
|
||||||
|
RegistrationResponseMessage responseMessage = new RegistrationResponseMessage(0, RegistrationResponseStatus.FAILURE_FULL);
|
||||||
|
os.write(responseMessage.getBuffer());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer sourceId = GameState.getUniquePlayerID();
|
||||||
|
RegistrationResponseMessage responseMessage = new RegistrationResponseMessage(sourceId, RegistrationResponseStatus.SUCCESS_PLAYING);
|
||||||
|
|
||||||
|
this.clientType = clientType;
|
||||||
|
this.sourceId = sourceId;
|
||||||
|
setUpYacht();
|
||||||
|
|
||||||
|
isRegistered = true;
|
||||||
|
os.write(responseMessage.getBuffer());
|
||||||
|
sendSetupMessages();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
int sync1;
|
int sync1;
|
||||||
int sync2;
|
int sync2;
|
||||||
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
|
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
|
||||||
|
|
||||||
|
|
||||||
while (socket.isConnected()) {
|
while (socket.isConnected()) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -173,6 +198,13 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
new StreamPacket(type, payloadLength, timeStamp, payload));
|
new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
GameState.updateBoat(sourceId, actionType);
|
GameState.updateBoat(sourceId, actionType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RACE_REGISTRATION_REQUEST:
|
||||||
|
ClientType requestedType = ServerPacketParser.extractClientType(
|
||||||
|
new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
|
|
||||||
|
completeRegistration(requestedType);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serverLog("Packet has been dropped", 1);
|
serverLog("Packet has been dropped", 1);
|
||||||
@@ -230,23 +262,6 @@ public class ServerToClientThread implements Runnable, Observer {
|
|||||||
* @return A boolean indicating if it was a successful handshake
|
* @return A boolean indicating if it was a successful handshake
|
||||||
*/
|
*/
|
||||||
private Boolean threeWayHandshake(Integer id) {
|
private Boolean threeWayHandshake(Integer id) {
|
||||||
Integer confirmationID = null;
|
|
||||||
Integer identificationAttempt = 0;
|
|
||||||
while (!userIdentified) {
|
|
||||||
try {
|
|
||||||
os.write(id); //Send out new ID looking for echo
|
|
||||||
confirmationID = is.read();
|
|
||||||
} catch (IOException e) {
|
|
||||||
serverLog("Three way handshake failed", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id.equals(confirmationID)) { //ID is echoed back. Connection is a client
|
|
||||||
return true;
|
|
||||||
} else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
identificationAttempt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
|
public enum ClientType {
|
||||||
|
SPECTATOR(0x00),
|
||||||
|
PLAYER(0x01),
|
||||||
|
CONTROL_TUTORIAL(0x02),
|
||||||
|
GHOST_MODE(0x03);
|
||||||
|
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
ClientType(int type){
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode(){
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientType getClientType(int typeCode){
|
||||||
|
switch (typeCode){
|
||||||
|
case 0x00:
|
||||||
|
return SPECTATOR;
|
||||||
|
case 0x01:
|
||||||
|
return PLAYER;
|
||||||
|
case 0x02:
|
||||||
|
return CONTROL_TUTORIAL;
|
||||||
|
case 0x03:
|
||||||
|
return GHOST_MODE;
|
||||||
|
default:
|
||||||
|
return PLAYER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,9 @@ public enum MessageType {
|
|||||||
MARK_ROUNDING(38),
|
MARK_ROUNDING(38),
|
||||||
COURSE_WIND(44),
|
COURSE_WIND(44),
|
||||||
AVERAGE_WIND(47),
|
AVERAGE_WIND(47),
|
||||||
BOAT_ACTION(100);
|
BOAT_ACTION(100),
|
||||||
|
REGISTRATION_REQUEST(101),
|
||||||
|
REGISTRATION_RESPONSE(102);
|
||||||
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
@@ -32,4 +34,6 @@ public enum MessageType {
|
|||||||
int getCode(){
|
int getCode(){
|
||||||
return this.code;
|
return this.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
|
|
||||||
|
public class RegistrationRequestMessage extends Message {
|
||||||
|
private static int MESSAGE_LENGTH = 2;
|
||||||
|
|
||||||
|
public RegistrationRequestMessage(ClientType type){
|
||||||
|
setHeader(new Header(MessageType.REGISTRATION_REQUEST, 1, (short) getSize()));
|
||||||
|
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
putInt(type.getCode(), 2);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return MESSAGE_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
|
public class RegistrationResponseMessage extends Message{
|
||||||
|
|
||||||
|
public RegistrationResponseMessage(int clientSourceID, RegistrationResponseStatus status){
|
||||||
|
setHeader(new Header(MessageType.REGISTRATION_RESPONSE, 1, (short) getSize()));
|
||||||
|
allocateBuffer();
|
||||||
|
writeHeaderToBuffer();
|
||||||
|
|
||||||
|
putInt(clientSourceID, 4);
|
||||||
|
putInt(status.getCode(), 1);
|
||||||
|
|
||||||
|
writeCRC();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package seng302.gameServer.server.messages;
|
||||||
|
|
||||||
|
public enum RegistrationResponseStatus {
|
||||||
|
SUCCESS_SPECTATING(0x00),
|
||||||
|
SUCCESS_PLAYING(0x01),
|
||||||
|
SUCCESS_TUTORIAL(0x02),
|
||||||
|
SUCCESS_GHOSTING(0x03),
|
||||||
|
|
||||||
|
FAILURE_GENERAL(0x10),
|
||||||
|
FAILURE_FULL(0x11);
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
RegistrationResponseStatus(int code){
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message code (From the API Spec)
|
||||||
|
* @return the message code
|
||||||
|
*/
|
||||||
|
int getCode(){
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RegistrationResponseStatus getResponseStatus(int typeCode){
|
||||||
|
switch (typeCode){
|
||||||
|
case 0x00:
|
||||||
|
return SUCCESS_SPECTATING;
|
||||||
|
case 0x01:
|
||||||
|
return SUCCESS_PLAYING;
|
||||||
|
case 0x02:
|
||||||
|
return SUCCESS_TUTORIAL;
|
||||||
|
case 0x03:
|
||||||
|
return SUCCESS_GHOSTING;
|
||||||
|
case 0x10:
|
||||||
|
return FAILURE_GENERAL;
|
||||||
|
case 0x11:
|
||||||
|
return FAILURE_FULL;
|
||||||
|
default:
|
||||||
|
return FAILURE_GENERAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,9 @@ public enum PacketType {
|
|||||||
COURSE_WIND,
|
COURSE_WIND,
|
||||||
AVG_WIND,
|
AVG_WIND,
|
||||||
BOAT_ACTION,
|
BOAT_ACTION,
|
||||||
OTHER;
|
OTHER,
|
||||||
|
RACE_REGISTRATION_REQUEST,
|
||||||
|
RACE_REGISTRATION_RESPONSE;
|
||||||
|
|
||||||
public static PacketType assignPacketType(int packetType, byte[] payload){
|
public static PacketType assignPacketType(int packetType, byte[] payload){
|
||||||
switch(packetType){
|
switch(packetType){
|
||||||
@@ -56,6 +58,10 @@ public enum PacketType {
|
|||||||
return AVG_WIND;
|
return AVG_WIND;
|
||||||
case 100:
|
case 100:
|
||||||
return BOAT_ACTION;
|
return BOAT_ACTION;
|
||||||
|
case 101:
|
||||||
|
return RACE_REGISTRATION_REQUEST;
|
||||||
|
case 102:
|
||||||
|
return RACE_REGISTRATION_RESPONSE;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
return OTHER;
|
return OTHER;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.io.OutputStream;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
@@ -15,9 +16,12 @@ import java.util.zip.Checksum;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
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.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
|
* 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 Socket socket;
|
||||||
private InputStream is;
|
private InputStream is;
|
||||||
private OutputStream os;
|
private OutputStream os;
|
||||||
|
private Logger logger = LoggerFactory.getLogger(ClientToServerThread.class);
|
||||||
|
|
||||||
private int clientId;
|
private int clientId = -1;
|
||||||
|
|
||||||
// private Boolean updateClient = true;
|
// private Boolean updateClient = true;
|
||||||
private ByteArrayOutputStream crcBuffer;
|
private ByteArrayOutputStream crcBuffer;
|
||||||
@@ -71,15 +76,8 @@ public class ClientToServerThread implements Runnable {
|
|||||||
socket = new Socket(ipAddress, portNumber);
|
socket = new Socket(ipAddress, portNumber);
|
||||||
is = socket.getInputStream();
|
is = socket.getInputStream();
|
||||||
os = socket.getOutputStream();
|
os = socket.getOutputStream();
|
||||||
Integer allocatedID = threeWayHandshake();
|
|
||||||
if (allocatedID != null) {
|
sendRegistrationRequest();
|
||||||
clientId = allocatedID;
|
|
||||||
clientLog("Successful handshake. Allocated ID: " + clientId, 1);
|
|
||||||
} else {
|
|
||||||
clientLog("Unsuccessful handshake", 1);
|
|
||||||
closeSocket();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread = new Thread(this);
|
thread = new Thread(this);
|
||||||
thread.start();
|
thread.start();
|
||||||
@@ -128,10 +126,16 @@ public class ClientToServerThread implements Runnable {
|
|||||||
if (streamPackets.size() > 0) {
|
if (streamPackets.size() > 0) {
|
||||||
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
} else {
|
} else {
|
||||||
|
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));
|
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||||
for (ClientSocketListener csl : listeners)
|
for (ClientSocketListener csl : listeners)
|
||||||
csl.newPacket();
|
csl.newPacket();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
clientLog("Packet has been dropped", 1);
|
clientLog("Packet has been dropped", 1);
|
||||||
}
|
}
|
||||||
@@ -155,28 +159,50 @@ public class ClientToServerThread implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for an allocated sourceID and returns it to the server
|
* Sends a request to the server asking for a source ID
|
||||||
*
|
|
||||||
* @return the sourceID allocated to us by the server
|
|
||||||
*/
|
*/
|
||||||
private Integer threeWayHandshake() {
|
private void sendRegistrationRequest() {
|
||||||
Integer ourSourceID = null;
|
RegistrationRequestMessage requestMessage = new RegistrationRequestMessage(ClientType.PLAYER);
|
||||||
while (true) {
|
|
||||||
try {
|
try {
|
||||||
ourSourceID = is.read();
|
os.write(requestMessage.getBuffer());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
clientLog("Three way handshake failed", 1);
|
logger.error("Could not send registration request. Exiting");
|
||||||
}
|
System.exit(1);
|
||||||
if (ourSourceID != null) {
|
|
||||||
try {
|
|
||||||
os.write(ourSourceID);
|
|
||||||
return ourSourceID;
|
|
||||||
} catch (IOException e) {
|
|
||||||
clientLog("Three way handshake failed", 1);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -185,6 +211,8 @@ public class ClientToServerThread implements Runnable {
|
|||||||
* @param boatActionMessage The message to send
|
* @param boatActionMessage The message to send
|
||||||
*/
|
*/
|
||||||
public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
|
public void sendBoatActionMessage(BoatActionMessage boatActionMessage) {
|
||||||
|
if (clientId == -1) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
os.write(boatActionMessage.getBuffer());
|
os.write(boatActionMessage.getBuffer());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public class GameClient {
|
|||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
System.out.println("Unable to connect to host...");
|
System.out.println("Unable to connect to host...");
|
||||||
}
|
}
|
||||||
|
|
||||||
socketThread.addStreamObserver(this::parsePackets);
|
socketThread.addStreamObserver(this::parsePackets);
|
||||||
LobbyController lobbyController = loadLobby();
|
LobbyController lobbyController = loadLobby();
|
||||||
lobbyController.setPlayerListSource(clientLobbyList);
|
lobbyController.setPlayerListSource(clientLobbyList);
|
||||||
|
|||||||
Reference in New Issue
Block a user