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;
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)
@@ -44,23 +44,15 @@ public class Game implements Serializable {
//TODO
Map<Player,Boolean> 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;
}
@@ -75,10 +67,18 @@ public class Game implements Serializable {
if(currentState.getGameStage().equals(GameStages.SLOT_CHOICE) )
{
disconnetedPlayers.remove(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;
}
@@ -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.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.*;
* <li>stops the watchdog;</li>
* <li>marks the player as offline in {@code playerList};</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>
* </ul>
*/
@@ -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);
@@ -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) {}
}
@@ -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<NetworkEvent> actionQueue;
LimitedMap<String, Boolean> playerList;
List<ClientHandler> clientHandlers;
@@ -88,13 +89,21 @@ public class TCPServer {
continue;
}
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);
}
}
}
String username = eventAddPlayer.getUsername();
@@ -139,6 +148,7 @@ public class TCPServer {
clientSocket.close();
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.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,8 +91,9 @@ public class ServerLauncher {
* @throws RemoteException if an RMI error occurs
*/
public boolean doFirstEvent() throws InterruptedException, RemoteException {
synchronized(gameController){
NetworkEvent event = actionQueue.take();
synchronized(gameController){
event.setIsError(!event.apply(gameController));
serverRMI.notifyAll(event);
serverTCP.notifyAll(event);
@@ -107,9 +106,7 @@ public class ServerLauncher {
System.out.println("\n!!! Save failed !!!\n");
}
}
if (!playerList.get(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName())) {
actionQueue.offer(new SkipPlayerDisconnected(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName()));
}
//actionQueue.offer(new DisconnectedPlayer(gameController.getModel().getCurrentState().getCurrentPlayer().getUserName()));
return !event.getIsError();
}
}