diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java index 54399af..3fbc4c8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/GameController.java @@ -1,7 +1,6 @@ package it.polimi.ingsw.gc14.Controller; import it.polimi.ingsw.gc14.Model.Game; -import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.Player; /** @@ -31,12 +30,12 @@ public class GameController { public GameController() { } //TODO - public boolean SkipNotConnectedPlayer(String username) + public boolean DisconnectedPlayer(String username) { Player player= model.getPlayerByUsername(username); if(player==null) return false; - return model.SkipNotConnectedPlayer(player); + return model.DisconnectedPlayer(player); } //TODO public boolean ReconnectPlayer(String username) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java index 3074ec1..f8c5e22 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -44,23 +44,15 @@ public class Game implements Serializable { //TODO Map disconnetedPlayers = new HashMap<>(); //TODO - public boolean SkipNotConnectedPlayer(Player player) + public boolean DisconnectedPlayer(Player player) { - if(currentState.getCurrentPlayer()!=player) + if(disconnetedPlayers.containsKey(player) && disconnetedPlayers.get(player)) { return false; } - - - if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE)) - { + disconnetedPlayers.put(player,true); + if(currentState.getCurrentPlayer().equals(player)) nextPlayerSetup(); - disconnetedPlayers.put(player,false); - } - else - { - nextPlayerSetup(); - } return true; } @@ -72,13 +64,21 @@ public class Game implements Serializable { return false; } disconnetedPlayers.put(player,false); - if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE)) + if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE) ) { disconnetedPlayers.remove(player); - orderLogicCard.pushNoEffect(player); + if(!orderLogicCard.players.contains(player)) + { + orderLogicCard.pushNoEffect(player); + } } return true; } + + public void ClearDisconnected() + { + disconnetedPlayers.clear(); + } /** * Returns the current number of players participating in the game. * @return the current number of players. @@ -645,7 +645,10 @@ public class Game implements Serializable { if (GameStages.SLOT_CHOICE == currentState.getGameStage()) { Player tempPlayer = orderLogicCard.pull(); - + if(disconnetedPlayers.containsKey(tempPlayer) && disconnetedPlayers.get(tempPlayer)) { + nextPlayerSetup(); + return; + } if (tempPlayer != null) { currentState.PlayerUpdate(tempPlayer, null); return; @@ -690,12 +693,15 @@ public class Game implements Serializable { for (Slot s : slotMap.keySet()) { if (slotMap.get(s) != null) { currentState.PlayerUpdate(slotMap.get(s), s); - + if(disconnetedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnetedPlayers.get(currentState.getCurrentPlayer())) + { + slotMap.put(currentState.getSlot(), null); + continue; + } boolean hasDrawableLower = currentState.getNLower() > 0 && (hasDrawableDown() || !getLowerListBuilding().isEmpty()); boolean hasDrawableUpper = currentState.getNUpper() > 0 && (hasDrawableUp() || !getUpperListBuilding().isEmpty()); - if (!hasDrawableLower && !hasDrawableUpper) { // This player also has nothing, skip and continue the loop orderLogicCard.push(currentState.getCurrentPlayer()); @@ -717,6 +723,9 @@ public class Game implements Serializable { if (optionalPlayer != null) { currentState.PlayerUpdate(optionalPlayer, null); + if(disconnetedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnetedPlayers.get(currentState.getCurrentPlayer())) { + nextPlayerSetup(); + } return; } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipPlayerDisconnected.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipPlayerDisconnected.java deleted file mode 100644 index 63ea7fd..0000000 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipPlayerDisconnected.java +++ /dev/null @@ -1,33 +0,0 @@ -package it.polimi.ingsw.gc14.Network.NetworkEvents; - -import it.polimi.ingsw.gc14.Controller.GameController; -import it.polimi.ingsw.gc14.Network.EventType; -import it.polimi.ingsw.gc14.Network.NetworkEvent; - -import java.io.Serializable; - -/** - * NetworkEvent to avoid drawing a card from the lower card list - */ -public class SkipPlayerDisconnected extends NetworkEvent implements Serializable{ - - /** - * Class constructor. - * Initializes all the attributes. - * @param username the name of the player requesting the event - */ - public SkipPlayerDisconnected(String username){ - super(username, EventType.SKIP_PLAYER_DISCONNECTED, false); - } - - /** - * @param gameController the Game Controller on which to apply the event - * @return true if the player could skipTheTurn, false otherwise - */ - @Override - public boolean apply(GameController gameController){ - return gameController.SkipNotConnectedPlayer(username); - } - -} - 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 315c99e..e38b489 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 @@ -3,7 +3,7 @@ package it.polimi.ingsw.gc14.Network.RMI.Server; import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Network.NetworkEvent; -import it.polimi.ingsw.gc14.Network.NetworkEvents.SkipPlayerDisconnected; +import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer; import java.util.Map; import java.util.concurrent.*; @@ -21,7 +21,7 @@ import java.util.concurrent.*; *
  • stops the watchdog;
  • *
  • marks the player as offline in {@code playerList};
  • *
  • removes the callback from {@code clients};
  • - *
  • optionally pushes a {@link SkipPlayerDisconnected} event if it was that + *
  • optionally pushes a {@link DisconnectedPlayer} event if it was that * player's turn.
  • * */ @@ -104,7 +104,7 @@ public class RMIHeartbeat { Game snapshot = this.game; if (snapshot != null && snapshot.getCurrentState().getCurrentPlayer().getUserName().equals(username)) { - actionQueue.add(new SkipPlayerDisconnected(username)); + actionQueue.add(new DisconnectedPlayer(username)); } System.out.println("RMI disconnected: " + username); 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 1071fee..d321664 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 @@ -3,7 +3,7 @@ package it.polimi.ingsw.gc14.Network.TCP.Server; import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Network.NetworkEvent; -import it.polimi.ingsw.gc14.Network.NetworkEvents.SkipPlayerDisconnected; +import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer; import java.io.*; import java.net.*; @@ -133,9 +133,7 @@ public class ClientHandler implements Runnable { running = false; clientHandlers.remove(this); limitedMap.put(username, false); - if(this.game!=null && this.game.getCurrentState().getCurrentPlayer().getUserName().equals(username)) { - actionQueue.add(new SkipPlayerDisconnected(username)); - } + actionQueue.add(new DisconnectedPlayer(username)); System.out.println("Disconnected player: " + username); try { clientSocket.close(); } catch (IOException ignored) {} } 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 d364ede..bce4110 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 @@ -3,6 +3,7 @@ package it.polimi.ingsw.gc14.Network.TCP.Server; import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.Model.Game; +import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Network.ClientPlayer; import it.polimi.ingsw.gc14.Network.EventType; import it.polimi.ingsw.gc14.Network.NetworkEvent; @@ -29,7 +30,7 @@ public class TCPServer { ServerSocket socketTCP; ServerSocket heartbeatSocketTCP; // ← nuovo ServerSocket - GameController controller; + final GameController controller; BlockingQueue actionQueue; LimitedMap playerList; List clientHandlers; @@ -88,57 +89,66 @@ public class TCPServer { continue; } - if (playerList.isEmpty()) { - if(controller.getModel() == null){ - Game model = new Game(eventAddPlayer.getProposedNPlayer()); - controller.setModel(model); - playerList.setLimit(eventAddPlayer.getProposedNPlayer()); - } - } - - String username = eventAddPlayer.getUsername(); - - if (controller.addPlayer(username)) { - // nuovo giocatore - playerList.put(username, true); - System.out.println("Accepted player: " + username); - ClientHandler handler = new ClientHandler( - username, clientSocket, clientSend, clientReceive, - clientHandlers,playerList, actionQueue - ); - clientSocket.getOutputStream().write(1); - pendingHeartbeat.put(username, handler); - Thread thread = new Thread(handler); - thread.start(); - clientHandlers.add(handler); - connectedPlayers++; - // metti in attesa del socket heartbeat + synchronized (controller) { + if (playerList.isEmpty()) { + if(controller.getModel() == null){ + Game model = new Game(eventAddPlayer.getProposedNPlayer()); + controller.setModel(model); + playerList.setLimit(eventAddPlayer.getProposedNPlayer()); + } + else + { + for(Player p:controller.getModel().getPlayers()) { + playerList.put(p.getUserName(),false); + } + } + } - } - else if(playerList.containsKey(username) && !playerList.get(username)){ - // riconnessione - playerList.put(username, true); - System.out.println("Reconnected player: " + username); + String username = eventAddPlayer.getUsername(); - ClientHandler handler = new ClientHandler( - username, clientSocket, clientSend, clientReceive, - clientHandlers, playerList, actionQueue - ); - clientSocket.getOutputStream().write(1); - pendingHeartbeat.put(username, handler); - handler.notifyModel(controller.getModel()); - Thread thread = new Thread(handler); - thread.start(); - clientHandlers.add(handler); - connectedPlayers++; - actionQueue.add(new ReconnectPlayer(username)); - } - else{ - clientSocket.getOutputStream().write(-1); - clientSocket.close(); - System.out.println("Player could not be added. Connection terminated."); - } + if (controller.addPlayer(username)) { + // nuovo giocatore + playerList.put(username, true); + System.out.println("Accepted player: " + username); + ClientHandler handler = new ClientHandler( + username, clientSocket, clientSend, clientReceive, + clientHandlers,playerList, actionQueue + ); + clientSocket.getOutputStream().write(1); + pendingHeartbeat.put(username, handler); + Thread thread = new Thread(handler); + thread.start(); + clientHandlers.add(handler); + connectedPlayers++; + // metti in attesa del socket heartbeat + + + } + else if(playerList.containsKey(username) && !playerList.get(username)){ + // riconnessione + playerList.put(username, true); + System.out.println("Reconnected player: " + username); + + ClientHandler handler = new ClientHandler( + username, clientSocket, clientSend, clientReceive, + clientHandlers, playerList, actionQueue + ); + clientSocket.getOutputStream().write(1); + pendingHeartbeat.put(username, handler); + handler.notifyModel(controller.getModel()); + Thread thread = new Thread(handler); + thread.start(); + clientHandlers.add(handler); + connectedPlayers++; + actionQueue.add(new ReconnectPlayer(username)); + } + else{ + clientSocket.getOutputStream().write(-1); + clientSocket.close(); + System.out.println("Player could not be added. Connection terminated."); + } + } } diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java index baaf454..2337f91 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java +++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java @@ -4,10 +4,8 @@ package it.polimi.ingsw.gc14; 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.ClientPlayer; import it.polimi.ingsw.gc14.Network.NetworkEvent; -import it.polimi.ingsw.gc14.Network.NetworkEvents.SkipPlayerDisconnected; +import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer; import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer; import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer; import it.polimi.ingsw.gc14.View.TUI.TUI; @@ -93,25 +91,24 @@ public class ServerLauncher { * @throws RemoteException if an RMI error occurs */ public boolean doFirstEvent() throws InterruptedException, RemoteException { - synchronized(gameController){ - NetworkEvent event = actionQueue.take(); - event.setIsError(!event.apply(gameController)); - serverRMI.notifyAll(event); - serverTCP.notifyAll(event); + NetworkEvent event = actionQueue.take(); + synchronized(gameController){ - if(!event.getIsError()){ - if(this.gameController.getModel().getCurrentState().getGameStage() == GameStages.ENDED){ - this.deleteSave(); - } - else if(!this.gameSave() ){ - System.out.println("\n!!! Save failed !!!\n"); - } + event.setIsError(!event.apply(gameController)); + serverRMI.notifyAll(event); + serverTCP.notifyAll(event); + + if(!event.getIsError()){ + if(this.gameController.getModel().getCurrentState().getGameStage() == GameStages.ENDED){ + this.deleteSave(); } - if (!playerList.get(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())) { - actionQueue.offer(new SkipPlayerDisconnected(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())); + else if(!this.gameSave() ){ + System.out.println("\n!!! Save failed !!!\n"); } - return !event.getIsError(); } + //actionQueue.offer(new DisconnectedPlayer(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())); + return !event.getIsError(); + } }