mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Server discovery bug fixes & error handling improvements
- Fixed concurrency bug that prevented players from connecting to servers - Discovery server can restart itself if it crashes - Added nicer error handling for server discovery. - Using AWS to get servers external IP address. Tags: #story[1281]
This commit is contained in:
@@ -80,6 +80,14 @@ public class App extends Application {
|
|||||||
ViewManager.getInstance().initialStartView(primaryStage);
|
ViewManager.getInstance().initialStartView(primaryStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void runDiscoveryServer(){
|
||||||
|
try{
|
||||||
|
new DiscoveryServer();
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
runDiscoveryServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
try {
|
try {
|
||||||
@@ -92,7 +100,7 @@ public class App extends Application {
|
|||||||
launch(args);
|
launch(args);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
new DiscoveryServer();
|
runDiscoveryServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,19 @@ package seng302.discoveryServer;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
import seng302.gameServer.messages.RoomCodeRequest;
|
import seng302.gameServer.messages.RoomCodeRequest;
|
||||||
import seng302.gameServer.messages.ServerRegistrationMessage;
|
import seng302.gameServer.messages.ServerRegistrationMessage;
|
||||||
import seng302.model.stream.packets.PacketType;
|
import seng302.model.stream.packets.PacketType;
|
||||||
import seng302.discoveryServer.util.ServerListing;
|
import seng302.visualiser.controllers.ViewManager;
|
||||||
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
@@ -20,9 +24,28 @@ public class DiscoveryServerClient {
|
|||||||
private static String roomCode = null;
|
private static String roomCode = null;
|
||||||
private Timer serverListingUpdateTimer;
|
private Timer serverListingUpdateTimer;
|
||||||
private Logger logger = LoggerFactory.getLogger(DiscoveryServerClient.class);
|
private Logger logger = LoggerFactory.getLogger(DiscoveryServerClient.class);
|
||||||
|
private String ip = "";
|
||||||
|
private Boolean isInInvalidState = false;
|
||||||
|
|
||||||
public DiscoveryServerClient() {
|
public DiscoveryServerClient() {
|
||||||
|
try {
|
||||||
|
ip = getInetIpAddr();
|
||||||
|
} catch (Exception e) {
|
||||||
|
failError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInetIp(){
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failError() {
|
||||||
|
isInInvalidState = true;
|
||||||
|
ViewManager.getInstance().showErrorSnackBar("You do not appear to be able to connect to the internet. Matchmaking will be unavailable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean didFail(){
|
||||||
|
return isInInvalidState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +53,8 @@ public class DiscoveryServerClient {
|
|||||||
* @param serverListing The listing to register
|
* @param serverListing The listing to register
|
||||||
*/
|
*/
|
||||||
public void register(ServerListing serverListing){
|
public void register(ServerListing serverListing){
|
||||||
|
if (isInInvalidState) return;
|
||||||
|
|
||||||
if (serverListingUpdateTimer != null){
|
if (serverListingUpdateTimer != null){
|
||||||
serverListingUpdateTimer.cancel();
|
serverListingUpdateTimer.cancel();
|
||||||
serverListingUpdateTimer = null;
|
serverListingUpdateTimer = null;
|
||||||
@@ -53,6 +78,7 @@ public class DiscoveryServerClient {
|
|||||||
* Stop updating the server registration updates
|
* Stop updating the server registration updates
|
||||||
*/
|
*/
|
||||||
public void unregister(){
|
public void unregister(){
|
||||||
|
if (serverListingUpdateTimer != null)
|
||||||
serverListingUpdateTimer.cancel();
|
serverListingUpdateTimer.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,5 +169,27 @@ public class DiscoveryServerClient {
|
|||||||
public static String getRoomCode(){
|
public static String getRoomCode(){
|
||||||
return roomCode;
|
return roomCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getInetIpAddr() throws Exception {
|
||||||
|
URL myIp = new URL("http://checkip.amazonaws.com");
|
||||||
|
BufferedReader in = null;
|
||||||
|
try {
|
||||||
|
in = new BufferedReader(new InputStreamReader(
|
||||||
|
myIp.openStream()));
|
||||||
|
String ip = in.readLine();
|
||||||
|
return ip;
|
||||||
|
} finally {
|
||||||
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class ServerTable {
|
|||||||
updateTtlForServer(server);
|
updateTtlForServer(server);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.debug("Added new server - " + server.getServerName());
|
logger.debug("Added new server - " + server.getServerName() + " at address: " + server.getAddress() + ":" + server.getPortNumber());
|
||||||
servers.add(server);
|
servers.add(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
@@ -18,6 +12,13 @@ import seng302.model.stream.xml.parser.RaceXMLData;
|
|||||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||||
import seng302.utilities.GeoUtility;
|
import seng302.utilities.GeoUtility;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class describing the overall server, which creates and collects server threads for each client
|
* A class describing the overall server, which creates and collects server threads for each client
|
||||||
* Created by wmu16 on 13/07/17.
|
* Created by wmu16 on 13/07/17.
|
||||||
@@ -158,6 +159,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendSetupMessages() {
|
private void sendSetupMessages() {
|
||||||
|
MessageFactory.updateBoats(new ArrayList<>(GameState.getYachts().values()));
|
||||||
|
|
||||||
broadcastMessage(MessageFactory.getRaceXML());
|
broadcastMessage(MessageFactory.getRaceXML());
|
||||||
broadcastMessage(MessageFactory.getRegattaXML());
|
broadcastMessage(MessageFactory.getRegattaXML());
|
||||||
broadcastMessage(MessageFactory.getBoatXML());
|
broadcastMessage(MessageFactory.getBoatXML());
|
||||||
@@ -253,16 +256,26 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
serverToClientThread.addConnectionListener(this::sendSetupMessages);
|
//serverToClientThread.addConnectionListener(this::sendSetupMessages);
|
||||||
MessageFactory.updateBoats(new ArrayList<>(GameState.getYachts().values()));
|
|
||||||
}
|
}
|
||||||
serverToClientThreads.add(serverToClientThread);
|
serverToClientThreads.add(serverToClientThread);
|
||||||
serverToClientThread.addDisconnectListener(this::clientDisconnected);
|
|
||||||
try {
|
try {
|
||||||
ServerAdvertiser.getInstance().setNumberOfPlayers(GameState.getNumberOfPlayers());
|
ServerAdvertiser.getInstance().setNumberOfPlayers(GameState.getNumberOfPlayers());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Couldn't update advertisement");
|
logger.warn("Couldn't update advertisement");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (regattaXMLData == null && raceXMLData == null){
|
||||||
|
try {
|
||||||
|
Thread.sleep(50);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
serverToClientThread.addConnectionListener(this::sendSetupMessages);
|
||||||
|
serverToClientThread.addDisconnectListener(this::clientDisconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,6 +296,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
|
|||||||
serverToClientThread.sendSetupMessages();
|
serverToClientThread.sendSetupMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serverToClientThreads.remove(closedConnection);
|
serverToClientThreads.remove(closedConnection);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import seng302.gameServer.messages.*;
|
||||||
import java.util.List;
|
|
||||||
import seng302.gameServer.messages.BoatLocationMessage;
|
|
||||||
import seng302.gameServer.messages.BoatSubMessage;
|
|
||||||
import seng302.gameServer.messages.RaceStartNotificationType;
|
|
||||||
import seng302.gameServer.messages.RaceStartStatusMessage;
|
|
||||||
import seng302.gameServer.messages.RaceStatus;
|
|
||||||
import seng302.gameServer.messages.RaceStatusMessage;
|
|
||||||
import seng302.gameServer.messages.RaceType;
|
|
||||||
import seng302.gameServer.messages.XMLMessage;
|
|
||||||
import seng302.gameServer.messages.XMLMessageSubType;
|
|
||||||
import seng302.gameServer.messages.YachtEventCodeMessage;
|
|
||||||
import seng302.gameServer.messages.YachtEventType;
|
|
||||||
import seng302.model.Player;
|
import seng302.model.Player;
|
||||||
import seng302.model.ServerYacht;
|
import seng302.model.ServerYacht;
|
||||||
import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
||||||
@@ -20,9 +8,11 @@ import seng302.model.stream.xml.generator.RegattaXMLTemplate;
|
|||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||||
import seng302.model.token.Token;
|
import seng302.model.token.Token;
|
||||||
import seng302.model.token.TokenType;
|
|
||||||
import seng302.utilities.XMLGenerator;
|
import seng302.utilities.XMLGenerator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Class for interfacing between the data we have in the GameState to the messages we need to send
|
* A Class for interfacing between the data we have in the GameState to the messages we need to send
|
||||||
* through the MainServerThread.
|
* through the MainServerThread.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import seng302.discoveryServer.util.ServerListing;
|
|
||||||
import seng302.discoveryServer.DiscoveryServerClient;
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
|
||||||
import javax.jmdns.JmDNS;
|
import javax.jmdns.JmDNS;
|
||||||
import javax.jmdns.ServiceInfo;
|
import javax.jmdns.ServiceInfo;
|
||||||
@@ -133,7 +133,7 @@ public class ServerAdvertiser {
|
|||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
ServerListing serverListing = new ServerListing(serverName, props.get("map"), getLocalHostIp(), portNo, Integer.parseInt(props.get("capacity")));
|
ServerListing serverListing = new ServerListing(serverName, props.get("map"), new DiscoveryServerClient().getInetIp(), portNo, Integer.parseInt(props.get("capacity")));
|
||||||
repositoryClient.register(serverListing);
|
repositoryClient.register(serverListing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import seng302.gameServer.messages.*;
|
||||||
|
import seng302.model.Player;
|
||||||
|
import seng302.model.ServerYacht;
|
||||||
|
import seng302.model.stream.packets.PacketType;
|
||||||
|
import seng302.model.stream.packets.StreamPacket;
|
||||||
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
|
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||||
|
import seng302.utilities.StreamParser;
|
||||||
|
import seng302.utilities.XMLGenerator;
|
||||||
|
import seng302.utilities.XMLParser;
|
||||||
|
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -12,26 +27,6 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import seng302.gameServer.messages.BoatAction;
|
|
||||||
import seng302.gameServer.messages.ChatterMessage;
|
|
||||||
import seng302.gameServer.messages.ClientType;
|
|
||||||
import seng302.gameServer.messages.CustomizeRequestType;
|
|
||||||
import seng302.gameServer.messages.Message;
|
|
||||||
import seng302.gameServer.messages.RegistrationResponseMessage;
|
|
||||||
import seng302.gameServer.messages.RegistrationResponseStatus;
|
|
||||||
import seng302.model.Player;
|
|
||||||
import seng302.model.ServerYacht;
|
|
||||||
import seng302.model.stream.packets.PacketType;
|
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
|
||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
|
||||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
|
||||||
import seng302.utilities.StreamParser;
|
|
||||||
import seng302.utilities.XMLGenerator;
|
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
|
||||||
import seng302.utilities.XMLParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@@ -196,6 +191,7 @@ public class ServerToClientThread implements Runnable {
|
|||||||
// TODO: 17/08/2017 ajm412: Send a response packet here, not really necessary until we do shapes.
|
// TODO: 17/08/2017 ajm412: Send a response packet here, not really necessary until we do shapes.
|
||||||
break;
|
break;
|
||||||
case RACE_XML:
|
case RACE_XML:
|
||||||
|
System.out.println("Got raceXML from client");
|
||||||
raceXMLProperty.set(
|
raceXMLProperty.set(
|
||||||
XMLParser.parseRace(
|
XMLParser.parseRace(
|
||||||
StreamParser.extractXmlMessage(packet)
|
StreamParser.extractXmlMessage(packet)
|
||||||
|
|||||||
@@ -1,36 +1,22 @@
|
|||||||
package seng302.visualiser;
|
package seng302.visualiser;
|
||||||
|
|
||||||
|
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.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
import javafx.util.Pair;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import seng302.gameServer.messages.BoatAction;
|
|
||||||
import seng302.gameServer.messages.BoatActionMessage;
|
|
||||||
import seng302.gameServer.messages.ChatterMessage;
|
|
||||||
import seng302.gameServer.messages.ClientType;
|
|
||||||
import seng302.gameServer.messages.CustomizeRequestMessage;
|
|
||||||
import seng302.gameServer.messages.CustomizeRequestType;
|
|
||||||
import seng302.gameServer.messages.Message;
|
|
||||||
import seng302.gameServer.messages.RegistrationRequestMessage;
|
|
||||||
import seng302.gameServer.messages.RegistrationResponseStatus;
|
|
||||||
import seng302.gameServer.messages.XMLMessage;
|
|
||||||
import seng302.gameServer.messages.XMLMessageSubType;
|
|
||||||
import seng302.model.stream.packets.PacketType;
|
|
||||||
import seng302.model.stream.packets.StreamPacket;
|
|
||||||
import seng302.utilities.XMLParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@@ -137,10 +123,12 @@ public class ClientToServerThread implements Runnable {
|
|||||||
else {
|
else {
|
||||||
if (clientId == -1) continue; // Do not continue if not registered
|
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));
|
||||||
|
synchronized (this) {
|
||||||
for (ClientSocketListener csl : listeners)
|
for (ClientSocketListener csl : listeners)
|
||||||
csl.newPacket();
|
csl.newPacket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Packet has been dropped", 1);
|
logger.warn("Packet has been dropped", 1);
|
||||||
}
|
}
|
||||||
@@ -322,20 +310,26 @@ public class ClientToServerThread implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addStreamObserver (ClientSocketListener streamListener) {
|
public void addStreamObserver (ClientSocketListener streamListener) {
|
||||||
|
synchronized (this){
|
||||||
listeners.add(streamListener);
|
listeners.add(streamListener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void removeStreamObserver (ClientSocketListener streamListener) {
|
public void removeStreamObserver (ClientSocketListener streamListener) {
|
||||||
listeners.remove(streamListener);
|
listeners.remove(streamListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addDisconnectionListener (DisconnectedFromHostListener listener) {
|
public void addDisconnectionListener (DisconnectedFromHostListener listener) {
|
||||||
|
synchronized (this){
|
||||||
disconnectionListeners.add(listener);
|
disconnectionListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void removeDisconnectionListener (DisconnectedFromHostListener listener) {
|
public void removeDisconnectionListener (DisconnectedFromHostListener listener) {
|
||||||
|
synchronized (this){
|
||||||
disconnectionListeners.remove(listener);
|
disconnectionListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int readByte() throws ByteReadException {
|
private int readByte() throws ByteReadException {
|
||||||
int currentByte = -1;
|
int currentByte = -1;
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
package seng302.visualiser;
|
package seng302.visualiser;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
@@ -48,6 +38,12 @@ import seng302.visualiser.controllers.LobbyController;
|
|||||||
import seng302.visualiser.controllers.RaceViewController;
|
import seng302.visualiser.controllers.RaceViewController;
|
||||||
import seng302.visualiser.controllers.ViewManager;
|
import seng302.visualiser.controllers.ViewManager;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated
|
* 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.
|
* with a JavaFX Pane to insert itself into.
|
||||||
@@ -114,7 +110,7 @@ public class GameClient {
|
|||||||
this.lobbyController = ViewManager.getInstance().goToLobby(true);
|
this.lobbyController = ViewManager.getInstance().goToLobby(true);
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
showConnectionError("Unable to find server");
|
ViewManager.getInstance().showErrorSnackBar("Unable to find server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,6 @@ package seng302.visualiser.controllers;
|
|||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.controls.JFXDialog;
|
import com.jfoenix.controls.JFXDialog;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
@@ -19,6 +13,7 @@ import javafx.scene.layout.AnchorPane;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
import seng302.gameServer.GameStages;
|
import seng302.gameServer.GameStages;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
@@ -28,12 +23,17 @@ import seng302.model.RaceState;
|
|||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.model.mark.Corner;
|
import seng302.model.mark.Corner;
|
||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
import seng302.discoveryServer.DiscoveryServerClient;
|
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.MapPreview;
|
import seng302.visualiser.MapPreview;
|
||||||
import seng302.visualiser.controllers.cells.PlayerCell;
|
import seng302.visualiser.controllers.cells.PlayerCell;
|
||||||
import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
|
import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
|
||||||
import seng302.visualiser.controllers.dialogs.DirectConnectController;
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class LobbyController implements Initializable {
|
public class LobbyController implements Initializable {
|
||||||
|
|
||||||
@@ -91,6 +91,17 @@ public class LobbyController implements Initializable {
|
|||||||
serverName.setText(ViewManager.getInstance().getProperty("serverName"));
|
serverName.setText(ViewManager.getInstance().getProperty("serverName"));
|
||||||
mapName.setText(ViewManager.getInstance().getProperty("mapName"));
|
mapName.setText(ViewManager.getInstance().getProperty("mapName"));
|
||||||
|
|
||||||
|
int tries = 0;
|
||||||
|
|
||||||
|
while (DiscoveryServerClient.getRoomCode() == null && tries <= 10){
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
tries ++;
|
||||||
|
}
|
||||||
|
|
||||||
if (DiscoveryServerClient.getRoomCode() != null){
|
if (DiscoveryServerClient.getRoomCode() != null){
|
||||||
setRoomCode(DiscoveryServerClient.getRoomCode());
|
setRoomCode(DiscoveryServerClient.getRoomCode());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,11 @@ import com.jfoenix.controls.JFXDialog;
|
|||||||
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
||||||
import com.jfoenix.controls.JFXTextField;
|
import com.jfoenix.controls.JFXTextField;
|
||||||
import com.jfoenix.validation.RequiredFieldValidator;
|
import com.jfoenix.validation.RequiredFieldValidator;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
@@ -23,19 +17,21 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.discoveryServer.DiscoveryServer;
|
|
||||||
import seng302.gameServer.ServerDescription;
|
|
||||||
import seng302.discoveryServer.util.ServerListing;
|
|
||||||
import seng302.discoveryServer.DiscoveryServerClient;
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
import seng302.gameServer.messages.RoomCodeRequest;
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
import seng302.gameServer.ServerDescription;
|
||||||
|
import seng302.gameServer.messages.ServerRegistrationMessage;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.ServerListener;
|
import seng302.visualiser.ServerListener;
|
||||||
import seng302.visualiser.ServerListenerDelegate;
|
import seng302.visualiser.ServerListenerDelegate;
|
||||||
import seng302.visualiser.controllers.cells.ServerCell;
|
import seng302.visualiser.controllers.cells.ServerCell;
|
||||||
import seng302.visualiser.controllers.dialogs.DirectConnectController;
|
import seng302.visualiser.controllers.dialogs.DirectConnectController;
|
||||||
import seng302.visualiser.validators.HostNameFieldValidator;
|
|
||||||
import seng302.visualiser.validators.NumberRangeValidator;
|
import java.io.IOException;
|
||||||
import seng302.visualiser.validators.ValidationTools;
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class ServerListController implements Initializable, ServerListenerDelegate {
|
public class ServerListController implements Initializable, ServerListenerDelegate {
|
||||||
|
|
||||||
@@ -90,6 +86,8 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
|||||||
Sounds.playButtonClick();
|
Sounds.playButtonClick();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
directConnectDialog = createDirectConnectDialog();
|
||||||
|
|
||||||
for (JFXTextField textField : Arrays.asList(roomNumber)) {
|
for (JFXTextField textField : Arrays.asList(roomNumber)) {
|
||||||
// Event for pressing enter to submit direct connection
|
// Event for pressing enter to submit direct connection
|
||||||
textField.setOnKeyPressed(event -> {
|
textField.setOnKeyPressed(event -> {
|
||||||
@@ -105,26 +103,26 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
|||||||
}
|
}
|
||||||
|
|
||||||
autoSelectGame.setOnMouseReleased(e -> {
|
autoSelectGame.setOnMouseReleased(e -> {
|
||||||
try {
|
ServerListing listing;
|
||||||
ServerListing listing = new DiscoveryServerClient().getRandomServer();
|
DiscoveryServerClient client = new DiscoveryServerClient();
|
||||||
|
|
||||||
if (listing == null){
|
try {
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
listing = client.getRandomServer();
|
||||||
alert.setHeaderText("Error finding game");
|
|
||||||
alert.setContentText("No servers are up");
|
|
||||||
alert.showAndWait();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber());
|
|
||||||
}
|
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
e1.printStackTrace();
|
ViewManager.getInstance().showErrorSnackBar("Unable to connect to matchmaking server. Are you connected to the internet?");
|
||||||
logger.error("Error getting listing");
|
return;
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
||||||
alert.setHeaderText("Error finding game");
|
|
||||||
alert.setContentText("Couldn't contact matchmaking server");
|
|
||||||
alert.showAndWait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client.didFail()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listing == null || listing.equals(ServerRegistrationMessage.getEmptyRegistration())) {
|
||||||
|
ViewManager.getInstance().showErrorSnackBar("There are currently no servers available for you to connect to.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewManager.getInstance().getGameClient().runAsClient(listing.getAddress(), listing.getPortNumber());
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -186,9 +184,6 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.warn("Could not create Server Creation Dialog.");
|
logger.warn("Could not create Server Creation Dialog.");
|
||||||
}
|
}
|
||||||
|
|
||||||
directConnectDialog = createDirectConnectDialog();
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,20 +230,30 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void connectToRoomCode(String roomCode){
|
private void connectToRoomCode(String roomCode){
|
||||||
|
DiscoveryServerClient client = new DiscoveryServerClient();
|
||||||
|
ServerListing serverListing;
|
||||||
|
|
||||||
|
if (client.didFail()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
serverListing = client.getServerForRoomCode(roomCode);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ViewManager.getInstance().showErrorSnackBar("Error connecting to matchmaking server. Please try again later.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverListing == null || serverListing.equals(new ServerListing("","","", 0, 0))){
|
||||||
|
ViewManager.getInstance().showErrorSnackBar("No servers could be found with that room code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ServerListing serverListing = new DiscoveryServerClient().getServerForRoomCode(roomCode);
|
|
||||||
ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber());
|
ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber());
|
||||||
}
|
}
|
||||||
catch (java.net.ConnectException e){
|
|
||||||
//TODO Add proper dialog
|
|
||||||
logger.warn("Couldn't connect to discovery server");
|
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
||||||
alert.setHeaderText("Couldn't connect to discovery server");
|
|
||||||
alert.setContentText("Couldn't connect to " + DiscoveryServer.DISCOVERY_SERVER);
|
|
||||||
alert.showAndWait();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
logger.warn("Error discovering room code");
|
ViewManager.getInstance().showErrorSnackBar("Error connecting to matchmaking service.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,16 +6,10 @@ import com.jfoenix.controls.JFXDialog;
|
|||||||
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
||||||
import com.jfoenix.controls.JFXSnackbar;
|
import com.jfoenix.controls.JFXSnackbar;
|
||||||
import com.jfoenix.svg.SVGGlyph;
|
import com.jfoenix.svg.SVGGlyph;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Cursor;
|
import javafx.scene.*;
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.Parent;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.SceneAntialiasing;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
@@ -28,6 +22,9 @@ import seng302.utilities.Sounds;
|
|||||||
import seng302.visualiser.GameClient;
|
import seng302.visualiser.GameClient;
|
||||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class ViewManager {
|
public class ViewManager {
|
||||||
|
|
||||||
private static ViewManager instance;
|
private static ViewManager instance;
|
||||||
@@ -369,6 +366,14 @@ public class ViewManager {
|
|||||||
return loader.getController();
|
return loader.getController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showErrorSnackBar(String msg){
|
||||||
|
decorator.getStylesheets()
|
||||||
|
.add(getClass().getResource("/css/dialogs/Snackbar.css").toExternalForm());
|
||||||
|
|
||||||
|
JFXSnackbar bar = new JFXSnackbar(decorator);
|
||||||
|
bar.enqueue(new JFXSnackbar.SnackbarEvent(msg));
|
||||||
|
}
|
||||||
|
|
||||||
public Stage getStage() {
|
public Stage getStage() {
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user