Merge pull request #122

GUI-2.0
This commit is contained in:
rubenpirreram
2026-05-27 20:50:37 +02:00
committed by GitHub
9 changed files with 76 additions and 24 deletions
@@ -21,6 +21,7 @@ public class MiniModel implements Serializable {
public ArrayList<TribeCard> lowerListTribeCards; public ArrayList<TribeCard> lowerListTribeCards;
public ArrayList<BuildingCard> upperListBuildingCards; public ArrayList<BuildingCard> upperListBuildingCards;
public ArrayList<BuildingCard> lowerListBuildingCards; public ArrayList<BuildingCard> lowerListBuildingCards;
public ArrayList<String> disconnectedPlayers;
/** /**
* Map associating each occupied slot with the corresponding player. * Map associating each occupied slot with the corresponding player.
@@ -64,6 +65,7 @@ public class MiniModel implements Serializable {
this.lowerListTribeCards = lowerListTribeCards; this.lowerListTribeCards = lowerListTribeCards;
this.upperListBuildingCards = upperListBuildingCards; this.upperListBuildingCards = upperListBuildingCards;
this.lowerListBuildingCards = lowerListBuildingCards; this.lowerListBuildingCards = lowerListBuildingCards;
this.disconnectedPlayers = new ArrayList<>();
} }
/** /**
@@ -80,7 +82,7 @@ public class MiniModel implements Serializable {
OrderLogicCard orderLogicCard, OrderLogicCard orderLogicCard,
CurrentState currentState, CurrentState currentState,
List<Player> players, List<Player> players,
List<Totems> availableTotems,ArrayList<TribeCard> upperListTribeCards,ArrayList<TribeCard>lowerListTribeCards,ArrayList<BuildingCard> upperListBuildingCards,ArrayList<BuildingCard>lowerListBuildingCards) { List<Totems> availableTotems,ArrayList<TribeCard> upperListTribeCards,ArrayList<TribeCard>lowerListTribeCards,ArrayList<BuildingCard> upperListBuildingCards,ArrayList<BuildingCard>lowerListBuildingCards, ArrayList<String> disconnectedPlayers) {
this.slotPlayerMap = slotPlayerMap; this.slotPlayerMap = slotPlayerMap;
this.orderLogicCard = orderLogicCard; this.orderLogicCard = orderLogicCard;
@@ -92,6 +94,7 @@ public class MiniModel implements Serializable {
this.lowerListTribeCards = lowerListTribeCards; this.lowerListTribeCards = lowerListTribeCards;
this.upperListBuildingCards = upperListBuildingCards; this.upperListBuildingCards = upperListBuildingCards;
this.lowerListBuildingCards = lowerListBuildingCards; this.lowerListBuildingCards = lowerListBuildingCards;
this.disconnectedPlayers = disconnectedPlayers;
setPlayers(players); setPlayers(players);
} }
@@ -181,4 +184,9 @@ public class MiniModel implements Serializable {
} }
return -1; return -1;
} }
//TODO
public void setDisconnectedPlayers (ArrayList<String> disconnectedPlayers){
this.disconnectedPlayers=disconnectedPlayers;
}
} }
@@ -6,13 +6,20 @@ import it.polimi.ingsw.gc14.Model.MiniModel;
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;
import javax.smartcardio.Card;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
/** /**
* NetworkEvent to avoid drawing a card from the lower card list * NetworkEvent to avoid drawing a card from the lower card list
*/ */
public class DisconnectedPlayer extends NetworkEvent implements Serializable{ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
private ArrayList<String> disconnectedPlayers;
public void setDisconnected(ArrayList<String> players)
{
this.disconnectedPlayers=players;
}
/** /**
* Class constructor. * Class constructor.
* Initializes all the attributes. * Initializes all the attributes.
@@ -22,6 +29,7 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
super(username, EventType.DISCONNECTED_PLAYER, false, ErrorType.GENERIC_ERROR); super(username, EventType.DISCONNECTED_PLAYER, false, ErrorType.GENERIC_ERROR);
} }
/** /**
* @param gameController the Game Controller on which to apply the event * @param gameController the Game Controller on which to apply the event
* @return true if the player could skipTheTurn, false otherwise * @return true if the player could skipTheTurn, false otherwise
@@ -42,6 +50,7 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
miniModel.setOrderLogicCard(orderLogicCard); miniModel.setOrderLogicCard(orderLogicCard);
miniModel.setCurrentState(currentState); miniModel.setCurrentState(currentState);
miniModel.setSlotPlayerMap(slotPlayerMap); miniModel.setSlotPlayerMap(slotPlayerMap);
miniModel.setDisconnectedPlayers(disconnectedPlayers);
} }
return true; return true;
} }
@@ -7,12 +7,17 @@ import it.polimi.ingsw.gc14.Network.EventType;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
/** /**
* Network event used to notify that a player has reconnected to the game. * Network event used to notify that a player has reconnected to the game.
*/ */
public class ReconnectPlayer extends NetworkEvent implements Serializable { public class ReconnectPlayer extends NetworkEvent implements Serializable {
private ArrayList<String> disconnectedPlayers;
public void setDisconnected(ArrayList<String> players)
{
this.disconnectedPlayers=players;
}
/** /**
* Constructs a reconnection event for the specified player. * Constructs a reconnection event for the specified player.
* *
@@ -55,6 +60,7 @@ public class ReconnectPlayer extends NetworkEvent implements Serializable {
miniModel.setOrderLogicCard(orderLogicCard); miniModel.setOrderLogicCard(orderLogicCard);
miniModel.setCurrentState(currentState); miniModel.setCurrentState(currentState);
miniModel.setSlotPlayerMap(slotPlayerMap); miniModel.setSlotPlayerMap(slotPlayerMap);
miniModel.setDisconnectedPlayers(disconnectedPlayers);
} }
return true; return true;
@@ -15,11 +15,14 @@ import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry; import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject; import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.rmi.*; import java.rmi.*;
import java.util.stream.Collectors;
/** /**
@@ -127,7 +130,7 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
System.out.println("Reconnected player: " + username); System.out.println("Reconnected player: " + username);
startWatchdog(username); startWatchdog(username);
Game game = controller.getModel(); Game game = controller.getModel();
callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding())); callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers(), game.getAvailableTotems(), game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new))));
System.out.println("Model sent: " + username); System.out.println("Model sent: " + username);
actionQueue.add(new ReconnectPlayer(username)); actionQueue.add(new ReconnectPlayer(username));
return null; return null;
@@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/** /**
* TCP server responsible for accepting client connections, * TCP server responsible for accepting client connections,
@@ -265,7 +266,7 @@ public class TCPServer {
game.getCurrentState(), game.getCurrentState(),
game.getPlayers(), game.getPlayers(),
game.getAvailableTotems(), game.getAvailableTotems(),
game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding() game.getUpperListTribeCards(), game.getLowerListTribeCards(), game.getUpperListBuilding(), game.getLowerListBuilding(), game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new))
)); ));
Thread thread = new Thread(handler); Thread thread = new Thread(handler);
@@ -9,9 +9,7 @@ import it.polimi.ingsw.gc14.Model.Player;
import it.polimi.ingsw.gc14.Model.Totems; import it.polimi.ingsw.gc14.Model.Totems;
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;
import it.polimi.ingsw.gc14.Network.NetworkEvents.ApplyNextRound; import it.polimi.ingsw.gc14.Network.NetworkEvents.*;
import it.polimi.ingsw.gc14.Network.NetworkEvents.EndedGame;
import it.polimi.ingsw.gc14.Network.NetworkEvents.TotemChoice;
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;
@@ -24,6 +22,7 @@ import java.rmi.RemoteException;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.net.*; import java.net.*;
import java.util.stream.Collectors;
/** /**
@@ -110,19 +109,25 @@ public class ServerLauncher {
if(gameController.getModel()!=null && gameController.getModel().getCurrentState().getGameStage()!=GameStages.ENDED) if(gameController.getModel()!=null && gameController.getModel().getCurrentState().getGameStage()!=GameStages.ENDED)
{ {
//if there is only one player ignore every event different by reconnection //if there is only one player ignore every event different by reconnection
if(disconnectionTimer!=null && event.getEventType() != EventType.RECONNECT_PLAYER) if(disconnectionTimer!=null )
{ {
event.setIsError(true); if(event.getEventType() != EventType.RECONNECT_PLAYER)
serverRMI.notifyAll(event); {
serverTCP.notifyAll(event); event.setIsError(true);
return false; serverRMI.notifyAll(event);
serverTCP.notifyAll(event);
return false;
}else if(event.getEventType() != EventType.DISCONNECTED_PLAYER)
{
disconnectionTimer.cancel(true);
disconnectionTimer = null;
playerList.clear();
gameController.setModel(null);
System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n");
return true;
}
} }
//Cancel the timer if another player is reconnected , so there are more than one player
if (event.getEventType() == EventType.RECONNECT_PLAYER && disconnectionTimer != null && !disconnectionTimer.isDone()) {
disconnectionTimer.cancel(false);
disconnectionTimer = null;
}
synchronized(gameController){ synchronized(gameController){
int roundPrev=gameController.getModel().getCurrentState().getRound(); int roundPrev=gameController.getModel().getCurrentState().getRound();
//applies the event and set if is an error //applies the event and set if is an error
@@ -131,19 +136,29 @@ public class ServerLauncher {
//if the event wasn't an error , it will be sent to players //if the event wasn't an error , it will be sent to players
if(!event.getIsError()) if(!event.getIsError())
{ {
//Cancel the timer if another player is reconnected , so there are more than one player
if (event.getEventType() == EventType.RECONNECT_PLAYER && disconnectionTimer != null && !disconnectionTimer.isDone()) {
disconnectionTimer.cancel(false);
disconnectionTimer = null;
}
if(!this.gameSave() ){ if(!this.gameSave() ){
System.out.println("\n!!! Save failed !!!\n"); System.out.println("\n!!! Save failed !!!\n");
} }
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)&& game.getCurrentState().getGameStage().equals(GameStages.WAITING)) if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)&& game.getCurrentState().getGameStage().equals(GameStages.WAITING))
{ {
playerList.remove(event.getUsername()); playerList.remove(event.getUsername());
return true;
}else { }else {
event.setData(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers()); event.setData(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers());
if (event.getEventType().equals(EventType.TOTEM_CHOICE)) { }
((TotemChoice) event).setAvailableTotems(gameController.getModel().getAvailableTotems()); if (event.getEventType().equals(EventType.TOTEM_CHOICE)) {
} else if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && game.getCurrentState().getGameStage().equals(GameStages.WAITING)) { ((TotemChoice) event).setAvailableTotems(gameController.getModel().getAvailableTotems());
playerList.remove(event.getUsername()); }else if (event.getEventType().equals(EventType.RECONNECT_PLAYER))
} {
((ReconnectPlayer) event).setDisconnected(game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)));
}else if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER))
{
((DisconnectedPlayer) event).setDisconnected(game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)));
} }
//if there is only one player the game will be suspended and starts the forfeit timer //if there is only one player the game will be suspended and starts the forfeit timer
if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1&& game.getCurrentState().getGameStage() != GameStages.ENDED) { if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1&& game.getCurrentState().getGameStage() != GameStages.ENDED) {
@@ -274,7 +289,7 @@ public class ServerLauncher {
MiniModel miniModel; MiniModel miniModel;
synchronized (gameController) { synchronized (gameController) {
Game game = gameController.getModel(); Game game = gameController.getModel();
miniModel= new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()); miniModel= new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding(), game.disconnetedPlayers.entrySet().stream().filter(Map.Entry::getValue).map(x -> x.getKey().getUserName()).collect(Collectors.toCollection(ArrayList::new)));
} }
serverRMI.notifyAll(miniModel); serverRMI.notifyAll(miniModel);
serverTCP.notifyAll(miniModel); serverTCP.notifyAll(miniModel);
@@ -324,6 +324,9 @@ public class MainFXMLController {
tt.play(); tt.play();
} }
} }
if (controller.miniModel.disconnectedPlayers.contains(player.getUserName())) {
card.getStyleClass().add("player-card-crashed");
}
headerRow.getChildren().addAll(totem, usernameLabel); headerRow.getChildren().addAll(totem, usernameLabel);
// Riga 2: cibo + prestigio + building // Riga 2: cibo + prestigio + building
@@ -75,7 +75,7 @@ public class TotemFXMLController {
if (myTurn) { if (myTurn) {
turnBanner.setText("✦ It's your turn to choose ✦"); turnBanner.setText("✦ It's your turn to choose ✦");
turnBanner.setStyle( turnBanner.setStyle(
"-fx-font-family: 'Cinzel'; -fx-font-size: 13; -fx-letter-spacing: 3;" + "-fx-font-family: 'Cinzel'; -fx-font-size: 13; -fx-font-weight: 'bold'; -fx-letter-spacing: 3;" +
"-fx-text-fill: #000000;" + "-fx-text-fill: #000000;" +
"-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" + "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" +
"-fx-border-color: #000000; -fx-border-width: 1;" + "-fx-border-color: #000000; -fx-border-width: 1;" +
+7
View File
@@ -41,6 +41,13 @@
-fx-background-radius: 15; -fx-background-radius: 15;
-fx-background-color: #f18f1c; -fx-background-color: #f18f1c;
} }
.player-card-crashed {
-fx-border-color: #711423;
-fx-border-width: 2;
-fx-border-radius: 15;
-fx-background-radius: 15;
-fx-background-color: #8C8C8CFF;
}
.frame { .frame {
-fx-background-color: rgba(255,255,255,0.35); -fx-background-color: rgba(255,255,255,0.35);