diff --git a/client/build.gradle b/client/build.gradle deleted file mode 100644 index 15c2d1d..0000000 --- a/client/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ - -apply plugin: 'java' -apply plugin: 'com.github.johnrengelman.shadow' - -group 'com.faforever' -version '1.0-SNAPSHOT' - -sourceCompatibility = JavaVersion.VERSION_17 - -repositories { - mavenCentral() -} - -dependencies { - annotationProcessor("org.projectlombok:lombok:$lombokVersion") - implementation("org.projectlombok:lombok:$lombokVersion") - - implementation("org.openjfx:javafx-base:${javafxVersion}:${javafxPlatform}") - implementation("org.openjfx:javafx-controls:${javafxVersion}:${javafxPlatform}") - implementation("org.openjfx:javafx-graphics:${javafxVersion}:${javafxPlatform}") - implementation("org.openjfx:javafx-fxml:${javafxVersion}:${javafxPlatform}") - implementation("org.openjfx:javafx-web:${javafxVersion}:${javafxPlatform}") - implementation("org.openjfx:javafx-media:${javafxVersion}:${javafxPlatform}") - - implementation project(":shared") -// implementation project(":ice-adapter") - implementation("com.sun.jna:jna:3.0.9") - implementation("net.java.dev.jna:jna-platform:5.12.1") - implementation("commons-io:commons-io:2.11.0") - implementation("com.github.Geosearchef:JJsonRpc:master") - implementation("com.google.code.gson:gson:$gsonVersion") - implementation("com.google.guava:guava:$guavaVersion") -} - - -jar { - manifest { - attributes 'Main-Class': 'client.TestClient' - } -} \ No newline at end of file diff --git a/client/src/main/java/client/GUI.java b/client/src/main/java/client/GUI.java deleted file mode 100644 index 05df92a..0000000 --- a/client/src/main/java/client/GUI.java +++ /dev/null @@ -1,384 +0,0 @@ -package client; - -import client.experimental.HolePunching; -import client.ice.ICEAdapter; -import common.ICEAdapterTest; -import data.ForgedAlliancePeer; -import javafx.application.Application; -import javafx.application.Platform; -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.geometry.Insets; -import javafx.geometry.Orientation; -import javafx.scene.Scene; -import javafx.scene.control.*; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Region; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; -import javafx.util.Callback; -import logging.Logger; -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; -import java.util.OptionalDouble; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; - -public class GUI extends Application { - - public static CompletableFuture started; - public static GUI instance; - - public Stage stage; - - public TableView table; - private TableColumn[] tableColumns = {new TableColumn<>("id"), new TableColumn<>("name"), new TableColumn<>("latency"), new TableColumn<>("last_rec"), new TableColumn<>("loc_cand"), new TableColumn<>("rem_cand"), new TableColumn("state"), new TableColumn("exp_pnch")}; - public StringProperty scenario = new SimpleStringProperty("none"); - - private ObservableList peers = FXCollections.observableArrayList(); - @Getter - private final VBox root = new VBox(); - - public static void showUsernameDialog(String preGeneratedUsername) { - runAndWait(() -> { - TextInputDialog nameDialog = new TextInputDialog(preGeneratedUsername); - nameDialog.setTitle("ICE adapter test"); - nameDialog.setHeaderText("Welcome to the ICE adapter test client"); - nameDialog.setContentText("Please enter an (alphanumerical) username:"); - - if(! TestClient.DEBUG_MODE) { - nameDialog.showAndWait().ifPresent(name -> { - if (name.length() > 0) { - TestClient.username = name; - } else { - Logger.error("invalid username provided: %s", name); - System.exit(1); - } - }); - } else { - TestClient.username = "iceTester" + (int)(Math.random() * 10000); - } - - if (TestClient.username == null) { - Logger.error("no username provided"); - System.exit(-1); - } - }); - } - - public static void showGDPRDialog() { - runAndWait(() -> { - Alert gdprDialog = new Alert(Alert.AlertType.CONFIRMATION); - gdprDialog.setTitle("ICE adapter test"); - gdprDialog.setHeaderText("Data usage"); - gdprDialog.setContentText(ICEAdapterTest.GDPR); - gdprDialog.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); - - if(! TestClient.DEBUG_MODE) { - Optional result = gdprDialog.showAndWait(); - if(! result.isPresent() || result.get() != ButtonType.OK) { - System.exit(0); - } - } - }); - } - - public static CompletableFuture showDialog(String s) { - CompletableFuture future = new CompletableFuture<>(); - Platform.runLater(() -> { - Alert alert = new Alert(Alert.AlertType.INFORMATION); - alert.setTitle("ICE adapter test"); - alert.setHeaderText(s); - alert.show(); - future.complete(alert); - }); - return future; - } - - public static void init(String args[]) { - Platform.setImplicitExit(false); - - started = new CompletableFuture<>(); - new Thread(() -> launch(args)).start(); - started.join(); - - new Thread(GUI.instance::uiUpdateThread).start(); - } - - public static void runAndWait(Runnable action) { - if (Platform.isFxApplicationThread()) { - action.run(); - return; - } - - CountDownLatch completed = new CountDownLatch(1); - Platform.runLater(() -> { - try { - action.run(); - } finally { - completed.countDown(); - } - }); - - try { - completed.await(); - } catch (InterruptedException e) { - } - } - - @Override - public void start(Stage stage) { - instance = this; - this.stage = stage; - stage.setTitle("ICE adapter testclient"); - stage.setWidth(700); - stage.setHeight(800); - - stage.show(); - stage.hide(); - - root.setSpacing(10); - root.setPadding(new Insets(10, 10, 10, 10)); - HBox connectionStatus = new HBox(); - - Label serverConnectionStatus = new Label("Connected: false"); - TestServerAccessor.connected.addListener(((observable, oldValue, newValue) -> runAndWait(() -> serverConnectionStatus.setText("TestServer: " + newValue + "(" + TestClient.playerID + ")")))); - connectionStatus.getChildren().add(serverConnectionStatus); - - - Separator separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - connectionStatus.getChildren().add(separator); - - Label iceConnectionStatus = new Label("ICE: false"); - ICEAdapter.connected.addListener(((observable, oldValue, newValue) -> runAndWait(() -> iceConnectionStatus.setText("ICE: " + newValue)))); - connectionStatus.getChildren().add(iceConnectionStatus); - - separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - connectionStatus.getChildren().add(separator); - - Label gameRunningStatus = new Label("ForgedAlliance: false"); - TestClient.isGameRunning.addListener(((observable, oldValue, newValue) -> runAndWait(() -> gameRunningStatus.setText("ForgedAlliance: " + (newValue ? "running" : "stopped"))))); - connectionStatus.getChildren().add(gameRunningStatus); - - - root.getChildren().add(connectionStatus); - - HBox FAstatus = new HBox(); - FAstatus.visibleProperty().bind(TestClient.isGameRunning); - FAstatus.managedProperty().bind(TestClient.isGameRunning); - - FAstatus.getChildren().add(peerCount); - separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - FAstatus.getChildren().add(separator); - FAstatus.getChildren().add(connectedCount); - separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - FAstatus.getChildren().add(separator); - FAstatus.getChildren().add(quietCount); - separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - FAstatus.getChildren().add(separator); - FAstatus.getChildren().add(outBandwidth); - separator = new Separator(Orientation.VERTICAL); - separator.setMinWidth(30); - FAstatus.getChildren().add(separator); - FAstatus.getChildren().add(inBandwidth); - - root.getChildren().add(FAstatus); - - - - separator = new Separator(Orientation.HORIZONTAL); - root.getChildren().add(separator); - root.getChildren().add(new Label("ICE Test is running. Please keep this window open.")); - - Label scenarioLabel = new Label(); - scenario.addListener((observableValue, oldValue, newValue) -> scenarioLabel.setText("Scenario: " + newValue)); - root.getChildren().add(scenarioLabel); - - separator = new Separator(Orientation.HORIZONTAL); - root.getChildren().add(separator); - - - table = new TableView(); - tableColumns[0].setMinWidth(50); - tableColumns[1].setMinWidth(150); - tableColumns[2].setMinWidth(50); - tableColumns[3].setMinWidth(50); - tableColumns[4].setMinWidth(80); - tableColumns[5].setMinWidth(80); - tableColumns[6].setMinWidth(80); - tableColumns[7].setMinWidth(50); - //TODO: use lambdas - tableColumns[0].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - return new ReadOnlyStringWrapper(String.valueOf(cellData.getValue().getRemoteId())); - } - }); - tableColumns[1].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - return new ReadOnlyStringWrapper(cellData.getValue().getRemoteUsername()); - } - }); - tableColumns[2].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - synchronized (cellData.getValue().getLatencies()) { - OptionalDouble lat = cellData.getValue().getLatencies().stream().mapToInt(Integer::intValue).average(); - if(lat.isPresent()) { - return new ReadOnlyStringWrapper(String.format("%.0f ms", lat.getAsDouble())); - } else { - return new ReadOnlyStringWrapper(""); - } - } - } - }); - tableColumns[3].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - return new ReadOnlyStringWrapper(String.valueOf(System.currentTimeMillis() - cellData.getValue().getLastPacketReceived()) + " ms"); - } - }); - tableColumns[4].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - if(ICEAdapter.latestIceStatus != null && ICEAdapter.latestIceStatus.getRelays() != null) { - return new ReadOnlyStringWrapper(Arrays.stream(ICEAdapter.latestIceStatus.getRelays()) - .filter(r -> r.getRemote_player_id() == cellData.getValue().remoteId) - .filter(r -> r.getIce() != null) - .findFirst() - .map(r -> r.getIce().getLoc_cand_type()) - .orElse("none")); - } - return new ReadOnlyStringWrapper(""); - } - }); - tableColumns[5].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - if(ICEAdapter.latestIceStatus != null && ICEAdapter.latestIceStatus.getRelays() != null) { - return new ReadOnlyStringWrapper(Arrays.stream(ICEAdapter.latestIceStatus.getRelays()) - .filter(r -> r.getRemote_player_id() == cellData.getValue().remoteId) - .filter(r -> r.getIce() != null) - .findFirst() - .map(r -> r.getIce().getRem_cand_type()) - .orElse("none")); - } - return new ReadOnlyStringWrapper(""); - } - }); - tableColumns[6].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - if (ICEAdapter.latestIceStatus != null && ICEAdapter.latestIceStatus.getRelays() != null) { - return new ReadOnlyStringWrapper(Arrays.stream(ICEAdapter.latestIceStatus.getRelays()) - .filter(r -> r.getRemote_player_id() == cellData.getValue().remoteId) - .filter(r -> r.getIce() != null) - .findFirst() - .map(r -> r.getIce().getState()) - .orElse("none")); - } - return new ReadOnlyStringWrapper(""); - } - }); - tableColumns[7].setCellValueFactory(new Callback, ObservableValue>() { - @Override - public ObservableValue call(TableColumn.CellDataFeatures cellData) { - return new ReadOnlyStringWrapper(HolePunching.latencies.containsKey(cellData.getValue().remoteId) ? String.valueOf(HolePunching.latencies.get(cellData.getValue().remoteId)) + " ms" : ""); - } - }); - table.setItems(peers); - table.getColumns().addAll(tableColumns); - root.getChildren().add(table); - - - separator = new Separator(Orientation.HORIZONTAL); - root.getChildren().add(separator); - - - HBox iceAdapterControls = new HBox(); - Button stopButton = new Button("SIGSTOP"); - stopButton.setOnAction(e -> { - ICEAdapter.sigStop(); - }); - iceAdapterControls.getChildren().add(stopButton); - Button contButton = new Button("SIGCONT"); - contButton.setOnAction(e -> { - ICEAdapter.sigCont(); - }); - iceAdapterControls.getChildren().add(contButton); - Button killButton = new Button("SIGKILL"); - killButton.setOnAction(e -> { - ICEAdapter.sigKill(); - }); - iceAdapterControls.getChildren().add(killButton); - - if(System.getProperty("os.name").contains("Windows")) { - stopButton.setDisable(true); - killButton.setDisable(true); - } - - - root.getChildren().add(iceAdapterControls); - - - - - stage.setScene(new Scene(root, stage.getWidth(), stage.getHeight())); - - - stage.setOnCloseRequest(e -> { - Logger.info("Close requested"); - TestClient.close(); - }); - - started.complete(instance); - } - - private Label peerCount = new Label(""); - private Label connectedCount = new Label(""); - private Label quietCount = new Label(""); - private Label outBandwidth = new Label(""); - private Label inBandwidth = new Label(""); - - private void uiUpdateThread() { - while(true) { - Platform.runLater(() -> { - if(TestClient.isGameRunning.get() && TestClient.forgedAlliance.peers != null) { - synchronized (TestClient.forgedAlliance.peers) { - - peerCount.setText("Peers: " + TestClient.forgedAlliance.peers.size()); - connectedCount.setText("Connected: " + TestClient.forgedAlliance.peers.stream().filter(ForgedAlliancePeer::isConnected).count()); - quietCount.setText("Quiet: " + TestClient.forgedAlliance.peers.stream().filter(ForgedAlliancePeer::isQuiet).count()); - - outBandwidth.setText(String.format("sent %.2f kB/s", TestClient.forgedAlliance.bytesPerSecondOut / 1000f)); - inBandwidth.setText(String.format("received %.2f kB/s", TestClient.forgedAlliance.bytesPerSecondOut / 1000f)); - - this.peers.clear(); - this.peers.addAll(TestClient.forgedAlliance.peers); - } - } - }); - - try { Thread.sleep(100); } catch(InterruptedException e) {} - } - } - - public void showStage() { - runAndWait(() -> { - stage.show(); - stage.centerOnScreen(); - }); - } -} diff --git a/client/src/main/java/client/TestClient.java b/client/src/main/java/client/TestClient.java deleted file mode 100644 index 75453e4..0000000 --- a/client/src/main/java/client/TestClient.java +++ /dev/null @@ -1,164 +0,0 @@ -package client; - -import client.experimental.VoiceChat; -import client.forgedalliance.ForgedAlliance; -import client.ice.ICEAdapter; -import data.IceStatus; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import logging.Logger; -import net.ClientInformationMessage; -import net.ScenarioOptionsMessage; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedList; - -import static com.github.nocatch.NoCatch.noCatch; - -public class TestClient { - - public static boolean DEBUG_MODE = false; - private static final int INFORMATION_INTERVAL = 2500; - - public static String username; - public static int playerID; - - public static ForgedAlliance forgedAlliance; - public static BooleanProperty isGameRunning = new SimpleBooleanProperty(false); - - public static ScenarioOptionsMessage scenarioOptions = new ScenarioOptionsMessage(); - - public static void joinGame(int gpgpnetPort, int lobbyPort) { - Logger.info("Starting ForgedAlliance."); - forgedAlliance = new ForgedAlliance(gpgpnetPort, lobbyPort); - isGameRunning.set(true); - } - - public static void leaveGame() { - Logger.info("Stopping ForgedAlliance."); - forgedAlliance.stop(); - forgedAlliance = null; - isGameRunning.set(false); - } - - - private static void informationThread() { - while(true) { - - if(Logger.collectedLog.length() > 30000) { - Logger.collectedLog = Logger.collectedLog.substring(0, 30000); - Logger.error("Log too long. Cannot send to server"); - } - - ClientInformationMessage message; - synchronized (TestServerAccessor.latencies) { - IceStatus iceStatus = ICEAdapter.status(); - message = new ClientInformationMessage(username, playerID, System.currentTimeMillis(), TestServerAccessor.latencies, scenarioOptions.isUploadIceStatus() ? iceStatus : new IceStatus(), scenarioOptions.isUploadLog() ? Logger.collectedLog : "", isGameRunning.get() ? forgedAlliance.getPeers() : null); - TestServerAccessor.latencies = new LinkedList<>(); - } - Logger.collectedLog = ""; - - TestServerAccessor.send(message); - - if(forgedAlliance != null) { - forgedAlliance.getPeers().forEach(p -> { - synchronized (p) { - p.clearLatencyHistory(); - } - }); - } - -// Logger.debug("Sent: %s", new Gson().toJson(message)); - - try { Thread.sleep(INFORMATION_INTERVAL); } catch(InterruptedException e) {} - } - } - - - - - public static void main(String args[]) { - boolean skipGDRP = false; - if (args.length >= 1) { - for (String arg : args) { - if (arg.equals("--debug")) { - DEBUG_MODE = true; - } - - if(arg.replaceAll("-","").equals("help") || arg.equals("/?")){ - System.out.println("Possible Arguments:\n" + - "--skip Skips the GDRP check\n" + - "--name=yourname Sets a custom name without asking\n" + - "--port=newport Changes external adapter port\n" + - "--debug Turns on debug mode"); - System.exit(0); - } - - if(arg.equals("--skip")){ - skipGDRP=true; - } - - if(arg.startsWith("--name=")){ - username = arg.replaceFirst("--name=",""); - } - - if(arg.startsWith("--port=")) { - ICEAdapter.EXTERNAL_ADAPTER_PORT = Integer.parseInt(arg.replaceFirst("--port=","")); - } - } - } - else { - Logger.enableLogging(); - } - Logger.init("ICE adapter testclient"); - - GUI.init(args); - - if(!skipGDRP) { - GUI.showGDPRDialog(); - } - if(username==null) { - getUsername(); - } - - TestServerAccessor.init(); - - ICEAdapter.init(); - - GUI.instance.showStage(); - - VoiceChat.init(); - - new Thread(TestClient::informationThread).start(); - } - - public static void getUsername() { - String preGeneratedUsername = "iceTester" + (int)(Math.random() * 10000); - - if(! TestClient.DEBUG_MODE && new File("iceTestUsername").exists()) { - try { - preGeneratedUsername = FileUtils.readFileToString(new File("iceTestUsername"),"UTF-8"); - } catch (IOException e) { - Logger.error("Error while reading old username from file.", e); - } - } - - GUI.showUsernameDialog(preGeneratedUsername); - - noCatch(() -> FileUtils.writeStringToFile(new File("iceTestUsername"), TestClient.username, "UTF-8")); - } - - public static void close() { - VoiceChat.close(); - - TestServerAccessor.disconnect(); - ICEAdapter.close(); - - Logger.close(); - - - System.exit(0); - } -} diff --git a/client/src/main/java/client/TestServerAccessor.java b/client/src/main/java/client/TestServerAccessor.java deleted file mode 100644 index 0e750c0..0000000 --- a/client/src/main/java/client/TestServerAccessor.java +++ /dev/null @@ -1,212 +0,0 @@ -package client; - -import client.experimental.HolePunching; -import client.ice.ICEAdapter; -import com.google.gson.Gson; -import common.ICEAdapterTest; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.scene.control.Alert; -import logging.Logger; -import net.*; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.util.ConcurrentModificationException; -import java.util.LinkedList; -import java.util.Queue; -import java.util.concurrent.CompletableFuture; - -import static com.github.nocatch.NoCatch.noCatch; - -public class TestServerAccessor { - - private static Gson gson = new Gson(); - public static BooleanProperty connected = new SimpleBooleanProperty(false); - - private static Socket socket; - private static DataInputStream in; - private static DataOutputStream out; - - public static Queue latencies = new LinkedList<>(); - - public static void init() { - connect(); - new Thread(TestServerAccessor::echoThread).start(); - } - - - private static void listener() { - CompletableFuture f = new CompletableFuture(); - ICEAdapter.connected.addListener(s -> f.complete(s)); - f.join(); - - try { - while(true) { - String messageClass = in.readUTF(); - Object message = gson.fromJson(in.readUTF(), Class.forName(messageClass)); - - if(message instanceof IceMessage) { - ICEAdapter.iceMsg(((IceMessage)message).getSrcPlayerId(), ((IceMessage)message).getMsg()); - } - - if(message instanceof HostGameMessage) { - if(TestClient.forgedAlliance != null) { - TestClient.leaveGame(); - } - - ICEAdapter.hostGame(((HostGameMessage)message).getMapName()); - TestClient.joinGame(ICEAdapter.GPG_PORT, ICEAdapter.LOBBY_PORT); - } - - if(message instanceof JoinGameMessage) { - if(TestClient.forgedAlliance != null) { - TestClient.leaveGame(); - } - - ICEAdapter.joinGame(((JoinGameMessage)message).getRemotePlayerLogin(), ((JoinGameMessage)message).getRemotePlayerId()); - TestClient.joinGame(ICEAdapter.GPG_PORT, ICEAdapter.LOBBY_PORT); - } - - if(message instanceof ConnectToPeerMessage) { - ICEAdapter.connectToPeer(((ConnectToPeerMessage)message).getRemotePlayerLogin(), ((ConnectToPeerMessage)message).getRemotePlayerId(), ((ConnectToPeerMessage)message).isOffer()); - } - - if(message instanceof DisconnectFromPeerMessage) { - ICEAdapter.disconnectFromPeer(((DisconnectFromPeerMessage)message).getRemotePlayerId()); - } - - if(message instanceof LeaveGameMessage) { - TestClient.leaveGame(); - } - - if(message instanceof IceAdapterSignalMessage) { - String signal = ((IceAdapterSignalMessage)message).getSignal(); - switch (signal) { - case "stop": ICEAdapter.sigStop();break; - case "cont": ICEAdapter.sigCont();break; - case "kill": ICEAdapter.sigKill();break; - default: Logger.warning("Unrecognized signal: %s", signal); - } - } - - if(message instanceof EchoResponse) { - latencies.add((int) (System.currentTimeMillis() - ((EchoResponse) message).getTimestamp())); - if(latencies.size() > 50) { - latencies.remove(); - } - } - - if(message instanceof HolePunchingMessage) { - HolePunchingMessage msg = (HolePunchingMessage) message; - HolePunching.addPeer(msg.getId(), InetAddress.getByName(msg.getAddress()), msg.getPort()); - } - - if(message instanceof ScenarioOptionsMessage) { - TestClient.scenarioOptions = (ScenarioOptionsMessage) message; - } - - } - } catch(IOException | ClassNotFoundException e) { - TestClient.close(); - } - } - - public static void send(Object message) { - synchronized (out) { - try { - String json = null; - try { - json = gson.toJson(message); - } catch (ConcurrentModificationException e) { - Logger.warning("ConcurrentModification exception during serialization of status"); - } - if (json != null) { -// System.out.println(json); - out.writeUTF(message.getClass().getName()); - out.writeUTF(json);//TODO: catch more concurrent modification exceptions - } - } catch(IOException e) { - Logger.error("Error while sending to server", e); - System.exit(123); - } - } - } - - private static void echoThread() { - while(connected.get()) { - send(new EchoRequest(System.currentTimeMillis())); - try { Thread.sleep(1000); } catch(InterruptedException e) {} - } - } - - private static void connect() { - Alert alert = noCatch(() -> GUI.showDialog("Connecting...").get()); - alert.setOnCloseRequest(event -> System.exit(0)); - Logger.info("Connecting to %s:%d...", ICEAdapterTest.TEST_SERVER_ADDRESS, ICEAdapterTest.TEST_SERVER_PORT); - - try { - socket = new Socket(ICEAdapterTest.TEST_SERVER_ADDRESS, ICEAdapterTest.TEST_SERVER_PORT); - in = new DataInputStream(socket.getInputStream()); - out = new DataOutputStream(socket.getOutputStream()); - - if(in.readInt() != ICEAdapterTest.VERSION) { - Logger.error("Wrong version: %d", ICEAdapterTest.VERSION); - socket.close(); - GUI.runAndWait(alert::close); - alert = noCatch(() -> GUI.showDialog("Please download the newest version.").get()); - try { Thread.sleep(3000); } catch(InterruptedException e) {} - System.exit(59); - } - - out.writeUTF(TestClient.username); - if(! in.readBoolean()) { - Logger.error("could not lock in username"); - System.exit(3); - } - - TestClient.playerID = in.readInt(); - GUI.instance.scenario.set(in.readUTF()); - HolePunching.init(in.readInt()); - - Logger.info("Got username: %s(%d)", TestClient.username, TestClient.playerID); - - } catch (IOException e) { - Logger.error("Could not connect to test server"); - alert.setOnCloseRequest(null); - GUI.runAndWait(alert::close); - alert = noCatch(() -> GUI.showDialog("Could not reach test server.\nPlease wait till the test starts.\nWill retry in 10 seconds.").get()); - alert.setOnCloseRequest(ev -> { - System.exit(-1); - }); - try { Thread.sleep(10000); } catch (InterruptedException e1) {} - alert.setOnCloseRequest(null); - GUI.runAndWait(alert::close); - - connect(); - return; - } - - - connected.set(true); - Logger.info("Connected to %s:%d", ICEAdapterTest.TEST_SERVER_ADDRESS, ICEAdapterTest.TEST_SERVER_PORT); - - new Thread(TestServerAccessor::listener).start(); - - alert.setOnCloseRequest(null); - GUI.runAndWait(alert::close); - } - - public static void disconnect() { - Logger.debug("Disconnecting from test server..."); - try { - socket.close(); - } catch (IOException e) { - Logger.error(e); - } - connected.set(false); - } -} diff --git a/client/src/main/java/client/experimental/HolePunching.java b/client/src/main/java/client/experimental/HolePunching.java deleted file mode 100644 index 7916bf2..0000000 --- a/client/src/main/java/client/experimental/HolePunching.java +++ /dev/null @@ -1,101 +0,0 @@ -package client.experimental; - -import client.TestClient; -import logging.Logger; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.util.AbstractMap; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class HolePunching { - private static int localPort; - private static DatagramSocket datagramSocket; - - private static HashMap> peers = new HashMap(); - public static HashMap latencies = new HashMap(); - - public static void init(int port) { - localPort = port; - try { - datagramSocket = new DatagramSocket(port); - } catch(SocketException e) { - Logger.error("Could not create udp socket for hole punching test.", e); - } - - new Thread(HolePunching::listener).start(); - new Thread(HolePunching::holePunching).start(); - } - - private static final Pattern messagePattern = Pattern.compile("(req|res)(\\d*):(\\d*)"); - private static void listener() { - - byte[] buffer = new byte[1024]; - DatagramPacket packet; - while(true) { - try { - packet = new DatagramPacket(buffer, 0, buffer.length); - datagramSocket.receive(packet); - String message = new String(buffer, 0, packet.getLength()); - Matcher matcher = messagePattern.matcher(message); - if(! matcher.find()) { - continue; - } - int fromId = Integer.parseInt(matcher.group(2)); - long startTime = Long.parseLong(matcher.group(3)); -// System.out.println(message); - if(matcher.group(1).equals("res")) { - latencies.put(fromId, System.currentTimeMillis() - startTime); - } else if(peers.containsKey(fromId)) { - byte[] responseBuffer = ("res" + String.valueOf(TestClient.playerID) + ":" + startTime).getBytes(); - DatagramPacket responsePacket = new DatagramPacket(responseBuffer, 0, responseBuffer.length); - responsePacket.setAddress(peers.get(fromId).getKey()); - responsePacket.setPort(peers.get(fromId).getValue()); - try { - datagramSocket.send(responsePacket); - } catch (IOException e2) { - e2.printStackTrace(); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static void holePunching() { - while(true) { - synchronized (peers) { -// latencies.clear(); - - byte[] buffer = ("req" + String.valueOf(TestClient.playerID) + ":" + System.currentTimeMillis()).getBytes(); - - peers.entrySet().stream() - .map(e -> e.getValue()) - .forEach(e -> { - DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); - packet.setAddress(e.getKey()); - packet.setPort(e.getValue()); - try { - datagramSocket.send(packet); - } catch (IOException e2) { - e2.printStackTrace(); - } - }); - } - try { Thread.sleep(300); } catch(InterruptedException e) {} - } - } - - public static void addPeer(int id, InetAddress address, int port) { - synchronized (peers) { - peers.put(id, new AbstractMap.SimpleImmutableEntry<>(address, port)); - } - } -} diff --git a/client/src/main/java/client/experimental/VoiceChat.java b/client/src/main/java/client/experimental/VoiceChat.java deleted file mode 100644 index 3f49148..0000000 --- a/client/src/main/java/client/experimental/VoiceChat.java +++ /dev/null @@ -1,70 +0,0 @@ -package client.experimental; - -import logging.Logger; - -import javax.sound.sampled.*; -import java.util.Arrays; - -public class VoiceChat { - - public static boolean ENABLED = false; - public static AudioFormat format = new AudioFormat(44_100.0F, 32, 1, true, false); - public static SourceDataLine sourceDataLine = null; - public static TargetDataLine targetDataLine = null; - - public static void init() { - if(ENABLED) { - try { - Logger.debug("Starting voice chat"); - DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format); - DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format); - - if(! AudioSystem.isLineSupported(sourceInfo)) { - throw new LineUnavailableException("Source line not supported."); - } - - if(! AudioSystem.isLineSupported(targetInfo)) { - throw new LineUnavailableException("Target line not supported."); - } - - sourceDataLine = (SourceDataLine) AudioSystem.getLine(sourceInfo); - sourceDataLine.open(format); - sourceDataLine.start(); - - targetDataLine = (TargetDataLine) AudioSystem.getLine(targetInfo); - targetDataLine.open(format); - targetDataLine.start(); - - new Thread(VoiceChat::listener).start(); - Logger.info("Started voice chat."); - } catch(LineUnavailableException e) { - Logger.error("Could not open audio data line.", e); - } - } - } - - public static void receivedVoiceData(byte[] data) { - sourceDataLine.write(data, 0, data.length - 1); - } - - public static void listener() { - while(targetDataLine.isOpen()) { - byte[] data = new byte[targetDataLine.getBufferSize()]; - int bytesRead = targetDataLine.read(data, 0, data.length); - receivedVoiceData(Arrays.copyOf(data, bytesRead - (bytesRead % (format.getFrameSize())))); - } - } - - - public static void close() { - if(ENABLED) { - Logger.debug("Stopping voice chat."); - if(sourceDataLine != null) { - sourceDataLine.close(); - } - if(targetDataLine != null) { - targetDataLine.close(); - } - } - } -} diff --git a/client/src/main/java/client/forgedalliance/FaDataInputStream.java b/client/src/main/java/client/forgedalliance/FaDataInputStream.java deleted file mode 100644 index 4f11558..0000000 --- a/client/src/main/java/client/forgedalliance/FaDataInputStream.java +++ /dev/null @@ -1,71 +0,0 @@ -package client.forgedalliance; - -import com.google.common.io.LittleEndianDataInputStream; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -/** - * Reads data from Forged Alliance (the forgedalliance, not the lobby). - */ -public class FaDataInputStream extends InputStream { - - private static final int MAX_CHUNK_SIZE = 10; - private static final int FIELD_TYPE_INT = 0; - - private final LittleEndianDataInputStream inputStream; - private final Charset charset; - - public FaDataInputStream(InputStream inputStream) { - this.inputStream = new LittleEndianDataInputStream(new BufferedInputStream(inputStream)); - charset = StandardCharsets.UTF_8; - } - - public List readChunks() throws IOException { - int numberOfChunks = readInt(); - - if (numberOfChunks > MAX_CHUNK_SIZE) { - throw new IOException("Too many chunks: " + numberOfChunks); - } - - List chunks = new ArrayList<>(numberOfChunks); - - for (int chunkNumber = 0; chunkNumber < numberOfChunks; chunkNumber++) { - int fieldType = read(); - - switch (fieldType) { - case FIELD_TYPE_INT: - chunks.add(readInt()); - break; - - default: - // This could surely be optimized - chunks.add(readString().replace("/t", "\t").replace("/n", "\n")); - } - } - - return chunks; - } - - public int readInt() throws IOException { - return inputStream.readInt(); - } - - @Override - public int read() throws IOException { - return inputStream.read(); - } - - public String readString() throws IOException { - int size = readInt(); - - byte[] buffer = new byte[size]; - inputStream.readFully(buffer); - return new String(buffer, charset); - } -} diff --git a/client/src/main/java/client/forgedalliance/FaDataOutputStream.java b/client/src/main/java/client/forgedalliance/FaDataOutputStream.java deleted file mode 100644 index 2b5bff9..0000000 --- a/client/src/main/java/client/forgedalliance/FaDataOutputStream.java +++ /dev/null @@ -1,76 +0,0 @@ -package client.forgedalliance; - -import com.google.common.io.LittleEndianDataOutputStream; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; - -/** - * Writes data to Forged Alliance (the forgedalliance, not the lobby). - */ -public class FaDataOutputStream extends OutputStream { - - public static final int FIELD_TYPE_INT = 0; - public static final int FIELD_TYPE_FOLLOWING_STRING = 2; - public static final int FIELD_TYPE_STRING = 1; - public static final char DELIMITER = '\b'; - private final LittleEndianDataOutputStream outputStream; - private Charset charset; - - public FaDataOutputStream(OutputStream outputStream) { - this.outputStream = new LittleEndianDataOutputStream(new BufferedOutputStream(outputStream)); - charset = StandardCharsets.UTF_8; - } - - @Override - public void write(int b) throws IOException { - outputStream.write(b); - } - - @Override - public void flush() throws IOException { - outputStream.flush(); - } - - public void writeArgs(List args) throws IOException { - writeInt(args.size()); - - for (Object arg : args) { - if (arg instanceof Double) { - writeByte(FIELD_TYPE_INT); - writeInt(((Double) arg).intValue()); - } else if (arg instanceof Integer) { - writeByte(FIELD_TYPE_INT); - writeInt((int) arg); - } else if (arg instanceof String) { - String value = (String) arg; - writeByte(FIELD_TYPE_STRING); - writeString(value); - } - } - } - - public void writeInt(int value) throws IOException { - outputStream.writeInt(value); - } - - public void writeByte(int b) throws IOException { - outputStream.writeByte(b); - } - - public void writeString(String string) throws IOException { - outputStream.writeInt(string.length()); - outputStream.write(string.getBytes(charset)); - } - - public void writeMessage(String header, Object... args) throws IOException { - writeString(header); - writeArgs(Arrays.asList(args)); - outputStream.flush(); - } -} diff --git a/client/src/main/java/client/forgedalliance/ForgedAlliance.java b/client/src/main/java/client/forgedalliance/ForgedAlliance.java deleted file mode 100644 index 8d74747..0000000 --- a/client/src/main/java/client/forgedalliance/ForgedAlliance.java +++ /dev/null @@ -1,357 +0,0 @@ -package client.forgedalliance; - -import client.GUI; -import client.TestClient; -import common.ICEAdapterTest; -import data.ForgedAlliancePeer; -import javafx.geometry.Insets; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundFill; -import javafx.scene.layout.CornerRadii; -import javafx.scene.paint.Color; -import logging.Logger; -import lombok.Getter; - -import java.io.*; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -import static util.Util.assertThat; - -@Getter -public class ForgedAlliance { - - private static final int ECHO_INTERVAL = 100; - private static final int CONNECTION_REQ_INTERVAL = 1000; - - private static final String CONNECTION_ACK = "conAck"; - private static final String CONNECTION_REQ = "conReq"; - private static final String ECHO_REQ = "echoReq"; - private static final String ECHO_RES = "echoRes"; - - private Random random = new Random(); - - private boolean running = true; - - private int gpgnetPort;//gpgnet to connect to - private int lobbyPort;//incoming messages - - private DatagramSocket lobbySocket; - - private Socket gpgnetSocket; - private FaDataInputStream gpgnetIn; - private FaDataOutputStream gpgnetOut; - - public List peers = new ArrayList<>(); - - public ForgedAlliance(int gpgnetPort, int lobbyPort) { - this.gpgnetPort = gpgnetPort; - this.lobbyPort = lobbyPort; - - try { - gpgnetSocket = new Socket("localhost", gpgnetPort); - lobbySocket = new DatagramSocket(lobbyPort); - - gpgnetIn = new FaDataInputStream(gpgnetSocket.getInputStream()); - gpgnetOut = new FaDataOutputStream(gpgnetSocket.getOutputStream()); - - new Thread(this::gpgpnetListener).start(); - new Thread(this::lobbyListener).start(); - - new Thread(this::echoThread).start(); - - synchronized (gpgnetOut) { - gpgnetOut.writeMessage("GameState", "Idle"); - } - - } catch(IOException e) { - Logger.error("Could not start lobby server. (GPGNET or lobbySocket failed)", e); - } - } - - private void echoThread() { - while(running) { - - if(System.currentTimeMillis() - lastMetricsUpdate >= 1000) { - updateMetrics(); - } - - synchronized (peers) { - peers.stream() - .filter(ForgedAlliancePeer::isConnected) - .forEach(peer -> { - try { - ByteArrayOutputStream data = new ByteArrayOutputStream(); - DataOutputStream packetOut = new DataOutputStream(data); - - packetOut.writeUTF(ECHO_REQ); - packetOut.writeInt(TestClient.playerID);//src - packetOut.writeInt(peer.remoteId);//target - packetOut.writeInt(peer.echoRequestsSent++); - packetOut.writeLong(System.currentTimeMillis()); - int randomBytes; - if(ICEAdapterTest.TEST_DATA_RANDOM_SIZE) { - randomBytes = 25 + random.nextInt(50); - } else { - randomBytes = 60;//FA sends 2 packets per tick, one ~15 bytes, one 30-70 bytes - } - byte[] randomData = new byte[randomBytes]; - random.nextBytes(randomData); - packetOut.writeInt(randomBytes); - packetOut.write(randomData, 0, randomData.length); - - sendLobby(peer.remoteAddress, peer.remotePort, data); - } catch(IOException e) { - Logger.warning("Error while sending to peer: %d", peer.remoteId); - } - }); - - peers.stream() - .filter(p -> !p.isConnected()) - .forEach(peer -> { - try { - if (peer.offerer == ForgedAlliancePeer.Offerer.LOCAL) { - if ((System.currentTimeMillis() - peer.lastConnectionRequestSent) >= CONNECTION_REQ_INTERVAL) { - peer.lastConnectionRequestSent = System.currentTimeMillis(); - - ByteArrayOutputStream data = new ByteArrayOutputStream(); - DataOutputStream packetOut = new DataOutputStream(data); - - packetOut.writeUTF(CONNECTION_REQ); - packetOut.writeInt(TestClient.playerID); - packetOut.writeUTF(TestClient.username); - - sendLobby(peer.remoteAddress, peer.remotePort, data); - - Logger.debug(" Sent CONNECTION_REQ to %s(%d) at %s:%d", peer.remoteUsername, peer.remoteId, peer.remoteAddress, peer.remotePort); - } - } else { -// Logger.error(" Awaiting CONNECTION_REQ"); - //TODO: log this case? - } - } catch(IOException e) { - Logger.warning("Error while sending to peer: %d", peer.remoteId); - } - }); - - //Data - peers.stream() - .filter(p -> System.currentTimeMillis() - p.lastPacketReceived > 10000) - .forEach(p -> p.addLatency((int)(System.currentTimeMillis() - p.lastPacketReceived))); - } - - try { Thread.sleep(ECHO_INTERVAL); } catch(InterruptedException e) {} - } - } - - private long lastMetricsUpdate = System.currentTimeMillis(); - public float bytesPerSecondIn = 0; - public float bytesPerSecondOut = 0; - private void updateMetrics() { - int d = (int)(System.currentTimeMillis() - lastMetricsUpdate); - lastMetricsUpdate += d; - - bytesPerSecondIn = (float)bytesReceived.getAndSet(0) / ((float)d / 1000f); - bytesPerSecondOut = (float)bytesSent.getAndSet(0) / ((float)d / 1000f); - } - - private volatile AtomicLong bytesReceived = new AtomicLong(0); - private void lobbyListener() { - try { - byte[] buffer = new byte[4096]; - while(running) { - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - lobbySocket.receive(packet); - - bytesReceived.addAndGet(packet.getLength()); - -// Logger.debug(" Received: %s", new String(packet.getData())); - - DataInputStream packetIn = new DataInputStream(new ByteArrayInputStream(packet.getData())); - String command = packetIn.readUTF(); - - - if(command.equals(CONNECTION_REQ)) { - int remoteId = packetIn.readInt(); - String remoteUsername = packetIn.readUTF(); - - ForgedAlliancePeer peer; - synchronized (peers) { - if(peers.stream().noneMatch(p -> p.remoteId == remoteId)) { - peer = new ForgedAlliancePeer(packet.getAddress().getHostAddress(), packet.getPort(), remoteId, remoteUsername, ForgedAlliancePeer.Offerer.REMOTE); - peers.add(peer); - } else { - peer = peers.stream().filter(p -> p.remoteId == remoteId).findAny().get(); - } - peer.setConnected(true); - } - - ByteArrayOutputStream data = new ByteArrayOutputStream(); - DataOutputStream packetOut = new DataOutputStream(data); - - packetOut.writeUTF(CONNECTION_ACK); - packetOut.writeInt(TestClient.playerID); - packetOut.writeUTF(TestClient.username); - - sendLobby(peer.remoteAddress, peer.remotePort, data); - - Logger.debug(" Sent CONNECTION_ACK to %s(%d) at %s:%d", peer.remoteUsername, peer.remoteId, peer.remoteAddress, peer.remotePort); - } - - if(command.equals(CONNECTION_ACK)) { - int remoteId = packetIn.readInt(); - String remoteUsername = packetIn.readUTF(); - - synchronized (peers) { - peers.stream().filter(p -> p.remoteId == remoteId).findAny().ifPresent(p -> p.setConnected(true)); - } - - Logger.debug(" Got CONNECTION_ACK from %s(%d) at %s:%d", remoteUsername, remoteId, packet.getAddress().getHostAddress(), packet.getPort()); - } - - if(command.equals(ECHO_REQ)) { - int remoteId = packetIn.readInt(); - int localId = packetIn.readInt(); - int echoReqId = packetIn.readInt(); - long echoReqTime = packetIn.readLong(); - int randomBytes = packetIn.readInt(); - byte[] randomData = new byte[randomBytes]; - packetIn.read(randomData, 0, randomBytes); - - assertThat(localId == TestClient.playerID); - - - - //Construct response - ByteArrayOutputStream data = new ByteArrayOutputStream(); - DataOutputStream packetOut = new DataOutputStream(data); - - packetOut.writeUTF(ECHO_RES); - packetOut.writeInt(TestClient.playerID);//src - packetOut.writeInt(remoteId);//target - packetOut.writeInt(echoReqId); - packetOut.writeLong(echoReqTime); - packetOut.writeInt(randomBytes); - packetOut.write(randomData, 0, randomData.length); - - sendLobby(packet.getAddress().getHostAddress(), packet.getPort(), data);//TODO return to peer address instead of src address? - } - - if(command.equals(ECHO_RES)) { - - int remoteId = packetIn.readInt(); - int localId = packetIn.readInt(); - int echoReqId = packetIn.readInt(); - long echoReqTime = packetIn.readLong(); - int randomBytes = packetIn.readInt(); - byte[] randomData = new byte[randomBytes]; - packetIn.read(randomData, 0, randomBytes); - - assertThat(localId == TestClient.playerID); - int latency = (int) (System.currentTimeMillis() - echoReqTime); - - - if(echoReqId > 5 && latency < 2000 /*TODO HOW?*/) {//block first connecting pings - synchronized (peers) { - peers.stream().filter(p -> p.remoteId == remoteId).findAny().ifPresent(p -> p.addLatency(latency)); - } - } - -// Logger.debug(" Recevied ECHO_RES %d after %d ms from %d", echoReqId, latency, remoteId); - } - } - } catch(IOException e) { - if(this.running) { - Logger.error("Error while listening for lobby messages.", e); - } - } - } - - private void gpgpnetListener() { - try { - while(running) { - - String command = gpgnetIn.readString(); - List args = gpgnetIn.readChunks(); - - if(command.equals("CreateLobby")) { -// assertThat(! args.get(0).toString().isEmpty()); - assertThat(args.get(1).equals(lobbyPort)); - assertThat(args.get(2).equals(TestClient.username)); - assertThat(args.get(3).equals(TestClient.playerID)); - - synchronized (gpgnetOut) { - gpgnetOut.writeMessage("GameState", "Lobby"); - } - - Logger.info(" Creating lobby"); - } - - if(command.equals("HostGame")) { - assertThat(! args.get(0).toString().isEmpty()); - Logger.info(" Hosting game on %s", args.get(0)); - } - - if(command.equals("ConnectToPeer")) { - ForgedAlliancePeer peer = new ForgedAlliancePeer(((String)args.get(0)).split(":")[0], Integer.parseInt(((String)args.get(0)).split(":")[1]), (Integer) args.get(2), (String)args.get(1), ForgedAlliancePeer.Offerer.LOCAL); - - synchronized (peers) { - if(peers.stream().noneMatch(p -> p.remoteId == peer.remoteId)) { - peers.add(peer); - } - } - } - - if(command.equals("DisconnectFromPeer")) { - synchronized (peers) { - peers.stream().filter(p -> p.remoteId == (Integer) args.get(0)).findAny() - .ifPresent(p -> { - p.setConnected(false); - peers.remove(p); - }); - } - } - - Logger.debug(" Received %s %s", command, args.stream().reduce("", (l, r) -> l + " " + r)); - } - } catch(IOException e) { - if(this.running) { - Logger.error("Error while listening for gpg messages.", e); - GUI.runAndWait(() -> GUI.instance.getRoot().setBackground(new Background(new BackgroundFill(new Color(189.0 / 255.0, 61.0 / 255.0, 58.0 / 255.0, 1.0), CornerRadii.EMPTY, Insets.EMPTY)))); - } - } - } - - - private volatile AtomicLong bytesSent = new AtomicLong(0); - private void sendLobby(String remoteAddress, int remotePort, byte[] data) { - try { - DatagramPacket datagramPacket = new DatagramPacket(data, data.length); - datagramPacket.setAddress(InetAddress.getByName(remoteAddress)); - datagramPacket.setPort(remotePort); - lobbySocket.send(datagramPacket); - - bytesSent.addAndGet(data.length); - } catch (IOException e) { - Logger.warning("Error while sending UDP Packet.", e); - } - } - - private void sendLobby(String remoteAddress, int remotePort, ByteArrayOutputStream dataStream) { - sendLobby(remoteAddress, remotePort, dataStream.toByteArray()); - } - - public void stop() { - running = false; - lobbySocket.close(); - try { - gpgnetSocket.close(); - } catch (IOException e) {} - } -} diff --git a/client/src/main/java/client/ice/ICEAdapter.java b/client/src/main/java/client/ice/ICEAdapter.java deleted file mode 100644 index 0b6d091..0000000 --- a/client/src/main/java/client/ice/ICEAdapter.java +++ /dev/null @@ -1,352 +0,0 @@ -package client.ice; - -import client.GUI; -import client.TestClient; -import client.nativeAccess.NativeAccess; -import com.google.gson.GsonBuilder; -import com.nbarraille.jjsonrpc.CallbackMethod; -import com.nbarraille.jjsonrpc.InvalidMethodException; -import com.nbarraille.jjsonrpc.JJsonPeer; -import com.nbarraille.jjsonrpc.TcpClient; -import data.IceStatus; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.scene.control.Alert; -import logging.Logger; -import util.OsUtil; -import util.Util; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.ConnectException; -import java.nio.charset.Charset; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import static com.github.nocatch.NoCatch.noCatch; - -public class ICEAdapter { - - private static final String LOG_LEVEL = "info"; - - private static final int CONNECTION_ATTEMPTS = 100; - - private static final String COTURN_HOST = "geosearchef.de"; - private static final String COTURN_KEY = "8T2o1yfSu29vf9cJ3WjHS9Ak6zJCB6qECL2Uxlza"; -// private static final String COTURN_HOST = "vmrbg145.informatik.tu-muenchen.de"; -// private static final Str ing COTURN_KEY = "banana"; - - public static int ADAPTER_PORT;//RPC Client <=> ICE - public static int GPG_PORT;//ICE <=> Lobby - public static int LOBBY_PORT;//forged alliance udp receive point (from other games) - - public static int EXTERNAL_ADAPTER_PORT = -1;//Indicates if an ICE adapter is already running and should be connected to - - private static Process process; - private static TcpClient tcpClient; - private static JJsonPeer peer; - - public static BooleanProperty connected = new SimpleBooleanProperty(false); - public static int processID = 0; - public static long processHandle = 0; - - private static IceAdapterCallbacks iceAdapterCallbacks = new IceAdapterCallbacks(); - - public static void init() { - Alert alert = noCatch(() -> GUI.showDialog("Starting ICE adapter...").get()); - startICEAdapter(); - - try { Thread.sleep(500); } catch(InterruptedException e) {} - - connectToICEAdapter(); - configureIceServers(); - - connected.set(true); - - GUI.runAndWait(alert::close); - - try { Thread.sleep(500); } catch(InterruptedException e) {} - } - - - public static void hostGame(String mapName) { - peer.sendAsyncRequest("hostGame", Arrays.asList(mapName), null, false); - } - - public static void joinGame(String remotePlayerLogin, long remotePlayerId) { - peer.sendAsyncRequest("joinGame", Arrays.asList(remotePlayerLogin, remotePlayerId), null, false); - } - public static void connectToPeer(String remotePlayerLogin, long remotePlayerId, boolean offer) { - peer.sendAsyncRequest("connectToPeer", Arrays.asList(remotePlayerLogin, remotePlayerId, offer), null, false); - } - - public static void disconnectFromPeer(long remotePlayerId) { - peer.sendAsyncRequest("disconnectFromPeer", Arrays.asList(remotePlayerId), null, false); - } - - public static void setLobbyInitMode(String lobbyInitMode) { - peer.sendAsyncRequest("setLobbyInitMode", Arrays.asList(lobbyInitMode), null, false); - } - - public static void iceMsg(long remotePlayerId, Object msg) { - peer.sendAsyncRequest("iceMsg", Arrays.asList(remotePlayerId, msg), null, false); - } - - public static void sendToGpgNet(String header, String... chunks) { - peer.sendAsyncRequest("sendToGpgNet", Arrays.asList(header, chunks), null, false); - } - - public static void setIceServers(List> iceServers) { - peer.sendAsyncRequest("setIceServers", Arrays.asList(iceServers), null, false); - } - - private static volatile CompletableFuture status = null; - public synchronized static IceStatus status() { -// long time = System.currentTimeMillis(); - status = new CompletableFuture<>(); - IceStatus iceStatus = null; - try { - peer.sendAsyncRequest("status", Collections.emptyList(), new CallbackMethod(StatusCallback.class.getMethod("statusCallback", Object.class), STATUS_CALLBACK_INSTANCE, null), false); - iceStatus = new GsonBuilder().serializeNulls().create().fromJson(status.get().toString().replace("{}", "null"), IceStatus.class); - } catch (InvalidMethodException | NoSuchMethodException | InterruptedException | ExecutionException e) { - Logger.error(e); - e.printStackTrace(); - } -// Logger.debug("Took %d ms.", System.currentTimeMillis() - time); - latestIceStatus = iceStatus; - - return iceStatus; - } - public static IceStatus latestIceStatus = null; - - private static StatusCallback STATUS_CALLBACK_INSTANCE = new StatusCallback(); - public static class StatusCallback { - public void statusCallback(Object res) { - status.complete(res); - } - } - - - private static void configureIceServers() { - int timestamp = (int)(System.currentTimeMillis() / 1000) + 3600 * 24; - String tokenName = String.format("%s:%s", timestamp, TestClient.username); - byte[] secret = null; - try { - Mac mac = Mac.getInstance("HmacSHA1"); - mac.init(new SecretKeySpec(Charset.forName("cp1252").encode(COTURN_KEY).array(), "HmacSHA1")); - secret = mac.doFinal(Charset.forName("cp1252").encode(tokenName).array()); - - } catch(NoSuchAlgorithmException | InvalidKeyException e) { Logger.crash(e); } - String authToken = Base64.getEncoder().encodeToString(secret); - - Map map = new HashMap<>(); - map.put("urls", Arrays.asList( - String.format("turn:%s?transport=tcp", COTURN_HOST), - String.format("turn:%s?transport=udp", COTURN_HOST), - String.format("stun:%s", COTURN_HOST) - )); - - map.put("credential", authToken); - map.put("credentialType", "authToken"); - map.put("username", tokenName); - - setIceServers(Arrays.asList(map)); - Logger.debug("Set ICE servers"); - } - - private static void connectToICEAdapter() { - for (int attempt = 0; attempt < CONNECTION_ATTEMPTS; attempt++) { - try { - tcpClient = new TcpClient("localhost", ADAPTER_PORT, iceAdapterCallbacks); - peer = tcpClient.getPeer(); - - break; - } catch (ConnectException e) { - Logger.debug("Could not connect to ICE adapter (attempt %s/%s)", attempt, CONNECTION_ATTEMPTS); - try { Thread.sleep(50); } catch(InterruptedException e2) {} - } catch (IOException e) { - Logger.crash(e); - } - } - - if(peer == null) { - Logger.error("Could not connect to ICE adapter."); - System.exit(45); - } - - Logger.debug("Connected to ICE adapter via JsonRPC."); - - //Read ports - IceStatus iceStatus = status(); - GPG_PORT = iceStatus.getOptions().getGpgnet_port(); - LOBBY_PORT = iceStatus.getLobby_port(); - - Logger.info("Got generated ports from IceAdapterStatus: LOBBY_PORT: %d GPGNET_PORT: %d", LOBBY_PORT, GPG_PORT); - } - - - public static void startICEAdapter() { - Logger.info("Launching ICE adapter..."); - - if(EXTERNAL_ADAPTER_PORT == -1) { - ADAPTER_PORT = Util.getAvaiableTCPPort(); - } else { - ADAPTER_PORT = EXTERNAL_ADAPTER_PORT; - } - - //Ports are now being generated by ICE adapter -// GPG_PORT = Util.getAvaiableTCPPort(); -// LOBBY_PORT = Util.getAvaiableTCPPort(); - -// if (ADAPTER_PORT == GPG_PORT) { -// Logger.crash(new RuntimeException("ADAPTER_PORT = GPG_PORT, you got very unlucky, this is NO error, just try again!")); -// } - - if(EXTERNAL_ADAPTER_PORT == -1) { - String command[] = new String[]{ -// (System.getProperty("os.name").contains("Windows") ? "faf-ice-adapter.exe" : "./faf-ice-adapter"), - "java", - "-jar", - "faf-ice-adapter.jar", - "--id", String.valueOf(TestClient.playerID), - "--login", TestClient.username, - "--rpc-port", String.valueOf(ADAPTER_PORT), -// "--gpgnet-port", String.valueOf(GPG_PORT), retrieved afterwards -// "--lobby-port", String.valueOf(LOBBY_PORT), - "--log-level", LOG_LEVEL, -// "--log-directory", "iceAdapterLogs/" - }; - - ProcessBuilder processBuilder = new ProcessBuilder(command); -// processBuilder.inheritIO(); - - - Logger.debug("Command: %s", Arrays.stream(command).reduce("", (l, r) -> l + " " + r)); - try { - process = processBuilder.start(); - } catch (IOException e) { - Logger.error("Could not start ICE adapter", e); - System.exit(10); - } - - try { - BufferedWriter iceAdapterLogWriter = new BufferedWriter(new FileWriter(new File(String.format("faf-ice-adapter_%s.log", TestClient.username)))); - OsUtil.gobbleLines(process.getInputStream(), s -> noCatch(() -> iceAdapterLogWriter.write(s + "\n"))); - OsUtil.gobbleLines(process.getErrorStream(), s -> noCatch(() -> iceAdapterLogWriter.write(s + "\n"))); - - Thread t = new Thread(() -> { - while(true) { - noCatch(() -> Thread.sleep(5000)); - noCatch(() -> iceAdapterLogWriter.flush()); - } - }); - t.setDaemon(true); - t.start(); - } catch (IOException e) { - Logger.warning("Could not open output writer for ice adapter log."); - } - - if (!process.isAlive()) { - Logger.error("ICE Adapter not running"); - System.exit(11); - } - - //Read pid - if (process.getClass().getName().equals("java.lang.Win32Process") || process.getClass().getName().equals("java.lang.ProcessImpl")) { - try { - Field f = process.getClass().getDeclaredField("handle"); - f.setAccessible(true); - processHandle = f.getLong(process); - } catch (Throwable e) { - e.printStackTrace(); - } - } else if(process.getClass().getName().equals("java.lang.UNIXProcess")) { - /* get the PID on unix/linux systems */ - try { - Field f = process.getClass().getDeclaredField("pid"); - f.setAccessible(true); - processID = f.getInt(process); - Logger.debug("ICEAdapter PID: %d", processID); - } catch (Throwable e) { - e.printStackTrace(); - } - } - -// IceAdapter.main(Arrays.copyOfRange(command, 1, command.length)); - } - - Logger.info("Launched ICE adapter."); - } - - - public static void sigStop() { - if(processID != 0) { - -// try { -// Runtime.getRuntime().exec("kill -SIGSTOP " + processID); - NativeAccess.sendSignal(processID, NativeAccess.SIGSTOP); - Logger.warning("Sent SIGSTOP to %d", processID); -// } catch (IOException e) { -// Logger.error("Could not sigstop process %d", processID); -// } - } - - if(processHandle != 0) { - NativeAccess.suspendWin32(processHandle); - } - } - - public static void sigCont() { - if(processID != 0) { -// try { -// Runtime.getRuntime().exec("kill -SIGCONT " + processID); - NativeAccess.sendSignal(processID, NativeAccess.SIGCONT); - Logger.warning("Sent SIGCONT to %d", processID); -// } catch (IOException e) { -// Logger.error("Could not sigcont process %d", processID); -// } - } - - if(processHandle != 0) { - NativeAccess.resumeWin32(processHandle); - } - } - - public static void sigKill() { - if(processID != 0) { -// try { -// Runtime.getRuntime().exec("kill -9" + processID); - NativeAccess.sendSignal(processID, NativeAccess.SIGKILL); - Logger.warning("Sent SIGKILL to %d", processID); -// } catch (IOException e) { -// Logger.error("Could not sigkill process %d", processID); -// } - } - } - - public static void close() { - Logger.debug("Closing ICE adapter..."); - if (peer != null && peer.isAlive()) { - peer.sendAsyncRequest("quit", Collections.emptyList(), null, false); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - } - } - - if (process != null && process.isAlive()) { - Logger.debug("ICE adapter running, killing..."); - process.destroyForcibly(); - } - - connected.set(false); - } -} diff --git a/client/src/main/java/client/ice/IceAdapterCallbacks.java b/client/src/main/java/client/ice/IceAdapterCallbacks.java deleted file mode 100644 index e5eefe1..0000000 --- a/client/src/main/java/client/ice/IceAdapterCallbacks.java +++ /dev/null @@ -1,43 +0,0 @@ -package client.ice; - -import client.TestServerAccessor; -import logging.Logger; -import net.IceMessage; - -import java.util.List; - -public class IceAdapterCallbacks { - - public IceAdapterCallbacks() { - - } - - public void onConnectionStateChanged(String newState) { - Logger.debug("ICE adapter connection state changed to: %s", newState); - } - - public void onGpgNetMessageReceived(String header, List chunks) { - Logger.debug("Message from forgedalliance: '%s' '%s'", header, chunks); - -// if(header.equals("GameState") && chunks.get(0).equals("Lobby")) { -// ICEAdapter.hostGame("mapName");//TODO -// } - } - - public void onIceMsg(long localPlayerId, long remotePlayerId, Object message) { - Logger.debug("ICE message for connection '%d/%d': %s", localPlayerId, remotePlayerId, message); - TestServerAccessor.send(new IceMessage((int)localPlayerId, (int)remotePlayerId, message)); - } - - public void onIceConnectionStateChanged(long localPlayerId, long remotePlayerId, String state) { - Logger.debug("ICE connection state for peer '%s' changed to: %s", remotePlayerId, state); - } - - public void onConnected(long localPlayerId, long remotePlayerId, boolean connected) { - if (connected) { - Logger.info("Connection between '%s' and '%s' has been established", localPlayerId, remotePlayerId); - } else { - Logger.info("Connection between '%s' and '%s' has been lost", localPlayerId, remotePlayerId); - } - } -} diff --git a/client/src/main/java/client/nativeAccess/Kernel32.java b/client/src/main/java/client/nativeAccess/Kernel32.java deleted file mode 100644 index 29fdc5c..0000000 --- a/client/src/main/java/client/nativeAccess/Kernel32.java +++ /dev/null @@ -1,12 +0,0 @@ -package client.nativeAccess; - -import com.sun.jna.Native; -import com.sun.jna.win32.W32APIOptions; - -public interface Kernel32 extends com.sun.jna.platform.win32.Kernel32 { - Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS); - - boolean DebugActiveProcess(int dwProcessId); - boolean DebugActiveProcessStop(int dwProcessId); - boolean DebugSetProcessKillOnExit(boolean KillOnExit); -} \ No newline at end of file diff --git a/client/src/main/java/client/nativeAccess/NativeAccess.java b/client/src/main/java/client/nativeAccess/NativeAccess.java deleted file mode 100644 index 7b690f8..0000000 --- a/client/src/main/java/client/nativeAccess/NativeAccess.java +++ /dev/null @@ -1,70 +0,0 @@ -package client.nativeAccess; - -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT; - -public class NativeAccess { - - private static final boolean windows; - private static final boolean arch64;//x86 or x86_64, windows will lie if this application is running in a 32 bit JVM - private static final int SYS_KILL;//EAX - - public static final int SIGKILL = 9; - public static final int SIGCONT = 18; - public static final int SIGSTOP = 19; - - private static CStdLib c; - - static { - windows = System.getProperty("os.name").contains("Windows"); - arch64 = System.getProperty("os.arch").endsWith("64"); - - //Setup posix syscall id's - if(arch64) { - SYS_KILL = 0x3E; - } else { - SYS_KILL = 0x25; - } - - if(windows) { - //TODO - } else { - c = (CStdLib)Native.loadLibrary("c", CStdLib.class); - } - } - - public interface CStdLib extends Library { - int syscall(int number, Object... args); - } - - - - public static void sendSignal(int pid, int sig) { - c.syscall(SYS_KILL, pid, sig); - } - - public static void suspendWin32(long handle) { - Kernel32 kernel = Kernel32.INSTANCE; - - WinNT.HANDLE hand = new WinNT.HANDLE(); - hand.setPointer(Pointer.createConstant(handle)); - - int processId = kernel.GetProcessId(hand); - - kernel.DebugActiveProcess(processId); - } - - public static void resumeWin32(long handle) { - Kernel32 kernel = Kernel32.INSTANCE; - - WinNT.HANDLE hand = new WinNT.HANDLE(); - hand.setPointer(Pointer.createConstant(handle)); - - int processId = kernel.GetProcessId(hand); - - kernel.DebugSetProcessKillOnExit(false); - kernel.DebugActiveProcessStop(processId); - } -} diff --git a/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindow.java b/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindow.java index 447e269..db47567 100644 --- a/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindow.java +++ b/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindow.java @@ -177,14 +177,16 @@ public void peerStateChanged(Peer peer) { @Override public void peerConnectivityUpdate(Peer peer) { - new Thread(() -> { + runOnUIThread(() -> { synchronized (peers) { peers.stream().filter(p -> p.id.get() == peer.getRemoteId()).forEach(p -> { - p.averageRtt.set(Optional.ofNullable(peer.getIce().getConnectivityChecker()).map(PeerConnectivityCheckerModule::getAverageRTT).orElse(-1.0f).intValue()); - p.lastReceived.set(Optional.ofNullable(peer.getIce().getConnectivityChecker()).map(PeerConnectivityCheckerModule::getLastPacketReceived).map(last -> System.currentTimeMillis() - last).orElse(-1L).intValue()); + Optional connectivityChecker = Optional.ofNullable(peer.getIce().getConnectivityChecker()); + p.averageRtt.set(connectivityChecker.map(PeerConnectivityCheckerModule::getAverageRTT).orElse(-1.0f).intValue()); + p.lastReceived.set(connectivityChecker.map(PeerConnectivityCheckerModule::getLastPacketReceived).map(last -> System.currentTimeMillis() - last).orElse(-1L).intValue()); + p.echosReceived.set(connectivityChecker.map(PeerConnectivityCheckerModule::getEchosReceived).orElse(-1L).intValue()); }); } - }).start(); + }); } private void runOnUIThread(Runnable runnable) { @@ -210,6 +212,7 @@ public static class DebugPeer { public SimpleStringProperty state = new SimpleStringProperty(""); public SimpleIntegerProperty averageRtt = new SimpleIntegerProperty(-1); public SimpleIntegerProperty lastReceived = new SimpleIntegerProperty(-1); + public SimpleIntegerProperty echosReceived = new SimpleIntegerProperty(-1); public SimpleStringProperty localCandidate = new SimpleStringProperty(""); public SimpleStringProperty remoteCandidate = new SimpleStringProperty(""); diff --git a/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindowController.java b/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindowController.java index aebd16c..74bb361 100644 --- a/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindowController.java +++ b/ice-adapter/src/main/java/com/faforever/iceadapter/debug/DebugWindowController.java @@ -36,6 +36,7 @@ public class DebugWindowController { public TableColumn stateColumn; public TableColumn rttColumn; public TableColumn lastColumn; + public TableColumn echosRcvColumn; public TableColumn localCandColumn; public TableColumn remoteCandColumn; @@ -64,6 +65,7 @@ private void initialize() { stateColumn.setCellValueFactory(new PropertyValueFactory<>("state")); rttColumn.setCellValueFactory(new PropertyValueFactory<>("averageRtt")); lastColumn.setCellValueFactory(new PropertyValueFactory<>("lastReceived")); + echosRcvColumn.setCellValueFactory(new PropertyValueFactory<>("echosReceived")); localCandColumn.setCellValueFactory(new PropertyValueFactory<>("localCandidate")); remoteCandColumn.setCellValueFactory(new PropertyValueFactory<>("remoteCandidate")); diff --git a/ice-adapter/src/main/resources/debugWindow.fxml b/ice-adapter/src/main/resources/debugWindow.fxml index c353653..5bd31b5 100644 --- a/ice-adapter/src/main/resources/debugWindow.fxml +++ b/ice-adapter/src/main/resources/debugWindow.fxml @@ -62,6 +62,7 @@ + diff --git a/server/build.gradle b/server/build.gradle deleted file mode 100644 index 7ad8282..0000000 --- a/server/build.gradle +++ /dev/null @@ -1,28 +0,0 @@ - -apply plugin: 'java' -apply plugin: 'com.github.johnrengelman.shadow' - -group 'com.faforever' -version '1.0-SNAPSHOT' - -sourceCompatibility = JavaVersion.VERSION_17 - -repositories { - mavenCentral() -} - -dependencies { - annotationProcessor("org.projectlombok:lombok:$lombokVersion") - implementation("org.projectlombok:lombok:$lombokVersion") - -// implementation project(":ice-adapter") - implementation(project(":shared")) - implementation("com.sparkjava:spark-core:2.9.4") - implementation("com.google.code.gson:gson:$gsonVersion") -} - -jar { - manifest { - attributes 'Main-Class': 'server.TestServer' - } -} \ No newline at end of file diff --git a/server/src/main/java/server/CollectedInformation.java b/server/src/main/java/server/CollectedInformation.java deleted file mode 100644 index a232f67..0000000 --- a/server/src/main/java/server/CollectedInformation.java +++ /dev/null @@ -1,31 +0,0 @@ -package server; - -import lombok.Data; -import net.ClientInformationMessage; -import net.IceMessage; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -@Data -public class CollectedInformation { - private final int id; - private final String username; - - private List informationMessages = new LinkedList<>(); - private Map> iceMessages = new HashMap<>(); - - public String getLog() { - return informationMessages.stream().map(ClientInformationMessage::getClientLog).reduce("", (l, r) -> l + r).replace("\\\\", "");//TODO: why is this necessary? - } - - public void addIceMessage(int to, IceMessage iceMessage) { - if(! iceMessages.containsKey(to)) { - iceMessages.put(to, new HashMap()); - } - - iceMessages.get(to).put(System.nanoTime(), iceMessage); - } -} diff --git a/server/src/main/java/server/Game.java b/server/src/main/java/server/Game.java deleted file mode 100644 index d80cd71..0000000 --- a/server/src/main/java/server/Game.java +++ /dev/null @@ -1,79 +0,0 @@ -package server; - -import lombok.Data; -import net.*; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -@Data -public class Game { - private final Player host; - private final List players = new LinkedList<>(); - - public Game(Player host) { - this.host = host; - players.add(host); - - host.send(new HostGameMessage("Seton's clutch")); - } - - public synchronized void join(Player player) { - host.send(new ConnectToPeerMessage(player.getUsername(), player.getId(), true)); - player.send(new JoinGameMessage(host.getUsername(), host.getId())); - - players.stream() - .filter(p -> p != host) - .forEach(p -> { - p.send(new ConnectToPeerMessage(player.getUsername(), player.getId(), true)); - player.send(new ConnectToPeerMessage(p.getUsername(), p.getId(), false)); - }); - - players.forEach(p -> { - HolePunchingServer.connect(p, player); - }); - - players.add(player); - } - - public synchronized void left(Player player) { - if(! TestServer.players.contains(player)) { - players.remove(player); - } - - if(player == host) { - close(); - } else { - for (Player p : players) { - p.send(new DisconnectFromPeerMessage(player.getId())); - player.send(new DisconnectFromPeerMessage(p.getId())); - } - } - - players.remove(player); - } - - //e.g. host left - public synchronized void close() { - //disconnect all players - - synchronized (TestServer.games) { - TestServer.games.remove(this); - } - - - Iterator iter = players.iterator(); - while(iter.hasNext()) { - Player rem = iter.next(); - iter.remove(); - - rem.send(new LeaveGameMessage()); - - for (Player p : players) { - p.send(new DisconnectFromPeerMessage(rem.getId())); - rem.send(new DisconnectFromPeerMessage(p.getId())); - } - } - } -} diff --git a/server/src/main/java/server/HolePunchingServer.java b/server/src/main/java/server/HolePunchingServer.java deleted file mode 100644 index 26cb759..0000000 --- a/server/src/main/java/server/HolePunchingServer.java +++ /dev/null @@ -1,23 +0,0 @@ -package server; - -import net.HolePunchingMessage; - -import java.util.HashMap; -import java.util.Map; - -public class HolePunchingServer { - - public static volatile int port = 51239; - public static Map ports = new HashMap<>(); - - public static synchronized int onPlayerConnected(Player player) { - int newPort = port++; - ports.put(player.getId(), newPort); - return newPort; - } - - public static synchronized void connect(Player player1, Player player2) { - player1.send(new HolePunchingMessage(player2.getId(), player2.getSocket().getInetAddress().getHostAddress(), ports.get(player2.getId()))); - player2.send(new HolePunchingMessage(player1.getId(), player1.getSocket().getInetAddress().getHostAddress(), ports.get(player1.getId()))); - } -} diff --git a/server/src/main/java/server/IceTestServerConfig.java b/server/src/main/java/server/IceTestServerConfig.java deleted file mode 100644 index f51f91c..0000000 --- a/server/src/main/java/server/IceTestServerConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -package server; - -import com.google.gson.Gson; -import logging.Logger; -import lombok.Data; - -import java.io.File; -import java.io.IOException; -import java.util.Scanner; - -@Data -public class IceTestServerConfig { - - public static IceTestServerConfig INSTANCE; - - public static void init() { - StringBuilder sb = new StringBuilder(); - try { - Scanner scanner = new Scanner(new File("iceServer.cfg")); - while(scanner.hasNext()) { - sb.append(scanner.nextLine()).append("\n"); - } - INSTANCE = new Gson().fromJson(sb.toString(), IceTestServerConfig.class); - } catch(IOException e) { - Logger.crash(e); - } - } - - private final int max_users; - private final boolean host; - private final boolean stun; - private final boolean turn; -} diff --git a/server/src/main/java/server/Player.java b/server/src/main/java/server/Player.java deleted file mode 100644 index dab4ff5..0000000 --- a/server/src/main/java/server/Player.java +++ /dev/null @@ -1,212 +0,0 @@ -package server; - -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; -import common.ICEAdapterTest; -import logging.Logger; -import lombok.Getter; -import net.*; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.Socket; -import java.util.regex.Pattern; - -import static server.TestServer.games; -import static server.TestServer.players; - -@Getter -public class Player { - public static final Pattern usernamePattern = Pattern.compile("[a-zA-Z0-9]+"); - - private static volatile int PLAYER_ID_FACTORY = 0; - - private Gson gson = new Gson(); - - private boolean connected = false; - private int id; - private String username; - private Socket socket; - private DataInputStream in; - private DataOutputStream out; - - public Player(Socket socket) { - this.socket = socket; - - login(); - if(connected == true) { - new Thread(this::listener).start(); - - ScenarioRunner.scenario.onPlayerConnect(this); - } - - //do not do anything here, player may not be logged in/connected anymore - } - - private void login() { - try { - in = new DataInputStream(socket.getInputStream()); - out = new DataOutputStream(socket.getOutputStream()); - - out.writeInt(ICEAdapterTest.VERSION); - - this.username = in.readUTF(); - - if(username.toLowerCase().contains("hitler") //@moonbearonmeth: nope - || ! usernamePattern.matcher(username).matches() - || username.length() > 49) { - out.writeBoolean(false); - out.flush(); - disconnect(); - return; - } - - if(players.stream().map(Player::getUsername).anyMatch(this.username::equals)) { - out.writeBoolean(false); - out.flush(); - disconnect(); - return; - } - - out.writeBoolean(true); - - this.id = PLAYER_ID_FACTORY++; - out.writeInt(id); - out.writeUTF(ScenarioRunner.scenario.getDescription()); - - //send hole punching port - out.writeInt(HolePunchingServer.onPlayerConnected(this)); - - synchronized (players) { - players.add(this); - } - - TestServer.collectedData.put(this.id, new CollectedInformation(id, username)); - connected = true; - - } catch(IOException e) { - Logger.error("Error while logging in player. ", e); - - synchronized (players) { - if(players.contains(this)) { - players.remove(this); - TestServer.collectedData.remove(this.id); - } - } - - disconnect(); - return; - } - - Logger.info("Player connected: %d, %s, %s", id, username, socket.getInetAddress().getHostAddress()); - } - - private void listener() { - try { - while(connected) { - String messageClass = in.readUTF(); - Object message = gson.fromJson(in.readUTF(), Class.forName(messageClass)); - - if(message instanceof IceMessage) { - Logger.debug("IceMessage: %s", gson.toJson(message)); - - if(filterIceMessage((IceMessage)message)) { - Logger.info("Filtered IceMessage"); - continue; - } - - TestServer.collectedData.get(this.id).addIceMessage(((IceMessage)message).getDestPlayerId(), (IceMessage)message); - - synchronized (players) { - players.stream() - .filter(p -> p.getId() == ((IceMessage)message).getDestPlayerId()) - .findFirst().ifPresent(p -> p.send(message)); - } - } - - if(message instanceof ClientInformationMessage) { - Logger.debug("Client information message: %s", gson.toJson(message)); - TestServer.collectedData.get(this.id).getInformationMessages().add((ClientInformationMessage) message); - } - - if(message instanceof EchoRequest) { - send(new EchoResponse(((EchoRequest)message).getTimestamp())); - } - } - } catch(IOException | ClassNotFoundException | JsonSyntaxException e) { - Logger.warning("Disconnecting client due to error while reading data from socket. %s", e.getClass().getName()); - disconnect(); - } - } - - public boolean filterIceMessage(IceMessage iceMessage) { - if(! IceTestServerConfig.INSTANCE.isHost() && - (((iceMessage.getMsg().toString()).contains("typ host")))) { - return true; - } - - if(! IceTestServerConfig.INSTANCE.isStun() && - (iceMessage.getMsg().toString().contains("typ srflx") || iceMessage.getMsg().toString().contains("typ prflx"))) { - return true; - } - - if(! IceTestServerConfig.INSTANCE.isTurn() && - (iceMessage.getMsg().toString().contains("typ relay"))) { - return true; - } - - return false; - } - - public void send(Object message) { - synchronized (out) { - try { - out.writeUTF(message.getClass().getName()); - out.writeUTF(gson.toJson(message)); - } catch(IOException e) { - Logger.error("Error while sending to client", e); - } - } - } - - public void disconnect() { - synchronized (TestServer.players) { - TestServer.players.remove(this); - } - - synchronized (TestServer.games) { - for (Game g : games) { - synchronized (players) { - if(g.getHost() == this) {//TODO - TestServer.close(); - } - - if (g.getPlayers().contains(this)) { - g.left(this); - } - } - } - } - - try { - in.close(); - out.close(); - socket.close(); - } catch(IOException e) {Logger.error("Error during disconnect.", e);} - - Logger.info("Disconnected player: %d, %s", id, username); - } - - public void sigStop() { - this.send(new IceAdapterSignalMessage("stop")); - } - - public void sigCont() { - this.send(new IceAdapterSignalMessage("cont")); - } - - public void sigKill() { - this.send(new IceAdapterSignalMessage("kill")); - } -} diff --git a/server/src/main/java/server/Scenario.java b/server/src/main/java/server/Scenario.java deleted file mode 100644 index 2eeb435..0000000 --- a/server/src/main/java/server/Scenario.java +++ /dev/null @@ -1,34 +0,0 @@ -package server; - -public abstract class Scenario { - - private long UPDATE_INTERVAL = 500; - - public abstract void init(); - - protected void init(long updateInterval) { - this.UPDATE_INTERVAL = updateInterval; - } - public abstract void update(float d); - public synchronized void onPlayerConnect(Player player) { } - - public void start() { - new Thread(this::run).start(); - } - - private void run() { - long time = System.currentTimeMillis(); - while(true) { - while(System.currentTimeMillis() - time < UPDATE_INTERVAL) { - try { Thread.sleep(UPDATE_INTERVAL / 10); } catch(InterruptedException e) {} - } - - long newTime = System.currentTimeMillis(); - this.update(newTime - time); - - time = newTime; - } - } - - public abstract String getDescription(); -} diff --git a/server/src/main/java/server/ScenarioRunner.java b/server/src/main/java/server/ScenarioRunner.java deleted file mode 100644 index a1c0a8b..0000000 --- a/server/src/main/java/server/ScenarioRunner.java +++ /dev/null @@ -1,12 +0,0 @@ -package server; - -import server.scenarios.SlowJoinScenario; - -public class ScenarioRunner { - public static final Scenario scenario = new SlowJoinScenario(); - - public static void start() { - scenario.init(); - scenario.start(); - } -} diff --git a/server/src/main/java/server/TestServer.java b/server/src/main/java/server/TestServer.java deleted file mode 100644 index 87b889c..0000000 --- a/server/src/main/java/server/TestServer.java +++ /dev/null @@ -1,224 +0,0 @@ -package server; - -import com.google.gson.Gson; -import common.ICEAdapterTest; -import logging.Logger; -import net.ClientInformationMessage; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; - -import static com.github.nocatch.NoCatch.noCatch; - -public class TestServer { - - public static List players = new LinkedList<>(); - public static List games = new LinkedList<>(); - - public static Map collectedData = new HashMap<>(); - private static volatile boolean running = true; - - public static void main(String args[]) { - Logger.enableLogging(); - Logger.setLogLevel(Logger.INFO); - Logger.init("ICE adapter testserver"); - - IceTestServerConfig.init(); - - new Thread(TestServer::stopListener).start(); - - Webserver.init(); - - ScenarioRunner.start(); - - try { - ServerSocket serverSocket = new ServerSocket(ICEAdapterTest.TEST_SERVER_PORT); - - while (running) { - try { - Socket socket = serverSocket.accept(); - - if(players.size() >= IceTestServerConfig.INSTANCE.getMax_users()) { - socket.close(); - } else if(running) { - new Player(socket); - } - - } catch(IOException e) { - Logger.warning("Error while accepting user."); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - - - } - - private static void stopListener() { - Scanner scan = new Scanner(System.in); - scan.next(); - - close(); - } - - public static void close() { - if(! running) { - return; - } - running = false; - Logger.info("Got end"); - -// synchronized (players) { - new Thread(() -> { - new HashSet<>(players).forEach(Player::disconnect); - }).start(); -// } - - writeCollectedData(); - Webserver.close(); - Logger.close(); - System.exit(0); - } - - - public static void writeCollectedData() { - Logger.info("Writing logs..."); - Path dir = Paths.get(String.valueOf(System.currentTimeMillis())); - File dirFile = dir.toFile(); - if(! dirFile.exists()) { - dirFile.mkdir(); - } - - Gson gson = new Gson(); - - try { - { - FileWriter writer = new FileWriter(dir.resolve("latency.log").toFile()); - - writer.write(getLatencyLog(false)); - - writer.flush(); - writer.close(); - } - - for(Map.Entry entry : collectedData.entrySet()) { - try { - FileWriter writer = new FileWriter(dir.resolve(entry.getKey() + ".userLog").toFile()); - writer.write("Id: " + entry.getKey() + "\n"); - writer.write("Name: " + entry.getValue().getUsername() + "\n\n"); - writer.write(entry.getValue().getLog()); - writer.flush(); - writer.close(); - } catch(Exception e) { - System.err.println("Error while writing log."); - } - } - - for(Map.Entry entry : collectedData.entrySet()) { - try { - FileWriter writer = new FileWriter(dir.resolve(entry.getKey() + ".iceStatusLog").toFile()); - writer.write("Id: " + entry.getKey() + "\n"); - writer.write("Name: " + entry.getValue().getUsername() + "\n\n"); - writer.write(entry.getValue().getInformationMessages().stream().map(ClientInformationMessage::getIceStatus).map(gson::toJson).reduce("", (l, r) -> l + "\n" + r)); - writer.flush(); - writer.close(); - } catch(Exception e) { - System.err.println("Error while writing log."); - } - - } - - for(Map.Entry entry1 : collectedData.entrySet()) { - for(Map.Entry entry2 : collectedData.entrySet()) { - if(entry1.getKey() == entry2.getKey() || entry1.getKey() > entry2.getKey()) { - continue; - } - - try { - FileWriter writer = new FileWriter(dir.resolve(String.format("%d-%d.iceMsgLog", entry1.getKey(), entry2.getKey())).toFile()); - writer.write(String.format("Ids: %d <-> %d\n", entry1.getKey(), entry2.getKey())); - writer.write(String.format("Names: %d <-> %d\n\n", entry1.getValue().getUsername(), entry2.getValue().getUsername())); - - Arrays.asList(entry1, entry2).stream() - .flatMap(e -> e.getValue().getIceMessages().entrySet().stream()) - .filter(e -> e.getKey() == entry1.getKey() || e.getKey() == entry2.getKey()) - .flatMap(e -> e.getValue().entrySet().stream()) - .sorted(Comparator.comparingLong(Map.Entry::getKey)) - .map(Map.Entry::getValue) - .forEach(im -> noCatch(() -> writer.write(String.format("%d -> %d:\t%s\n", im.getSrcPlayerId(), im.getDestPlayerId(), gson.toJson(im.getMsg()))))); - - writer.flush(); - writer.close(); - } catch(Exception e) { - System.err.println("Error while writing log."); - } - } - } - - Logger.info("Wrote logs to " + dir.toAbsolutePath().toString()); - } catch(IOException e) { - Logger.error("Could not write data logs.", e); - } - } - - - public static String getLatencyLog(boolean filterNonConnected) { - StringBuilder sb = new StringBuilder(); - for (Map.Entry entry1 : collectedData.entrySet()) { - for (Map.Entry entry2 : collectedData.entrySet()) { - try { - if(entry1 == entry2) { - continue; - } - -// if(filterNonConnected && (players.stream().noneMatch(p -> p.getId() == entry1.getKey()) || players.stream().noneMatch(p -> p.getId() == entry2.getKey()))) { -// continue; -// } - - sb.append(String.format("%d -> %d: ", entry1.getKey(), entry2.getKey())); - - double[] pings = entry1.getValue().getInformationMessages().stream() - .filter(im -> im.getForgedAlliancePeers() != null) - .flatMap(im -> im.getForgedAlliancePeers().stream()) - .filter(p -> p.getRemoteId() == entry2.getKey()) - .flatMap(p -> p.getLatencies().stream()) - .mapToDouble(Integer::doubleValue).toArray(); - - double min = Arrays.stream(pings).min().orElse(99999); - double max = Arrays.stream(pings).max().orElse(99999); - double avg = Arrays.stream(pings).average().orElse(99999); - double avgLimited = Arrays.stream(pings).filter(p -> p < 2000).average().orElse(99999); - - double serverPing = collectedData.get(entry1.getKey()).getInformationMessages().stream().flatMap(im -> im.getLatencies().stream()).mapToDouble(Integer::doubleValue).average().orElse(99999) - + collectedData.get(entry2.getKey()).getInformationMessages().stream().flatMap(im -> im.getLatencies().stream()).mapToDouble(Integer::doubleValue).average().orElse(99999); - - sb.append(String.format("%.0f/%.0f(%.0f)/%.0f", min, avg, avgLimited, max)); - sb.append(String.format("\t(Server: %.0f)", serverPing)); -// writer.write("\tConnected: " + ); - - sb.append("\tQuiet for: " + entry1.getValue().getInformationMessages().stream() - .filter(Objects::nonNull) - .filter(im -> im.getForgedAlliancePeers().stream().filter(Objects::nonNull).anyMatch(p -> p.getRemoteId() == entry2.getKey() && im.getCurrentTimeMillis() - p.getLastPacketReceived() > 5000)) - .count() - ); - sb.append("\n"); - } catch(Exception e) { - Logger.error("Error while writing log.", e); - } - if (entry1.getKey() == entry2.getKey()) { - continue; - } - } - } - - return sb.toString(); - } - -} diff --git a/server/src/main/java/server/Webserver.java b/server/src/main/java/server/Webserver.java deleted file mode 100644 index 0e5bb73..0000000 --- a/server/src/main/java/server/Webserver.java +++ /dev/null @@ -1,124 +0,0 @@ -package server; - -import com.google.gson.Gson; -import common.ICEAdapterTest; -import logging.Logger; -import net.ClientInformationMessage; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Date; -import java.util.stream.Collectors; - -import static spark.Spark.*; - -public class Webserver { - - private static final Gson gson = new Gson(); - - private static final String interfaceHTML = readFile("/overview.html"); - private static final String loginString = readFile("/login.html"); - - public static void init() { - - port(ICEAdapterTest.TEST_SERVER_WEB_INTERFACE_PORT); - - get("/", (req, res) -> loginString); - - get("/login", (req, res) -> { - if(req.queryParams("pw").equals("8102faf")) { - req.session(true).attribute("loggedIn", true); - res.redirect("/data/overview"); - } else { - res.redirect("/"); - } - return null; - }); - - - path("/data", () -> { - before("/*", (req, res) -> { - if(! req.session(true).attributes().contains("loggedIn") || !req.session(true).attribute("loggedIn").equals(Boolean.TRUE)) { - res.redirect("/"); - halt(401); - } - }); - - get("/overview", (req, res) -> { - String iceStatusLinks = ""; - String playerLogLinks = ""; - synchronized (TestServer.players) { - iceStatusLinks = TestServer.players.stream().mapToInt(Player::getId).mapToObj(i -> String.format("id: %d", i, i)).collect(Collectors.joining(" ")); - playerLogLinks = TestServer.players.stream().mapToInt(Player::getId).mapToObj(i -> String.format("id: %d", i, i)).collect(Collectors.joining(" ")); - } - - return String.format(interfaceHTML, - new Date(System.currentTimeMillis()).toString(), - TestServer.players.size(), - iceStatusLinks, - playerLogLinks, - "" + TestServer.getLatencyLog(true).replace("\n", "
") + "
", - "" + Logger.collectedLog.replace("\n", "
") + "
" - ); - }); - - - get("/iceStatus", (req, res) -> { - if(! req.queryParams().contains("id")) { - return "400 Bad request"; - } - int id = Integer.parseInt(req.queryParams("id")); - if(TestServer.collectedData.containsKey(id)) { - res.type("application/json"); - return gson.toJson(TestServer.collectedData.get(id).getInformationMessages().stream().reduce((l, r) -> r).orElse(null)); - } else { - return "404 User ID not present"; - } - }); - - get("/playerLog", (req, res) -> { - if(! req.queryParams().contains("id")) { - return "400 Bad request"; - } - int id = Integer.parseInt(req.queryParams("id")); - if(TestServer.collectedData.containsKey(id)) { - return "" + - TestServer.collectedData.get(id).getInformationMessages().stream().map(ClientInformationMessage::getClientLog).map(s -> s.replace("\n", "
")).collect(Collectors.joining("
")) + - "
"; - } else { - return "404 User ID not present"; - } - }); - - get("/writeLogs", (req, res) -> { - TestServer.writeCollectedData(); - return "Logs written!"; - }); - - get("/stop", (req, res) -> { - new Thread(TestServer::close).start(); - return "Stopped."; - }); - }); - } - - public static void close() { - stop(); - } - - - private static String readFile(String fileName) { - StringBuilder sb = new StringBuilder(); - BufferedReader scanner = new BufferedReader(new InputStreamReader(TestServer.class.getResourceAsStream(fileName))); - String line; - try { - while((line = scanner.readLine()) != null) { - sb.append(line).append("\n"); - } - } catch (IOException e) { - e.printStackTrace(); - } - return sb.toString(); - } -} diff --git a/server/src/main/java/server/scenarios/DefaultScenario.java b/server/src/main/java/server/scenarios/DefaultScenario.java deleted file mode 100644 index f172f91..0000000 --- a/server/src/main/java/server/scenarios/DefaultScenario.java +++ /dev/null @@ -1,52 +0,0 @@ -package server.scenarios; - -import server.Game; -import server.Player; -import server.Scenario; -import server.TestServer; - -import java.util.LinkedList; -import java.util.List; - -public class DefaultScenario extends Scenario { - - - @Override - public void init() { - //Set update interval (update will be called all X ms) - this.init(1500); - } - - private static List stoppedAdapters = new LinkedList<>(); - - @Override - public synchronized void update(float d) { - synchronized (TestServer.games) { - for(Game game : TestServer.games) { - for(Player player : TestServer.players) { - //Do sth in here... - -// if(Math.random() < 0.01) { -// player.sigKill(); -// } - } - } - } - } - - @Override - public synchronized void onPlayerConnect(Player player) { - synchronized (TestServer.games) { - if(TestServer.games.isEmpty()) { - TestServer.games.add(new Game(player)); - } else { - TestServer.games.get(0).join(player); - } - } - } - - @Override - public String getDescription() { - return "default - single game"; - } -} diff --git a/server/src/main/java/server/scenarios/NoLogScenario.java b/server/src/main/java/server/scenarios/NoLogScenario.java deleted file mode 100644 index 6fc96dc..0000000 --- a/server/src/main/java/server/scenarios/NoLogScenario.java +++ /dev/null @@ -1,40 +0,0 @@ -package server.scenarios; - -import net.ScenarioOptionsMessage; -import server.Game; -import server.Player; -import server.Scenario; -import server.TestServer; - -public class NoLogScenario extends Scenario { - - - @Override - public void init() { - //Set update interval (update will be called all X ms) - this.init(1500); - } - - @Override - public synchronized void update(float d) { - - } - - @Override - public synchronized void onPlayerConnect(Player player) { - player.send(new ScenarioOptionsMessage(false, false)); - - synchronized (TestServer.games) { - if(TestServer.games.isEmpty()) { - TestServer.games.add(new Game(player)); - } else { - TestServer.games.get(0).join(player); - } - } - } - - @Override - public String getDescription() { - return "default - logging disabled"; - } -} diff --git a/server/src/main/java/server/scenarios/RandomStopScenario.java b/server/src/main/java/server/scenarios/RandomStopScenario.java deleted file mode 100644 index 7a2c814..0000000 --- a/server/src/main/java/server/scenarios/RandomStopScenario.java +++ /dev/null @@ -1,63 +0,0 @@ -package server.scenarios; - -import server.Game; -import server.Player; -import server.Scenario; -import server.TestServer; - -import java.util.LinkedList; -import java.util.List; - -public class RandomStopScenario extends Scenario { - - @Override - public void init() { - //Set update interval (update will be called all X ms) - this.init(1500); - } - - private static List stoppedAdapters = new LinkedList<>(); - - @Override - public synchronized void update(float d) { - synchronized (TestServer.games) { - for(Game game : TestServer.games) { - for(Player player : TestServer.players) { - - if(stoppedAdapters.contains(player)) { - if(Math.random() < 0.8) { - stoppedAdapters.remove(player); - player.sigCont(); - } - } else { - if(Math.random() < 0.2) { - stoppedAdapters.add(player); - player.sigStop(); - } - } - -// if(Math.random() < 0.01) { -// player.sigKill(); -// } - } - } - } - } - - @Override - public synchronized void onPlayerConnect(Player player) { - synchronized (TestServer.games) { - if(TestServer.games.isEmpty()) { - TestServer.games.add(new Game(player)); - } else { - TestServer.games.get(0).join(player); - } - } - } - - @Override - public String getDescription() { - return "random stop/cont of ice adapters"; - } - -} diff --git a/server/src/main/java/server/scenarios/SlowJoinScenario.java b/server/src/main/java/server/scenarios/SlowJoinScenario.java deleted file mode 100644 index 5e7e975..0000000 --- a/server/src/main/java/server/scenarios/SlowJoinScenario.java +++ /dev/null @@ -1,39 +0,0 @@ -package server.scenarios; - -import server.Game; -import server.Player; -import server.Scenario; -import server.TestServer; - -public class SlowJoinScenario extends Scenario { - - - @Override - public void init() { - //Set update interval (update will be called all X ms) - this.init(3000); - } - - @Override - public synchronized void update(float d) { - synchronized (TestServer.games) { - if(TestServer.games.size() > 0) { - TestServer.players.stream().filter(p -> ! TestServer.games.get(0).getPlayers().contains(p)).findFirst().ifPresent(TestServer.games.get(0)::join); - } - } - } - - @Override - public synchronized void onPlayerConnect(Player player) { - synchronized (TestServer.games) { - if(TestServer.games.isEmpty()) { - TestServer.games.add(new Game(player)); - } - } - } - - @Override - public String getDescription() { - return "delay joins"; - } -} diff --git a/server/src/main/resources/login.html b/server/src/main/resources/login.html deleted file mode 100644 index 73159b9..0000000 --- a/server/src/main/resources/login.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Login - - -
- - - \ No newline at end of file diff --git a/server/src/main/resources/overview.html b/server/src/main/resources/overview.html deleted file mode 100644 index 34dd2d8..0000000 --- a/server/src/main/resources/overview.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - FAF Ice Test Server - - - - -

FAF ICE Test Server

- %s
- Users: %d
-
-
- -
-
- -

-

iceStatus

- - - - - %s - -

-

Player logs

- %s - -

-

Latencies

- %s - -

-

Server log

- %s - - - - - - \ No newline at end of file diff --git a/shared/build.gradle b/shared/build.gradle deleted file mode 100644 index d8cf631..0000000 --- a/shared/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ - -apply plugin: 'java' - -group 'com.faforever' -version '1.0-SNAPSHOT' - -sourceCompatibility = JavaVersion.VERSION_17 - -dependencies{ - annotationProcessor("org.projectlombok:lombok:$lombokVersion") - implementation("org.projectlombok:lombok:$lombokVersion") -} diff --git a/shared/src/main/java/com/github/nocatch/NoCatch.java b/shared/src/main/java/com/github/nocatch/NoCatch.java deleted file mode 100644 index f3fe098..0000000 --- a/shared/src/main/java/com/github/nocatch/NoCatch.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.github.nocatch; - -import java.lang.reflect.Constructor; -import java.util.concurrent.Callable; - -public final class NoCatch { - - public interface NoCatchRunnable { - - void run() throws Exception; - } - - /** - * Specifies the default runtime exception used to wrap checked exceptions. - */ - private static Class DEFAULT_WRAPPER_EXCEPTION = NoCatchException.class; - - private NoCatch() { - throw new AssertionError("Not instantiatable"); - } - - public static void setDefaultWrapperException(Class defaultWrapperException) { - DEFAULT_WRAPPER_EXCEPTION = defaultWrapperException; - } - - /** - * Runs the specified runnable and wraps any checked exception into a RuntimeException. - * - * @param runnable the runnable to run - * - * @throws RuntimeException if any checked exception is thrown - */ - public static void noCatch(NoCatchRunnable runnable) { - noCatch(runnable, DEFAULT_WRAPPER_EXCEPTION); - } - - /** - * Runs the specified runnable and wraps any checked exception into a RuntimeException. - * - * @param runnable the runnable to run - * @param wrapperException a RuntimeException to use to wrap any thrown exception in. The wrapper exception - * must provide a constructor that takes a cause as paramter and it must be a static - * class. - * - * @throws NoCatchException if any checked exception occurred - */ - public static void noCatch(NoCatchRunnable runnable, Class wrapperException) { - try { - runnable.run(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw wrapException(e, wrapperException); - } - } - - private static RuntimeException wrapException(Exception exception, Class wrapperException) { - try { - Constructor constructor = wrapperException.getDeclaredConstructor(Throwable.class); - constructor.setAccessible(true); - throw constructor.newInstance(exception); - } catch (ReflectiveOperationException e) { - NoCatchException fallbackException = new NoCatchException("WARN: Could not wrap thrown exception using the " + - "specified wrapper (" + wrapperException.getName() + ". Your wrapper needs to have a constructor that takes a " + - "cause.", exception); - fallbackException.addSuppressed(e); - throw fallbackException; - } - } - - /** - * Calls the specified callable and wraps any checked exception into a RuntimeException. - * - * @param callable the callable to call - * @param the callable's return type - * - * @return the result of the callable - * - * @throws NoCatchException if any checked exception is thrown - */ - public static T noCatch(Callable callable) { - return noCatch(callable, DEFAULT_WRAPPER_EXCEPTION); - } - - /** - * Calls the specified callable and wraps any checked exception into a RuntimeException. - * - * @param callable the callable to call - * @param wrapperException a RuntimeException to use to wrap any thrown exception in. The wrapper exception - * must provide a constructor that takes a cause as paramter and it must be a static - * class. - * @param the callable's return type - * - * @return the result of the callable - * - * @throws NoCatchException if any checked exception occurred - */ - public static T noCatch(Callable callable, Class wrapperException) { - try { - return callable.call(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw wrapException(e, wrapperException); - } - } -} diff --git a/shared/src/main/java/com/github/nocatch/NoCatchException.java b/shared/src/main/java/com/github/nocatch/NoCatchException.java deleted file mode 100644 index 4d64506..0000000 --- a/shared/src/main/java/com/github/nocatch/NoCatchException.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.github.nocatch; - -/** - * Default wrapper exception for any checked exception. Also thrown if the API isn't used correctly. - */ -public class NoCatchException extends RuntimeException { - - public NoCatchException(String message) { - super(message); - } - - public NoCatchException(Throwable cause) { - super(cause); - } - - public NoCatchException(String message, Throwable cause) { - super(message, cause); - } -} \ No newline at end of file diff --git a/shared/src/main/java/common/ICEAdapterTest.java b/shared/src/main/java/common/ICEAdapterTest.java deleted file mode 100644 index f5177c5..0000000 --- a/shared/src/main/java/common/ICEAdapterTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package common; - - -public class ICEAdapterTest { - public static final int VERSION = 32; - public static int TEST_SERVER_PORT = 39456; - public static int TEST_SERVER_WEB_INTERFACE_PORT = 39457; - public static final String TEST_SERVER_ADDRESS = "localhost"; - - public static final boolean TEST_DATA_RANDOM_SIZE = false; - - public static final String GDPR = "By using this application you consent to it collecting your username and IP address(es) during the test." + - "This information is stored on the test server. It will be used to investigate problems currently present in this software." + - "All collected data will be deleted immediately after investigation." + - "To get information about the stored data or to request deletion please contact geosearchef@geosearchef.de."; -} \ No newline at end of file diff --git a/shared/src/main/java/data/ForgedAlliancePeer.java b/shared/src/main/java/data/ForgedAlliancePeer.java deleted file mode 100644 index b9f1f81..0000000 --- a/shared/src/main/java/data/ForgedAlliancePeer.java +++ /dev/null @@ -1,65 +0,0 @@ -package data; - -import lombok.Data; - -import java.util.LinkedList; -import java.util.Queue; - -@Data -public class ForgedAlliancePeer { - - private boolean connected = false; - public final String remoteAddress; - public final int remotePort; - public final int remoteId; - public final String remoteUsername; - public final Offerer offerer; - - public int echoRequestsSent; - public long lastPacketReceived = System.currentTimeMillis(); - public final Queue latencies = new LinkedList<>(); - - public long lastConnectionRequestSent = 0; - - public void clearLatencyHistory() { - synchronized (latencies) { - latencies.clear(); - } - } - - public int addLatency(int lat) { - lastPacketReceived = System.currentTimeMillis(); - - synchronized (latencies) { - latencies.add(lat); - if (latencies.size() > 25) { - latencies.remove(); - } - } - return getAverageLatency(); - } - - public int getAverageLatency() { - synchronized (latencies) { - return (int) latencies.stream().mapToInt(Integer::intValue).average().orElse(0); - } - } - - public int getJitter() { - int averageLatency = getAverageLatency(); - synchronized (latencies) { - int maxLatency = latencies.stream().mapToInt(Integer::intValue).max().orElse(0); - int minLatency = latencies.stream().mapToInt(Integer::intValue).min().orElse(0); - return Math.max(maxLatency - averageLatency, averageLatency - minLatency); - } - } - - public boolean isQuiet() { - return System.currentTimeMillis() - lastPacketReceived > 5000; - } - - public enum Offerer { - REMOTE, LOCAL - } - -} diff --git a/shared/src/main/java/data/IceStatus.java b/shared/src/main/java/data/IceStatus.java deleted file mode 100644 index 33eada1..0000000 --- a/shared/src/main/java/data/IceStatus.java +++ /dev/null @@ -1,53 +0,0 @@ -package data; - -import lombok.Data; - -@Data -public class IceStatus { - private String version; - private int ice_servers_size; - private int lobby_port; - private String init_mode; - private IceOptions options; - private IceGPGNetState gpgpnet; - private IceRelay[] relays; - - @Data - public static class IceOptions { - private int player_id; - private String player_login; - private int rpc_port; - private int gpgnet_port; - } - - @Data - public static class IceGPGNetState { - private int local_port; - private boolean connected; - private String game_state; - private String task_string; - } - - @Data - public static class IceRelay { - - private int remote_player_id; - private String remote_player_login; - private int local_game_udp_port; - private IceRelayICEState ice; - - @Data - public static class IceRelayICEState { - private boolean offerer; - private String state; - private String gathering_state; - private String datachannel_state; - private boolean connected; - private String loc_cand_addr; - private String rem_cand_addr; - private String loc_cand_type; - private String rem_cand_type; - private Double time_to_connected; - } - } -} diff --git a/shared/src/main/java/logging/Logger.java b/shared/src/main/java/logging/Logger.java deleted file mode 100644 index 7d37a02..0000000 --- a/shared/src/main/java/logging/Logger.java +++ /dev/null @@ -1,186 +0,0 @@ -package logging; - -import java.io.FileWriter; -import java.io.IOException; -import java.util.Date; - -public class Logger { - public static final int ERROR = 0; - public static final int WARNING = 1; - public static final int INFO = 2; - public static final int DEBUG = 3; - - public static String collectedLog = ""; - - public static boolean loggingEnabled = false; - public static int logLevel = DEBUG; - - - static FileWriter fileWriter; - private static long lastFlush = 0; - - public synchronized static void init(String programTitle) { - if (fileWriter != null) - return; - - try { - Date date = new Date(); - System.out.println(programTitle + "\n"); - System.out.println("Logging started: " + date.toString()); - - initFileWriter(programTitle, date); - } catch (IOException e) { - System.err.println("Could not initialize logging!"); - } - } - - private synchronized static void initFileWriter(String programTitle, Date date) throws IOException { - if (loggingEnabled) { - fileWriter = new FileWriter((date.getYear() + 1900) + "-" + (date.getMonth() + 1) + "-" + date.getDate() + "_" + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + "-" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + "-" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ".log"); - fileWriter.write(programTitle + "\n\n"); - fileWriter.write("Logging started: " + date.toString() + "\n"); - fileWriter.flush(); - } - } - - public synchronized static void close() { - try { - if (fileWriter != null) { - fileWriter.write("Logging stopped"); - fileWriter.flush(); - fileWriter.close(); - } - } catch (IOException e) { - System.err.println("Could not close log file!"); - } - -// System.out.println("Logging stopped"); - } - - public synchronized static void crash(String string) { - error(string); - crash(new RuntimeException(string)); - } - - public synchronized static void crash(String string, Exception e) { - error(string); - crash(e); - } - - public synchronized static void crash(Exception e) { - if (logLevel >= ERROR) { - Date date = new Date(); - String logString = "[CRASH] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + " : " + e.getCause() + " " + e.getMessage() + "\n"; - System.err.print(logString); - - writeToLog(logString); - for (StackTraceElement element : e.getStackTrace()) { - logString = "[STACKTRACE]:\t\t" + element.toString() + "\n"; - System.err.print(logString); - writeToLog(logString); - } - close(); - } - - System.exit(-1); - } - - public synchronized static void debug(String string, Object... args) { - if (args.length > 0) { - string = String.format(string, args); - } - - if (logLevel >= DEBUG) { - Date date = new Date(); - String logString = "[DEBUG] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ":\t\t" + string + "\n"; - System.out.print(logString); - writeToLog(logString); - } - } - - public synchronized static void info(String string, Object... args) { - if (args.length > 0) { - string = String.format(string, args); - } - if (logLevel >= INFO) { - Date date = new Date(); - String logString = "[INFO] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ":\t\t" + string + "\n"; - System.out.print(logString); - writeToLog(logString); - } - } - - public synchronized static void warning(String string, Object... args) { - if (args.length > 0) { - string = String.format(string, args); - } - - if (logLevel >= WARNING) { - Date date = new Date(); - String logString = "[WARNING] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ":\t\t" + string + "\n"; - System.out.print(logString); - writeToLog(logString); - } - } - - public synchronized static void error(String string, Object... args) { - if (args.length > 0) { - string = String.format(string, args); - } - - if (logLevel >= ERROR) { - Date date = new Date(); - String logString = "[ERROR] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ":\t\t" + string + "\n"; - System.err.print(logString); - writeToLog(logString); - } - } - - public synchronized static void error(Exception e) { - if (logLevel >= ERROR) { - Date date = new Date(); - String logString = "[ERROR] " + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":" + (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()) + ":\t\t" + e.getMessage() + "\n"; - System.err.print(logString); - writeToLog(logString); - - for (StackTraceElement element : e.getStackTrace()) { - logString = "[STACKTRACE]:\t\t" + element.toString() + "\n"; - System.err.print(logString); - writeToLog(logString); - } - } - } - - public synchronized static void error(String string, Exception e) { - error(string); - error(e); - } - - private synchronized static void writeToLog(String logString) { - collectedLog = collectedLog.concat(logString); - - if (loggingEnabled) { - try { - fileWriter.write(logString); - if (System.currentTimeMillis() - lastFlush > 2000) { - fileWriter.flush(); - lastFlush = System.currentTimeMillis(); - } - } catch (IOException e) { - System.err.println("Could not write to log file!"); - } - } - } - - public synchronized static void enableLogging() { - loggingEnabled = true; - } - - public synchronized static void disableLogging() { - loggingEnabled = false; - } - - public static void setLogLevel(int level) { - logLevel = level; - } -} diff --git a/shared/src/main/java/net/ClientInformationMessage.java b/shared/src/main/java/net/ClientInformationMessage.java deleted file mode 100644 index 1c9e450..0000000 --- a/shared/src/main/java/net/ClientInformationMessage.java +++ /dev/null @@ -1,22 +0,0 @@ -package net; - -import data.ForgedAlliancePeer; -import data.IceStatus; -import lombok.Data; - -import java.util.List; -import java.util.Queue; - -@Data -public class ClientInformationMessage { - - private final String username; - private final int playerId; - private final long currentTimeMillis; - private final Queue latencies; - private final IceStatus iceStatus; - - private final String clientLog; - private final List forgedAlliancePeers; - -} diff --git a/shared/src/main/java/net/ConnectToPeerMessage.java b/shared/src/main/java/net/ConnectToPeerMessage.java deleted file mode 100644 index 12c923b..0000000 --- a/shared/src/main/java/net/ConnectToPeerMessage.java +++ /dev/null @@ -1,10 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class ConnectToPeerMessage { - private final String remotePlayerLogin; - private final int remotePlayerId; - private final boolean offer; -} diff --git a/shared/src/main/java/net/DisconnectFromPeerMessage.java b/shared/src/main/java/net/DisconnectFromPeerMessage.java deleted file mode 100644 index 9dded67..0000000 --- a/shared/src/main/java/net/DisconnectFromPeerMessage.java +++ /dev/null @@ -1,8 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class DisconnectFromPeerMessage { - private final int remotePlayerId; -} diff --git a/shared/src/main/java/net/EchoRequest.java b/shared/src/main/java/net/EchoRequest.java deleted file mode 100644 index c363ad8..0000000 --- a/shared/src/main/java/net/EchoRequest.java +++ /dev/null @@ -1,8 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class EchoRequest { - private final long timestamp; -} diff --git a/shared/src/main/java/net/EchoResponse.java b/shared/src/main/java/net/EchoResponse.java deleted file mode 100644 index 218f3c1..0000000 --- a/shared/src/main/java/net/EchoResponse.java +++ /dev/null @@ -1,8 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class EchoResponse { - private final long timestamp; -} diff --git a/shared/src/main/java/net/HolePunchingMessage.java b/shared/src/main/java/net/HolePunchingMessage.java deleted file mode 100644 index f8437e5..0000000 --- a/shared/src/main/java/net/HolePunchingMessage.java +++ /dev/null @@ -1,12 +0,0 @@ -package net; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public class HolePunchingMessage { - private final int id; - private final String address; - private final int port; -} diff --git a/shared/src/main/java/net/HostGameMessage.java b/shared/src/main/java/net/HostGameMessage.java deleted file mode 100644 index 928ee31..0000000 --- a/shared/src/main/java/net/HostGameMessage.java +++ /dev/null @@ -1,8 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class HostGameMessage { - private final String mapName; -} diff --git a/shared/src/main/java/net/IceAdapterSignalMessage.java b/shared/src/main/java/net/IceAdapterSignalMessage.java deleted file mode 100644 index ee87a15..0000000 --- a/shared/src/main/java/net/IceAdapterSignalMessage.java +++ /dev/null @@ -1,10 +0,0 @@ -package net; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public class IceAdapterSignalMessage { - private final String signal;//stop, cont, kill -} diff --git a/shared/src/main/java/net/IceMessage.java b/shared/src/main/java/net/IceMessage.java deleted file mode 100644 index a649b2d..0000000 --- a/shared/src/main/java/net/IceMessage.java +++ /dev/null @@ -1,10 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class IceMessage { - private final int srcPlayerId; - private final int destPlayerId; - private final Object msg; -} \ No newline at end of file diff --git a/shared/src/main/java/net/JoinGameMessage.java b/shared/src/main/java/net/JoinGameMessage.java deleted file mode 100644 index 4688642..0000000 --- a/shared/src/main/java/net/JoinGameMessage.java +++ /dev/null @@ -1,9 +0,0 @@ -package net; - -import lombok.Data; - -@Data -public class JoinGameMessage { - private final String remotePlayerLogin; - private final int remotePlayerId; -} diff --git a/shared/src/main/java/net/LeaveGameMessage.java b/shared/src/main/java/net/LeaveGameMessage.java deleted file mode 100644 index f836337..0000000 --- a/shared/src/main/java/net/LeaveGameMessage.java +++ /dev/null @@ -1,4 +0,0 @@ -package net; - -public class LeaveGameMessage { -} diff --git a/shared/src/main/java/net/ScenarioOptionsMessage.java b/shared/src/main/java/net/ScenarioOptionsMessage.java deleted file mode 100644 index 7036669..0000000 --- a/shared/src/main/java/net/ScenarioOptionsMessage.java +++ /dev/null @@ -1,13 +0,0 @@ -package net; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class ScenarioOptionsMessage { - private boolean uploadLog = true; - private boolean uploadIceStatus = true; -} diff --git a/shared/src/main/java/util/OsUtil.java b/shared/src/main/java/util/OsUtil.java deleted file mode 100644 index af679cb..0000000 --- a/shared/src/main/java/util/OsUtil.java +++ /dev/null @@ -1,25 +0,0 @@ -package util; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.function.Consumer; - -import static com.github.nocatch.NoCatch.noCatch; - -public class OsUtil { - - public static void gobbleLines(InputStream stream, Consumer lineConsumer) { - Thread thread = new Thread(() -> noCatch(() -> { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - lineConsumer.accept(line); - } - } - })); - thread.setDaemon(true); - thread.start(); - } - -} diff --git a/shared/src/main/java/util/Util.java b/shared/src/main/java/util/Util.java deleted file mode 100644 index c6990a1..0000000 --- a/shared/src/main/java/util/Util.java +++ /dev/null @@ -1,78 +0,0 @@ -package util; - -import logging.Logger; - -import java.io.IOException; -import java.net.DatagramSocket; -import java.net.ServerSocket; -import java.net.SocketException; - -public class Util { -// private static final Random random = new Random(); - - public static int getAvaiableTCPPort() { - try { - ServerSocket socket = new ServerSocket(0); - int port = socket.getLocalPort(); - socket.close(); - return port; - } catch (IOException e) { - Logger.error("Could not find available TCP port."); - Logger.crash(e); - return -1; - } - } - - public static int getAvaiableUDPPort() { - try { - DatagramSocket socket = new DatagramSocket(0); - int port = socket.getLocalPort(); - socket.close(); - return port; - } catch (SocketException e) { - Logger.error("Could not find available TCP port."); - Logger.crash(e); - return -1; - } - } - -// public static int getAvaiableTCPPort() { -// return getAvailableTCPPort(49152, 65535); -// } -// -// public static int getAvailableTCPPort(int min, int max) { -// while (true) { -// int randomPort = min + random.nextInt(max - min); -// if (isPortAvaiable(randomPort)) { -// return randomPort; -// } -// } -// } -// -// public static boolean isPortAvaiable(int port) { -// ServerSocket socket = null; -// try { -// socket = new ServerSocket(port); -// } catch (IOException e) { -// return false; -// } finally { -// if (socket != null) { -// try { -// socket.close(); -// } catch (IOException e) { -// Logger.crash("Could not close socket while searching for availabe port"); -// } -// } -// } -// -// return true; -// } - - - public static void assertThat(boolean b) { - if(! b) { - Throwable t = new Throwable(); - Logger.error("Assertion failed!!! %s->%s:%d", t.getStackTrace()[1].getClassName(), t.getStackTrace()[1].getMethodName(), t.getStackTrace()[1].getLineNumber()); - } - } -}