Fix: TCP Reconnection system -> model too

This commit is contained in:
rubenpirreram
2026-05-10 18:59:49 +02:00
parent f9fa12ac64
commit 670afb40a8
7 changed files with 107 additions and 127 deletions
@@ -1,7 +1,6 @@
package it.polimi.ingsw.gc14.Controller; package it.polimi.ingsw.gc14.Controller;
import it.polimi.ingsw.gc14.Model.Game; 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.Model.Player;
/** /**
@@ -31,12 +30,12 @@ public class GameController {
public GameController() { public GameController() {
} }
//TODO //TODO
public boolean SkipNotConnectedPlayer(String username) public boolean DisconnectedPlayer(String username)
{ {
Player player= model.getPlayerByUsername(username); Player player= model.getPlayerByUsername(username);
if(player==null) if(player==null)
return false; return false;
return model.SkipNotConnectedPlayer(player); return model.DisconnectedPlayer(player);
} }
//TODO //TODO
public boolean ReconnectPlayer(String username) public boolean ReconnectPlayer(String username)
@@ -44,23 +44,15 @@ public class Game implements Serializable {
//TODO //TODO
Map<Player,Boolean> disconnetedPlayers = new HashMap<>(); Map<Player,Boolean> disconnetedPlayers = new HashMap<>();
//TODO //TODO
public boolean SkipNotConnectedPlayer(Player player) public boolean DisconnectedPlayer(Player player)
{ {
if(currentState.getCurrentPlayer()!=player) if(disconnetedPlayers.containsKey(player) && disconnetedPlayers.get(player))
{ {
return false; return false;
} }
disconnetedPlayers.put(player,true);
if(currentState.getCurrentPlayer().equals(player))
if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE))
{
nextPlayerSetup(); nextPlayerSetup();
disconnetedPlayers.put(player,false);
}
else
{
nextPlayerSetup();
}
return true; return true;
} }
@@ -75,10 +67,18 @@ public class Game implements Serializable {
if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE) ) if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE) )
{ {
disconnetedPlayers.remove(player); disconnetedPlayers.remove(player);
if(!orderLogicCard.players.contains(player))
{
orderLogicCard.pushNoEffect(player); orderLogicCard.pushNoEffect(player);
} }
}
return true; return true;
} }
public void ClearDisconnected()
{
disconnetedPlayers.clear();
}
/** /**
* Returns the current number of players participating in the game. * Returns the current number of players participating in the game.
* @return the current number of players. * @return the current number of players.
@@ -645,7 +645,10 @@ public class Game implements Serializable {
if (GameStages.SLOT_CHOICE == currentState.getGameStage()) { if (GameStages.SLOT_CHOICE == currentState.getGameStage()) {
Player tempPlayer = orderLogicCard.pull(); Player tempPlayer = orderLogicCard.pull();
if(disconnetedPlayers.containsKey(tempPlayer) && disconnetedPlayers.get(tempPlayer)) {
nextPlayerSetup();
return;
}
if (tempPlayer != null) { if (tempPlayer != null) {
currentState.PlayerUpdate(tempPlayer, null); currentState.PlayerUpdate(tempPlayer, null);
return; return;
@@ -690,12 +693,15 @@ public class Game implements Serializable {
for (Slot s : slotMap.keySet()) { for (Slot s : slotMap.keySet()) {
if (slotMap.get(s) != null) { if (slotMap.get(s) != null) {
currentState.PlayerUpdate(slotMap.get(s), s); 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 boolean hasDrawableLower = currentState.getNLower() > 0
&& (hasDrawableDown() || !getLowerListBuilding().isEmpty()); && (hasDrawableDown() || !getLowerListBuilding().isEmpty());
boolean hasDrawableUpper = currentState.getNUpper() > 0 boolean hasDrawableUpper = currentState.getNUpper() > 0
&& (hasDrawableUp() || !getUpperListBuilding().isEmpty()); && (hasDrawableUp() || !getUpperListBuilding().isEmpty());
if (!hasDrawableLower && !hasDrawableUpper) { if (!hasDrawableLower && !hasDrawableUpper) {
// This player also has nothing, skip and continue the loop // This player also has nothing, skip and continue the loop
orderLogicCard.push(currentState.getCurrentPlayer()); orderLogicCard.push(currentState.getCurrentPlayer());
@@ -717,6 +723,9 @@ public class Game implements Serializable {
if (optionalPlayer != null) { if (optionalPlayer != null) {
currentState.PlayerUpdate(optionalPlayer, null); currentState.PlayerUpdate(optionalPlayer, null);
if(disconnetedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnetedPlayers.get(currentState.getCurrentPlayer())) {
nextPlayerSetup();
}
return; return;
} }
@@ -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);
}
}
@@ -3,7 +3,7 @@ package it.polimi.ingsw.gc14.Network.RMI.Server;
import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.LimitedMap;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Network.NetworkEvent; 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.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
@@ -21,7 +21,7 @@ import java.util.concurrent.*;
* <li>stops the watchdog;</li> * <li>stops the watchdog;</li>
* <li>marks the player as offline in {@code playerList};</li> * <li>marks the player as offline in {@code playerList};</li>
* <li>removes the callback from {@code clients};</li> * <li>removes the callback from {@code clients};</li>
* <li>optionally pushes a {@link SkipPlayerDisconnected} event if it was that * <li>optionally pushes a {@link DisconnectedPlayer} event if it was that
* player's turn.</li> * player's turn.</li>
* </ul> * </ul>
*/ */
@@ -104,7 +104,7 @@ public class RMIHeartbeat {
Game snapshot = this.game; Game snapshot = this.game;
if (snapshot != null && if (snapshot != null &&
snapshot.getCurrentState().getCurrentPlayer().getUserName().equals(username)) { snapshot.getCurrentState().getCurrentPlayer().getUserName().equals(username)) {
actionQueue.add(new SkipPlayerDisconnected(username)); actionQueue.add(new DisconnectedPlayer(username));
} }
System.out.println("RMI disconnected: " + username); System.out.println("RMI disconnected: " + username);
@@ -3,7 +3,7 @@ package it.polimi.ingsw.gc14.Network.TCP.Server;
import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.LimitedMap;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Network.NetworkEvent; 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.io.*;
import java.net.*; import java.net.*;
@@ -133,9 +133,7 @@ public class ClientHandler implements Runnable {
running = false; running = false;
clientHandlers.remove(this); clientHandlers.remove(this);
limitedMap.put(username, false); limitedMap.put(username, false);
if(this.game!=null && this.game.getCurrentState().getCurrentPlayer().getUserName().equals(username)) { actionQueue.add(new DisconnectedPlayer(username));
actionQueue.add(new SkipPlayerDisconnected(username));
}
System.out.println("Disconnected player: " + username); System.out.println("Disconnected player: " + username);
try { clientSocket.close(); } catch (IOException ignored) {} try { clientSocket.close(); } catch (IOException ignored) {}
} }
@@ -3,6 +3,7 @@ package it.polimi.ingsw.gc14.Network.TCP.Server;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.LimitedMap;
import it.polimi.ingsw.gc14.Model.Game; 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.ClientPlayer;
import it.polimi.ingsw.gc14.Network.EventType; import it.polimi.ingsw.gc14.Network.EventType;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
@@ -29,7 +30,7 @@ public class TCPServer {
ServerSocket socketTCP; ServerSocket socketTCP;
ServerSocket heartbeatSocketTCP; // ← nuovo ServerSocket ServerSocket heartbeatSocketTCP; // ← nuovo ServerSocket
GameController controller; final GameController controller;
BlockingQueue<NetworkEvent> actionQueue; BlockingQueue<NetworkEvent> actionQueue;
LimitedMap<String, Boolean> playerList; LimitedMap<String, Boolean> playerList;
List<ClientHandler> clientHandlers; List<ClientHandler> clientHandlers;
@@ -88,13 +89,21 @@ public class TCPServer {
continue; continue;
} }
synchronized (controller) {
if (playerList.isEmpty()) { if (playerList.isEmpty()) {
if(controller.getModel() == null){ if(controller.getModel() == null){
Game model = new Game(eventAddPlayer.getProposedNPlayer()); Game model = new Game(eventAddPlayer.getProposedNPlayer());
controller.setModel(model); controller.setModel(model);
playerList.setLimit(eventAddPlayer.getProposedNPlayer()); playerList.setLimit(eventAddPlayer.getProposedNPlayer());
} }
else
{
for(Player p:controller.getModel().getPlayers()) {
playerList.put(p.getUserName(),false);
} }
}
}
String username = eventAddPlayer.getUsername(); String username = eventAddPlayer.getUsername();
@@ -139,6 +148,7 @@ public class TCPServer {
clientSocket.close(); clientSocket.close();
System.out.println("Player could not be added. Connection terminated."); System.out.println("Player could not be added. Connection terminated.");
} }
}
} }
@@ -4,10 +4,8 @@ package it.polimi.ingsw.gc14;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; 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.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.RMI.Server.RMIServer;
import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer; import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer;
import it.polimi.ingsw.gc14.View.TUI.TUI; import it.polimi.ingsw.gc14.View.TUI.TUI;
@@ -93,8 +91,9 @@ public class ServerLauncher {
* @throws RemoteException if an RMI error occurs * @throws RemoteException if an RMI error occurs
*/ */
public boolean doFirstEvent() throws InterruptedException, RemoteException { public boolean doFirstEvent() throws InterruptedException, RemoteException {
synchronized(gameController){
NetworkEvent event = actionQueue.take(); NetworkEvent event = actionQueue.take();
synchronized(gameController){
event.setIsError(!event.apply(gameController)); event.setIsError(!event.apply(gameController));
serverRMI.notifyAll(event); serverRMI.notifyAll(event);
serverTCP.notifyAll(event); serverTCP.notifyAll(event);
@@ -107,9 +106,7 @@ public class ServerLauncher {
System.out.println("\n!!! Save failed !!!\n"); System.out.println("\n!!! Save failed !!!\n");
} }
} }
if (!playerList.get(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())) { //actionQueue.offer(new DisconnectedPlayer(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName()));
actionQueue.offer(new SkipPlayerDisconnected(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName()));
}
return !event.getIsError(); return !event.getIsError();
} }
} }