diff --git a/pom.xml b/pom.xml index e184d76..9a3c997 100644 --- a/pom.xml +++ b/pom.xml @@ -15,28 +15,8 @@ UTF-8 org.toop.Main - - 3.3.6 - - lwjgl-natives-windows-amd64windowsamd64natives-windows - lwjgl-natives-linux-amd64unixlinuxamd64natives-linux - lwjgl-natives-macos-aarch64macaarch64natives-macos-arm64 - - - - - - org.lwjgl - lwjgl-bom - ${lwjgl.version} - import - pom - - - - org.junit @@ -117,15 +97,6 @@ netty-all 4.2.6.Final - - org.lwjgllwjgl - org.lwjgllwjgl-glfw - org.lwjgllwjgl-opengl - org.lwjgllwjgl-stb - org.lwjgllwjgl${lwjgl.natives} - org.lwjgllwjgl-glfw${lwjgl.natives} - org.lwjgllwjgl-opengl${lwjgl.natives} - org.lwjgllwjgl-stb${lwjgl.natives} @@ -198,13 +169,6 @@ true true - - - - - diff --git a/src/main/java/org/toop/ConsoleGui.java b/src/main/java/org/toop/ConsoleGui.java deleted file mode 100644 index 1e6a860..0000000 --- a/src/main/java/org/toop/ConsoleGui.java +++ /dev/null @@ -1,214 +0,0 @@ -//package org.toop; -// -//import java.util.*; -//import java.util.concurrent.CompletableFuture; -//import java.util.concurrent.ExecutionException; -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -//import org.toop.eventbus.events.Events; -//import org.toop.eventbus.GlobalEventBus; -//import org.toop.game.tictactoe.*; -//import org.toop.game.tictactoe.ai.MinMaxTicTacToe; -// -//public class ConsoleGui { -// -// private static final Logger logger = LogManager.getLogger(ConsoleGui.class); -// -// private Scanner scanner; -// -// private TicTacToe game; -// private MinMaxTicTacToe ai; -// -// private String ai1 = null; -// private String ai2 = null; -// -// private String serverId = null; -// private String connectionId = null; -// private String ticTacToeGameId = null; -// -// public ConsoleGui() throws ExecutionException, InterruptedException { -// scanner = new Scanner(System.in); -// Random random = new Random(3453498); -// -// int mode = -1; -// -// System.out.print( -// """ -// 1. player vs player -// 2. player vs ai -// 3. ai vs player -// 4. ai v ai -// Choose mode (default is 1):\s\ -// """); -// String modeString = scanner.nextLine(); -// -// try { -// mode = Integer.parseInt(modeString); -// } catch (Exception e) { -// logger.error(e.getMessage()); -// } -// -// String player1 = null; -// String player2 = null; -// -// switch (mode) { -// // player vs ai -// case 2: -// { -// System.out.print("Please enter your name: "); -// String name = scanner.nextLine(); -// -// player1 = name; -// ai2 = player2 = "AI#" + random.nextInt(); -// -// break; -// } -// -// // ai vs player -// case 3: -// { -// System.out.print("Enter your name: "); -// String name = scanner.nextLine(); -// -// ai1 = player1 = "AI#" + random.nextInt(); -// player2 = name; -// -// break; -// } -// -// // ai vs ai -// case 4: -// { -// ai1 = player1 = "AI#" + random.nextInt(); -// ai2 = player2 = "AI2" + random.nextInt(); -// -// break; -// } -// -// // player vs player -// case 1: -// default: -// { -// System.out.print("Player 1. Please enter your name: "); -// String name1 = scanner.nextLine(); -// -// System.out.print("Player 2. Please enter your name: "); -// String name2 = scanner.nextLine(); -// -// player1 = name1; -// player2 = name2; -// } -// } -// -// game = new TicTacToe(player1, player2); -// ai = new MinMaxTicTacToe(); -// -// CompletableFuture serverIdFuture = new CompletableFuture<>(); -// GlobalEventBus.post( -// new Events.ServerEvents.StartServerRequest("5001", "tictactoe", serverIdFuture)); -// serverId = serverIdFuture.get(); -// -// CompletableFuture connectionIdFuture = new CompletableFuture<>(); -// GlobalEventBus.post( -// new Events.ServerEvents.StartConnectionRequest( -// "127.0.0.1", "5001", connectionIdFuture)); -// connectionId = connectionIdFuture.get(); -// -// CompletableFuture ticTacToeGame = new CompletableFuture<>(); -// GlobalEventBus.post( -// new Events.ServerEvents.CreateTicTacToeGameRequest( -// serverId, player1, player2, ticTacToeGame)); -// ticTacToeGameId = ticTacToeGame.get(); -// GlobalEventBus.post(new Events.ServerEvents.RunTicTacToeGame(serverId, ticTacToeGameId)); -// } -// -// public void print() { -// char[] seperator = new char[game.getSize() * 4 - 1]; -// Arrays.fill(seperator, '-'); -// -// for (int i = 0; i < game.getSize(); i++) { -// String buffer = " "; -// -// for (int j = 0; j < game.getSize() - 1; j++) { -// buffer += game.getGrid()[i * game.getSize() + j] + " | "; -// } -// -// buffer += game.getGrid()[i * game.getSize() + game.getSize() - 1]; -// System.out.println(buffer); -// -// if (i < game.getSize() - 1) { -// System.out.println(seperator); -// } -// } -// } -// -// public boolean next() { -// Player current = game.getCurrentPlayer(); -// int move = -1; -// -// if (ai1 != null && current.getName() == ai1 || ai2 != null && current.getName() == ai2) { -// move = ai.findBestMove(game); -// } else { -// System.out.printf( -// "%s's (%c) turn. Please choose an empty cell between 0-8: ", -// current.getName(), current.getSymbol()); -// String input = scanner.nextLine(); -// -// try { -// move = Integer.parseInt(input); -// } catch (NumberFormatException e) { -// } -// } -// -// GameBase.State state = game.play(move); -// boolean keepRunning = true; -// -// switch (state) { -// case INVALID: -// { -// System.out.println("Please select an empty cell. Between 0-8"); -// return true; -// } -// -// case DRAW: -// { -// System.out.println("Game ended in a draw."); -// keepRunning = false; -// break; -// } -// -// case WIN: -// { -// System.out.printf("%s has won the game.\n", current.getName()); -// keepRunning = false; -// break; -// } -// -// case NORMAL: -// default: -// { -// keepRunning = true; -// break; -// } -// } -// -// GlobalEventBus.post( -// new Events.ServerEvents.SendCommand( -// connectionId, -// "gameid " + ticTacToeGameId, -// "player " + current.getName(), -// "MOVE", -// String.valueOf(move))); -// -// if (!keepRunning) { -// GlobalEventBus.post( -// new Events.ServerEvents.EndTicTacToeGame(serverId, ticTacToeGameId)); -// } -// -// return keepRunning; -// } -// -// public GameBase getGame() { -// return game; -// } -//} diff --git a/src/main/java/org/toop/Main.java b/src/main/java/org/toop/Main.java index c389d8c..52830ed 100644 --- a/src/main/java/org/toop/Main.java +++ b/src/main/java/org/toop/Main.java @@ -7,7 +7,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.toop.backend.tictactoe.ServerManager; import org.toop.eventbus.EventPublisher; -import org.toop.eventbus.EventRegistry; import org.toop.eventbus.events.Events; import org.toop.eventbus.GlobalEventBus; import org.toop.frontend.UI.LocalServerSelector; diff --git a/src/main/java/org/toop/MainTest.java b/src/main/java/org/toop/MainTest.java deleted file mode 100644 index 79ac469..0000000 --- a/src/main/java/org/toop/MainTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.toop; - -import org.toop.eventbus.EventFlow; -import org.toop.eventbus.GlobalEventBus; -import org.toop.eventbus.events.NetworkEvents; -import org.toop.frontend.networking.NetworkingGameClientHandler; - -import java.util.function.Supplier; - -public class MainTest { - MainTest() { - var a = new EventFlow() - .addPostEvent(NetworkEvents.StartClient.class, - (Supplier) NetworkingGameClientHandler::new, - "127.0.0.1", - 5001) - .onResponse(NetworkEvents.StartClientSuccess.class) - .perform(this::handleStartClientSuccess) - .unsubscribeAfterSuccess().asyncPostEvent(); - } - - private void handleStartClientSuccess(NetworkEvents.StartClientSuccess event) { - GlobalEventBus.post(new NetworkEvents.CloseClient(event.clientId())); - } -} diff --git a/src/main/java/org/toop/backend/tictactoe/ParsedCommand.java b/src/main/java/org/toop/backend/tictactoe/ParsedCommand.java deleted file mode 100644 index 5ff9615..0000000 --- a/src/main/java/org/toop/backend/tictactoe/ParsedCommand.java +++ /dev/null @@ -1,216 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class ParsedCommand { - private static final Logger logger = LogManager.getLogger(ParsedCommand.class); - - public TicTacToeServerCommand command; - public ArrayList arguments; - public boolean isValidCommand; - public boolean isServerCommand; - public TicTacToeServerMessage returnMessage; - public String errorMessage; - public String originalCommand; - public String gameId; - public String player; - - public ParsedCommand(String receivedCommand) { - - if (receivedCommand.isEmpty()) { - logger.info("Received empty command"); - this.gameId = null; - this.player = null; - this.command = null; - this.arguments = null; - this.isValidCommand = false; - this.isServerCommand = true; - this.returnMessage = TicTacToeServerMessage.ERR; - this.errorMessage = "The received command is empty"; - this.originalCommand = receivedCommand; - return; - } - - // Case-insensitive regex to match: game_id {id} player {name} - Pattern pattern = - Pattern.compile( - "(?i)\\bgame[_]?id\\s+(\\S+)\\s+player\\s+(\\S+)", - Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(receivedCommand); - - String tempGameId = null; - String tempPlayer = null; - String tempPayload = receivedCommand; - - if (matcher.find()) { - tempGameId = matcher.group(1); // first capture group → game_id - tempPlayer = matcher.group(2); // second capture group → player - // Remove the matched part from the original command - tempPayload = matcher.replaceFirst("").trim(); - } - - this.gameId = tempGameId; - this.player = tempPlayer; - receivedCommand = tempPayload; - - logger.info("Received gameId: {}", gameId); - logger.info("Received player: {}", player); - logger.info("Received command: {}", receivedCommand); - - String[] segments = receivedCommand.split(" "); - if (segments[0].isEmpty()) { - this.command = null; - this.arguments = null; - this.isValidCommand = false; - this.isServerCommand = true; - this.returnMessage = TicTacToeServerMessage.ERR; - this.errorMessage = "The received command is empty or couldn't be split"; - this.originalCommand = receivedCommand; - return; - } - - TicTacToeServerCommand commandEnum = TicTacToeServerCommand.getCommand(segments[0]); - - switch (commandEnum) { - case CREATE_GAME -> { - if (segments.length == 3 && !segments[1].isEmpty() && !segments[2].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(2); - this.arguments.add(segments[1]); - this.arguments.add(segments[2]); - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } - } - case END_GAME, START_GAME -> { - if (segments.length == 2 && !segments[1].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(1); - this.arguments.add(segments[1]); - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } - } - case MOVE -> { - if (segments.length == 2 && !segments[1].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(1); - this.arguments.add(segments[1]); - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = false; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } - } - case MESSAGE -> { - if (segments.length == 3 && !segments[2].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(2); - this.arguments.add(segments[2]); - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } - } - case CHALLENGE -> { - if (!segments[1].isEmpty() - && segments[1].equals("accept") - && !segments[2].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(2); - this.arguments.add(segments[1]); - this.arguments.add(segments[2]); // TODO: Needs to be a number. - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } else { - this.command = commandEnum; - this.arguments = null; - this.returnMessage = TicTacToeServerMessage.ERR; - this.isValidCommand = false; - this.isServerCommand = true; - this.errorMessage = "The challenge was not parsable"; - this.originalCommand = receivedCommand; - return; - } - } - case LOGIN -> { // TODO: Challenge needs to accept different game types later. - if (!segments[1].isEmpty()) { - this.command = commandEnum; - this.arguments = new ArrayList<>(1); - this.arguments.add(segments[1]); - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } else { - this.command = commandEnum; - this.arguments = null; - this.returnMessage = TicTacToeServerMessage.ERR; - this.isValidCommand = false; - this.isServerCommand = true; - this.errorMessage = "The received name is empty or couldn't be understood"; - this.originalCommand = receivedCommand; - return; - } - } - // case GET -> { // TODO: Get needs to accept different game types later. - // And get the players - // - // } - case BYE, DISCONNECT, LOGOUT, QUIT, EXIT, FORFEIT, SUBSCRIBE -> { - this.command = commandEnum; - this.arguments = null; - this.returnMessage = TicTacToeServerMessage.OK; - this.isValidCommand = true; - this.isServerCommand = true; - this.errorMessage = null; - this.originalCommand = receivedCommand; - return; - } - case null, default -> { - this.command = null; - this.arguments = null; - this.returnMessage = TicTacToeServerMessage.ERR; - this.isValidCommand = false; - this.isServerCommand = true; - this.errorMessage = segments[0] + " is not a supported command"; - this.originalCommand = receivedCommand; - return; - } - } - } - - @Override - public String toString() { - return this.originalCommand; // TODO: Maybe return more info. - } - - // - // public ParsedCommand parseCommand(String command) { - // return null; - // } - -} diff --git a/src/main/java/org/toop/backend/tictactoe/ServerManager.java b/src/main/java/org/toop/backend/tictactoe/ServerManager.java deleted file mode 100644 index 2290139..0000000 --- a/src/main/java/org/toop/backend/tictactoe/ServerManager.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.toop.eventbus.EventPublisher; -import org.toop.eventbus.events.Events; - -// TODO more methods. - -public class ServerManager { - - private static final Logger logger = LogManager.getLogger(ServerManager.class); - - /** Map of serverId -> Server instances */ - private final Map servers = new ConcurrentHashMap<>(); - - /** Starts a server manager, to manage, servers. */ - public ServerManager() { - new EventPublisher<>(Events.ServerEvents.StartServerRequest.class, this::handleStartServerRequest); - new EventPublisher<>(Events.ServerEvents.StartServer.class, this::handleStartServer); - new EventPublisher<>(Events.ServerEvents.ForceCloseAllServers.class, _ -> shutdownAll()); - new EventPublisher<>(Events.ServerEvents.CreateTicTacToeGameRequest.class, this::handleStartTicTacToeGameOnAServer); - new EventPublisher<>(Events.ServerEvents.RunTicTacToeGame.class, this::handleRunTicTacToeGameOnAServer); - new EventPublisher<>(Events.ServerEvents.EndTicTacToeGame.class, this::handleEndTicTacToeGameOnAServer); - } - - private String startServer(int port, String gameType) { - String serverId = UUID.randomUUID().toString(); - gameType = gameType.toLowerCase(); - try { - TcpServer server = null; - if (Objects.equals(gameType, "tictactoe")) { - server = new TicTacToeServer(port); - } else { - logger.error("Manager could not create a server for game type: {}", gameType); - return null; - } - this.servers.put(serverId, server); - new Thread(server, "Server-" + serverId).start(); - logger.info("Created server with id: {}, port: {}", serverId, port); - return serverId; - } catch (Exception e) { - logger.error("Failed to start server", e); - return null; - } - } - - private void handleStartServerRequest(Events.ServerEvents.StartServerRequest request) { - request.future() - .complete( - this.startServer( - request.port(), - request.gameType())); // TODO: Maybe post StartServer event. - } - - private void handleStartServer(Events.ServerEvents.StartServer event) { - new EventPublisher<>(Events.ServerEvents.ServerStarted.class, this.startServer(event.port(), event.gameType()), event.port()); - } - - private void handleStartTicTacToeGameOnAServer( - Events.ServerEvents.CreateTicTacToeGameRequest event) { - TicTacToeServer serverThing = (TicTacToeServer) this.servers.get(event.serverUuid()); - String gameId = null; - if (serverThing != null) { - try { - gameId = serverThing.newGame(event.playerA(), event.playerB()); - logger.info("Created game on server: {}", event.serverUuid()); - } catch (Exception e) { // TODO: Error handling - logger.error("Could not create game on server: {}", event.serverUuid()); - } - } else { - logger.warn("Could not find server: {}", event.serverUuid()); - } - event.future().complete(gameId); - } - - private void handleRunTicTacToeGameOnAServer(Events.ServerEvents.RunTicTacToeGame event) { - TicTacToeServer gameServer = (TicTacToeServer) this.servers.get(event.serverUuid()); - gameServer.runGame(event.gameUuid()); - } - - private void handleEndTicTacToeGameOnAServer(Events.ServerEvents.EndTicTacToeGame event) { - TicTacToeServer gameServer = (TicTacToeServer) this.servers.get(event.serverUuid()); - gameServer.endGame(event.gameUuid()); - } - - private void getAllServers(Events.ServerEvents.RequestsAllServers request) { - ArrayList a = new ArrayList<>(this.servers.values()); - request.future().complete(a.toString()); - } - - public void shutdownAll() { - this.servers.values().forEach(TcpServer::stop); - this.servers.clear(); - logger.info("All servers shut down"); - } -} diff --git a/src/main/java/org/toop/backend/tictactoe/TcpServer.java b/src/main/java/org/toop/backend/tictactoe/TcpServer.java deleted file mode 100644 index 5422ef9..0000000 --- a/src/main/java/org/toop/backend/tictactoe/TcpServer.java +++ /dev/null @@ -1,230 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Map; -import java.util.concurrent.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** - * Lightweight, thread-pool based TCP server base class. - * - *

Responsibilities: - accept sockets - hand off socket I/O to connectionExecutor (pooled - * threads) - provide thread-safe queues (receivedQueue / sendQueue) to subclasses - * - *

Notes: - Subclasses should consume receivedQueue (or call getNewestCommand()) and use - * sendQueue to send messages to all clients (or per-client, if implemented). - */ -public abstract class TcpServer implements Runnable { - - protected static final Logger logger = LogManager.getLogger(TcpServer.class); - - // Executor used for per-connection I/O tasks (reading/writing) - protected final ExecutorService connectionExecutor = Executors.newCachedThreadPool(); - - // Shared queues for subclasses / consumers - public final BlockingQueue receivedQueue = new LinkedBlockingQueue<>(); - public final BlockingQueue sendQueue = new LinkedBlockingQueue<>(); - - // Association for sockets -> player ids - public final Map knownPlayers = new ConcurrentHashMap<>(); - public final Map playersGames = new ConcurrentHashMap<>(); - - // tunables - public final int WAIT_TIME = 500; // ms used by poll-based methods - public final int RETRY_ATTEMPTS = 3; - - protected final int port; - protected final ServerSocket serverSocket; - private volatile boolean running = true; - - public TcpServer(int port) throws IOException { - this.port = port; - this.serverSocket = new ServerSocket(port); - } - - public boolean isRunning() { - return running; - } - - /** - * Default run: accept connections and hand off to connectionExecutor. Subclasses overriding - * run() should still call startWorkers(Socket) for each accepted socket. - */ - @Override - public void run() { - logger.info("Server listening on port {}", port); - try { - while (running) { - Socket clientSocket = serverSocket.accept(); - logger.info("Accepted connection from {}", clientSocket.getRemoteSocketAddress()); - // hand off to pool to manage I/O for this socket - connectionExecutor.submit(() -> startWorkers(clientSocket)); - } - } catch (IOException e) { - if (running) { - logger.error("Accept failed", e); - } else { - logger.info("Server socket closed, stopping acceptor"); - } - } - } - - /** - * Listen/Write workers for an accepted client socket. This method submits two tasks to the - * connectionExecutor: - inputLoop: reads lines and enqueues them to receivedQueue - outputLoop: - * polls sendQueue and writes messages to the client - * - *

Note: This is a simple model where sendQueue is global; if you need per-client - * send-queues, adapt this method to use one per socket. - */ - protected void startWorkers(Socket clientSocket) { - try { - BufferedReader in = - new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); - PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); - - // Input task: read lines and put them on receivedQueue - Runnable inputTask = - () -> { - logger.info( - "Starting read loop for {}", clientSocket.getRemoteSocketAddress()); - try { - String line; - while (running && (line = in.readLine()) != null) { - if (line.isEmpty()) continue; - logger.debug( - "Received from {}: {}", - clientSocket.getRemoteSocketAddress(), - line); - - boolean offered = false; - for (int i = 0; i < RETRY_ATTEMPTS && !offered; i++) { - try { - // Use offer to avoid blocking indefinitely; adapt - // timeout/policy as needed - offered = - this.receivedQueue.offer( - line, 200, TimeUnit.MILLISECONDS); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - break; - } - } - - if (!offered) { - logger.warn( - "Backpressure: dropping line from {}: {}", - clientSocket.getRemoteSocketAddress(), - line); - // Policy choice: drop, notify, or close connection. We drop - // here. - } - } - } catch (IOException e) { - logger.info( - "Connection closed by remote: {}", - clientSocket.getRemoteSocketAddress()); - } finally { - try { - clientSocket.close(); - } catch (IOException ignored) { - } - logger.info( - "Stopped read loop for {}", - clientSocket.getRemoteSocketAddress()); - } - }; - - // Output task: poll global sendQueue and write to this specific client. - // NOTE: With a single global sendQueue, every message is sent to every connected - // client. - // If you want per-client sends, change this to use per-client queue map. - Runnable outputTask = - () -> { - logger.info( - "Starting write loop for {}", - clientSocket.getRemoteSocketAddress()); - try { - while (running && !clientSocket.isClosed()) { - String msg = sendQueue.poll(WAIT_TIME, TimeUnit.MILLISECONDS); - if (msg != null) { - out.println(msg); - out.flush(); - logger.debug( - "Sent to {}: {}", - clientSocket.getRemoteSocketAddress(), - msg); - } - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.info( - "Writer interrupted for {}", - clientSocket.getRemoteSocketAddress()); - } catch (Exception e) { - logger.error( - "Writer error for {}: {}", - clientSocket.getRemoteSocketAddress(), - e.toString()); - } finally { - try { - clientSocket.close(); - } catch (IOException ignored) { - } - logger.info( - "Stopped write loop for {}", - clientSocket.getRemoteSocketAddress()); - } - }; - - // Input and Output mappings - connectionExecutor.submit(inputTask); - connectionExecutor.submit(outputTask); - - } catch (IOException e) { - logger.error("Could not start workers for client: {}", e.toString()); - try { - clientSocket.close(); - } catch (IOException ignored) { - } - } - } - - /** - * Convenience: wrapper to obtain the latest command (non-blocking poll). Subclasses can use - * this, but for blocking behavior consider using receivedQueue.take() - */ - protected ParsedCommand getNewestCommand() { - try { - String rec = receivedQueue.poll(WAIT_TIME, TimeUnit.MILLISECONDS); - if (rec != null) return new ParsedCommand(rec); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.warn("Interrupted while polling receivedQueue", e); - } - return null; - } - - /** Stop server and cleanup executors/sockets. */ - public void stop() { - running = false; - - try { - serverSocket.close(); - } catch (IOException ignored) { - } - - connectionExecutor.shutdownNow(); - - logger.info( - "TcpServer stopped. receivedQueue size={}, sendQueue size={}", - receivedQueue.size(), - sendQueue.size()); - } -} diff --git a/src/main/java/org/toop/backend/tictactoe/TicTacToeServer.java b/src/main/java/org/toop/backend/tictactoe/TicTacToeServer.java deleted file mode 100644 index f937d4f..0000000 --- a/src/main/java/org/toop/backend/tictactoe/TicTacToeServer.java +++ /dev/null @@ -1,186 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.io.IOException; -import java.net.Socket; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.toop.game.tictactoe.TicTacToe; - -public class TicTacToeServer extends TcpServer { - - protected static final Logger logger = LogManager.getLogger(TicTacToeServer.class); - - private final ExecutorService connectionExecutor = - Executors.newCachedThreadPool(); // socket I/O - private final ExecutorService dispatcherExecutor; - private final ExecutorService forwarderExecutor = Executors.newSingleThreadExecutor(); - - private final BlockingQueue incomingCommands; - private final Map games = new ConcurrentHashMap<>(); - - public TicTacToeServer(int port) throws IOException { - super(port); - - int dispatchers = Math.max(2, Runtime.getRuntime().availableProcessors()); - this.dispatcherExecutor = - Executors.newFixedThreadPool( - dispatchers + 1); // TODO: Magic number for forwardMessages - this.incomingCommands = new LinkedBlockingQueue<>(5_000); - - forwarderExecutor.submit(this::forwardLoop); - - for (int i = 0; i < dispatchers; i++) { - dispatcherExecutor.submit(this::dispatchLoop); - } - } - - @Override - public void run() { - try { - logger.info("TicTacToe server listening on port {}", this.port); - - while (isRunning()) { - Socket clientSocket = this.serverSocket.accept(); - logger.info("Connected to client: {}", clientSocket.getInetAddress()); - - connectionExecutor.submit(() -> this.startWorkers(clientSocket)); - } - } catch (IOException e) { - logger.error("I/O error in server run loop", e); - } - } - - /** Forwards raw messages from TcpServer.receivedQueue into ParsedCommand objects. */ - private void forwardLoop() { - logger.info("Forwarder loop started"); - try { - while (isRunning()) { - String raw = this.receivedQueue.take(); // blocks - logger.info("Received command: {}", raw); - try { - ParsedCommand pc = new ParsedCommand(raw); - this.incomingCommands.put(pc); // blocks if full - } catch (Exception e) { - logger.warn("Invalid message ignored: {}", raw, e); - } - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.info("Forwarder loop interrupted"); - } - } - - /** Dispatches parsed commands into the game logic. */ - private void dispatchLoop() { - logger.info("Dispatcher thread started"); - try { - while (isRunning()) { - ParsedCommand command = this.incomingCommands.take(); // blocks - if (command.isServerCommand) { - handleServerCommand(command); - continue; - } - - // Find game by ID - TicTacToe game = this.games.get(command.gameId); - if (game != null) { - game.addCommandToQueue(command); - logger.info( - "Dispatched command {} to game {}", command.toString(), command.gameId); - } else { - logger.warn( - "No active game with ID {} for command {}", - command.gameId, - command.toString()); - // TODO: reply back - } - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.info("Dispatcher interrupted"); - } - } - - private void handleServerCommand(ParsedCommand command) { - if (command.isValidCommand) { - this.sendQueue.offer("ok"); - } - - if (command.command == TicTacToeServerCommand.CREATE_GAME) { - String gameId = - this.newGame( - (String) command.arguments.getFirst(), - (String) command.arguments.get(1)); - this.sendQueue.offer("game created successfully|gameid " + gameId); - } else if (command.command == TicTacToeServerCommand.START_GAME) { - boolean success = this.runGame((String) command.arguments.getFirst()); - if (success) { - this.sendQueue.offer("svr game is running successfully"); - } else { - this.sendQueue.offer("svr running game failed"); - } - } else if (command.command == TicTacToeServerCommand.END_GAME) { - this.endGame((String) command.arguments.getFirst()); - this.sendQueue.offer("svr game ended successfully"); - } else if (command.command == TicTacToeServerCommand.LOGIN) { - this.endGame((String) command.arguments.getFirst()); - this.sendQueue.offer("svr login successful"); - } else if (command.command == TicTacToeServerCommand.SUBSCRIBE) { - this.endGame((String) command.arguments.getFirst()); - this.sendQueue.offer("svr added {} to the queue"); - } - } - - public void forwardGameMessages(TicTacToe game) { - dispatcherExecutor.submit( - () -> { - try { - while (isRunning()) { - String msg = - game.sendQueue - .take(); // blocks until a message is added to the queue - logger.info( - "Games: {}, Adding: {} to the send queue", game.gameId, msg); - this.sendQueue.put(msg); // push to network layer - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - }); - } - - public String newGame(String playerA, String playerB) { - logger.info("Creating a new game: {} vs {}", playerA, playerB); - String gameId = UUID.randomUUID().toString(); - TicTacToe game = new TicTacToe(playerA, playerB, gameId); - this.games.put(gameId, game); - forwardGameMessages(game); - logger.info("Created new game: {}. {} vs {}", gameId, playerA, playerB); - return gameId; - } - - public boolean runGame(String gameId) { - TicTacToe game = this.games.get(gameId); - if (game != null) { - game.run(); - logger.info("Running game: {}, players: {}", gameId, game.getPlayers()); - return true; - } else { - logger.warn("Tried to run unknown game {}", gameId); - return false; - } - } - - public void endGame(String gameId) { - TicTacToe game = this.games.remove(gameId); - if (game != null) { - logger.info("Ended game: {}", gameId); - // TODO: gracefully stop game thread - } else { - logger.warn("Tried to end unknown game {}", gameId); - } - } -} diff --git a/src/main/java/org/toop/backend/tictactoe/TicTacToeServerCommand.java b/src/main/java/org/toop/backend/tictactoe/TicTacToeServerCommand.java deleted file mode 100644 index 5c7e34b..0000000 --- a/src/main/java/org/toop/backend/tictactoe/TicTacToeServerCommand.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.util.EnumSet; - -public enum TicTacToeServerCommand { - CREATE_GAME, - START_GAME, - END_GAME, - /** Login, "username" */ - LOGIN, - /** Logout, "username" */ - LOGOUT, - EXIT, - QUIT, - DISCONNECT, - BYE, - GET, - SUBSCRIBE, - MOVE, - CHALLENGE, - FORFEIT, - MESSAGE, - HELP; - - private static final EnumSet VALID_COMMANDS = - EnumSet.of( - TicTacToeServerCommand.LOGIN, - TicTacToeServerCommand.LOGOUT, - TicTacToeServerCommand.EXIT, - TicTacToeServerCommand.QUIT, - TicTacToeServerCommand.DISCONNECT, - TicTacToeServerCommand.BYE, - TicTacToeServerCommand.GET, - TicTacToeServerCommand.SUBSCRIBE, - TicTacToeServerCommand.MOVE, - TicTacToeServerCommand.CHALLENGE, - TicTacToeServerCommand.FORFEIT, - TicTacToeServerCommand.MESSAGE, - TicTacToeServerCommand.HELP); - - public static EnumSet getValidCommands() { - return VALID_COMMANDS; - } - - // TODO: Garbage code. - - /** - * @param command Checks if string is a valid command. - * @return returns a boolean if string is a valid command. - */ - public static boolean isValid(String command) { - try { - TicTacToeServerCommand.valueOf(command.toUpperCase()); - return true; - } catch (IllegalArgumentException err) { - return false; - } - } - - // TODO: Return something better - /** - * @param command Converts a string into a TicTacToeServerCommand. - * @return returns a TicTacToeServerCommand enum. - */ - public static TicTacToeServerCommand getCommand(String command) { - if (isValid(command)) { - return TicTacToeServerCommand.valueOf(command.toUpperCase()); - } - return null; - } -} diff --git a/src/main/java/org/toop/backend/tictactoe/TicTacToeServerMessage.java b/src/main/java/org/toop/backend/tictactoe/TicTacToeServerMessage.java deleted file mode 100644 index 62ad856..0000000 --- a/src/main/java/org/toop/backend/tictactoe/TicTacToeServerMessage.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.toop.backend.tictactoe; - -import java.util.EnumSet; - -public enum TicTacToeServerMessage { - OK, - ERR, - SVR; - - private static final EnumSet VALID_COMMANDS = - EnumSet.of( - TicTacToeServerMessage.OK, - TicTacToeServerMessage.ERR, - TicTacToeServerMessage.SVR); - - public static EnumSet getValidCommands() { - return VALID_COMMANDS; - } - - // TODO: Garbage code. - /** - * @param command Checks if string is a valid command. - * @return returns a boolean if string is a valid command. - */ - public static boolean isValid(String command) { - try { - TicTacToeServerMessage.valueOf(command.toUpperCase()); - return true; - } catch (IllegalArgumentException err) { - return false; - } - } - - // TODO: Return something better - /** - * @param command Converts a string into a ServerCommand. - * @return returns a ServerCommand enum. - */ - public static TicTacToeServerMessage getCommand(String command) { - if (isValid(command)) { - return TicTacToeServerMessage.valueOf(command.toUpperCase()); - } - return null; - } -} diff --git a/src/main/java/org/toop/core/FileSystem.java b/src/main/java/org/toop/core/FileSystem.java deleted file mode 100644 index 54b403a..0000000 --- a/src/main/java/org/toop/core/FileSystem.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.toop.core; - -import java.io.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class FileSystem { - public record File(String path, CharSequence buffer) {} - ; - - private static final Logger logger = LogManager.getLogger(FileSystem.class); - - public static File read(String path) { - File file; - - try (BufferedReader reader = new BufferedReader(new FileReader(path))) { - StringBuilder buffer = new StringBuilder(); - String line = reader.readLine(); - - while (line != null) { - buffer.append(line); - buffer.append(System.lineSeparator()); - line = reader.readLine(); - } - - file = new File(path, buffer); - } catch (IOException e) { - logger.error("{}", e.getMessage()); - return null; - } - - return file; - } -} diff --git a/src/main/java/org/toop/core/ICallable.java b/src/main/java/org/toop/core/ICallable.java deleted file mode 100644 index 4be42c6..0000000 --- a/src/main/java/org/toop/core/ICallable.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.toop.core; - -public interface ICallable { - public T call(); -} diff --git a/src/main/java/org/toop/core/Window.java b/src/main/java/org/toop/core/Window.java deleted file mode 100644 index 98a91cd..0000000 --- a/src/main/java/org/toop/core/Window.java +++ /dev/null @@ -1,50 +0,0 @@ -//package org.toop.core; -// -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -//import org.toop.frontend.platform.core.glfw.GlfwWindow; -// -//public abstract class Window { -// public enum API { -// NONE, -// GLFW, -// } -// -// public record Size(int width, int height) {} -// -// protected static final Logger logger = LogManager.getLogger(Window.class); -// -// private static API api = API.NONE; -// private static Window instance = null; -// -// public static Window setup(API api, String title, Size size) { -// if (instance != null) { -// logger.warn("Window is already setup."); -// return instance; -// } -// -// switch (api) { -// case GLFW: -// instance = new GlfwWindow(title, size); -// break; -// -// default: -// logger.fatal("No valid window api chosen"); -// return null; -// } -// -// Window.api = api; -// return instance; -// } -// -// public static API getApi() { -// return api; -// } -// -// public void cleanup() { -// instance = null; -// logger.info("Window cleanup."); -// } -// -// public abstract void update(); -//} diff --git a/src/main/java/org/toop/eventbus/EventMeta.java b/src/main/java/org/toop/eventbus/EventMeta.java deleted file mode 100644 index 913345c..0000000 --- a/src/main/java/org/toop/eventbus/EventMeta.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.toop.eventbus; - -/** Wraps an event with its type and a ready flag. */ -public class EventMeta { - private final Class type; - private final Object event; - private boolean ready; - - public EventMeta(Class type, Object event) { - this.type = type; - this.event = event; - this.ready = false; // default not ready - } - - public Class getType() { - return type; - } - - public Object getEvent() { - return event; - } - - public boolean isReady() { - return ready; - } - - public void setReady(boolean ready) { - this.ready = ready; - } - - @Override - public String toString() { - return "ReadyEvent{" - + "type=" - + type.getSimpleName() - + ", event=" - + event - + ", ready=" - + ready - + '}'; - } -} diff --git a/src/main/java/org/toop/eventbus/EventRegistry.java b/src/main/java/org/toop/eventbus/EventRegistry.java deleted file mode 100644 index 0862a5f..0000000 --- a/src/main/java/org/toop/eventbus/EventRegistry.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.toop.eventbus; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -/** Thread-safe registry for storing events and tracking readiness of event types. */ -public class EventRegistry { - - private static final Logger logger = LogManager.getLogger(EventRegistry.class); - - private static final Map, CopyOnWriteArrayList>> eventHistory = - new ConcurrentHashMap<>(); - - private static final Map, Boolean> readyStates = new ConcurrentHashMap<>(); - - /** Stores an event in the registry. Safe for concurrent use. */ - public static void storeEvent(EventMeta eventMeta) { - logger.info("Storing event: {}", eventMeta.toString()); - eventHistory - .computeIfAbsent(eventMeta.getType(), k -> new CopyOnWriteArrayList<>()) - .add(new EventEntry<>(eventMeta)); - } - - /** Marks a specific event type as ready (safe to post). */ - public static void markReady(Class type) { - logger.info("Marking event as ready: {}", type.toString()); - readyStates.put(type, true); - } - - /** Marks a specific event type as not ready (posting will fail). */ - public static void markNotReady(Class type) { - logger.info("Marking event as not ready: {}", type.toString()); - readyStates.put(type, false); - } - - /** Returns true if this event type is marked ready. */ - public static boolean isReady(Class type) { - return readyStates.getOrDefault(type, false); - } - - /** Gets all stored events of a given type. */ - @SuppressWarnings("unchecked") - public static List> getEvents(Class type) { - return (List>) - (List) eventHistory.getOrDefault(type, new CopyOnWriteArrayList<>()); - } - - /** Gets the most recent event of a given type, or null if none exist. */ - @SuppressWarnings("unchecked") - public static EventEntry getLastEvent(Class type) { - List> entries = eventHistory.get(type); - if (entries == null || entries.isEmpty()) { - return null; - } - return (EventEntry) entries.getLast(); - } - - /** Clears the stored events for a given type. */ - public static void clearEvents(Class type) { - logger.info("Clearing events: {}", type.toString()); - eventHistory.remove(type); - } - - /** Clears all events and resets readiness. */ - public static void reset() { - logger.info("Resetting event registry events"); - eventHistory.clear(); - readyStates.clear(); - } - - /** Wrapper for stored events, with a ready flag for per-event state. */ - public static class EventEntry { - private final T event; - private volatile boolean ready = false; - - public EventEntry(T event) { - this.event = event; - } - - public T getEvent() { - return event; - } - - public boolean isReady() { - return ready; - } - - public void setReady(boolean ready) { - this.ready = ready; - } - - @Override - public String toString() { - return "EventEntry{" + "event=" + event + ", ready=" + ready + '}'; - } - } -} diff --git a/src/main/java/org/toop/frontend/graphics/Renderer.java b/src/main/java/org/toop/frontend/graphics/Renderer.java deleted file mode 100644 index f626494..0000000 --- a/src/main/java/org/toop/frontend/graphics/Renderer.java +++ /dev/null @@ -1,50 +0,0 @@ -//package org.toop.frontend.graphics; -// -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -//import org.toop.frontend.platform.graphics.opengl.OpenglRenderer; -// -//public abstract class Renderer { -// public enum API { -// NONE, -// OPENGL, -// }; -// -// protected static final Logger logger = LogManager.getLogger(Renderer.class); -// -// private static API api = API.NONE; -// private static Renderer instance = null; -// -// public static Renderer setup(API api) { -// if (instance != null) { -// logger.warn("Renderer is already setup."); -// return instance; -// } -// -// switch (api) { -// case OPENGL: -// instance = new OpenglRenderer(); -// break; -// -// default: -// logger.fatal("No valid renderer api chosen"); -// return null; -// } -// -// Renderer.api = api; -// return instance; -// } -// -// public static API getApi() { -// return api; -// } -// -// public void cleanup() { -// instance = null; -// logger.info("Renderer cleanup."); -// } -// -// public abstract void clear(); -// -// public abstract void render(); -//} diff --git a/src/main/java/org/toop/frontend/graphics/Shader.java b/src/main/java/org/toop/frontend/graphics/Shader.java deleted file mode 100644 index e884151..0000000 --- a/src/main/java/org/toop/frontend/graphics/Shader.java +++ /dev/null @@ -1,27 +0,0 @@ -//package org.toop.frontend.graphics; -// -//import org.toop.frontend.platform.graphics.opengl.OpenglShader; -// -//public abstract class Shader { -// public static Shader create(String vertexPath, String fragmentPath) { -// Shader shader = null; -// -// switch (Renderer.getApi()) { -// case OPENGL: -// shader = new OpenglShader(vertexPath, fragmentPath); -// break; -// -// case NONE: -// default: -// break; -// } -// -// return shader; -// } -// -// public abstract void cleanup(); -// -// public abstract void start(); -// -// public abstract void stop(); -//} diff --git a/src/main/java/org/toop/frontend/graphics/node/Button.java b/src/main/java/org/toop/frontend/graphics/node/Button.java deleted file mode 100644 index 429a8d2..0000000 --- a/src/main/java/org/toop/frontend/graphics/node/Button.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.toop.frontend.graphics.node; - -import org.toop.core.*; -import org.toop.frontend.math.Color; - -public class Button extends Node { - ICallable onHover; - ICallable onClick; - - public Button( - int x, - int y, - int width, - int height, - Color color, - ICallable onHover, - ICallable onClick) { - super(x, y, width, height, color); - - this.onHover = onHover; - this.onClick = onClick; - } - - @Override - public void hover() { - onHover.call(); - } - - @Override - public void click() { - onClick.call(); - } -} diff --git a/src/main/java/org/toop/frontend/graphics/node/Node.java b/src/main/java/org/toop/frontend/graphics/node/Node.java deleted file mode 100644 index 781098c..0000000 --- a/src/main/java/org/toop/frontend/graphics/node/Node.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.toop.frontend.graphics.node; - -import org.toop.frontend.math.Bounds; -import org.toop.frontend.math.Color; - -public abstract class Node { - protected Bounds bounds; - protected Color color; - - public Node(int x, int y, int width, int height, Color color) { - bounds = new Bounds(x, y, width, height); - this.color = color; - } - - public boolean check(int x, int y) { - return bounds.check(x, y); - } - - public void hover() {} - - public void click() {} -} diff --git a/src/main/java/org/toop/frontend/graphics/node/NodeManager.java b/src/main/java/org/toop/frontend/graphics/node/NodeManager.java deleted file mode 100644 index afc17e7..0000000 --- a/src/main/java/org/toop/frontend/graphics/node/NodeManager.java +++ /dev/null @@ -1,68 +0,0 @@ -//package org.toop.frontend.graphics.node; -// -//import java.util.*; -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -//import org.toop.eventbus.*; -//import org.toop.eventbus.events.Events; -//import org.toop.frontend.graphics.Shader; -// -//public class NodeManager { -// private static final Logger logger = LogManager.getLogger(NodeManager.class); -// -// private static NodeManager instance = null; -// -// public static NodeManager setup() { -// if (instance != null) { -// logger.warn("NodeManager is already setup."); -// return instance; -// } -// -// instance = new NodeManager(); -// return instance; -// } -// -// private Shader shader; -// private ArrayList nodes; -// private Node active; -// -// private NodeManager() { -// shader = -// Shader.create( -// "src/main/resources/shaders/gui_vertex.glsl", -// "src/main/resources/shaders/gui_fragment.glsl"); -// -// nodes = new ArrayList(); -// -// GlobalEventBus.subscribeAndRegister( -// Events.WindowEvents.OnMouseMove.class, -// event -> { -// for (int i = 0; i < nodes.size(); i++) { -// Node node = nodes.get(i); -// -// if (node.check(event.x(), event.y())) { -// active = node; -// node.hover(); -// -// break; -// } -// } -// }); -// -// GlobalEventBus.subscribeAndRegister( -// Events.WindowEvents.OnMouseClick.class, -// event -> { -// if (active != null) { -// active.click(); -// } -// }); -// } -// -// public void cleanup() {} -// -// public void add(Node node) { -// nodes.add(node); -// } -// -// public void render() {} -//} diff --git a/src/main/java/org/toop/frontend/graphics/node/Widget.java b/src/main/java/org/toop/frontend/graphics/node/Widget.java deleted file mode 100644 index 0cb38d8..0000000 --- a/src/main/java/org/toop/frontend/graphics/node/Widget.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.toop.frontend.graphics.node; - -import java.util.*; -import org.toop.frontend.math.Bounds; - -public class Widget { - Bounds bounds; - private ArrayList nodes; - - public Widget(Bounds bounds) { - this.bounds = bounds; - nodes = new ArrayList(); - } - - public boolean check(int x, int y) { - return bounds.check(x, y); - } - - public void add(Node node) { - nodes.add(node); - } - - public boolean hover(int x, int y) { - for (int i = 0; i < nodes.size(); i++) { - Node node = nodes.get(i); - - if (node.check(x, y)) { - node.hover(); - return true; - } - } - - return false; - } - - public boolean click(int x, int y) { - for (int i = 0; i < nodes.size(); i++) { - Node node = nodes.get(i); - - if (node.check(x, y)) { - node.click(); - return true; - } - } - - return false; - } -} diff --git a/src/main/java/org/toop/frontend/math/Bounds.java b/src/main/java/org/toop/frontend/math/Bounds.java deleted file mode 100644 index 36d0aac..0000000 --- a/src/main/java/org/toop/frontend/math/Bounds.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.toop.frontend.math; - -public class Bounds { - private int x; - private int y; - private int width; - private int height; - - public Bounds(int x, int y, int width, int height) { - set(x, y, width, height); - } - - public void set(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public boolean check(int x, int y) { - return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height; - } -} diff --git a/src/main/java/org/toop/frontend/math/Color.java b/src/main/java/org/toop/frontend/math/Color.java deleted file mode 100644 index 0d61fce..0000000 --- a/src/main/java/org/toop/frontend/math/Color.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.toop.frontend.math; - -public class Color { - private float r; - private float g; - private float b; - - public Color(float r, float g, float b) { - this.r = r; - this.g = g; - this.b = b; - } - - public float r() { - return r; - } - - public float g() { - return g; - } - - public float b() { - return b; - } -} diff --git a/src/main/java/org/toop/frontend/networking/ServerConnection.java b/src/main/java/org/toop/frontend/networking/ServerConnection.java deleted file mode 100644 index 820ed03..0000000 --- a/src/main/java/org/toop/frontend/networking/ServerConnection.java +++ /dev/null @@ -1,167 +0,0 @@ -package org.toop.frontend.networking; - -import java.io.IOException; -import java.net.InetAddress; -import java.util.concurrent.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.toop.eventbus.EventPublisher; -import org.toop.eventbus.events.Events; -import org.toop.eventbus.GlobalEventBus; -import org.toop.eventbus.events.NetworkEvents; - -public final class ServerConnection extends TcpClient implements Runnable { - - private static final Logger logger = LogManager.getLogger(ServerConnection.class); - - private final BlockingQueue receivedQueue = new LinkedBlockingQueue<>(); - private final BlockingQueue sendQueue = new LinkedBlockingQueue<>(); - - private final ExecutorService executor = Executors.newFixedThreadPool(2); - - String uuid; - volatile boolean running = false; - - public ServerConnection(String uuid, String ip, String port) throws IOException { - super(ip, Integer.parseInt(port)); - this.uuid = uuid; - this.initEvents(); - } - - /** - * Sends a command to the server. - * - * @param args The arguments for the command. - */ - public void sendCommandByString(String... args) { - // if (!TicTacToeServerCommand.isValid(command)) { - // logger.error("Invalid command: {}", command); - // return; - // } // TODO: DO I CARE? - - // if (!this.running) { - // logger.warn("Server has been stopped"); - // return; - // } // TODO: Server not running - - String command = String.join(" ", args); - - this.sendQueue.add(command); - logger.info("Command '{}' added to the queue", command); // TODO: Better log, which uuid? - } - - private void addReceivedMessageToQueue(String message) { - try { - receivedQueue.put(message); - } catch (InterruptedException e) { - logger.error("{}", e); // TODO: Make more informative - } - } - - private void initEvents() {} - - private void startWorkers() { - running = true; - this.executor.submit(this::inputLoop); - this.executor.submit(this::outputLoop); - } - - private void stopWorkers() { - this.running = false; - this.sendQueue.clear(); - try { - this.closeSocket(); - } catch (IOException e) { - logger.warn("Error closing client socket", e); // TODO: Better log - } - - this.executor.shutdownNow(); - } - - void inputLoop() { - logger.info("Starting {}:{} connection read", this.serverAddress, this.serverPort); - try { - while (running) { - String received = this.readLine(); // blocks - if (received != null) { - logger.info("Connection: {} received: '{}'", this.uuid, received); - // this.addReceivedMessageToQueue(received); // TODO: Will never go empty - new EventPublisher<>(NetworkEvents.ReceivedMessage.class, this.uuid, received).postEvent(); - } else { - break; - } - } - } catch (IOException e) { - logger.error("Error reading from server", e); - } - } - - void outputLoop() { - logger.info("Starting {}:{} connection write", this.serverAddress, this.serverPort); - try { - while (this.running) { - String command = this.sendQueue.poll(500, TimeUnit.MILLISECONDS); - if (command != null) { - this.sendMessage(command); - logger.info("Sent command: '{}'", command); - } - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (IOException e) { - logger.error("Error sending command", e); - } - } - - /** - * Connect to a new server. - * - * @param ip The ip to connect to. - * @param port The port to connect to. - */ - public void connect(InetAddress ip, int port) { - if (this.running) { - this.closeConnection(); // Also stops workers. - } - - this.serverAddress = ip; - this.serverPort = port; - - this.startWorkers(); - } - - /** - * Reconnects to previous address. - * - * @throws IOException wip - */ - public void reconnect() throws IOException { - this.connect(this.serverAddress, this.serverPort); - } - - /** Close connection to server. */ - public void closeConnection() { - this.stopWorkers(); - logger.info( - "Closed connection: {}, to server {}:{}", - this.uuid, - this.serverAddress, - this.serverPort); - } - - @Override - public void run() { - try { - reconnect(); - } catch (IOException e) { - logger.error("Initial connection failed", e); - } - } - - @Override - public String toString() { - return String.format( - "Server {ip: \"%s\", port: \"%s\", running: %s}", - this.serverAddress, this.serverPort, this.running); - } -} diff --git a/src/main/java/org/toop/frontend/networking/TcpClient.java b/src/main/java/org/toop/frontend/networking/TcpClient.java deleted file mode 100644 index c9d62d0..0000000 --- a/src/main/java/org/toop/frontend/networking/TcpClient.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.toop.frontend.networking; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetAddress; -import java.net.Socket; - -/** A simple wrapper for creating TCP clients. */ -public abstract class TcpClient { - - InetAddress serverAddress; - int serverPort; - Socket socket; - BufferedReader in; - PrintWriter out; - - public TcpClient(byte[] serverIp, int serverPort) throws IOException { - this.serverAddress = InetAddress.getByAddress(serverIp); - this.serverPort = serverPort; - this.socket = createSocket(); - this.in = createIn(); - this.out = createOut(); - } - - public TcpClient(String serverIp, int serverPort) throws IOException { - this.serverAddress = InetAddress.getByName(serverIp); - this.serverPort = serverPort; - this.socket = createSocket(); - this.in = createIn(); - this.out = createOut(); - } - - public Socket createSocket() throws IOException { - return new Socket(serverAddress, serverPort); - } - - public void closeSocket() throws IOException { - this.socket.close(); - } - - BufferedReader createIn() throws IOException { - return new BufferedReader(new InputStreamReader(this.socket.getInputStream())); - } - - PrintWriter createOut() throws IOException { - return new PrintWriter(this.socket.getOutputStream(), true); - } - - public void sendMessage(String message) throws IOException { - this.out.println(message); - } - - public String readLine() throws IOException { - return this.in.readLine(); - } - - public void close() throws IOException { - this.socket.close(); - } -} diff --git a/src/main/java/org/toop/frontend/platform/core/glfw/GlfwWindow.java b/src/main/java/org/toop/frontend/platform/core/glfw/GlfwWindow.java deleted file mode 100644 index ac494a2..0000000 --- a/src/main/java/org/toop/frontend/platform/core/glfw/GlfwWindow.java +++ /dev/null @@ -1,109 +0,0 @@ -//package org.toop.frontend.platform.core.glfw; -// -//import org.lwjgl.glfw.*; -//import org.lwjgl.system.*; -//import org.toop.core.*; -//import org.toop.eventbus.*; -//import org.toop.eventbus.events.Events; -// -//public class GlfwWindow extends Window { -// private long window; -// -// public GlfwWindow(String title, Size size) { -// if (!GLFW.glfwInit()) { -// logger.fatal("Failed to initialize glfw"); -// return; -// } -// -// GLFW.glfwDefaultWindowHints(); -// GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); -// GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE); -// -// GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()); -// -// int width = size.width(); -// int height = size.height(); -// -// if (width <= 0 || height <= 0 || width > videoMode.width() || height > videoMode.height()) { -// width = videoMode.width(); -// height = videoMode.height(); -// -// GLFW.glfwWindowHint(GLFW.GLFW_MAXIMIZED, GLFW.GLFW_TRUE); -// } -// -// long window = GLFW.glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL); -// -// if (window == MemoryUtil.NULL) { -// GLFW.glfwTerminate(); -// -// logger.fatal("Failed to create glfw window"); -// return; -// } -// -// int[] widthBuffer = new int[1]; -// int[] heightBuffer = new int[1]; -// GLFW.glfwGetWindowSize(window, widthBuffer, heightBuffer); -// -// GLFW.glfwMakeContextCurrent(window); -// GLFW.glfwSwapInterval(1); -// -// GLFW.glfwSetWindowCloseCallback( -// window, -// (lwindow) -> { -// GlobalEventBus.post(new Events.WindowEvents.OnQuitRequested()); -// }); -// -// GLFW.glfwSetFramebufferSizeCallback( -// window, -// (lwindow, lwidth, lheight) -> { -// GlobalEventBus.post( -// new Events.WindowEvents.OnResize(new Size(lwidth, lheight))); -// }); -// -// GLFW.glfwSetCursorPosCallback( -// window, -// (lwindow, lx, ly) -> { -// GlobalEventBus.post(new Events.WindowEvents.OnMouseMove((int) lx, (int) ly)); -// }); -// -// GLFW.glfwSetMouseButtonCallback( -// window, -// (lwindow, lbutton, laction, lmods) -> { -// switch (laction) { -// case GLFW.GLFW_PRESS: -// GlobalEventBus.post(new Events.WindowEvents.OnMouseClick(lbutton)); -// break; -// -// case GLFW.GLFW_RELEASE: -// GlobalEventBus.post(new Events.WindowEvents.OnMouseRelease(lbutton)); -// break; -// -// default: -// break; -// } -// }); -// -// this.window = window; -// GLFW.glfwShowWindow(window); -// -// logger.info( -// "Glfw window setup. Title: {}. Width: {}. Height: {}.", -// title, -// size.width(), -// size.height()); -// } -// -// @Override -// public void cleanup() { -// GLFW.glfwDestroyWindow(window); -// GLFW.glfwTerminate(); -// -// super.cleanup(); -// } -// -// @Override -// public void update() { -// GLFW.glfwSwapBuffers(window); -// GLFW.glfwPollEvents(); -// } -//} diff --git a/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglRenderer.java b/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglRenderer.java deleted file mode 100644 index 020ff22..0000000 --- a/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglRenderer.java +++ /dev/null @@ -1,79 +0,0 @@ -//package org.toop.frontend.platform.graphics.opengl; -// -//import org.lwjgl.opengl.*; -//import org.lwjgl.system.*; -//import org.toop.eventbus.*; -//import org.toop.eventbus.events.Events; -//import org.toop.frontend.graphics.Renderer; -//import org.toop.frontend.graphics.Shader; -// -//public class OpenglRenderer extends Renderer { -// private Shader shader; -// private int vao; -// -// public OpenglRenderer() { -// GL.createCapabilities(); -// GL45.glClearColor(0.65f, 0.9f, 0.65f, 1f); -// -// GlobalEventBus.subscribeAndRegister( -// Events.WindowEvents.OnResize.class, -// event -> { -// GL45.glViewport(0, 0, event.size().width(), event.size().height()); -// }); -// -// logger.info("Opengl renderer setup."); -// -// // Form here on, everything is temporary -// float vertices[] = { -// -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -// -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -// 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, -// 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -// }; -// -// int indicies[] = { -// 0, 1, 2, -// 2, 3, 0, -// }; -// -// vao = GL45.glCreateVertexArrays(); -// GL45.glBindVertexArray(vao); -// -// int vbo = GL45.glCreateBuffers(); -// GL45.glBindBuffer(GL45.GL_ARRAY_BUFFER, vbo); -// GL45.glBufferData(GL45.GL_ARRAY_BUFFER, vertices, GL45.GL_STATIC_DRAW); -// -// GL45.glVertexAttribPointer(0, 2, GL45.GL_FLOAT, false, 5 * 4, 0); -// GL45.glVertexAttribPointer(1, 3, GL45.GL_FLOAT, false, 5 * 4, 2 * 4); -// -// GL45.glEnableVertexAttribArray(0); -// GL45.glEnableVertexAttribArray(1); -// -// int ib = GL45.glCreateBuffers(); -// GL45.glBindBuffer(GL45.GL_ELEMENT_ARRAY_BUFFER, ib); -// GL45.glBufferData(GL45.GL_ELEMENT_ARRAY_BUFFER, indicies, GL45.GL_STATIC_DRAW); -// -// shader = -// Shader.create( -// "src/main/resources/shaders/gui_vertex.glsl", -// "src/main/resources/shaders/gui_fragment.glsl"); -// } -// -// @Override -// public void cleanup() { -// super.cleanup(); -// } -// -// @Override -// public void clear() { -// GL45.glClear(GL45.GL_COLOR_BUFFER_BIT); -// } -// -// @Override -// public void render() { -// // temporary -// // shader.start(); -// GL45.glBindVertexArray(vao); -// GL45.glDrawElements(GL45.GL_TRIANGLES, 6, GL45.GL_UNSIGNED_INT, MemoryUtil.NULL); -// } -//} diff --git a/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglShader.java b/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglShader.java deleted file mode 100644 index e288300..0000000 --- a/src/main/java/org/toop/frontend/platform/graphics/opengl/OpenglShader.java +++ /dev/null @@ -1,57 +0,0 @@ -//package org.toop.frontend.platform.graphics.opengl; -// -//import org.lwjgl.opengl.*; -//import org.toop.core.*; -//import org.toop.frontend.graphics.Shader; -// -//public class OpenglShader extends Shader { -// private int programID; -// -// public OpenglShader(String vertexPath, String fragmentPath) { -// FileSystem.File vertexSource = FileSystem.read(vertexPath); -// FileSystem.File fragmentSource = FileSystem.read(fragmentPath); -// -// if (vertexSource == null || fragmentPath == null) { -// return; -// } -// -// programID = GL45.glCreateProgram(); -// -// int vertexShader = GL45.glCreateShader(GL45.GL_VERTEX_SHADER); -// int fragmentShader = GL45.glCreateShader(GL45.GL_FRAGMENT_SHADER); -// -// GL45.glShaderSource(vertexShader, vertexSource.buffer()); -// GL45.glShaderSource(fragmentShader, fragmentSource.buffer()); -// -// GL45.glCompileShader(vertexShader); -// GL45.glCompileShader(fragmentShader); -// -// GL45.glAttachShader(programID, vertexShader); -// GL45.glAttachShader(programID, fragmentShader); -// -// GL45.glLinkProgram(programID); -// GL45.glValidateProgram(programID); -// -// GL45.glDetachShader(programID, vertexShader); -// GL45.glDetachShader(programID, fragmentShader); -// -// GL45.glDeleteShader(vertexShader); -// GL45.glDeleteShader(fragmentShader); -// } -// -// @Override -// public void cleanup() { -// stop(); -// GL45.glDeleteProgram(programID); -// } -// -// @Override -// public void start() { -// GL45.glUseProgram(programID); -// } -// -// @Override -// public void stop() { -// GL45.glUseProgram(0); -// } -//}