mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Made discovery more reliable & added docs/tests
- Added unit tests - Added documentation for discovery classes - Improved error handling Tags: #story[1281]
This commit is contained in:
@@ -10,7 +10,7 @@ import org.apache.commons.cli.Options;
|
|||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.serverRepository.ServerRepository;
|
import seng302.discoveryServer.DiscoveryServer;
|
||||||
import seng302.visualiser.controllers.ViewManager;
|
import seng302.visualiser.controllers.ViewManager;
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
@@ -27,12 +27,19 @@ public class App extends Application {
|
|||||||
.getLogger(Logger.ROOT_LOGGER_NAME);
|
.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
|
||||||
options.addOption("debugLevel", true, "Set the application debug level");
|
options.addOption("debugLevel", true, "Set the application debug level");
|
||||||
options.addOption("runAsCache", false, "Run as a server cache for server discovery");
|
options.addOption("runAsDiscoveryServer", false, "Run as a discovery server");
|
||||||
|
options.addOption("discoveryDevMode", false, "Use a local discovery server");
|
||||||
|
|
||||||
cmd = parser.parse(options, args);
|
cmd = parser.parse(options, args);
|
||||||
|
|
||||||
if (cmd.hasOption("runAsCache")){
|
if (cmd.hasOption("runAsDiscoveryServer")){
|
||||||
isRunningAsCache = true;
|
isRunningAsCache = true;
|
||||||
|
rootLogger.setLevel(Level.ALL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd.hasOption("discoveryDevMode")) {
|
||||||
|
DiscoveryServer.DISCOVERY_SERVER = "localhost";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.hasOption("debugLevel")) {
|
if (cmd.hasOption("debugLevel")) {
|
||||||
@@ -85,7 +92,7 @@ public class App extends Application {
|
|||||||
launch(args);
|
launch(args);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ServerRepository serverRepository = new ServerRepository();
|
new DiscoveryServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package seng302.discoveryServer;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import seng302.gameServer.messages.Message;
|
||||||
|
import seng302.gameServer.messages.RoomCodeRequest;
|
||||||
|
import seng302.gameServer.messages.ServerRegistrationMessage;
|
||||||
|
import seng302.model.stream.packets.PacketType;
|
||||||
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||||
|
import seng302.discoveryServer.util.ServerTable;
|
||||||
|
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class DiscoveryServer {
|
||||||
|
public static final String ANSI_GREEN = "\u001B[32m";
|
||||||
|
public static final String ANSI_YELLOW = "\u001B[33m";
|
||||||
|
public static final String ANSI_BLUE = "\u001B[34m";
|
||||||
|
public static final String ANSI_RESET = "\u001B[0m";
|
||||||
|
public static String DISCOVERY_SERVER = "party.sydney.srv.michaelrausch.nz";
|
||||||
|
|
||||||
|
private ServerTable serverTable;
|
||||||
|
public static final Integer PORT_NUMBER = 9969;
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class);
|
||||||
|
|
||||||
|
private void displayHeader(){
|
||||||
|
String selectedColor = Arrays.asList(ANSI_BLUE, ANSI_GREEN, ANSI_YELLOW).get(new Random().nextInt(2));
|
||||||
|
System.out.println(selectedColor);
|
||||||
|
System.out.println(" .ccccc. \n" +
|
||||||
|
" .cc;'coooxkl;. \n" +
|
||||||
|
" .:c:::c:,,,,,;c;;,.'. \n" +
|
||||||
|
" .clc,',:,..:xxocc;'..c; \n" +
|
||||||
|
" .c:,';:ox:..:c,,,,,,...cd, \n" +
|
||||||
|
" .c:'.,oxxxxl::l:.,loll;..;ol. \n" +
|
||||||
|
" ;Oc..:xxxxxxxxx:.,llll,....oc \n" +
|
||||||
|
" .,;,',:loxxxxxxxxx:.,llll;.,,.'ld, \n" +
|
||||||
|
" .lo;..:xxxxxxxxxxxx:.'cllc,.:l:'cO; \n" +
|
||||||
|
" .:;...'cxxxxxxxxxxxxoc;,::,..cdl;;l' \n" +
|
||||||
|
" .cl;':,'';oxxxxxxdxxxxxx:....,cooc,cO; \n" +
|
||||||
|
" .,,,::;,lxoc:,,:lxxxxxxxxxxxo:,,;lxxl;'oNc \n" +
|
||||||
|
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v0.1 " + selectedColor +"\n" +
|
||||||
|
" .loc'.'lxxxxxxxxocc;''''';ccoxxxxxxxxx:..oc \n" +
|
||||||
|
"olc,..',:cccccccccccc:;;;;;;;;:ccccccccc,.'c, \n" +
|
||||||
|
"Ol;......................................;l' ");
|
||||||
|
System.out.println(ANSI_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscoveryServer() throws Exception {
|
||||||
|
displayHeader();
|
||||||
|
serverTable = new ServerTable();
|
||||||
|
|
||||||
|
ServerSocket serverSocket;
|
||||||
|
|
||||||
|
try{
|
||||||
|
serverSocket = new ServerSocket(PORT_NUMBER);
|
||||||
|
}
|
||||||
|
catch(java.net.BindException e){
|
||||||
|
logger.error("FATAL - Could not bind socket, are you sure there isn't already an instance running?");
|
||||||
|
System.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Started successfully - Now accepting connections");
|
||||||
|
|
||||||
|
while (true){
|
||||||
|
Socket clientSocket = serverSocket.accept();
|
||||||
|
|
||||||
|
parseRequest(clientSocket);
|
||||||
|
|
||||||
|
clientSocket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void parseRequest(Socket clientSocket) throws Exception {
|
||||||
|
ServerRepoStreamParser parser = new ServerRepoStreamParser(clientSocket.getInputStream());
|
||||||
|
|
||||||
|
if (clientSocket.isConnected() && !clientSocket.isClosed()){
|
||||||
|
PacketType parsePacketResult = parser.parse();
|
||||||
|
|
||||||
|
switch (parsePacketResult){
|
||||||
|
case SERVER_REGISTRATION:
|
||||||
|
ServerListing listing = parser.getServerListing();
|
||||||
|
|
||||||
|
if (!serverTable.getAllServers().contains(listing)){
|
||||||
|
listing.setRoomCode(serverTable.getNextRoomCode().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
serverTable.addServer(listing);
|
||||||
|
|
||||||
|
Message serverRegMessage = new RoomCodeRequest(listing.getRoomCode());
|
||||||
|
clientSocket.getOutputStream().write(serverRegMessage.getBuffer());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROOM_CODE_REQUEST:
|
||||||
|
String desiredRoomCode = parser.getRoomCode();
|
||||||
|
|
||||||
|
ServerListing serverListing = serverTable.getServerByRoomCode(desiredRoomCode);
|
||||||
|
Message response;
|
||||||
|
|
||||||
|
if (serverListing != null){
|
||||||
|
response = new ServerRegistrationMessage(serverListing.getServerName(), serverListing.getMapName(), serverListing.getAddress(), serverListing.getPortNumber(), 0, 0, desiredRoomCode);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
response = new ServerRegistrationMessage("", "", "", 0, 0, 0, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
clientSocket.getOutputStream().write(response.getBuffer());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
-10
@@ -1,24 +1,39 @@
|
|||||||
package seng302.serverRepository;
|
package seng302.discoveryServer;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
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.discoveryServer.util.ServerRepoStreamParser;
|
||||||
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
public class ServerRepositoryClient {
|
public class DiscoveryServerClient {
|
||||||
|
private final Integer UPDATE_INTERVAL_MS = 5000;
|
||||||
|
|
||||||
private static String roomCode = null;
|
private static String roomCode = null;
|
||||||
private Timer serverListingUpdateTimer;
|
private Timer serverListingUpdateTimer;
|
||||||
|
private Logger logger = LoggerFactory.getLogger(DiscoveryServerClient.class);
|
||||||
|
|
||||||
public ServerRepositoryClient() {
|
public DiscoveryServerClient() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the server with the discovery server
|
||||||
|
* @param serverListing The listing to register
|
||||||
|
*/
|
||||||
public void register(ServerListing serverListing){
|
public void register(ServerListing serverListing){
|
||||||
|
if (serverListingUpdateTimer != null){
|
||||||
|
serverListingUpdateTimer.cancel();
|
||||||
|
serverListingUpdateTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
serverListingUpdateTimer = new Timer();
|
serverListingUpdateTimer = new Timer();
|
||||||
|
|
||||||
serverListingUpdateTimer.schedule(new TimerTask() {
|
serverListingUpdateTimer.schedule(new TimerTask() {
|
||||||
@@ -27,19 +42,28 @@ public class ServerRepositoryClient {
|
|||||||
try {
|
try {
|
||||||
sendRegistrationUpdate(serverListing);
|
sendRegistrationUpdate(serverListing);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();//todo proper error handling
|
logger.debug("Could not update server listing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 0, 5000);
|
}, 0, UPDATE_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop updating the server registration updates
|
||||||
|
*/
|
||||||
public void unregister(){
|
public void unregister(){
|
||||||
serverListingUpdateTimer.cancel();
|
serverListingUpdateTimer.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the connection information for a server given a room code
|
||||||
|
*
|
||||||
|
* @param roomCode The room code to search for
|
||||||
|
* @return The ServerListing, or null if there was an error
|
||||||
|
* @throws Exception .
|
||||||
|
*/
|
||||||
public ServerListing getServerForRoomCode(String roomCode) throws Exception {
|
public ServerListing getServerForRoomCode(String roomCode) throws Exception {
|
||||||
// TODO replace localhost with server
|
Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER);
|
||||||
Socket socket = new Socket("localhost", 9999);
|
|
||||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
||||||
|
|
||||||
Message request = new RoomCodeRequest(roomCode); //roomCode);
|
Message request = new RoomCodeRequest(roomCode); //roomCode);
|
||||||
@@ -48,7 +72,7 @@ public class ServerRepositoryClient {
|
|||||||
PacketType packetType = parser.parse();
|
PacketType packetType = parser.parse();
|
||||||
|
|
||||||
if (packetType != PacketType.SERVER_REGISTRATION){
|
if (packetType != PacketType.SERVER_REGISTRATION){
|
||||||
System.out.println("Wrong packet type");
|
logger.debug("Wrong packet received in response to a room code request");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,8 +81,14 @@ public class ServerRepositoryClient {
|
|||||||
return parser.getServerListing();
|
return parser.getServerListing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a registration update to the discovery server.
|
||||||
|
*
|
||||||
|
* @param serverListing The server listing to send
|
||||||
|
* @throws Exception IF there was an error sending the update
|
||||||
|
*/
|
||||||
private void sendRegistrationUpdate(ServerListing serverListing) throws Exception {
|
private void sendRegistrationUpdate(ServerListing serverListing) throws Exception {
|
||||||
Socket socket = new Socket("localhost", 9999);
|
Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER);
|
||||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
||||||
|
|
||||||
Message req = new ServerRegistrationMessage(serverListing);
|
Message req = new ServerRegistrationMessage(serverListing);
|
||||||
@@ -68,18 +98,22 @@ public class ServerRepositoryClient {
|
|||||||
PacketType packetType = parser.parse();
|
PacketType packetType = parser.parse();
|
||||||
|
|
||||||
if (packetType != PacketType.ROOM_CODE_REQUEST){
|
if (packetType != PacketType.ROOM_CODE_REQUEST){
|
||||||
|
socket.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String roomCode = parser.getRoomCode();
|
String roomCode = parser.getRoomCode();
|
||||||
|
|
||||||
if (roomCode.length() != 0){
|
if (roomCode.length() != 0){
|
||||||
ServerRepositoryClient.roomCode = roomCode;
|
DiscoveryServerClient.roomCode = roomCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The last room code received by the client
|
||||||
|
*/
|
||||||
public static String getRoomCode(){
|
public static String getRoomCode(){
|
||||||
return roomCode;
|
return roomCode;
|
||||||
}
|
}
|
||||||
+17
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.serverRepository;
|
package seng302.discoveryServer.util;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@@ -9,6 +9,12 @@ public class ReadableByteInputStream {
|
|||||||
this.is = is;
|
this.is = is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get n bytes from the input stream
|
||||||
|
* @param n number of bytes
|
||||||
|
* @return the bytes read
|
||||||
|
* @throws Exception .
|
||||||
|
*/
|
||||||
public byte[] getBytes(int n) throws Exception {
|
public byte[] getBytes(int n) throws Exception {
|
||||||
byte[] bytes = new byte[n];
|
byte[] bytes = new byte[n];
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
@@ -17,12 +23,22 @@ public class ReadableByteInputStream {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip n bytes
|
||||||
|
* @param n number of bytes to skip
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public void skipBytes(long n) throws Exception {
|
public void skipBytes(long n) throws Exception {
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
readByte();
|
readByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next byte from the stream
|
||||||
|
* @return The byte that was read
|
||||||
|
* @throws Exception .
|
||||||
|
*/
|
||||||
public int readByte() throws Exception {
|
public int readByte() throws Exception {
|
||||||
int currentByte = is.read();
|
int currentByte = is.read();
|
||||||
|
|
||||||
+6
-2
@@ -1,7 +1,7 @@
|
|||||||
package seng302.serverRepository;
|
package seng302.discoveryServer.util;
|
||||||
|
|
||||||
public class ServerListing {
|
public class ServerListing {
|
||||||
private static final int SERVER_TTL_DEFAULT = 10;
|
public final static int SERVER_TTL_DEFAULT = 10;
|
||||||
|
|
||||||
private String serverName = "";
|
private String serverName = "";
|
||||||
private String mapName = "";
|
private String mapName = "";
|
||||||
@@ -106,4 +106,8 @@ public class ServerListing {
|
|||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTtl(Integer ttl){
|
||||||
|
this.ttl = ttl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package seng302.serverRepository;
|
package seng302.discoveryServer.util;
|
||||||
|
|
||||||
|
|
||||||
import seng302.gameServer.messages.Message;
|
import seng302.gameServer.messages.Message;
|
||||||
+30
-12
@@ -1,12 +1,14 @@
|
|||||||
package seng302.serverRepository;
|
package seng302.discoveryServer.util;
|
||||||
|
|
||||||
import com.sun.corba.se.spi.activation.Server;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ServerTable {
|
public class ServerTable {
|
||||||
private List<ServerListing> servers;
|
private List<ServerListing> servers;
|
||||||
private int lastRoomCode = 4020;
|
private int lastRoomCode = 4020;
|
||||||
|
private Logger logger = LoggerFactory.getLogger(ServerTable.class);
|
||||||
|
|
||||||
public ServerTable(){
|
public ServerTable(){
|
||||||
servers = new ArrayList<>();
|
servers = new ArrayList<>();
|
||||||
@@ -17,9 +19,11 @@ public class ServerTable {
|
|||||||
updateServers();
|
updateServers();
|
||||||
}
|
}
|
||||||
}, 0, 1000);
|
}, 0, 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the servers TTL values, and then remove expired servers
|
||||||
|
*/
|
||||||
private void updateServers() {
|
private void updateServers() {
|
||||||
List<ServerListing> serversToRemove = new ArrayList<>();
|
List<ServerListing> serversToRemove = new ArrayList<>();
|
||||||
|
|
||||||
@@ -27,38 +31,52 @@ public class ServerTable {
|
|||||||
server.decrementTtl();
|
server.decrementTtl();
|
||||||
|
|
||||||
if (server.hasTtlExpired()){
|
if (server.hasTtlExpired()){
|
||||||
|
logger.debug("Removed expired server - " + server.getServerName());
|
||||||
serversToRemove.add(server);
|
serversToRemove.add(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ServerListing server : serversToRemove){
|
servers.removeAll(serversToRemove);
|
||||||
System.out.println("Removing " + server.getServerName());
|
|
||||||
servers.remove(server);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a server to the table
|
||||||
|
* @param server The server to add
|
||||||
|
*/
|
||||||
public void addServer(ServerListing server){
|
public void addServer(ServerListing server){
|
||||||
if (servers.contains(server)){
|
if (servers.contains(server)){
|
||||||
updateTtlForServer(server);
|
updateTtlForServer(server);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.debug("Added new server - " + server.getServerName());
|
||||||
servers.add(server);
|
servers.add(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the TTL for a given server to the default TTL value
|
||||||
|
* @param server The server to update
|
||||||
|
*/
|
||||||
private void updateTtlForServer(ServerListing server) {
|
private void updateTtlForServer(ServerListing server) {
|
||||||
for (ServerListing serverListing : servers){
|
for (ServerListing serverListing : servers){
|
||||||
if (server.equals(serverListing)){
|
if (server.equals(serverListing)){
|
||||||
System.out.println("Refreshing TTL For " + server.getServerName());
|
|
||||||
serverListing.refreshTtl();
|
serverListing.refreshTtl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return All the servers in the table
|
||||||
|
*/
|
||||||
public List<ServerListing> getAllServers(){
|
public List<ServerListing> getAllServers(){
|
||||||
return Collections.unmodifiableList(servers);
|
return Collections.unmodifiableList(servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a server from the table given its room code
|
||||||
|
* @param roomCode The room code to search for
|
||||||
|
* @return The ServerListing of the found server, or null
|
||||||
|
* the server wasn't found
|
||||||
|
*/
|
||||||
public ServerListing getServerByRoomCode(String roomCode){
|
public ServerListing getServerByRoomCode(String roomCode){
|
||||||
for (ServerListing serverListing : servers){
|
for (ServerListing serverListing : servers){
|
||||||
if (serverListing.getRoomCode().equals(roomCode)){
|
if (serverListing.getRoomCode().equals(roomCode)){
|
||||||
@@ -69,11 +87,11 @@ public class ServerTable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The next available room code
|
||||||
|
*/
|
||||||
public Integer getNextRoomCode(){
|
public Integer getNextRoomCode(){
|
||||||
System.out.println(lastRoomCode);
|
|
||||||
lastRoomCode += 1;
|
lastRoomCode += 1;
|
||||||
return lastRoomCode;
|
return lastRoomCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
package seng302.gameServer;
|
package seng302.gameServer;
|
||||||
|
|
||||||
import com.sun.org.apache.xpath.internal.operations.Bool;
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
import org.slf4j.Logger;
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import seng302.serverRepository.ServerListing;
|
|
||||||
import seng302.serverRepository.ServerRepositoryClient;
|
|
||||||
|
|
||||||
import javax.jmdns.JmDNS;
|
import javax.jmdns.JmDNS;
|
||||||
import javax.jmdns.ServiceInfo;
|
import javax.jmdns.ServiceInfo;
|
||||||
@@ -38,14 +35,14 @@ public class ServerAdvertiser {
|
|||||||
private static ServerAdvertiser instance = null;
|
private static ServerAdvertiser instance = null;
|
||||||
private static JmDNS jmdnsInstance = null;
|
private static JmDNS jmdnsInstance = null;
|
||||||
private ServiceInfo serviceInfo; // Note: Whenever this is changed, our service will be re-registered on the network.
|
private ServiceInfo serviceInfo; // Note: Whenever this is changed, our service will be re-registered on the network.
|
||||||
private ServerRepositoryClient repositoryClient;
|
private DiscoveryServerClient repositoryClient;
|
||||||
|
|
||||||
private Hashtable<String ,String> props;
|
private Hashtable<String ,String> props;
|
||||||
|
|
||||||
private ServerAdvertiser() throws IOException{
|
private ServerAdvertiser() throws IOException{
|
||||||
jmdnsInstance = JmDNS.create(InetAddress.getByName(getLocalHostIp()));
|
jmdnsInstance = JmDNS.create(InetAddress.getByName(getLocalHostIp()));
|
||||||
|
|
||||||
repositoryClient = new ServerRepositoryClient();
|
repositoryClient = new DiscoveryServerClient();
|
||||||
|
|
||||||
props = new Hashtable<>();
|
props = new Hashtable<>();
|
||||||
props.put("map", "");
|
props.put("map", "");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package seng302.gameServer.messages;
|
package seng302.gameServer.messages;
|
||||||
|
|
||||||
import seng302.serverRepository.ServerListing;
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
|
||||||
public class ServerRegistrationMessage extends Message {
|
public class ServerRegistrationMessage extends Message {
|
||||||
private int size;
|
private int size;
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
package seng302.serverRepository;
|
|
||||||
|
|
||||||
import seng302.gameServer.messages.Message;
|
|
||||||
import seng302.gameServer.messages.RoomCodeRequest;
|
|
||||||
import seng302.gameServer.messages.ServerRegistrationMessage;
|
|
||||||
import seng302.model.stream.packets.PacketType;
|
|
||||||
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class ServerRepository {
|
|
||||||
private ServerTable serverTable;
|
|
||||||
|
|
||||||
public ServerRepository() throws Exception {
|
|
||||||
System.out.println(" -- Starting Server Repository -- ");
|
|
||||||
serverTable = new ServerTable();
|
|
||||||
|
|
||||||
ServerSocket serverSocket = new ServerSocket(9999);
|
|
||||||
|
|
||||||
|
|
||||||
// // TODO Remove later, this is for testing
|
|
||||||
// new Timer().schedule(new TimerTask() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
// try {
|
|
||||||
// System.out.println("Starting repo client");
|
|
||||||
// new ServerRepositoryClient();
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }, 5000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (true){
|
|
||||||
Socket clientSocket = serverSocket.accept();
|
|
||||||
|
|
||||||
parseRequest(clientSocket);
|
|
||||||
|
|
||||||
clientSocket.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void parseRequest(Socket clientSocket) throws Exception {
|
|
||||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(clientSocket.getInputStream());
|
|
||||||
|
|
||||||
if (clientSocket.isConnected() && !clientSocket.isClosed()){
|
|
||||||
PacketType parsePacketResult = parser.parse();
|
|
||||||
|
|
||||||
switch (parsePacketResult){
|
|
||||||
case SERVER_REGISTRATION:
|
|
||||||
ServerListing listing = parser.getServerListing();
|
|
||||||
|
|
||||||
if (!serverTable.getAllServers().contains(listing)){
|
|
||||||
listing.setRoomCode(serverTable.getNextRoomCode().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
serverTable.addServer(listing);
|
|
||||||
|
|
||||||
Message serverRegMessage = new RoomCodeRequest(listing.getRoomCode());
|
|
||||||
clientSocket.getOutputStream().write(serverRegMessage.getBuffer());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ROOM_CODE_REQUEST:
|
|
||||||
String desiredRoomCode = parser.getRoomCode();
|
|
||||||
|
|
||||||
ServerListing serverListing = serverTable.getServerByRoomCode(desiredRoomCode);
|
|
||||||
Message response;
|
|
||||||
|
|
||||||
if (serverListing != null){
|
|
||||||
response = new ServerRegistrationMessage(serverListing.getServerName(), serverListing.getMapName(), serverListing.getAddress(), serverListing.getPortNumber(), 0, 0, desiredRoomCode);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
response = new ServerRegistrationMessage("", "", "", 0, 0, 0, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
clientSocket.getOutputStream().write(response.getBuffer());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,7 @@ 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.serverRepository.ServerRepositoryClient;
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.GameView;
|
import seng302.visualiser.GameView;
|
||||||
import seng302.visualiser.controllers.cells.PlayerCell;
|
import seng302.visualiser.controllers.cells.PlayerCell;
|
||||||
@@ -83,8 +83,8 @@ 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"));
|
||||||
|
|
||||||
if (ServerRepositoryClient.getRoomCode() != null){
|
if (DiscoveryServerClient.getRoomCode() != null){
|
||||||
setRoomCode(ServerRepositoryClient.getRoomCode());
|
setRoomCode(DiscoveryServerClient.getRoomCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewManager.getInstance().getPlayerList().addListener((ListChangeListener<String>) c -> Platform.runLater(this::refreshPlayerList));
|
ViewManager.getInstance().getPlayerList().addListener((ListChangeListener<String>) c -> Platform.runLater(this::refreshPlayerList));
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ 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;
|
||||||
@@ -22,9 +23,10 @@ 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.gameServer.ServerDescription;
|
||||||
import seng302.serverRepository.ServerListing;
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
import seng302.serverRepository.ServerRepositoryClient;
|
import seng302.discoveryServer.DiscoveryServerClient;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.ServerListener;
|
import seng302.visualiser.ServerListener;
|
||||||
import seng302.visualiser.ServerListenerDelegate;
|
import seng302.visualiser.ServerListenerDelegate;
|
||||||
@@ -169,10 +171,19 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
|||||||
|
|
||||||
private void connectToRoomCode(String roomCode){
|
private void connectToRoomCode(String roomCode){
|
||||||
try {
|
try {
|
||||||
ServerListing serverListing = new ServerRepositoryClient().getServerForRoomCode(roomCode);
|
ServerListing serverListing = new DiscoveryServerClient().getServerForRoomCode(roomCode);
|
||||||
ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber());
|
ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber());
|
||||||
} catch (Exception e) {
|
}
|
||||||
e.printStackTrace();
|
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) {
|
||||||
|
logger.warn("Error discovering room code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import javafx.stage.Stage;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.gameServer.ServerAdvertiser;
|
import seng302.gameServer.ServerAdvertiser;
|
||||||
import seng302.serverRepository.ServerRepositoryClient;
|
|
||||||
import seng302.utilities.BonjourInstallChecker;
|
import seng302.utilities.BonjourInstallChecker;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.GameClient;
|
import seng302.visualiser.GameClient;
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package seng302.serverDiscovery;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import seng302.discoveryServer.util.ServerListing;
|
||||||
|
import seng302.discoveryServer.util.ServerTable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class ServerTableTest {
|
||||||
|
private static ServerTable serverTable;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup(){
|
||||||
|
serverTable = new ServerTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddServer(){
|
||||||
|
ServerListing listing = new ServerListing("", "", "", 12, 12);
|
||||||
|
serverTable.addServer(listing);
|
||||||
|
|
||||||
|
assertTrue(serverTable.getAllServers().contains(listing));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetNextRoomCodeIsUnique(){
|
||||||
|
assertTrue(!Objects.equals(serverTable.getNextRoomCode(), serverTable.getNextRoomCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetServerRoomCode(){
|
||||||
|
ServerListing listing = new ServerListing("123", "", "", 12, 12);
|
||||||
|
listing.setRoomCode(serverTable.getNextRoomCode().toString());
|
||||||
|
serverTable.addServer(listing);
|
||||||
|
|
||||||
|
ServerListing result = serverTable.getServerByRoomCode(listing.getRoomCode());
|
||||||
|
|
||||||
|
assertTrue(result.equals(listing));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServersRemovedOnExpiry() throws InterruptedException {
|
||||||
|
ServerListing listing = new ServerListing("432", "221", "", 12, 12);
|
||||||
|
listing.setTtl(1);
|
||||||
|
|
||||||
|
serverTable.addServer(listing);
|
||||||
|
|
||||||
|
listing.decrementTtl();
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
assertTrue(!serverTable.getAllServers().contains(listing));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package seng302.serverDiscovery;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import seng302.gameServer.messages.Message;
|
||||||
|
import seng302.gameServer.messages.RoomCodeRequest;
|
||||||
|
import seng302.model.stream.packets.PacketType;
|
||||||
|
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class testStreamParser {
|
||||||
|
private static ServerRepoStreamParser parser;
|
||||||
|
private static InputStream inputStream;
|
||||||
|
|
||||||
|
private static void setupWithByteArray(byte[] bytes){
|
||||||
|
inputStream = new ByteArrayInputStream(bytes);
|
||||||
|
parser = new ServerRepoStreamParser(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseRoomCodeRequest() throws Exception {
|
||||||
|
Message roomCodeMsg = new RoomCodeRequest("1234");
|
||||||
|
setupWithByteArray(roomCodeMsg.getBuffer());
|
||||||
|
|
||||||
|
assertTrue(parser.parse() == PacketType.ROOM_CODE_REQUEST);
|
||||||
|
assertTrue(parser.getRoomCode().equals("1234"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user