mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
cf4f8813d2
- Correct player count is shown in server list - Servers now advertise their capacity and number of players connected - Players can click join on the servers in the server list - Direct connect works - Can set max players / server name in host dialog - Server starts correctly when host clicked - Implemented boat customization - Implemented 'begin race button', and disabled it for players that aren't hosts - Added countdown timer in lobby - Fixed bug where app wouldn't close Tags: #story[1245]
174 lines
5.5 KiB
Java
174 lines
5.5 KiB
Java
package seng302.gameServer;
|
|
|
|
import javax.jmdns.JmDNS;
|
|
import javax.jmdns.ServiceInfo;
|
|
import java.io.IOException;
|
|
import java.net.Inet4Address;
|
|
import java.net.InetAddress;
|
|
import java.net.NetworkInterface;
|
|
import java.util.Enumeration;
|
|
import java.util.Hashtable;
|
|
|
|
/**
|
|
* Advertises the game server on the local network
|
|
*/
|
|
public class ServerAdvertiser {
|
|
/*
|
|
Our service name & protocol
|
|
|
|
This must be in the format _Service._Proto.Name as per http://www.ietf.org/rfc/rfc2782.txt
|
|
Where Service is unique on the network, and protocol is usually _tcp.
|
|
|
|
The pseudo-domain 'local.' must end in a full-stop. This is used to indicate that
|
|
the lookup should be performed using an IP multicast query on the local IP network.
|
|
|
|
Read this before changing any of the following values
|
|
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/NetServices/Articles/domainnames.html#//apple_ref/doc/uid/TP40002460-SW1
|
|
*/
|
|
private static String SERVICE = "_partyatsea";
|
|
private static String PROTOCOL = "_tcp";
|
|
public static String SERVICE_TYPE = SERVICE + "." + PROTOCOL + ".local.";
|
|
|
|
private static ServerAdvertiser instance = null;
|
|
private static JmDNS jmdnsInstance = null;
|
|
private ServiceInfo serviceInfo; // Note: Whenever this is changed, our service will be re-registered on the network.
|
|
|
|
private Hashtable<String ,String> props;
|
|
|
|
private ServerAdvertiser() throws IOException{
|
|
jmdnsInstance = JmDNS.create(InetAddress.getByName(getLocalHostIp()));
|
|
|
|
props = new Hashtable<>();
|
|
props.put("map", "");
|
|
props.put("spacesLeft", "0");
|
|
props.put("capacity", "0");
|
|
props.put("players", "0");
|
|
}
|
|
|
|
/**
|
|
* Get an instance of the ServerAdvertiser, create an instance if there isn't already one
|
|
* @return A ServerAdvertiser Instance
|
|
* @throws IOException If there was an exception creating the instance
|
|
*/
|
|
public static ServerAdvertiser getInstance() throws IOException {
|
|
if (instance == null){
|
|
instance = new ServerAdvertiser();
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Set the map name and broadcast an update on the network
|
|
* @param mapName The new map name
|
|
* @return The current ServerAdvertiser instance
|
|
*/
|
|
public ServerAdvertiser setMapName(String mapName){
|
|
props.replace("map", mapName);
|
|
|
|
if (serviceInfo != null){
|
|
serviceInfo.setText(props);
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Set the number of players on the server and broadcast an update on the network
|
|
* @param numPlayers The number of players on the server
|
|
* @return The current ServerAdvertiser instance
|
|
*/
|
|
public ServerAdvertiser setNumberOfPlayers(Integer numPlayers){
|
|
props.replace("players", numPlayers.toString());
|
|
|
|
if (serviceInfo != null){
|
|
serviceInfo.setText(props);
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Set the max capacity of the server and broadcast an update on the network
|
|
* @param capacity The maximum capacity of the server
|
|
* @return The current ServerAdvertiser instance
|
|
*/
|
|
public ServerAdvertiser setCapacity(Integer capacity){
|
|
props.replace("capacity", capacity.toString());
|
|
|
|
if (serviceInfo != null){
|
|
serviceInfo.setText(props);
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* Register this service on the network
|
|
*
|
|
* Note: other parameters (map name/spaces left etc) are set after the
|
|
* service has been registered
|
|
* @param portNo The servers port number
|
|
* @param serverName The servers name
|
|
*/
|
|
public void registerGame(Integer portNo, String serverName) {
|
|
|
|
serviceInfo = ServiceInfo.create(SERVICE_TYPE, serverName, portNo, 0, 0, props);
|
|
|
|
new java.util.Timer().schedule(
|
|
new java.util.TimerTask() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
jmdnsInstance.registerService(serviceInfo);
|
|
} catch (IOException e) {
|
|
System.out.println("Failed");
|
|
}
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
/**
|
|
* Unregister the service
|
|
*/
|
|
public void unregister(){
|
|
if (serviceInfo != null)
|
|
jmdnsInstance.unregisterService(serviceInfo);
|
|
}
|
|
|
|
/**
|
|
* Gets the local host ip address.
|
|
*
|
|
* @return the localhost ip address
|
|
*/
|
|
public static String getLocalHostIp() {
|
|
String ipAddress = null;
|
|
try {
|
|
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
|
|
while (e.hasMoreElements()) {
|
|
NetworkInterface ni = e.nextElement();
|
|
if (ni.isLoopback())
|
|
continue;
|
|
if(ni.isPointToPoint())
|
|
continue;
|
|
if(ni.isVirtual())
|
|
continue;
|
|
|
|
Enumeration<InetAddress> addresses = ni.getInetAddresses();
|
|
while(addresses.hasMoreElements()) {
|
|
InetAddress address = addresses.nextElement();
|
|
if(address instanceof Inet4Address) { // skip all ipv6
|
|
ipAddress = address.getHostAddress();
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
if (ipAddress == null) {
|
|
System.out.println("[HOST] Cannot obtain local host ip address.");
|
|
}
|
|
return ipAddress;
|
|
}
|
|
}
|