start online game

This commit is contained in:
Luca Conte 2024-11-30 17:58:24 +01:00
parent 8bc64bd9ba
commit 3eeb4d25bd
1 changed files with 122 additions and 9 deletions

View File

@ -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
}
}