From 3a39d889e4fcbc890850f2542b9df88a6fd5fb9b Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Mon, 11 May 2026 18:05:53 +0200 Subject: [PATCH] Fix: Only one player logic (todo go to end-game) --- .../polimi/ingsw/gc14/Network/EventType.java | 2 +- .../NetworkEvents/DisconnectedPlayer.java | 2 +- .../Network/NetworkEvents/SkipNoDrawable.java | 2 +- .../gc14/Network/RMI/Server/RMIServer.java | 3 + .../gc14/Network/TCP/Server/TCPServer.java | 4 + .../it/polimi/ingsw/gc14/ServerLauncher.java | 97 +++++++++++++------ 6 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/EventType.java b/src/main/java/it/polimi/ingsw/gc14/Network/EventType.java index dd697c3..8d01f34 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/EventType.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/EventType.java @@ -14,7 +14,7 @@ public enum EventType { PICK_OPTIONAL_TRIBE, PICK_OPTIONAL_BUILD, SKIP_NO_DRAWABLE, - SKIP_PLAYER_DISCONNECTED, + DISCONNECTED_PLAYER, RECONNECT_PLAYER, NO_OPTIONAL_CARD } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java index e1400cd..f38151a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java @@ -17,7 +17,7 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{ * @param username the name of the player requesting the event */ public DisconnectedPlayer(String username){ - super(username, EventType.SKIP_PLAYER_DISCONNECTED, false); + super(username, EventType.DISCONNECTED_PLAYER, false); } /** diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipNoDrawable.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipNoDrawable.java index 3f84ec8..249c218 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipNoDrawable.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipNoDrawable.java @@ -17,7 +17,7 @@ public class SkipNoDrawable extends NetworkEvent implements Serializable{ * @param username the name of the player requesting the event */ public SkipNoDrawable(String username){ - super(username, EventType.SKIP_PLAYER_DISCONNECTED, false); + super(username, EventType.SKIP_NO_DRAWABLE, false); } /** 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 d148ac5..e9862ad 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 @@ -43,6 +43,9 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer { private LimitedMap playerList; private boolean serverCrashed; + public void setServerCrashed(boolean serverCrashed) { + this.serverCrashed = serverCrashed; + } public RMIServer(GameController controller, int nPort, BlockingQueue actionQueue, 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 eaea963..e2d5215 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 @@ -36,6 +36,10 @@ public class TCPServer { List clientHandlers; boolean serverCrashed; + public void setServerCrashed(boolean serverCrashed) { + this.serverCrashed = serverCrashed; + } + // Mappa temporanea: username → ClientHandler // Serve per associare il socket heartbeat al giusto ClientHandler private final Map pendingHeartbeat = new ConcurrentHashMap<>(); diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index 294400a..309200c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -5,6 +5,7 @@ import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.Player; +import it.polimi.ingsw.gc14.Network.EventType; import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer; import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer; @@ -17,8 +18,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.rmi.RemoteException; import java.util.*; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.*; import java.net.*; @@ -64,9 +64,13 @@ public class ServerLauncher { */ static LimitedMap playerList; - TUI view; + static TUI view; + // Campo da aggiungere in ServerLauncher + private final ScheduledExecutorService timerExecutor = Executors.newSingleThreadScheduledExecutor(); + private ScheduledFuture disconnectionTimer; + /** * Class constructor that initializes the attributes. * @param actionQueue The queue containing the events @@ -93,23 +97,57 @@ public class ServerLauncher { */ public boolean doFirstEvent() throws InterruptedException, RemoteException { NetworkEvent event = actionQueue.take(); - synchronized(gameController){ - - event.setIsError(!event.apply(gameController)); - serverRMI.notifyAll(event); - serverTCP.notifyAll(event); - - if(!event.getIsError()){ - if(this.gameController.getModel().getCurrentState().getGameStage() == GameStages.ENDED){ - this.deleteSave(); - } - else if(!this.gameSave() ){ - System.out.println("\n!!! Save failed !!!\n"); - } + if(gameController.getModel()!=null && !gameController.getModel().getCurrentState().equals(GameStages.ENDED)) + { + if(disconnectionTimer!=null && event.getEventType() != EventType.RECONNECT_PLAYER) + { + event.setIsError(true); + serverRMI.notifyAll(event); + serverTCP.notifyAll(event); + return false; + } + if (event.getEventType() == EventType.RECONNECT_PLAYER && disconnectionTimer != null && !disconnectionTimer.isDone()) { + disconnectionTimer.cancel(false); + disconnectionTimer = null; + } + synchronized(gameController){ + event.setIsError(!event.apply(gameController)); + serverRMI.notifyAll(event); + serverTCP.notifyAll(event); + if(!event.getIsError()){ + if(this.gameController.getModel().getCurrentState().getGameStage() == GameStages.ENDED){ + this.deleteSave(); + for(Map.Entry entry:playerList.entrySet()){ + if(entry.getValue()) + playerList.remove(entry.getKey()); + } + serverRMI.setServerCrashed(false); + serverTCP.setServerCrashed(false); + } + else if(!this.gameSave() ){ + System.out.println("\n!!! Save failed !!!\n"); + } + + } + if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1) { + if (disconnectionTimer != null && !disconnectionTimer.isDone()) { + disconnectionTimer.cancel(false); + } + disconnectionTimer = timerExecutor.schedule(() -> { + System.out.println("Timer scaduto: nessun giocatore riconnesso in 30s."); + }, 500, TimeUnit.MILLISECONDS); + } + return !event.getIsError(); } - //actionQueue.offer(new DisconnectedPlayer(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())); - return !event.getIsError(); } + else{ + if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)) + { + playerList.remove(event.getUsername()); + } + return false; + } + } @@ -153,14 +191,25 @@ public class ServerLauncher { playerList.setAction(()->{ new Thread(()->{ try { - launcher.run(); - } catch (InterruptedException e) { - throw new RuntimeException(e); + System.out.println("\n\nNotifying model"); + serverRMI.notifyAll(gameController.getModel()); + serverTCP.notifyAll(gameController.getModel()); + view = new TUI(gameController.getModel()); + view.fullRender(); } catch (RemoteException e) { throw new RuntimeException(e); } }).start(); }); + new Thread(()-> { + try { + launcher.run(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + }).start(); serverRMI.start(serverCrashed); new Thread(()->{serverTCP.start(serverCrashed);}).start(); @@ -175,12 +224,6 @@ public class ServerLauncher { * @throws RemoteException if an RMI error occurs */ public void run() throws InterruptedException, RemoteException { - // Game creation - System.out.println("\n\nNotifying model"); - serverRMI.notifyAll(gameController.getModel()); - serverTCP.notifyAll(gameController.getModel()); - this.view = new TUI(gameController.getModel()); - this.view.fullRender(); // Game execution while (true) {