diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java index 35db3ca..62aa8cd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java @@ -8,7 +8,6 @@ import javafx.stage.Stage; public class ClientLauncherGUI { public static void main(String[] args) { - System.setProperty("glass.win.uiScale", "1.0"); Application.launch(GUIApp.class, args); } diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 78296bd..06e26fc 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -1,5 +1,6 @@ package it.polimi.ingsw.gc14; import it.polimi.ingsw.gc14.Controller.ClientController; +import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient; @@ -38,6 +39,7 @@ public class ClientLauncherTUI { */ public void main() throws InterruptedException { view = new TUI(null); + admissibleChar.add("0"); admissibleChar.add("1"); admissibleChar.add("2"); admissibleChar.add("3"); @@ -57,6 +59,7 @@ public class ClientLauncherTUI { System.out.println("Insert username: "); String username = scanner.next(); view.setUsername(username); + controller.setMyUsername(username); System.out.println("Insert preferred number of players: "); int proposedNumPlayers = scanner.nextInt(); System.out.println("Select RMI[0] o TCP[1]: "); @@ -137,7 +140,16 @@ public class ClientLauncherTUI { if(admissibleChar.contains(action)) { - if (!action.equals("6") && !action.equals("A") && !action.equals("B") && !action.equals("C")&&!action.equals("a") && !action.equals("b") && !action.equals("c")) { + if(action.equals("0")) + { + System.out.println("Are you sure? Y/N"); + String c= scanner.next(); + if(!c.equals("Y") && !c.equals("y")) + { + view.render(); + return; + } + }else if (!action.equals("6") && !action.equals("A") && !action.equals("B") && !action.equals("C")&&!action.equals("a") && !action.equals("b") && !action.equals("c")) { try { System.out.println("Insert the required position:"); pos = scanner.nextInt(); @@ -147,13 +159,17 @@ public class ClientLauncherTUI { } } switch (action) { - case "1" -> controller.slotChoice(username, pos); - case "2" -> controller.drawUpperTribeCard(username, pos); - case "3" -> controller.drawUpperBuildingCard(username, pos); - case "4" -> controller.drawLowerTribeCard(username, pos); - case "5" -> controller.drawLowerBuildingCard(username, pos); - case "6" -> controller.skipTurn(username); - case "7" -> controller.totemChoice(username,pos); + case "0" -> { + controller.disconnect(); + System.exit(0); + } + case "1" -> controller.slotChoice(pos); + case "2" -> controller.drawUpperTribeCard(pos); + case "3" -> controller.drawUpperBuildingCard(pos); + case "4" -> controller.drawLowerTribeCard(pos); + case "5" -> controller.drawLowerBuildingCard(pos); + case "6" -> controller.skipTurn(); + case "7" -> controller.totemChoice(pos); case "A", "a" -> view.fullRender(); case "B", "b" -> view.renderBoard(); case "C", "c" -> view.renderPlayer(); diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 13edbd4..a37f39c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -83,15 +83,11 @@ public class ClientController { *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. * - * @param playerUsername the username of the player performing the action. * @param pos the index of the card to draw. */ - public void drawUpperTribeCard(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.drawUpperTribeCard(playerUsername, pos); - } + public void drawUpperTribeCard(int pos) { + client.drawUpperTribeCard(myUsername, pos); + } /** @@ -100,15 +96,11 @@ public class ClientController { *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. * - * @param playerUsername the username of the player performing the action. * @param pos the index of the card to draw. */ - public void drawLowerTribeCard(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.drawLowerTribeCard(playerUsername, pos); - } + public void drawLowerTribeCard(int pos) { + client.drawLowerTribeCard(myUsername, pos); + } /** @@ -117,15 +109,11 @@ public class ClientController { *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. * - * @param playerUsername the username of the player performing the action. * @param pos the index of the card to draw. */ - public void drawUpperBuildingCard(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.drawUpperBuildingCard(playerUsername, pos); - } + public void drawUpperBuildingCard(int pos) { + client.drawUpperBuildingCard(myUsername, pos); + } /** @@ -134,15 +122,10 @@ public class ClientController { *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. * - * @param playerUsername the username of the player performing the action. * @param pos the index of the card to draw. */ - public void drawLowerBuildingCard(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.drawLowerBuildingCard(playerUsername, pos); - } + public void drawLowerBuildingCard(int pos) { + client.drawLowerBuildingCard(myUsername, pos); } /** @@ -150,15 +133,9 @@ public class ClientController { * *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. - * - * @param playerUsername the username of the player performing the action. */ - public void skipTurn(String playerUsername) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.skipTurn(playerUsername); - } + public void skipTurn() { + client.skipTurn(myUsername); } /** @@ -167,15 +144,10 @@ public class ClientController { *

If the specified player is not the current player, an error message * is shown. Otherwise, the request is forwarded to the network client. * - * @param playerUsername the username of the player performing the action. * @param pos the index of the selected slot. */ - public void slotChoice(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.slotChoice(playerUsername, pos); - } + public void slotChoice(int pos) { + client.slotChoice(myUsername, pos); } /** @@ -185,14 +157,15 @@ public class ClientController { * is shown. Otherwise, the selected totem is retrieved from the available * totems list and the choice is forwarded to the network client. * - * @param playerUsername the username of the player making the choice. * @param pos the index of the selected totem in the available totems list. */ - public void totemChoice(String playerUsername, int pos) { - if (!Objects.equals(playerUsername, miniModel.currentState.getCurrentPlayer().getUserName())) { - view.showError("It's not your turn!"); - } else { - client.totemChoice(playerUsername, String.valueOf(miniModel.availableTotems.get(pos))); - } + public void totemChoice(int pos) { + client.totemChoice(myUsername, String.valueOf(miniModel.availableTotems.get(pos))); + + } + + public void disconnect() + { + client.notifyDisconnection(); } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java index 43704e2..2bf79b9 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java @@ -70,4 +70,7 @@ public interface IClient { * @param totem the name of the selected totem. */ void totemChoice(String playerUsername, String totem); + + //TODO + void notifyDisconnection(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index 44f425a..f276426 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -107,7 +107,7 @@ public class RMIClient implements IClient { future.get(PING_TIMEOUT_MS, TimeUnit.MILLISECONDS); // mirrors setSoTimeout(5000) } catch (TimeoutException e) { future.cancel(true); - System.out.println("RMI ping timeout: " + username); + //error sending disconnect(); } catch (Exception e) { disconnect(); @@ -124,7 +124,7 @@ public class RMIClient implements IClient { if (!running) return; running = false; if (pingSender != null) pingSender.shutdownNow(); - controller.view.showError("Connessione al server persa"); + controller.view.showError("Connection with server closed"); } @@ -235,5 +235,15 @@ public class RMIClient implements IClient { } } + public void notifyDisconnection() { + pingSender.shutdownNow(); + try{ + stub.disconnectPlayer(username); + } + catch (RemoteException e){ + System.out.println("Error during remote disconnection"); + } + } + } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Common/IGameServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Common/IGameServer.java index aef508d..629f7ea 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Common/IGameServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Common/IGameServer.java @@ -93,4 +93,6 @@ public interface IGameServer extends Remote { * @throws RemoteException if an RMI communication error occurs. */ void ping(String username) throws RemoteException; + + void disconnectPlayer(String username) throws RemoteException; } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIHeartbeat.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIHeartbeat.java index 4d29816..a1ca275 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIHeartbeat.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIHeartbeat.java @@ -89,7 +89,7 @@ public class RMIHeartbeat { * the associated RMI callback is removed, and a disconnection event is * added to the action queue for server-side processing. */ - private void disconnect() { + public void disconnect() { if (!running) return; running = false; watchdog.shutdownNow(); diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java index bca2e27..9cc59fd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java @@ -47,16 +47,6 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { BlockingQueue actionQueue; private LimitedMap playerList; - private boolean serverCrashed; - - /** - * Sets whether the server is recovering from a previous crash. - * - * @param serverCrashed {@code true} if the server is in crash-recovery mode, - */ - public void setServerCrashed(boolean serverCrashed) { - this.serverCrashed = serverCrashed; - } /** * Constructs an RMI server with the required game and network components. @@ -96,30 +86,25 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { if (preferredInt < 2 || preferredInt > 5) return false; synchronized (controller) { - if(serverCrashed) - { - if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) { - clients.put(username, callback); - playerList.put(username, true); - startWatchdog(username); - System.out.println("(After crash)Reconnected player: " + username); - return true; - } + + if (playerList.isEmpty() && controller.getModel()==null) { + controller.setModel(new Game(preferredInt)); + playerList.setLimit(preferredInt); + System.out.println("Game Created With :"+preferredInt+" Players"); } - else - { - if (playerList.isEmpty()) { - controller.setModel(new Game(preferredInt)); - playerList.setLimit(preferredInt); - System.out.println("Game Created With :"+preferredInt+" Players"); - } - if (controller.addPlayer(username)) { - clients.put(username, callback); - playerList.put(username, true); - startWatchdog(username); - System.out.println("Accepted player: " + username); - return true; - } + if (controller.addPlayer(username)) { + clients.put(username, callback); + playerList.put(username, true); + startWatchdog(username); + System.out.println("Accepted player: " + username); + return true; + } + if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) { + clients.put(username, callback); + playerList.put(username, true); + startWatchdog(username); + System.out.println("(After crash)Reconnected player: " + username); + return true; } if (playerList.containsKey(username) && !playerList.get(username)) { playerList.put(username, true); @@ -279,13 +264,10 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { * on the specified port, and registers this server instance under the * {@code RMIGameServer} name. * - * @param serverCrashed {@code true} if the server is being restarted after a crash, - * {@code false} otherwise. * @return {@code true} if the server starts successfully, * {@code false} otherwise. */ - public boolean start(boolean serverCrashed) { - this.serverCrashed = serverCrashed; + public boolean start() { try { System.setProperty("java.rmi.server.hostname", host); registry = LocateRegistry.createRegistry(nPort); @@ -332,6 +314,10 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { watchdogs.put(username, wd); wd.start(); } + public void disconnectPlayer(String username) { + RMIHeartbeat wd = watchdogs.get(username); + wd.disconnect(); + } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java index 67ae202..279d9b7 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java @@ -107,8 +107,12 @@ public class TCPClient implements IClient { ScheduledExecutorService sender = Executors.newSingleThreadScheduledExecutor(); sender.scheduleAtFixedRate(() -> { try { - heartbeatOut.write(PING); - heartbeatOut.flush(); + synchronized (heartbeatOut) + { + heartbeatOut.write(PING); + heartbeatOut.flush(); + } + } catch (IOException e) { sender.shutdownNow(); disconnect(); @@ -263,4 +267,17 @@ public class TCPClient implements IClient { public void totemChoice(String playerUsername,String totems) { doEvent(new TotemChoice(playerUsername,totems)); } + + public void notifyDisconnection() + { + synchronized (heartbeatOut) + { + try { + heartbeatOut.write(-1); + } catch (IOException e) { + disconnect(); + } + } + disconnect(); + } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java index 8e36e01..bd8e2ae 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java @@ -94,10 +94,9 @@ public class ClientHandler implements Runnable { } } } catch (IOException e) { - clientHandlers.remove(this); - e.printStackTrace(); + System.err.println("Error in incoming connection/disconnection"); } catch (ClassNotFoundException e) { - throw new RuntimeException(e); + System.err.println("Class not found"); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/HeartbeatHandler.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/HeartbeatHandler.java index fdf9f8e..6e477fe 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/HeartbeatHandler.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/HeartbeatHandler.java @@ -94,7 +94,13 @@ public class HeartbeatHandler implements Runnable { try { while (running) { int b = in.read(); // blocca finché non arriva un byte - if (b == -1) { disconnect(); break; } // stream chiusa + if (b == -1) { + synchronized (this) + { + out.write(-1); + } + disconnect(); break; + } // stream chiusa if (b == PING) { lastReceivedTime = System.currentTimeMillis(); out.write(PONG); @@ -127,7 +133,7 @@ public class HeartbeatHandler implements Runnable { *

The handler is stopped, the watchdog task is terminated, the main * {@link ClientHandler} is disconnected, and the heartbeat socket is closed. */ - private void disconnect() { + private synchronized void disconnect() { running = false; watchdog.shutdownNow(); mainHandler.disconnect(); // disconnette anche il socket principale diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java index 9c618ef..2af3f18 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java @@ -73,20 +73,6 @@ public class TCPServer { */ List clientHandlers; - /** - * Flag indicating whether the server is recovering from a previous crash. - */ - boolean serverCrashed; - - /** - * Sets whether the server is recovering from a previous crash. - * - * @param serverCrashed {@code true} if the server is in crash-recovery mode, - * {@code false} otherwise. - */ - public void setServerCrashed(boolean serverCrashed) { - this.serverCrashed = serverCrashed; - } /** * Temporary map associating each username with the corresponding @@ -129,12 +115,8 @@ public class TCPServer { * the connection is handled either as a new player joining the game * or as a reconnection attempt. * - * @param serverCrashed {@code true} if the server is being restarted after a crash, - * {@code false} otherwise. */ - public void start(boolean serverCrashed) { - this.serverCrashed = serverCrashed; - + public void start() { try { socketTCP = new ServerSocket(port); heartbeatSocketTCP = new ServerSocket(heartbeatPort); @@ -180,70 +162,64 @@ public class TCPServer { synchronized (controller) { String username = eventAddPlayer.getUsername(); //reconnect players after a server crash - if (serverCrashed) { - if (controller.getModel().getPlayers().stream() - .anyMatch(p -> p.getUserName().equals(username)) - && !playerList.containsKey(username)) { - playerList.put(username, true); - System.out.println("(After crash)Reconnected player: " + username); + if (playerList.isEmpty()&& controller.getModel()==null) { + Game model = new Game(eventAddPlayer.getProposedNPlayer()); + controller.setModel(model); + playerList.setLimit(eventAddPlayer.getProposedNPlayer()); + System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players"); + } - ClientHandler handler = new ClientHandler( - username, - clientSocket, - clientSend, - clientReceive, - clientHandlers, - playerList, - actionQueue - ); + if (controller.addPlayer(username)) { + playerList.put(username, true); + System.out.println("Accepted player: " + username); - clientSocket.getOutputStream().write(1); - pendingHeartbeat.put(username, handler); + ClientHandler handler = new ClientHandler( + username, + clientSocket, + clientSend, + clientReceive, + clientHandlers, + playerList, + actionQueue + ); - Thread thread = new Thread(handler); - thread.start(); + clientSocket.getOutputStream().write(1); + pendingHeartbeat.put(username, handler); - clientHandlers.add(handler); - connectedPlayers++; - return; + Thread thread = new Thread(handler); + thread.start(); - } + clientHandlers.add(handler); + connectedPlayers++; + continue; } - //manages a new player adding - else { - if (playerList.isEmpty()) { - Game model = new Game(eventAddPlayer.getProposedNPlayer()); - controller.setModel(model); - playerList.setLimit(eventAddPlayer.getProposedNPlayer()); - System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players"); - } + if (controller.getModel().getPlayers().stream() + .anyMatch(p -> p.getUserName().equals(username)) + && !playerList.containsKey(username)) { + playerList.put(username, true); + System.out.println("(After crash)Reconnected player: " + username); - if (controller.addPlayer(username)) { - playerList.put(username, true); - System.out.println("Accepted player: " + username); + ClientHandler handler = new ClientHandler( + username, + clientSocket, + clientSend, + clientReceive, + clientHandlers, + playerList, + actionQueue + ); - ClientHandler handler = new ClientHandler( - username, - clientSocket, - clientSend, - clientReceive, - clientHandlers, - playerList, - actionQueue - ); + clientSocket.getOutputStream().write(1); + pendingHeartbeat.put(username, handler); - clientSocket.getOutputStream().write(1); - pendingHeartbeat.put(username, handler); + Thread thread = new Thread(handler); + thread.start(); - Thread thread = new Thread(handler); - thread.start(); + clientHandlers.add(handler); + connectedPlayers++; + continue; - clientHandlers.add(handler); - connectedPlayers++; - return; - - } } //reconnect a previously disconnected player if (playerList.containsKey(username) @@ -288,8 +264,6 @@ public class TCPServer { System.out.println("Player could not be added. Connection terminated."); } } - - } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 2138468..30ce506 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -186,8 +186,6 @@ public class ServerLauncher { if(!entry.getValue()) playerList.remove(entry.getKey()); } - serverRMI.setServerCrashed(false); - serverTCP.setServerCrashed(false); } //notify the event else { @@ -195,6 +193,10 @@ public class ServerLauncher { serverTCP.notifyAll(event); } } + else { + serverRMI.notifyAll(event); + serverTCP.notifyAll(event); + } return !event.getIsError(); } } @@ -202,13 +204,15 @@ public class ServerLauncher { // removes disconneted players when the game is ended if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)) { - playerList.remove(event.getUsername()); - if(playerList.isEmpty()) - { - gameController.setModel(null); - System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n"); + synchronized (gameController) { + playerList.remove(event.getUsername()); + if (playerList.isEmpty()) { + + gameController.setModel(null); + System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n"); + } + return true; } - return true; } return false; } @@ -241,7 +245,6 @@ public class ServerLauncher { BlockingQueue actionQueue = new LinkedBlockingQueue<>(); GameController gameController = new GameController(); String IP; - boolean serverCrashed; try { IP=chooseNetworkInterface(new Scanner(System.in)); System.out.println(IP); @@ -262,10 +265,6 @@ public class ServerLauncher { playerList.put(entry.getKey().getUserName(),false); } } - serverCrashed = true; - - } else { - serverCrashed = false; } playerList.setAction(()->{ new Thread(()->{ @@ -277,8 +276,6 @@ public class ServerLauncher { } serverRMI.notifyAll(miniModel); serverTCP.notifyAll(miniModel); - view = new TUI(miniModel); - view.render(); }).start(); }); new Thread(()-> { @@ -291,8 +288,8 @@ public class ServerLauncher { } }).start(); - serverRMI.start(serverCrashed); - new Thread(()->{serverTCP.start(serverCrashed);}).start(); + serverRMI.start(); + new Thread(()->{serverTCP.start();}).start(); System.out.println("Server RMI: "+System.getProperty("java.rmi.server.hostname")); } @@ -310,10 +307,6 @@ public class ServerLauncher { while (true) { try{ this.doFirstEvent(); -// if(view!=null) -// { -// view.fullRender(); -// } } catch(InterruptedException e){ Thread.currentThread().interrupt(); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java index 550d582..a3bb8df 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java @@ -13,7 +13,9 @@ import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; import javafx.scene.Scene; +import javafx.stage.Screen; import javafx.stage.Stage; import javafx.util.Duration; @@ -62,23 +64,28 @@ public class GUI extends Application implements IView { loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml")); - loaderMain.setControllerFactory(clazz -> { - MainFXMLController controllerMain = new MainFXMLController(); - controllerMain.setController(controller); - return controllerMain; - }); + mainScene = new Scene(loaderMain.load()); + controllerMain = loaderMain.getController(); + controllerMain.setController(controller); loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml")); leaderboardScene = new Scene(loaderLeaderboard.load()); controllerLeaderboard = loaderLeaderboard.getController(); controllerLeaderboard.setController(controller,primaryStage,loginScene); - mainScene = new Scene(loaderMain.load()); - controllerMain = loaderMain.getController(); - showLogin(); + + primaryStage.setScene(loginScene); + primaryStage.setFullScreen(true); + Rectangle2D tmp = Screen.getPrimary().getVisualBounds(); + primaryStage.setWidth(tmp.getWidth()); + primaryStage.setHeight(tmp.getHeight()); + primaryStage.setX(tmp.getMinX()); + primaryStage.setY(tmp.getMinY()); + primaryStage.setResizable(false); + primaryStage.setTitle("Mesos"); primaryStage.setOnCloseRequest(e -> { Platform.exit(); @@ -87,10 +94,6 @@ public class GUI extends Application implements IView { primaryStage.show(); } - public void showLogin() throws IOException { - primaryStage.setScene(loginScene); - } - @Override public void setModel(MiniModel miniModel) { @@ -103,24 +106,34 @@ public class GUI extends Application implements IView { public void render() { Platform.runLater(() -> { + boolean toFull=false; + synchronized (miniModel) { if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) { - primaryStage.setScene(totemScene); + if (primaryStage.getScene()!=leaderboardScene) { + toFull=true; + } controllerTotem.render(); + primaryStage.setScene(totemScene); } else if (controller.miniModel.currentState.getGameStage() == ENDED) { - primaryStage.setScene(leaderboardScene); + if (primaryStage.getScene()!=leaderboardScene) { + toFull=true; + } controllerLeaderboard.render(); + primaryStage.setScene(leaderboardScene); } else { - double w = primaryStage.getWidth(); - double h = primaryStage.getHeight(); + if (primaryStage.getScene()!=mainScene) { + toFull=true; + } + //double w = primaryStage.getWidth(); + //double h = primaryStage.getHeight(); primaryStage.setScene(mainScene); - primaryStage.setWidth(w); - primaryStage.setHeight(h); - primaryStage.setMinHeight(h); - primaryStage.setMinWidth(w); - primaryStage.setResizable(false); controllerMain.render(); } + + if (toFull) { + primaryStage.setFullScreen(true); + } } }); @@ -136,6 +149,7 @@ public class GUI extends Application implements IView { synchronized (miniModel) { controllerMain.isError = true; controllerMain.render(); + System.out.println("ERRORE PORCODIDODODODOD"); } }); } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java index e49a6c9..8e5b716 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java @@ -362,6 +362,7 @@ public class LeaderboardFXMLController { // ==== ACTIONS ==== @FXML private void onNewGame() { + controller.disconnect(); primaryStage.setScene(loginScene); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java index 3c6efce..6431de6 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java @@ -41,6 +41,7 @@ import java.util.*; public class MainFXMLController { + @FXML private GridPane leftGrid; @FXML private ScrollPane playerSide; @FXML private HBox mainHBox; @FXML private ImageView backgroundImage; @@ -75,6 +76,7 @@ public class MainFXMLController { public void initialize() { Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14); + popup = new Popup(); mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> { if (newScene != null) { @@ -102,11 +104,16 @@ public class MainFXMLController { // ==== RENDER ==== public void render() { - renderUpper(); - renderBoard(); - renderLower(); - renderMyHand(); + + if(!isError) { + renderUpper(); + renderBoard(); + renderLower(); + renderMyHand(); + } renderSidePanel(); + + } @@ -156,7 +163,7 @@ public class MainFXMLController { // ==== ELEMENTS ==== private StackPane createOrder(String num) { ImageView img = new ImageView(loadImage("/GUIImages/Orders/order-" + num + ".png")); - img.fitHeightProperty().bind(board.heightProperty().multiply(0.94)); + img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(40).divide(4).multiply(0.94)); img.setPreserveRatio(true); addClip(img); return new StackPane(img); @@ -165,7 +172,7 @@ public class MainFXMLController { private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) { ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png")); img.setPreserveRatio(true); - img.fitHeightProperty().bind(board.heightProperty().multiply(0.94)); // TODO perchè è tutto moltiplicato per una costante ma in board facciamo -15? + img.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(40).divide(4).multiply(0.94)); addClip(img); StackPane wrapper = new StackPane(img); @@ -175,7 +182,7 @@ public class MainFXMLController { totem.fitHeightProperty().bind(img.fitHeightProperty().multiply(0.332)); totem.setPreserveRatio(true); StackPane.setAlignment(totem, Pos.TOP_LEFT); - StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight())); // TODO perchè margine sx incrementa con altezza e non larghezza? + StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight())); wrapper.getChildren().add(totem); } @@ -187,7 +194,7 @@ public class MainFXMLController { private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) { ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png")); img.setPreserveRatio(true); - img.fitHeightProperty().bind(parent.heightProperty().multiply(0.90)); + img.fitHeightProperty().bind(parent.getScene().heightProperty().subtract(40).divide(4).multiply(0.90)); addClip(img); StackPane wrapper = new StackPane(img); if (withShadow) addShadow(wrapper); @@ -207,7 +214,7 @@ public class MainFXMLController { for (TribeCard card : controller.miniModel.upperListTribeCards) { final int index = i; StackPane img = createCard(card, true, true, upperList); - img.setOnMouseClicked(e -> controller.drawUpperTribeCard(controller.myUsername, index)); + img.setOnMouseClicked(e -> controller.drawUpperTribeCard(index)); upperList.getChildren().add(img); i++; } @@ -223,7 +230,7 @@ public class MainFXMLController { for (TribeCard card : controller.miniModel.lowerListTribeCards) { final int index = i; StackPane img = createCard(card, true, true, lowerList); - img.setOnMouseClicked(e -> controller.drawLowerTribeCard(controller.myUsername, index)); + img.setOnMouseClicked(e -> controller.drawLowerTribeCard(index)); lowerList.getChildren().add(img); i++; } @@ -273,7 +280,7 @@ public class MainFXMLController { myHand.getChildren().add(img); } else { Region placeholder = new Region(); - placeholder.prefHeightProperty().bind(myHand.heightProperty().multiply(0.90)); + placeholder.prefHeightProperty().bind(myHand.getScene().heightProperty().subtract(40).divide(4).multiply(0.90)); placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675)); placeholder.setStyle("-fx-background-color: transparent;"); myHand.getChildren().add(placeholder); @@ -282,7 +289,7 @@ public class MainFXMLController { private void renderPlayer(Player player,VBox target) { VBox card = new VBox(3); - VBox.setMargin(card, new Insets(8,15,8,15)); + VBox.setMargin(card, new Insets(15,15,0,15)); card.getStyleClass().add("player-card"); card.setPadding(new Insets(4)); @@ -291,6 +298,8 @@ public class MainFXMLController { scaleUp.setToX(1.1); scaleUp.setToY(1.1); scaleUp.play(); + + card.setStyle("-fx-effect: dropshadow(gaussian, #fff8dc, 15, 0.10, 0, 0)"); } @@ -303,8 +312,9 @@ public class MainFXMLController { totem.setPreserveRatio(true); Label usernameLabel = new Label(player.getUserName()); usernameLabel.getStyleClass().add("label-medium"); + usernameLabel.setStyle("-fx-text-fill: #711423;"); if (player.getUserName().equals(controller.myUsername)) { - usernameLabel.setStyle("-fx-text-fill: #9d0208"); + usernameLabel.setText(usernameLabel.getText() + " (you)"); if(isError) { TranslateTransition tt = new TranslateTransition(Duration.millis(50), card); @@ -454,7 +464,7 @@ public class MainFXMLController { default -> "/GUIImages/Backs/back-001.png"; }; ImageView back = new ImageView(loadImage(path)); - back.fitHeightProperty().bind(board.heightProperty().multiply(0.94)); + back.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().divide(4).multiply(0.94)); back.setPreserveRatio(true); addClip(back); addShadow(back); @@ -525,7 +535,7 @@ public class MainFXMLController { Slot slot = entry.getKey(); final int index = i; StackPane img = createSlot(slot, true, true); - img.setOnMouseClicked(e -> controller.slotChoice(controller.myUsername, index)); + img.setOnMouseClicked(e -> controller.slotChoice(index)); board.getChildren().add(img); i++; } @@ -548,7 +558,7 @@ public class MainFXMLController { private void renderSidePanel() { infoText.setText("Round: "+Integer.toString(controller.miniModel.currentState.getRound()) + " • " + controller.miniModel.currentState.getGameStage().toString()); - skipBtn.setOnAction(e -> controller.skipTurn(controller.myUsername)); + skipBtn.setOnAction(e -> controller.skipTurn()); detailsBtn.setOnAction(e -> openDetailsPopup()); addHoverZoom(skipBtn); @@ -609,7 +619,7 @@ public class MainFXMLController { StackPane img = createCardPopup(cardList.get(i), true, false); img.setOnMouseClicked(e -> { popup.hide(); - controller.drawUpperBuildingCard(controller.myUsername, index); + controller.drawUpperBuildingCard(index); }); popupCards.getChildren().add(img); } @@ -624,7 +634,7 @@ public class MainFXMLController { StackPane img = createCardPopup(cardList.get(i), true, false); img.setOnMouseClicked(e -> { popup.hide(); - controller.drawLowerBuildingCard(controller.myUsername, index); + controller.drawLowerBuildingCard(index); }); popupCards.getChildren().add(img); } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java index c9bd7b9..a6ec413 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/TotemFXMLController.java @@ -197,7 +197,7 @@ public class TotemFXMLController { @FXML private void onConfirm() { if (selectedIndex >= 0) { - controller.totemChoice(controller.myUsername, selectedIndex); + controller.totemChoice(selectedIndex); } } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index 6b318fa..606f998 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -257,6 +257,7 @@ public class TUI implements IView { table.addRow(List.of("4-DrawLowerTribe(pos)", "")); table.addRow(List.of("5-DrawLowerBuilding(pos)", "")); table.addRow(List.of("6-SkipTurn", "")); + table.addRow(List.of("0-Disconnect", "")); return table.build(); } diff --git a/src/main/resources/GUIScene/main.fxml b/src/main/resources/GUIScene/main.fxml index 324e2ef..bff8d0a 100644 --- a/src/main/resources/GUIScene/main.fxml +++ b/src/main/resources/GUIScene/main.fxml @@ -13,78 +13,78 @@ fx:controller="it.polimi.ingsw.gc14.View.GUI.MainFXMLController" stylesheets="@styles.css"> - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - -