Various bug fixes

- Closed socket when discovery server crashes, so it can be restarted
- Flattened water on terrain mesh
- Added checks to ensure server is started before connecting
- Added a check to ensure client has started  before connecting to the server
- Fixed concurrency issue in server-> client thread list

Tags: #story[1281]
This commit is contained in:
Michael Rausch
2017-09-28 01:58:49 +13:00
parent 00ddf117b2
commit 8b7407bf89
7 changed files with 301 additions and 213 deletions
+8 -6
View File
@@ -80,12 +80,14 @@ public class App extends Application {
ViewManager.getInstance().initialiseSplashScreen(primaryStage);
}
private static void runDiscoveryServer(){
try{
new DiscoveryServer();
}
catch (Exception e){
runDiscoveryServer();
private static void runDiscoveryServer() throws Exception {
while (true){
try {
new DiscoveryServer();
}
catch (Exception ignored){
;
}
}
}
@@ -11,11 +11,13 @@ import seng302.discoveryServer.util.ServerRepoStreamParser;
import seng302.discoveryServer.util.ServerTable;
import seng302.visualiser.ServerListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Timer;
public class DiscoveryServer {
public static final String ANSI_GREEN = "\u001B[32m";
@@ -27,6 +29,7 @@ public class DiscoveryServer {
private ServerTable serverTable;
public static final Integer PORT_NUMBER = 9969;
private ServerSocket serverSocket;
private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class);
@@ -56,8 +59,6 @@ public class DiscoveryServer {
displayHeader();
serverTable = new ServerTable();
ServerSocket serverSocket;
try{
serverSocket = new ServerSocket(PORT_NUMBER);
}
@@ -69,12 +70,17 @@ public class DiscoveryServer {
logger.info("Started successfully - Now accepting connections");
while (true){
Socket clientSocket = serverSocket.accept();
try{
while (true){
Socket clientSocket = serverSocket.accept();
parseRequest(clientSocket);
parseRequest(clientSocket);
clientSocket.close();
clientSocket.close();
}
}
catch (Exception e){
close();
}
}
@@ -147,6 +153,18 @@ public class DiscoveryServer {
tries++;
}
if (serverToJoin != null && serverToJoin.isMaxPlayersReached()){
return null;
}
return serverToJoin;
}
public void close(){
try {
serverSocket.close();
} catch (IOException ignored) {
;
}
}
}
@@ -40,6 +40,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
private boolean terminated;
private Thread thread;
private boolean hasStarted = false;
private ServerSocket serverSocket = null;
private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>();
@@ -98,6 +99,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
new HeartbeatThread(this);
new ServerListenThread(serverSocket, this);
hasStarted = true;
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
while (!terminated) {
if (GameState.getPlayerHasLeftFlag()) {
@@ -146,8 +149,10 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
}
}
try {
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.terminate();
synchronized (this){
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.terminate();
}
}
serverSocket.close();
} catch (IOException e) {
@@ -450,4 +455,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
);
}
}
public boolean hasStarted() {
return hasStarted;
}
}
@@ -1,5 +1,14 @@
package seng302.visualiser;
import javafx.application.Platform;
import javafx.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.*;
import seng302.model.stream.packets.PacketType;
import seng302.model.stream.packets.StreamPacket;
import seng302.utilities.XMLParser;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -42,6 +51,8 @@ import seng302.visualiser.controllers.ViewManager;
*/
public class ClientToServerThread implements Runnable {
private boolean isStarted = false;
/**
* Functional interface for receiving packets from client socket.
*/
@@ -117,6 +128,8 @@ public class ClientToServerThread implements Runnable {
* variable is false.
*/
public void run() {
isStarted = true;
int sync1;
int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
@@ -167,8 +180,10 @@ public class ClientToServerThread implements Runnable {
notifyDisconnectListeners("Connection to server was terminated");
closeSocket();
ViewManager.getInstance().goToStartView();
ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
Platform.runLater(() -> {
ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
ViewManager.getInstance().goToStartView();
});
}
public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) {
@@ -194,12 +209,6 @@ public class ClientToServerThread implements Runnable {
if (connectionErrorListener != null){
connectionErrorListener.notifyConnectionError(message);
}
try {
this.socket.close();
} catch (IOException e) {
logger.error("Couldn't close socket");
}
}
/**
@@ -390,9 +399,9 @@ public class ClientToServerThread implements Runnable {
}
if (currentByte == -1) {
notifyDisconnectListeners("Cannot read from server.");
closeSocket();
logger.warn("InputStream reach end of stream", 1);
handleConnectionError("Could not connect to server. Server is no longer available.");
closeSocket();
}
return currentByte;
}
@@ -435,4 +444,8 @@ public class ClientToServerThread implements Runnable {
).getBuffer()
);
}
public boolean hasStarted() {
return isStarted;
}
}
@@ -119,7 +119,7 @@ public class GameClient {
getServerThread().setConnectionErrorListener((eMessage) -> {
ViewManager.getInstance().showErrorSnackBar(eMessage);
destroyClientToServerThread();
//destroyClientToServerThread();
});
this.lobbyController = ViewManager.getInstance().goToLobby(true);
@@ -147,18 +147,45 @@ public class GameClient {
server = new MainServerThread();
while (!server.hasStarted()){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
startClientToServerThread(ipAddress, 4942);
} catch (IOException e) {
showConnectionError("Cannot connect to server as host");
}
// Wait for C2S thread
while (!socketThread.hasStarted()){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
socketThread.sendXML(race, serverName, numLegs, maxPlayers, tokensEnabled);
while (regattaData == null){
int triesLeft = 15;
while (regattaData == null && triesLeft > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
triesLeft--;
}
if (triesLeft <= 0){
showConnectionError("Could not launch server");
return null;
}
this.lobbyController = ViewManager.getInstance().goToLobby(false);
@@ -119,6 +119,12 @@ public class ServerCreationController implements Initializable {
.runAsHost("localhost", 4941, serverName.getText(), (int) maxPlayersSlider
.getValue(), mapMaker.getCurrentRacePath(), (int) legsSlider.getValue(), pickupsCheckBox.isSelected());
if (serverDescription == null){
ViewManager.getInstance().getGameClient().getServerThread().closeSocket();
ViewManager.getInstance().getGameClient().stopGame();
return;
}
ViewManager.getInstance().setProperty("serverName", serverDescription.getName());
ViewManager.getInstance().setProperty("mapName", serverDescription.getMapName());
}