start online game
This commit is contained in:
parent
8bc64bd9ba
commit
3eeb4d25bd
|
@ -2,19 +2,29 @@ import java.io.IOException;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GameController {
|
||||
|
||||
// Connection timeout for client sockets in milliseconds
|
||||
public static final int CONNECTION_TIMEOUT = 10 * 1000;
|
||||
|
||||
public HashMap<String, Class<? extends OnlinePlayer>> supportedVersions = new HashMap<>(Map.of(
|
||||
"1.1.0", OnlinePlayer_1_1_0.class
|
||||
));
|
||||
|
||||
public void startOnlineGame(Class<? extends LocalPlayer> localPlayerClass, InetSocketAddress address) throws IOException {
|
||||
AsyncSocket clientSocket;
|
||||
if (address.getHostName() == null) {
|
||||
|
||||
boolean localPlayerIsServer = address.getHostName() == null;
|
||||
|
||||
if (localPlayerIsServer) {
|
||||
// SERVER MODE
|
||||
|
||||
ServerSocket serverSocket = new ServerSocket(address.getPort());
|
||||
|
||||
System.out.println("Waiting for client connection...");
|
||||
|
@ -23,10 +33,21 @@ public class GameController {
|
|||
|
||||
serverSocket.close();
|
||||
} else {
|
||||
Socket socket = new Socket();
|
||||
socket.connect(address);
|
||||
// CLIENT MODE
|
||||
|
||||
Socket socket = new Socket();
|
||||
|
||||
try {
|
||||
socket.connect(address, CONNECTION_TIMEOUT);
|
||||
|
||||
clientSocket = new AsyncSocket(socket, null);
|
||||
} catch (SocketTimeoutException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Connection timed out");
|
||||
} finally {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
clientSocket = new AsyncSocket(socket, null);
|
||||
}
|
||||
|
||||
clientSocket.send("VERSION", "Gruppe03 " + String.join(" ", supportedVersions.keySet()));
|
||||
|
@ -34,15 +55,101 @@ public class GameController {
|
|||
|
||||
SocketPackage socketPackage = new SocketPackage(message);
|
||||
if (socketPackage.getName().equals("VERSION")) {
|
||||
// TODO: check version matches - instantiate online player
|
||||
|
||||
List<String> opponentSupportedVersions = socketPackage.splitData();
|
||||
|
||||
String usedVersion = findMostRecentVersion(new ArrayList<String>(supportedVersions.keySet()), opponentSupportedVersions);
|
||||
|
||||
if (usedVersion == null) {
|
||||
throw new RuntimeException("No common versions found");
|
||||
}
|
||||
|
||||
// instantiate players
|
||||
Class<? extends OnlinePlayer> onlinePlayerClass = supportedVersions.get(usedVersion);
|
||||
|
||||
LocalPlayer localPlayer;
|
||||
OnlinePlayer onlinePlayer;
|
||||
try {
|
||||
localPlayer = localPlayerClass.getDeclaredConstructor().newInstance();
|
||||
onlinePlayer = onlinePlayerClass.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Unable to instantiate players");
|
||||
}
|
||||
|
||||
localPlayer.isServer = localPlayerIsServer;
|
||||
onlinePlayer.isServer = !localPlayerIsServer;
|
||||
|
||||
startGameWithInstancedPlayers(localPlayer, onlinePlayer);
|
||||
|
||||
} else {
|
||||
// TODO: received invalid package / package out of order
|
||||
throw new RuntimeException("Unexpected Package received before game initialisation");
|
||||
}
|
||||
});
|
||||
// TODO: instantiate local player, set server / client roles
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* finds the largest common version in two lists of version strings
|
||||
* @return null if no common versions are found
|
||||
*/
|
||||
public String findMostRecentVersion(List<String> versions1, List<String> versions2) {
|
||||
if (versions1 == null || versions2 == null) return null;
|
||||
String largestCommonVersion = null;
|
||||
for (String v1 : versions1) {
|
||||
if (!checkVersionString(v1)) continue;
|
||||
|
||||
for (String v2 : versions2) {
|
||||
if (!checkVersionString(v2)) continue;
|
||||
|
||||
// strings within the lists must be equal
|
||||
// if no largest common version has been found or currently checked version is larger than
|
||||
// previous largest common version, new largest version has been found
|
||||
if (compareVersions(v1, v2) == 0 && (largestCommonVersion == null || compareVersions(v1, largestCommonVersion) >= 1)) {
|
||||
largestCommonVersion = v1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return largestCommonVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* compares two version strings
|
||||
* @return
|
||||
* 0 if versions are equal
|
||||
* 1 if version1 is more recent than version2
|
||||
* -1 otherwise
|
||||
*/
|
||||
public int compareVersions(String version1, String version2) {
|
||||
if (!checkVersionString(version1) || !checkVersionString(version2)) {
|
||||
throw new IllegalArgumentException("Version is not valid version string");
|
||||
}
|
||||
|
||||
String[] version1Split = version1.split("\\.");
|
||||
String[] version2Split = version2.split("\\.");
|
||||
|
||||
for (int i = 0; i < version1Split.length; i++) {
|
||||
int v1 = Integer.parseInt(version1Split[i]);
|
||||
int v2 = Integer.parseInt(version2Split[i]);
|
||||
|
||||
if (v1 == v2) continue;
|
||||
if (v1 > v2) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a provided string matches the format of a version number
|
||||
*/
|
||||
public boolean checkVersionString(String versionString) {
|
||||
return versionString != null && versionString.matches("\\d+\\.\\d+\\.\\d+");
|
||||
}
|
||||
|
||||
public void startLocalGame(Class<? extends LocalPlayer> localPlayerClass, Class<? extends AiPlayer> enemyClass, int size) {
|
||||
|
||||
LocalPlayer localPlayer;
|
||||
|
@ -52,10 +159,16 @@ public class GameController {
|
|||
aiPlayer = enemyClass.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
throw new RuntimeException("Unable to instantiate players");
|
||||
}
|
||||
localPlayer.setEnemy(aiPlayer);
|
||||
aiPlayer.setEnemy(localPlayer);
|
||||
startGameWithInstancedPlayers(localPlayer, aiPlayer);
|
||||
}
|
||||
|
||||
private void startGameWithInstancedPlayers(LocalPlayer p1, Player p2) {
|
||||
p1.setEnemy(p2);
|
||||
p2.setEnemy(p1);
|
||||
|
||||
// TODO: frontend configuration
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue