NonObjCards = new ArrayList<>();
diff --git a/src/main/java/it/polimi/ingsw/am32/client/PlayerPub.java b/src/main/java/it/polimi/ingsw/am32/client/PlayerPub.java
index f06c95a7..9bc9a404 100644
--- a/src/main/java/it/polimi/ingsw/am32/client/PlayerPub.java
+++ b/src/main/java/it/polimi/ingsw/am32/client/PlayerPub.java
@@ -84,6 +84,7 @@ public void updateResources(int[] resources){
}
/**
* Update the points of the player with the points updated received from the message.
+ * @param points the new version of the points.
*/
public void updatePoints(int points){
this.points = points;
diff --git a/src/main/java/it/polimi/ingsw/am32/client/View.java b/src/main/java/it/polimi/ingsw/am32/client/View.java
index 78cc3957..303f7735 100644
--- a/src/main/java/it/polimi/ingsw/am32/client/View.java
+++ b/src/main/java/it/polimi/ingsw/am32/client/View.java
@@ -1,6 +1,7 @@
package it.polimi.ingsw.am32.client;
+import it.polimi.ingsw.am32.network.exceptions.ConnectionSetupFailedException;
import it.polimi.ingsw.am32.utilities.IsValid;
import it.polimi.ingsw.am32.client.listener.AskListener;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSLobbyMessage;
@@ -9,7 +10,6 @@
import it.polimi.ingsw.am32.network.ClientNode.RMIClientNode;
import it.polimi.ingsw.am32.network.ClientNode.SKClientNode;
-import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collections;
@@ -170,16 +170,16 @@ public View() {
* Also, it creates a new thread to listen for messages from the client.
* @param serverIP The IP address of the server.
* @param port The port number of the server.
- * @throws IOException If an I/O error occurs when creating the socket.
+ * @throws ConnectionSetupFailedException if the connection setup fails.
*/
- public void setSocketClient(String serverIP, int port) throws IOException {
+ public void setSocketClient(String serverIP, int port) throws ConnectionSetupFailedException {
SKClientNode clientNode = new SKClientNode(this,serverIP,port);
this.clientNode = clientNode;
clientNode.startConnection();
- this.askListener = new AskListener(clientNode);
+
+ this.askListener = new AskListener(clientNode);
Thread askListener = new Thread(this.askListener); // Create a new thread listen for messages from the client
askListener.start();
- //TODO verify if this is correct
}
/**
@@ -187,9 +187,9 @@ public void setSocketClient(String serverIP, int port) throws IOException {
* Also, it creates a new thread to listen for messages from the client.
* @param serverIP The IP address of the server.
* @param port The port number of the server.
+ * @throws ConnectionSetupFailedException if the connection setup fails.
*/
- public void setRMIClient(String serverIP, int port) {
- //TODO verify if this is correct
+ public void setRMIClient(String serverIP, int port) throws ConnectionSetupFailedException {
try{
RMIClientNode clientNode = new RMIClientNode(this, serverIP, port);
this.clientNode = clientNode;
@@ -199,7 +199,7 @@ public void setRMIClient(String serverIP, int port) {
Thread askListenerThread = new Thread(this.askListener);
askListenerThread.start();
}catch (RemoteException e) {
- //TODO
+ throw new ConnectionSetupFailedException();
}
}
/**
@@ -514,6 +514,10 @@ public abstract void updateRollback(String playerNickname, int removedCard, int
* @param nickname The nickname of the player will be used to handle the event.
*/
public abstract void handleEvent(Event event, String nickname);
+
+ public abstract void nodeDisconnected();
+
+ public abstract void nodeReconnected();
}
diff --git a/src/main/java/it/polimi/ingsw/am32/client/view/gui/ChatArea.java b/src/main/java/it/polimi/ingsw/am32/client/view/gui/ChatArea.java
index 0c3dbba7..f127333e 100644
--- a/src/main/java/it/polimi/ingsw/am32/client/view/gui/ChatArea.java
+++ b/src/main/java/it/polimi/ingsw/am32/client/view/gui/ChatArea.java
@@ -6,7 +6,11 @@
import java.util.ArrayList;
-
+/**
+ * This class represents the chat area in the GUI.
+ * It contains the message display area, the message input area, and the submit button.
+ * It also contains a combo box that allows the user to select a recipient for the message.
+ */
public class ChatArea {
/**
* An object representing the chat area in the GUI
@@ -45,7 +49,7 @@ public class ChatArea {
/**
* Constructor for the ChatArea class
- *
+ * @param gui A reference to the GUI
* @param X X coordinate of the chat area
* @param Y Y coordinate of the chat area
* @param width Width of the chat area
@@ -136,8 +140,8 @@ private void initializeChatArea(int X, int Y, int width, int height, ArrayList {
selectionPane.getChildren().remove(connectionRoot); // exit from the choose connection page
selectionPane.getChildren().add(socketRoot); // enter the socket connection page
});
OkButton.setOnAction(e -> {
+ OkButton.setDisable(true);
String ServerIP = ip.getText(); // Read the player's input and save it the server IP address
String ServerPort = port.getText();
try {
@@ -406,26 +410,29 @@ public void chooseConnection() {
selectionPane.getChildren().remove(socketRoot);
askSelectGameMode();
} else {
- createAlert("Invalid IP/port number");
+ createAlert("Invalid IP or PORT number!");
ip.clear();
port.clear();
}
} catch (NumberFormatException ex) {
- createAlert("Invalid port number");
+ createAlert("Invalid PORT number!");
port.clear();
- } catch (IOException ex) {
- createAlert("Connection failed");
+ } catch (ConnectionSetupFailedException ex) {
+ createAlert("Connection failed! You can try again!");
ip.clear();
port.clear();
}
+ OkButton.setDisable(false);
});
- // set the action of the buttons
+
+ // set the action of the buttons (RMI)
rmiButton.setOnAction(e -> {
selectionPane.getChildren().remove(connectionRoot); // exit from the choose connection page
selectionPane.getChildren().add(RMIRoot); // enter the socket connection page
});
OkRMIButton.setOnAction(e -> {
+ OkRMIButton.setDisable(true);
String ServerIP = RMIIp.getText(); // Read the player's input and save it the server IP address
String ServerPort = RMIPort.getText();
try {
@@ -436,36 +443,41 @@ public void chooseConnection() {
askSelectGameMode();
} else {
createAlert("Invalid IP/port number");
- ip.clear();
- port.clear();
+ RMIIp.clear();
+ RMIPort.clear();
}
} catch (NumberFormatException ex) {
createAlert("Invalid port number");
- port.clear();
- } /*catch (IOException ex) { //TODO
- createAlert("Connection failed");
- ip.clear();
- port.clear();
- }*/
+ RMIPort.clear();
+ } catch (ConnectionSetupFailedException ex) {
+ createAlert("Connection failed! You can try again!");
+ RMIIp.clear();
+ RMIPort.clear();
+ }
+ OkRMIButton.setDisable(false);
});
}
+
/**
* Set the socket connection between the client and the server.
- *
* @param ServerIP the IP address of the server
* @param portNumber the port number of the server
- * @throws IOException if the connection to the server fails
*/
@Override
- public void setSocketClient(String ServerIP, int portNumber) throws IOException {
+ public void setSocketClient(String ServerIP, int portNumber) throws ConnectionSetupFailedException {
super.setSocketClient(ServerIP, portNumber);
}
+
+ /**
+ * Set the RMI connection between the client and the server.
+ * @param serverURL the URL of the server
+ * @param port the port number of the server
+ */
@Override
- public void setRMIClient(String serverURL, int port) {
- super.setRMIClient(serverURL, port); // see the method in the superclass
+ public void setRMIClient(String serverURL, int port) throws ConnectionSetupFailedException {
+ super.setRMIClient(serverURL, port);
}
-
/**
* Set the page where the player can select the game mode. The player can choose between creating a new game, joining
* an existing game or reconnecting to a game. The player can choose the game mode using the buttons βNew Gameβ, βJoin
@@ -2187,9 +2199,9 @@ public String convertToColour(int colour) {
/**
* Generates the selection area for the initial card side selection.
- * The selection area is composed of a prompt label, 2 cards to choose from
- *
- * @return a VBox containing the selection area for the initial card side selection
+ * The selection area is composed of a prompt label, 2 cards to choose from.
+ * @param imageNumber the number of the image to load.
+ * @return a VBox containing the selection area for the initial card side selection.
*/
public VBox setupInitialCardSideSelectionArea(int imageNumber) {
VBox selectionArea = new VBox(); // Entire selection area
@@ -2256,8 +2268,9 @@ public VBox setupInitialCardSideSelectionArea(int imageNumber) {
/**
* Generates the selection area for the secret objective card selection.
- * The selection area is composed of a prompt label, 2 cards to choose from
- *
+ * The selection area is composed of a prompt label, 2 cards to choose from.
+ * @param card1 the ID of the first card
+ * @param card2 the ID of the second card
* @return a VBox containing the selection area for the secret objective card selection
*/
public VBox setupSecretObjectiveCardSelectionArea(int card1, int card2) {
@@ -2346,4 +2359,11 @@ private void handleButtonClick(Button clickedButton, Button button1, Button butt
public String getThisPlayerNickname() {
return thisPlayerNickname;
}
+
+ // TODO implementare metodo
+ public void nodeDisconnected(){}
+
+ // TODO implementare metodo
+ public void nodeReconnected(){}
+
}
diff --git a/src/main/java/it/polimi/ingsw/am32/client/view/tui/TextUI.java b/src/main/java/it/polimi/ingsw/am32/client/view/tui/TextUI.java
index c166e7b2..6aaeb4c0 100644
--- a/src/main/java/it/polimi/ingsw/am32/client/view/tui/TextUI.java
+++ b/src/main/java/it/polimi/ingsw/am32/client/view/tui/TextUI.java
@@ -1,11 +1,10 @@
package it.polimi.ingsw.am32.client.view.tui;
+import it.polimi.ingsw.am32.network.exceptions.ConnectionSetupFailedException;
import it.polimi.ingsw.am32.utilities.IsValid;
-import it.polimi.ingsw.am32.client.ChatMessage;
import it.polimi.ingsw.am32.client.*;
import it.polimi.ingsw.am32.message.ClientToServer.*;
-import java.io.IOException;
import java.io.PrintStream;
import java.util.*;
@@ -31,7 +30,7 @@
* For the design of the cards, the class includes a method to print the card, a method to convert the corner type
* of the card to an icon and a method to convert the object type of the card to an icon as well. The class uses
* Unicode characters to represent the icons of the cards and the objects. In addition, the class
- * includes ASCI escape codes to set the color of the printed cards and the printed text.
+ * includes ASCII escape codes to set the color of the printed cards and the printed text.
* By the playing phase, players also have the possibility to interact with the chat and use the keyword to interact
* with the game, for example, type βSHβ to show the hand of the player.
* @author Jie
@@ -109,7 +108,7 @@ public class TextUI extends View{
* Unicode characters used to represent the icon PLANT
*/
private static final String PLANT = "\uD83C\uDF3F";
- /**
+ /**
* Unicode characters used to represent the icon FUNGI
*/
private static final String FUNGI = "\uD83C\uDF44";
@@ -125,9 +124,9 @@ public class TextUI extends View{
* Unicode characters used to represent the icon INKWELL
*/
private static final String INKWELL = "\uD83C\uDF6F";
-/**
- * Unicode characters used to represent the icon MANUSCRIPT
- */
+ /**
+ * Unicode characters used to represent the icon MANUSCRIPT
+ */
private static final String MANUSCRIPT = "\uD83D\uDCDC";
/**
* Unicode characters used to represent the icon βXβ;
@@ -168,6 +167,7 @@ public class TextUI extends View{
/**
* Constructor of the class TextUI
+ * @implSpec NON-BLOCKING
*/
public TextUI() {
super();
@@ -191,6 +191,13 @@ public void launch() {
boolean isEnd = false;
while (!isEnd) { // TODO think about a better way to handle the flow of the game
switch (Status) {
+ case WELCOME -> {
+ switch (currentEvent) {
+ case CREATE_GAME_FAILURE -> askCreateGame();
+ case JOIN_GAME_FAILURE -> askJoinGame();
+ case RECONNECT_GAME_FAILURE -> askReconnectGame();
+ }
+ }
case PREPARATION -> {
if(currentEvent.equals(Event.SELECT_STARTER_CARD_SIDE)) {
requestSelectStarterCardSide(startCard);
@@ -222,6 +229,7 @@ public void launch() {
* RMI connection, the method asks the player to insert the server URL.
* The method uses the {@link IsValid} class to check the validity of the IP address and the port number entered by
* the player.
+ * @implSpec BLOCKING-NON-INTERRUPTIBLE
*/
@Override
public void chooseConnection() {
@@ -240,68 +248,71 @@ public void chooseConnection() {
switch (connectionChoice) {
case 1: { // Player chooses socket connection
// Ask the player to insert the server IP
- out.println("Insert the server IP:"); // Ask the player to insert the server IP
+ out.println("Insert the server IP: "); // Ask the player to insert the server IP
String serverIP = in.nextLine(); // Read the player's input
while (!isValid.isIpValid(serverIP)) { // Check if the IP address is valid
- out.println("Invalid IP, please try again"); // Print an error message
+ out.println("Invalid IP, please try again!"); // Print an error message
serverIP = in.nextLine(); // Ask the player to re-enter the IP address
}
// Ask the player to insert the server port
- out.println("Insert the server port:"); // Ask the player to insert the server port
+ out.println("Insert the server port: "); // Ask the player to insert the server port
int port = getInputInt(); // Read the player's input
while (!isValid.isPortValid(port)) { // Check if the port number is valid
- out.println("Invalid port, please try again"); // Print an error message
+ out.println("Invalid port, please try again!"); // Print an error message
port = getInputInt(); // Ask the player to re-enter the port number
}
try {
setSocketClient(serverIP, port); // Set the socket client
isConnected = true; // Set the connection status to true
- } catch (IOException e) { // If an I/O error occurs
- Thread.currentThread().interrupt(); // Interrupt the current thread
- // TODO Should probably log this
+ } catch (ConnectionSetupFailedException e) {
+ // Do nothing, the connection status is already false.
+ // We will print a connection failed message later and loop again
}
break;
}
case 2: { // Player chooses RMI connection
// Ask the player to insert the server IP
- out.println("Insert the server IP"); // Ask the player to insert the server URL
- // TODO Should ask the player to insert the server URL in a specific format
+ out.println("Insert the server IP: "); // Ask the player to insert the server IP
String serverIP = in.nextLine(); // Read the player's input
while (!isValid.isIpValid(serverIP)) { // Check if the IP is valid
- out.println("Invalid IP, please try again"); // Print an error message
+ out.println("Invalid IP, please try again!"); // Print an error message
serverIP = in.nextLine(); // Ask the player to re-enter the IP
}
// Ask the player to insert the server port
- out.println("Insert the server port:"); // Ask the player to insert the server port
+ out.println("Insert the server port: "); // Ask the player to insert the server port
int port = getInputInt(); // Read the player's input
while (!isValid.isPortValid(port)) { // Check if the port number is valid
- out.println("Invalid port, please try again"); // Print an error message
+ out.println("Invalid port, please try again!"); // Print an error message
port = getInputInt(); // Ask the player to re-enter the port number
}
- // TODO mettere exception come
- setRMIClient(serverIP, port); // Set the RMI client
- isConnected = true; // Set the connection status to true
+ try {
+ setRMIClient(serverIP, port); // Set the RMI client
+ isConnected = true; // Set the connection status to true
+ } catch (ConnectionSetupFailedException e) {
+ // Do nothing, the connection status is already false.
+ // We will print a connection failed message later and loop again
+ }
break;
}
default: { // If the player's input is not one of the valid options
- out.println("Invalid input, please select 1 or 2");
+ out.println("Invalid input, please select 1 or 2!");
continue; // Continue here to avoid a printing connection failed message
}
}
// We have now attempted to establish a connection, but it may have failed
if (!isConnected) { // If the connection is not established
- out.println("Connection failed, please try again"); // Print an error message
+ out.println("Connection failed, you are free to try again!"); // Print an error message
}
} while (!isConnected); // Keep looping until the connection is established
}
@@ -309,31 +320,32 @@ public void chooseConnection() {
/**
* Method that sets the socket client with the server IP and the server port entered by the player and attempts to
* establish the connection between the client and the server.
- *
+ * @implSpec NON-BLOCKING
* @param serverIP the server IP entered by the player
* @param port the server port entered by the player
- * @throws IOException if an I/O error occurs
*/
@Override
- public void setSocketClient(String serverIP, int port) throws IOException {
+ public void setSocketClient(String serverIP, int port) throws ConnectionSetupFailedException {
super.setSocketClient(serverIP, port);
}
/**
* Method that sets the RMI client with the server URL entered by the player and attempts to establish the
* connection between the client and the server.
- *
+ * @implSpec NON-BLOCKING
* @param serverURL the server URL entered by the player
* @see View#setSocketClient(String, int)
*/
@Override
- public void setRMIClient(String serverURL, int port) {
+ public void setRMIClient(String serverURL, int port) throws ConnectionSetupFailedException {
super.setRMIClient(serverURL, port); // see the method in the superclass
}
+
//-------------------Title-------------------
/**
* Method that prints the welcome message and link to the game rules.
+ * @implSpec NON-BLOCKING
*/
@Override
public void showWelcome() {
@@ -345,8 +357,9 @@ public void showWelcome() {
βββ βββ ββββββ βββββββββ ββββββ ββββββββββββββββββ βββ βββ ββββββββββββββββββββββ βββββββββββ
βββββββββββββββββββββββββββββββββββββ βββ βββ βββββββββ βββ βββ ββββββββββββ ββββββ ββββββββββββββββββββββ
ββββββ βββββββ βββββββ βββββββββββ βββ βββ ββββββββ βββ βββ βββββββ βββ ββββββ ββββββββββββββββββββββ""");
- out.println("Game rule:https://it.boardgamearena.com/link?url=https%3A%2F%2Fcdn.1j1ju.com%2Fmedias%2Fa7%2Fd7%2F66-codex-naturalis-rulebook.pdf&id=9212");
+ out.println("Game rule:https://t.ly/ZtnYH");
}
+
//-------------------Game mode-------------------
/**
@@ -461,7 +474,7 @@ public void askReconnectGame() {
/**
* Once the player receives the NewGameConfirmationMessage from the server, the method is called by processMessage
* to store the gameID, the nickname of the player who created the game, and add it in the list of players.
- *
+ * @implSpec NON-BLOCKING
* @param gameID the game ID returned by the server after the confirmation of the new game
* @param recipientNickname the nickname of the player who asked to create the new game
*/
@@ -476,6 +489,7 @@ public void updateNewGameConfirm(int gameID, String recipientNickname) {
/**
* Once the player receives the LobbyPlayerList message from the server, the method is called by
* processMessage, to update the player's list in the Lobby phase and print the player's list updated.
+ * @implSpec NON-BLOCKING
* @param players the list updated of players in the game.
*/
@Override
@@ -487,6 +501,7 @@ public void updatePlayerList(ArrayList players) {
/**
* The Method used to update the player's board and public info when the player disconnects from the game after the
* placement of the card.
+ * @implSpec NON-BLOCKING
* @param playerNickname the nickname of the player whose board should be updated with the rollback
* @param removedCard the ID of the card that should be removed from the board and the public info of the player
* @param playerPoints the points of the player after the rollback
@@ -541,6 +556,7 @@ public void updateRollback(String playerNickname, int removedCard, int playerPoi
/**
* After receiving the GameStarted message from the server, the method is called to set up the view of the player
* and initialize the data and the boards of the players.
+ * @implSpec NON-BLOCKING
*/
@Override
public void setUpPlayersData() {
@@ -551,12 +567,14 @@ public void setUpPlayersData() {
boards.put(player, new BoardView(new int[]{80, 80, 80, 80}, new String[160][160]));
}
}
+
/**
* Once the player receives the MatchStatus message from the server, the method is called by processMessage to
* update the match status of the player, and print the message to notify the player of the current match status.
* And if the match status is TERMINATING, the method is called to show the points of all players in the game.
* One time the match status is PLAYING, the method is called to start the readInputThread to get the input from
* the player when it is not the player's turn.
+ * @implSpec NON-BLOCKING
* @param matchStatus the current match status received from the server
*/
@Override
@@ -601,7 +619,8 @@ public void requestSelectStarterCardSide(int ID) {
/**
* Once received the ConfirmedStarterCardSideSelectionMessage from the server, the method is called by processMessage to
- * update the view of the player and print the message to notify the player that the starter card is selected
+ * update the view of the player and print the message to notify the player that the starter card is selected.
+ * @implSpec NON-BLOCKING
* @param colour the colour of the player in the game.
* @param cardID the ID of the starter card selected by the player and received from the server.
* @param isUp indicates the side of the card selected by the player to be placed.
@@ -631,6 +650,7 @@ public void updateConfirmStarterCard(int colour, int cardID, boolean isUp, Array
* processMessage to request the player to select the secret objective card they want to use. The player will be
* able to see the front and back side of the card and select the card they want to use. Also, the player will be
* able to see the common objective cards and three cards received from the server with this message.
+ * @implSpec NON-BLOCKING
* @param secrets the secret objective cards received from the server and assigned to the player.
* @param common the common objective cards of the game received from the server.
* @param hand the three cards received from the server and should be stored in the player's hand.
@@ -652,6 +672,7 @@ public void setCardsReceived(ArrayList secrets, ArrayList comm
/**
* Method that save the ID of the starter card received from the server.
+ * @implSpec NON-BLOCKING
* @param cardId the ID of the starter card received from the server.
*/
@Override
@@ -685,6 +706,7 @@ public void requestSelectSecretObjectiveCard() {
/**
* Once received the SecretObjCardConfirmationMessage from the server, the method is called by processMessage to
* update the view of the player and print the message to notify the player that the secret objective card is selected
+ * @implSpec NON-BLOCKING
* @param chosenSecretObjectiveCard the ID of the secret objective card selected by the player.
*/
@Override
@@ -699,7 +721,7 @@ public void updateConfirmSelectedSecretCard(int chosenSecretObjectiveCard) {
/**
* This method is called by processMessage to update the all data of the players in the game when the game enters
* the playing phase or when the player reconnects to the game.
- *
+ * @implSpec NON-BLOCKING
* @param playerNicknames the nicknames of the players in the game.
* @param playerConnected the connection status of the players in the game.
* @param playerColours the colours assigned to the players in the game.
@@ -873,6 +895,7 @@ public void updatePlayerData(ArrayList playerNicknames, ArrayList hand) {
* Once the player receives the DeckSizeUpdateMessage from the server, the method is called by processMessage to
* update the deck size and the current visible resource cards and gold cards in the game. Also, the method prints
* the message to notify the player the situation of the deck after this turn.
+ * @implSpec NON-BLOCKING
* @param resourceDeckSize the size of the resource deck in the game.
* @param goldDeckSize the size of the gold deck in the game.
* @param currentResourceCards the current visible resource cards in the game that the player can draw.
@@ -1239,6 +1266,7 @@ public void updateDeck(int resourceDeckSize, int goldDeckSize, int[]currentResou
* Method called when player opens chat from getInput method.
* Enables the user to select a player to chat with, or chat with all players.
* The user can also exit the chat.
+ * @implSpec BLOCKING-BUT-RAN-FROM-RIT
*/
@Override
public void startChatting() {
@@ -1316,6 +1344,8 @@ else if (messageContent.equals("EXIT")) { // Abort sending message
/**
* Method to print out the chat history of the player.
+ * @implSpec NON-BLOCKING
+ * @param chatHistory the chat history of the player.
*/
@Override
public void showChatHistory(List chatHistory){
@@ -1336,6 +1366,7 @@ else if(chat.getRecipientNickname().equals(thisPlayerNickname) || chat.isMultica
/**
* Method used to update the chat history of the player when a new message is received, add the message to the chat
* history and print the chat history if the player is in the chat mode.
+ * @implSpec NON-BLOCKING
* @param recipientString the nickname of the recipient of the message.
* @param senderNickname the nickname of the sender of the message.
* @param content the content of the message.
@@ -1351,8 +1382,10 @@ public void updateChat(String recipientString, String senderNickname, String con
}
//-------------------Show Methods-------------------
+
/**
* Print the deck size and the current visible resource cards and gold cards in the game.
+ * @implSpec NON-BLOCKING
*/
@Override
public void showDeck() {
@@ -1368,6 +1401,7 @@ public void showDeck() {
/**
* Print the list of commands that the player can use in the service mode.
+ * @implSpec NON-BLOCKING
*/
@Override
public void showHelpInfo() {
@@ -1387,11 +1421,13 @@ public void showHelpInfo() {
SGO: to see the game order.
SID: to see the game ID.
SCD: to see the deck size and the current visible cards in the game.
-
+
""");
}
+
/**
* Print list of the players in the game.
+ * @implSpec NON-BLOCKING
*/
public void showPlayerInGame() {
out.println("The players in the game are: " + players);
@@ -1399,6 +1435,7 @@ public void showPlayerInGame() {
/**
* Print the board view and the resources in the field of the given player.
+ * @implSpec NON-BLOCKING
* @param playerNickname the nickname of the player whose field should be printed.
*/
public void showPlayersField(String playerNickname) {
@@ -1408,6 +1445,7 @@ public void showPlayersField(String playerNickname) {
/**
* Print the resources in the field of the player.
+ * @implSpec NON-BLOCKING
* @param playerNickname the nickname of the player whose resources should be printed.
*/
@Override
@@ -1424,7 +1462,7 @@ public void showPointsAndResource(String playerNickname) {
/**
* Print the zone of the board where the player placed his cards and the available positions for the next
* placement.
- *
+ * @implSpec NON-BLOCKING
* @param nickname the nickname of the player, the owner of the board that should be printed.
*/
private void showBoard(String nickname) {
@@ -1441,8 +1479,10 @@ private void showBoard(String nickname) {
out.println();
}
}
+
/**
* Print the cards in the hand of the player.
+ * @implSpec NON-BLOCKING
*/
@Override
public void showHand() {
@@ -1457,6 +1497,7 @@ public void showHand() {
/**
* Print the objective cards.
+ * @implSpec NON-BLOCKING
* @param ObjCards the ID of the objective cards that should be printed.
*/
private void showObjectiveCards(ArrayList ObjCards) {
@@ -1469,6 +1510,9 @@ private void showObjectiveCards(ArrayList ObjCards) {
/**
* Print a card based on the ID of the card and the side of the card.
+ * @implSpec NON-BLOCKING
+ * @param ID the ID of the card.
+ * @param isUp the side of the card.
*/
@Override
public void showCard(int ID, boolean isUp) {
@@ -1489,6 +1533,7 @@ public void showCard(int ID, boolean isUp) {
/**
* Print at the end of the match the final points of the players, the secret objective card of the players, and the
* points gained from the objective card. Also, the method prints the winners of the match.
+ * @implSpec NON-BLOCKING
* @param players the nicknames of the players in the game.
* @param points the final points of the players in the game.
* @param secrets the secret objective card of the players.
@@ -1498,7 +1543,7 @@ public void showCard(int ID, boolean isUp) {
@Override
public void showMatchWinners(ArrayList players, ArrayList points, ArrayList secrets,
ArrayList pointsGainedFromObj, ArrayList winners) {
- currentEvent = Event.TERMINATED;
+ Status = Event.TERMINATED;
out.println("The match is ended !!!");
out.println("The winners of the match are: "+winners);
out.println("The final points of the players are following:");
@@ -1516,8 +1561,10 @@ public void showMatchWinners(ArrayList players, ArrayList point
}
//-------------------Card Factory-------------------
+
/**
* Search the card description based on the ID of the card.
+ * @implSpec NON-BLOCKING
* @param ID the ID of the card.
* @return the card description.
*/
@@ -1537,6 +1584,7 @@ private NonObjCardFactory searchNonObjCardById(int ID) {
/**
* Set the image of the card based on the card description, the view of the card in TUI. Store the image of the card
* in the hashmap with the ID of the card as the key.
+ * @implSpec NON-BLOCKING
* @return hashmap with the ID of the card as the key and the image of the card as the value.
*/
private HashMap> setImg() {
@@ -1730,7 +1778,7 @@ private HashMap> setImg() {
}
case "AllSpecial": {
// description of the three objects that should be count in the field.
- description = "INSKELL+QUILL+MANUSCRIPT";
+ description = "INKWELL+QUILL+MANUSCRIPT";
paddingDescription = 26 - description.length();
paddingIcon = 26 - 3 * icon("INKWELL").length();
paddingPoint = 26 - (value + " POINTS" + strategy).length();
@@ -1752,9 +1800,9 @@ private HashMap> setImg() {
/**
* Use this method to set the color of the card based on the kingdom of the card.
- *
+ * @implSpec NON-BLOCKING
* @param kingdom the kingdom of the card.
- * @return the string of the color in ASCI escape code.
+ * @return the string of the color in ASCII escape code.
*/
private static String ColourCard(String kingdom) {
String colour = "";
@@ -1771,7 +1819,7 @@ private static String ColourCard(String kingdom) {
/**
* The Method used to convert the integer array of the condition count of the card to a string of icons, using the
* Unicode characters and added it in one string.
- *
+ * @implSpec NON-BLOCKING
* @param conditionCount the integer array of the requirement counts of the card.
* @return the string of icons which contains the icons of the requirements of the card.
*/
@@ -1791,7 +1839,7 @@ private static String iconArray(int[] conditionCount) {
/**
* Method used to convert the corner type of the card to an icon, using the Unicode characters.
- *
+ * @implSpec NON-BLOCKING
* @param type the corner type of the card.
* @return the icon of the corner type of the card.
*/
@@ -1814,6 +1862,7 @@ private static String icon(String type) {
/**
* Method used to convert the type of the resource/object that stored in the array of requirements of the card or
* in the array of the permanent resources of the card to an icon, using the Unicode characters.
+ * @implSpec NON-BLOCKING
*/
private static String iconArrayElement(int type) {
String icon;
@@ -1832,6 +1881,7 @@ private static String iconArrayElement(int type) {
/**
* Method used to convert the colour of the card to an icon, using the Unicode characters.
+ * @implSpec NON-BLOCKING
*/
private static String iconCard(String type) {
String icon;
@@ -1847,6 +1897,7 @@ private static String iconCard(String type) {
/**
* Colour the string based on the integer received.
+ * @implSpec NON-BLOCKING
* @param colour indicates the colour of the string.
* @return the string βcolourβ coloured.
*/
@@ -1873,12 +1924,13 @@ public String convertToColour(int colour) {
}
}
}
+
//-------------------utilities-------------------
/**
* Used method to update the dimensions of the player's board view after placing a card on the board.
* The method is called by the {@link View#updateAfterPlacedCard} method.
- *
+ * @implSpec NON-BLOCKING
* @param posX the x coordinate of the card placed.
* @param posY the y coordinate of the card placed.
* @param limits the array of the limits contains the maximum x and y and the minimum x and y updated.
@@ -1889,56 +1941,55 @@ private void updateBoardViewLimits(int posX, int posY, int[] limits) {
limits[2] = Math.max(limits[2], posY + 1);
limits[3] = Math.min(limits[3], posY - 1);
}
+
/**
* Used method to handle the failure messages received from the server and to ask the user to try again.
+ * @implSpec NON-BLOCKING
* @param event the event that failed.
* @param reason the reason of the failure.
*/
@Override
- public void handleFailureCase(Event event,String reason){
- out.println(reason);
+ public void handleFailureCase(Event event, String reason){
switch (event){
- case CHOOSE_CONNECTION -> { // Connection failure
- out.println("Please try again:");
- chooseConnection();
- }
- case CREATE_GAME-> { // Create game failure
- out.println("Please try again:");
- askCreateGame();
+ case CREATE_GAME-> { // Should never happen!
+ out.println("Please try again! Reason: " + reason);
+ currentEvent = Event.CREATE_GAME_FAILURE;
}
- case JOIN_GAME-> { // Join game failure
- out.println("Please try again:");
- askJoinGame();
+ case JOIN_GAME-> {
+ out.println("Please try again! Reason: " + reason);
+ currentEvent = Event.JOIN_GAME_FAILURE;
}
- case RECONNECT_GAME -> { // Reconnect game failure
- out.println("Please try again:");
- askReconnectGame();
+ case RECONNECT_GAME -> {
+ out.println("Please try again! Reason: " + reason);
+ currentEvent = Event.RECONNECT_GAME_FAILURE;
}
- case PLACE_CARD_FAILURE -> { // Place card failure
- out.println("Please try again:");
+ case PLACE_CARD_FAILURE -> {
+ out.println("Please try again! Reason: " + reason);
currentEvent = Event.PLACE_CARD;
}
- case DRAW_CARD_FAILURE -> { // Draw card failure
- out.println("Please try again:");
+ case DRAW_CARD_FAILURE -> {
+ out.println("Please try again! Reason: " + reason);
currentEvent = Event.DRAW_CARD;
}
- case SELECT_SECRET_OBJ_CARD_FAILURE -> { // Select secret objective card failure
- out.println("Please try again:");
+ case SELECT_SECRET_OBJ_CARD_FAILURE -> {
+ out.println("Please try again! Reason: " + reason);
currentEvent = Event.SELECTED_SECRET_OBJ_CARD;
}
- case SELECT_STARTER_CARD_SIDE_FAILURE -> { // Select starter card side failure
- out.println("Please try again:");
+ case SELECT_STARTER_CARD_SIDE_FAILURE -> {
+ out.println("Please try again! Reason: " + reason);
currentEvent = Event.SELECT_STARTER_CARD_SIDE;
}
- case CHAT_ERROR -> { // Chat error
- out.println("!The last message was not sent!");
- ChatMessage error = new ChatMessage("NOTICE",thisPlayerNickname, false,"The last message was not sent! "+reason);
+ case CHAT_ERROR -> {
+ out.println("The last message was not sent! Reason: " + reason);
+ ChatMessage error = new ChatMessage("NOTICE", thisPlayerNickname, false,"The last message was not sent! " + reason);
chatHistory.add(error);
}
}
}
+
/**
* Used method to print the message to notify the player when is necessary.
+ * @implSpec NON-BLOCKING
* @param event the type of the event that should be handled.
* @param nickname the nickname of the player will be used in the message.
*/
@@ -1970,22 +2021,6 @@ public void handleEvent(Event event,String nickname) {
}
}
- /**
- * Use this method to clear the console screen.
- */
- private void clearCMD() { //TODO: ADDED THIS METHOD TO CLEAR THE SCREEN
- try {
- if (System.getProperty("os.name").contains("Windows"))
- new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
- else
- Runtime.getRuntime().exec("clear");
- } catch (IOException | InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- System.out.print("\033[H\033[2J");
- System.out.flush();
- }
-
/**
* The Method used to get the input from the user and handle the commands that the user can use to interact with the
* game in the service mode.
@@ -1993,7 +2028,7 @@ private void clearCMD() { //TODO: ADDED THIS METHOD TO CLEAR THE SCREEN
*/
private synchronized String getInput() {
String input = "";
- if (!currentEvent.equals(Event.TERMINATED)) {
+ if (!Status.equals(Event.TERMINATED)) {
input= in.nextLine();
}
switch (input) {
@@ -2002,7 +2037,7 @@ private synchronized String getInput() {
case "Chat" -> startChatting();
case "SP" -> showPlayerInGame();
case "SGS" -> out.println("The match status is: " + Status);
- case "SR" -> out.println("Game rule:https://it.boardgamearena.com/link?url=https%3A%2F%2Fcdn.1j1ju.com%2Fmedias%2Fa7%2Fd7%2F66-codex-naturalis-rulebook.pdf&id=9212");
+ case "SR" -> out.println("Game rule:https://t.ly/ZtnYH");
case "SH" -> showHand();
case "SCO" -> showObjectiveCards(commonObjCards);
case "SSO" -> showCard(secretObjCardSelected, true);
@@ -2049,11 +2084,10 @@ private int getInputInt() {
}
}
}
-}
-
-
-
-
-
+ // TODO implementare metodo
+ public void nodeDisconnected(){}
+ // TODO implementare metodo
+ public void nodeReconnected(){}
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/GamesManager.java b/src/main/java/it/polimi/ingsw/am32/controller/GamesManager.java
index 4c43fe4a..6030fcb5 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/GamesManager.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/GamesManager.java
@@ -114,9 +114,9 @@ public synchronized GameController createGame(String creatorName, int playerCoun
* @throws GameNotFoundException If no game with the given code is found
* @throws FullLobbyException If the lobby of the game is full
* @throws GameAlreadyStartedException If the game has already started
- * @throws DuplicateNicknameException If the player with the given nickname is already in the game
+ * @throws CTRDuplicateNicknameException If the player with the given nickname is already in the game
*/
- public synchronized GameController accessGame(String nickname, int gameCode, NodeInterface node) throws GameNotFoundException, FullLobbyException, GameAlreadyStartedException, DuplicateNicknameException {
+ public synchronized GameController accessGame(String nickname, int gameCode, NodeInterface node) throws GameNotFoundException, FullLobbyException, GameAlreadyStartedException, CTRDuplicateNicknameException {
logger.debug("Received request to access game. Nickname: {}, game code: {}, node: {}", nickname, gameCode, node);
if(nickname == null || nickname.isBlank()) {
throw new CriticalFailureException("Nickname cannot be null or empty");
@@ -149,6 +149,8 @@ public synchronized GameController accessGame(String nickname, int gameCode, Nod
}
} catch (VirtualViewNotFoundException e) { // Player was added, but his virtual view could not be found
throw new CriticalFailureException("VirtualViewNotFoundException when player joined the game");
+ } catch (DuplicateNicknameException e) { // Player is not added to the game as he has a duplicate nickname
+ throw new CTRDuplicateNicknameException("Player with nickname " + nickname + " is already in the game");
}
if (game.getGameSize() == game.getLobbyPlayerCount()) { // Lobby is now full
@@ -169,12 +171,13 @@ public synchronized GameController accessGame(String nickname, int gameCode, Nod
* @param node The server node associated with the given player
* @return The GameController of the game with the given code
* @throws GameAlreadyEndedException If the game has already ended
- * @throws PlayerNotFoundException If the player with the given nickname is not found in the game
+ * @throws CTRPlayerNotFoundException If the player with the given nickname is not found in the game
* @throws GameNotFoundException If no game with the given code is found
* @throws PlayerAlreadyConnectedException If the player with the given nickname is already connected to the game
+ * @throws GameNotYetStartedException If the game has not yet started
*/
public synchronized GameController reconnectToGame(String nickname, int gameCode, NodeInterface node) throws
- GameAlreadyEndedException, PlayerNotFoundException, GameNotFoundException, PlayerAlreadyConnectedException,
+ GameAlreadyEndedException, CTRPlayerNotFoundException, GameNotFoundException, PlayerAlreadyConnectedException,
GameNotYetStartedException
{
logger.debug("Received request to reconnect to game. Nickname: {}, game code: {}, node: {}", nickname, gameCode, node);
@@ -206,6 +209,8 @@ public synchronized GameController reconnectToGame(String nickname, int gameCode
}
} catch (VirtualViewNotFoundException e) {
throw new CriticalFailureException("VirtualViewNotFoundException when player reconnected to the game");
+ } catch (PlayerNotFoundException e) {
+ throw new CTRPlayerNotFoundException("Player with nickname " + nickname + " not found in the game");
}
return game;
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRDuplicateNicknameException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRDuplicateNicknameException.java
new file mode 100644
index 00000000..3ad2c33c
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRDuplicateNicknameException.java
@@ -0,0 +1,20 @@
+package it.polimi.ingsw.am32.controller.exceptions;
+
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
+/**
+ * This exception is thrown when a player tries to join a lobby with a nickname that is already in use.
+ */
+public class CTRDuplicateNicknameException extends LobbyMessageException {
+ /**
+ * Creates a new CTRDuplicateNicknameException with the given message.
+ * @param message The message of the exception.
+ */
+ public CTRDuplicateNicknameException(String message) {
+ super(
+ LobbyMessageExceptionEnumeration.DUPLICATE_NICKNAME_EXCEPTION,
+ message
+ );
+ }
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRPlayerNotFoundException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRPlayerNotFoundException.java
new file mode 100644
index 00000000..0996e42b
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/CTRPlayerNotFoundException.java
@@ -0,0 +1,20 @@
+package it.polimi.ingsw.am32.controller.exceptions;
+
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
+/**
+ * This exception is thrown when a player tries to join a lobby with a nickname that is already in use.
+ */
+public class CTRPlayerNotFoundException extends LobbyMessageException {
+ /**
+ * Creates a new CTRPlayerNotFoundException with the given message.
+ * @param message The message of the exception.
+ */
+ public CTRPlayerNotFoundException(String message) {
+ super(
+ LobbyMessageExceptionEnumeration.PLAYER_NOT_FOUND_EXCEPTION,
+ message
+ );
+ }
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/FullLobbyException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/FullLobbyException.java
index f139da40..95dd25b5 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/FullLobbyException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/FullLobbyException.java
@@ -1,13 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
* This exception is thrown when a player tries to join a full lobby.
*/
-public class FullLobbyException extends Exception {
+public class FullLobbyException extends LobbyMessageException {
/**
- * Constructor for the exception.
- *
- * @param message The message to be displayed when the exception is thrown
+ * Creates a new FullLobbyException with the given message.
+ * @param message The message of the exception.
*/
- public FullLobbyException(String message) { super(message); }
+ public FullLobbyException(String message) {
+ super(
+ LobbyMessageExceptionEnumeration.FULL_LOBBY_EXCEPTION,
+ message
+ );
+ }
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyEndedException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyEndedException.java
index 127b32a6..a31422f1 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyEndedException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyEndedException.java
@@ -1,15 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
* This exception is thrown when a game is already ended and a player tries to join it.
*/
-public class GameAlreadyEndedException extends Exception {
+public class GameAlreadyEndedException extends LobbyMessageException {
/**
- * Constructor
- *
- * @param message The message to be shown
+ * Creates a new GameAlreadyEndedException with the given message.
+ * @param message The message of the exception.
*/
public GameAlreadyEndedException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.GAME_ALREADY_ENDED_EXCEPTION,
+ message
+ );
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyStartedException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyStartedException.java
index af034783..c1222a65 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyStartedException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameAlreadyStartedException.java
@@ -1,15 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
* This exception is thrown when a game is already started and a player tries to join it.
*/
-public class GameAlreadyStartedException extends Exception {
+public class GameAlreadyStartedException extends LobbyMessageException {
/**
- * Constructor
- *
- * @param message The message to be shown
+ * Creates a new GameAlreadyStartedException with the given message.
+ * @param message The message of the exception.
*/
public GameAlreadyStartedException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.GAME_ALREADY_STARTED_EXCEPTION,
+ message
+ );
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotFoundException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotFoundException.java
index 3234039c..b4efcae8 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotFoundException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotFoundException.java
@@ -1,17 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
* This class represents an exception that is thrown when no game is found.
- * It extends the Exception class, meaning it's a checked exception.
- * Checked exceptions need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.
*/
-public class GameNotFoundException extends Exception {
+public class GameNotFoundException extends LobbyMessageException {
/**
- * Constructs a new NoGameFoundException with the specified detail message.
- *
- * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method.
+ * Constructs a new NoGameFoundException with the given message.
+ * @param message The message of the exception.
*/
public GameNotFoundException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.GAME_NOT_FOUND_EXCEPTION,
+ message
+ );
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotYetStartedException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotYetStartedException.java
index f30a8b8c..b2d5b1f2 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotYetStartedException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/GameNotYetStartedException.java
@@ -1,17 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
- * This class represents a custom exception that is thrown when a game operation is attempted
- * before the game has officially started. It extends the Exception class, thereby inheriting
- * its methods and can be used in a try-catch block.
+ * This exception is thrown when a player tries to connect to a game that has not yet started.
*/
-public class GameNotYetStartedException extends Exception {
+public class GameNotYetStartedException extends LobbyMessageException {
/**
- * Constructor for the GameNotYetStartedException class.
- *
- * @param message The detail message which is saved for later retrieval by the Throwable.getMessage() method.
+ * Creates a new GameNotYetStartedException with the given message.
+ * @param message The message of the exception.
*/
public GameNotYetStartedException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.GAME_NOT_YET_STARTED_EXCEPTION,
+ message
+ );
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/InvalidPlayerNumberException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/InvalidPlayerNumberException.java
index 0b7d081f..9f28c3b2 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/InvalidPlayerNumberException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/InvalidPlayerNumberException.java
@@ -1,15 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
* This exception is thrown when the number of players in a game is invalid.
*/
-public class InvalidPlayerNumberException extends Exception {
+public class InvalidPlayerNumberException extends LobbyMessageException {
/**
* Creates a new InvalidPlayerNumberException with the given message.
- *
- * @param message The message of the exception
+ * @param message The message of the exception.
*/
public InvalidPlayerNumberException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.INVALID_PLAYER_NUMBER_EXCEPTION,
+ message
+ );
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/PlayerAlreadyConnectedException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/PlayerAlreadyConnectedException.java
index 5eba39f3..b8e41ac7 100644
--- a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/PlayerAlreadyConnectedException.java
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/PlayerAlreadyConnectedException.java
@@ -1,15 +1,20 @@
package it.polimi.ingsw.am32.controller.exceptions;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration;
+
/**
- * PlayerAlreadyConnectedException is thrown when a player tries to connect to the server but he is already connected
+ * This exception is thrown when a player is already connected but tries to connect again somehow.
*/
-public class PlayerAlreadyConnectedException extends Exception {
+public class PlayerAlreadyConnectedException extends LobbyMessageException {
/**
- * Constructor
- *
- * @param message the message to be shown
+ * Creates a new PlayerAlreadyConnectedException with the given message.
+ * @param message The message of the exception.
*/
public PlayerAlreadyConnectedException(String message) {
- super(message);
+ super(
+ LobbyMessageExceptionEnumeration.PLAYER_ALREADY_CONNECTED_EXCEPTION,
+ message
+ );
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageException.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageException.java
new file mode 100644
index 00000000..3ea0f3b0
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageException.java
@@ -0,0 +1,32 @@
+package it.polimi.ingsw.am32.controller.exceptions.abstraction;
+
+/**
+ * The LobbyMessageException class represents an exception that can be thrown during
+ * the elaboration of a generic Lobby-Message.
+ * It contains the type of the exception and a message associated with it.
+ * @see it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration
+ */
+public abstract class LobbyMessageException extends Exception {
+ /**
+ * The type of LobbyMessageException.
+ */
+ private final LobbyMessageExceptionEnumeration exceptionType;
+
+ /**
+ * Constructor for the LobbyMessageException class.
+ * @param exceptionType The type of LobbyMessageException.
+ * @param message The message associated with the exception.
+ */
+ public LobbyMessageException(LobbyMessageExceptionEnumeration exceptionType, String message) {
+ super(message);
+ this.exceptionType = exceptionType;
+ }
+
+ /**
+ * Gets the enumeration type of the exception.
+ * @return The enumeration type of the exception.
+ */
+ public LobbyMessageExceptionEnumeration getExceptionType() {
+ return exceptionType;
+ }
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageExceptionEnumeration.java b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageExceptionEnumeration.java
new file mode 100644
index 00000000..06ab0e79
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/controller/exceptions/abstraction/LobbyMessageExceptionEnumeration.java
@@ -0,0 +1,40 @@
+package it.polimi.ingsw.am32.controller.exceptions.abstraction;
+
+/**
+ * The LobbyMessageExceptionEnumeration enum represents the different exceptions that can be thrown during
+ * the elaboration of a generic Lobby-Message.
+ * Each exception is associated with a specific integer value.
+ * @value The integer value associated with each exception.
+ */
+public enum LobbyMessageExceptionEnumeration {
+ INVALID_PLAYER_NUMBER_EXCEPTION(0),
+ GAME_ALREADY_STARTED_EXCEPTION(1),
+ FULL_LOBBY_EXCEPTION(2),
+ DUPLICATE_NICKNAME_EXCEPTION(3),
+ GAME_NOT_FOUND_EXCEPTION(4),
+ GAME_ALREADY_ENDED_EXCEPTION(5),
+ PLAYER_NOT_FOUND_EXCEPTION(6),
+ PLAYER_ALREADY_CONNECTED_EXCEPTION(7),
+ GAME_NOT_YET_STARTED_EXCEPTION(8);
+
+ /**
+ * The integer value associated with each state.
+ */
+ private final int value;
+
+ /**
+ * Constructor for the MatchStatus enum.
+ * @param value The integer value associated with the state.
+ */
+ LobbyMessageExceptionEnumeration(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the integer value associated with the state.
+ * @return The integer value of the state.
+ */
+ public int getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/AccessGameMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/AccessGameMessage.java
index 761fab40..d9e3a076 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/AccessGameMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/AccessGameMessage.java
@@ -2,10 +2,10 @@
import it.polimi.ingsw.am32.controller.GameController;
import it.polimi.ingsw.am32.controller.GamesManager;
+import it.polimi.ingsw.am32.controller.exceptions.CTRDuplicateNicknameException;
import it.polimi.ingsw.am32.controller.exceptions.FullLobbyException;
import it.polimi.ingsw.am32.controller.exceptions.GameAlreadyStartedException;
import it.polimi.ingsw.am32.controller.exceptions.GameNotFoundException;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
import it.polimi.ingsw.am32.network.ServerNode.NodeInterface;
/**
@@ -33,11 +33,12 @@ public AccessGameMessage(int matchId, String senderNickname) {
* @return the game controller of the game the player wants to join
* @throws GameAlreadyStartedException if the game has already started
* @throws FullLobbyException if the lobby is full
- * @throws DuplicateNicknameException if the nickname is already in use
* @throws GameNotFoundException if the game was not found
+ * @throws CTRDuplicateNicknameException if the nickname is already in use
*/
@Override
- public GameController elaborateMessage(NodeInterface nodeInterface) throws GameAlreadyStartedException, FullLobbyException, DuplicateNicknameException, GameNotFoundException {
+ public GameController elaborateMessage(NodeInterface nodeInterface) throws GameAlreadyStartedException,
+ FullLobbyException, GameNotFoundException, CTRDuplicateNicknameException {
return GamesManager.getInstance().accessGame(senderNickname, matchId, nodeInterface);
}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSLobbyMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSLobbyMessage.java
index af5f8738..5bbef5d3 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSLobbyMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSLobbyMessage.java
@@ -1,9 +1,7 @@
package it.polimi.ingsw.am32.message.ClientToServer;
import it.polimi.ingsw.am32.controller.GameController;
-import it.polimi.ingsw.am32.controller.exceptions.*;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
import it.polimi.ingsw.am32.network.ServerNode.NodeInterface;
import java.io.Serializable;
@@ -13,9 +11,6 @@
* It contains a single method to elaborate the message
*/
public interface CtoSLobbyMessage extends Serializable {
- GameController elaborateMessage(NodeInterface nodeInterface) throws InvalidPlayerNumberException,
- GameAlreadyStartedException, FullLobbyException, DuplicateNicknameException, GameNotFoundException,
- GameAlreadyEndedException, PlayerNotFoundException, PlayerAlreadyConnectedException,
- GameNotYetStartedException;
+ GameController elaborateMessage(NodeInterface nodeInterface) throws LobbyMessageException;
String toString(); // Used for debugging purposes
}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSMessage.java
index 5b6565de..dab4e356 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/CtoSMessage.java
@@ -1,7 +1,6 @@
package it.polimi.ingsw.am32.message.ClientToServer;
import it.polimi.ingsw.am32.controller.GameController;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import java.io.Serializable;
@@ -13,7 +12,6 @@ public interface CtoSMessage extends Serializable {
/**
* Elaborates the message with the specified game controller.
- *
* @param gameController The game controller with which the message should be elaborated
*/
void elaborateMessage(GameController gameController);
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/ReconnectGameMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/ReconnectGameMessage.java
index 7f9818b3..1621709d 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/ReconnectGameMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/ReconnectGameMessage.java
@@ -2,11 +2,7 @@
import it.polimi.ingsw.am32.controller.GameController;
import it.polimi.ingsw.am32.controller.GamesManager;
-import it.polimi.ingsw.am32.controller.exceptions.GameAlreadyEndedException;
-import it.polimi.ingsw.am32.controller.exceptions.GameNotFoundException;
-import it.polimi.ingsw.am32.controller.exceptions.GameNotYetStartedException;
-import it.polimi.ingsw.am32.controller.exceptions.PlayerAlreadyConnectedException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
+import it.polimi.ingsw.am32.controller.exceptions.*;
import it.polimi.ingsw.am32.network.ServerNode.NodeInterface;
public class ReconnectGameMessage implements CtoSLobbyMessage {
@@ -20,8 +16,7 @@ public ReconnectGameMessage(String senderNickname, int matchId) {
@Override
public GameController elaborateMessage(NodeInterface nodeInterface) throws GameAlreadyEndedException,
- PlayerNotFoundException, GameNotFoundException, PlayerAlreadyConnectedException, GameNotYetStartedException
- {
+ GameNotFoundException, PlayerAlreadyConnectedException, GameNotYetStartedException, CTRPlayerNotFoundException {
return GamesManager.getInstance().reconnectToGame(senderNickname, matchId, nodeInterface);
}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/RequestPlayerFieldMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/RequestPlayerFieldMessage.java
index f4f710b8..b35d0de4 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/RequestPlayerFieldMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ClientToServer/RequestPlayerFieldMessage.java
@@ -1,7 +1,6 @@
package it.polimi.ingsw.am32.message.ClientToServer;
import it.polimi.ingsw.am32.controller.GameController;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
/**
* This class is used to manage the message sent by the client when he wants to see the field of another player.
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ErrorMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ErrorMessage.java
index cc1b5871..2f46f289 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ErrorMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ErrorMessage.java
@@ -5,15 +5,17 @@
public class ErrorMessage implements StoCMessage{
private final String message;
private final String recipientNickname;
+ private final int errorType;
- public ErrorMessage(String message, String recipientNickname) {
+ public ErrorMessage(String message, String recipientNickname, int errorType) {
this.message = message;
this.recipientNickname = recipientNickname;
+ this.errorType = errorType;
}
@Override
public void processMessage(View view) {
- view.handleFailureCase(view.getEvent(),message);
+ view.handleFailureCase(view.getEvent(), message);
}
@Override
@@ -26,6 +28,7 @@ public String toString() {
return "ErrorMessage:{" +
"message='" + message + '\'' +
", recipientNickname='" + recipientNickname + '\'' +
+ ", errorType=" + errorType +
'}';
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/InvalidInboundChatMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/InvalidInboundChatMessage.java
index 02e84711..e01ae854 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/InvalidInboundChatMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/InvalidInboundChatMessage.java
@@ -1,6 +1,5 @@
package it.polimi.ingsw.am32.message.ServerToClient;
-
import it.polimi.ingsw.am32.client.Event;
import it.polimi.ingsw.am32.client.View;
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/PlaceCardConfirmationMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/PlaceCardConfirmationMessage.java
index 2516e47b..5c9a5c42 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/PlaceCardConfirmationMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/PlaceCardConfirmationMessage.java
@@ -1,6 +1,5 @@
package it.polimi.ingsw.am32.message.ServerToClient;
-import it.polimi.ingsw.am32.client.Event;
import it.polimi.ingsw.am32.client.View;
import java.util.ArrayList;
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ResponseGameStatusFailedMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ResponseGameStatusFailedMessage.java
deleted file mode 100644
index 1fc2a9e3..00000000
--- a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/ResponseGameStatusFailedMessage.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package it.polimi.ingsw.am32.message.ServerToClient;
-
-public class ResponseGameStatusFailedMessage {
-}
diff --git a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/StoCMessage.java b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/StoCMessage.java
index 128440c6..42bed70d 100644
--- a/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/StoCMessage.java
+++ b/src/main/java/it/polimi/ingsw/am32/message/ServerToClient/StoCMessage.java
@@ -11,10 +11,8 @@
public interface StoCMessage extends Serializable {
/**
* Delivers the message to the specified virtual view.
- *
- *
*/
void processMessage(View view);
- String getRecipientNickname(); // Method needed for submitVirtualViewMessage method in Gamecontroller; GameController needs to know who to send message to
+ String getRecipientNickname(); // Method needed for submitVirtualViewMessage method in Gamecontroller; GameController needs to know who to send message to.
String toString(); // Used for debugging purposes
}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptor.java b/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptor.java
index 2a53ce56..ae16147b 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptor.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptor.java
@@ -1,10 +1,8 @@
package it.polimi.ingsw.am32.network.ClientAcceptor;
import it.polimi.ingsw.am32.controller.GameController;
-import it.polimi.ingsw.am32.controller.exceptions.*;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSLobbyMessage;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import it.polimi.ingsw.am32.network.ClientNode.RMIClientNodeInt;
import it.polimi.ingsw.am32.network.GameTuple;
import it.polimi.ingsw.am32.network.ServerNode.RMIServerNode;
@@ -22,10 +20,9 @@ public RMIClientAcceptor() throws RemoteException {}
// TODO export stuff
@Override
- public GameTuple uploadToServer(RMIClientNodeInt node, CtoSLobbyMessage message) throws RemoteException,
- GameAlreadyStartedException, FullLobbyException, InvalidPlayerNumberException, DuplicateNicknameException,
- GameNotFoundException, GameAlreadyEndedException, PlayerNotFoundException, PlayerAlreadyConnectedException,
- GameNotYetStartedException {
+ public GameTuple uploadToServer(RMIClientNodeInt node, CtoSLobbyMessage message)
+ throws RemoteException, LobbyMessageException
+ {
logger.info("Received a CtoSLobbyMessage from a RMI client: {}", message.toString());
@@ -34,9 +31,8 @@ public GameTuple uploadToServer(RMIClientNodeInt node, CtoSLobbyMessage message)
GameController gameController = null;
try {
gameController = message.elaborateMessage(rmiServerNode);
- } catch (DuplicateNicknameException | InvalidPlayerNumberException | GameAlreadyStartedException |
- GameNotYetStartedException | FullLobbyException | GameNotFoundException | GameAlreadyEndedException |
- PlayerNotFoundException | PlayerAlreadyConnectedException e) {
+ } catch (LobbyMessageException e) {
+ // TODO: Handle the exception, send ErrorMessage to the client instead
rmiServerNode.destroy();
logger.error("GameController access failed: {}", e.getMessage());
throw e;
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptorInt.java b/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptorInt.java
index 031fe52d..bff7a719 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptorInt.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientAcceptor/RMIClientAcceptorInt.java
@@ -1,9 +1,7 @@
package it.polimi.ingsw.am32.network.ClientAcceptor;
-import it.polimi.ingsw.am32.controller.exceptions.*;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSLobbyMessage;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import it.polimi.ingsw.am32.network.ClientNode.RMIClientNodeInt;
import it.polimi.ingsw.am32.network.GameTuple;
@@ -11,8 +9,6 @@
import java.rmi.RemoteException;
public interface RMIClientAcceptorInt extends Remote {
- GameTuple uploadToServer(RMIClientNodeInt node, CtoSLobbyMessage message) throws RemoteException,
- GameAlreadyStartedException, FullLobbyException, InvalidPlayerNumberException, DuplicateNicknameException,
- GameNotFoundException, GameAlreadyEndedException, PlayerNotFoundException, PlayerAlreadyConnectedException,
- GameNotYetStartedException;
+ GameTuple uploadToServer(RMIClientNodeInt node, CtoSLobbyMessage message)
+ throws RemoteException, LobbyMessageException;
}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientNodeInterface.java b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientNodeInterface.java
index eaa22dea..0f64dc71 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientNodeInterface.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientNodeInterface.java
@@ -4,8 +4,6 @@
import it.polimi.ingsw.am32.message.ClientToServer.CtoSMessage;
import it.polimi.ingsw.am32.network.exceptions.UploadFailureException;
-import java.io.IOException;
-
public interface ClientNodeInterface {
void uploadToServer(CtoSMessage message) throws UploadFailureException;
void uploadToServer(CtoSLobbyMessage message) throws UploadFailureException;
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientPingTask.java b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientPingTask.java
index e58bd9f6..ebd5b3a9 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientPingTask.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/ClientPingTask.java
@@ -8,4 +8,4 @@ public class ClientPingTask extends TimerTask {
public void run() {
node.pongTimeOverdue();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNode.java b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNode.java
index 2ea5c00e..90054b57 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNode.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNode.java
@@ -1,14 +1,12 @@
package it.polimi.ingsw.am32.network.ClientNode;
import it.polimi.ingsw.am32.client.View;
-import it.polimi.ingsw.am32.controller.exceptions.*;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSLobbyMessage;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSMessage;
import it.polimi.ingsw.am32.message.ClientToServer.PingMessage;
import it.polimi.ingsw.am32.message.ServerToClient.PongMessage;
import it.polimi.ingsw.am32.message.ServerToClient.StoCMessage;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import it.polimi.ingsw.am32.network.ClientAcceptor.RMIClientAcceptorInt;
import it.polimi.ingsw.am32.network.GameTuple;
import it.polimi.ingsw.am32.network.exceptions.NodeClosedException;
@@ -85,7 +83,7 @@ public void uploadToServer(CtoSMessage message) throws UploadFailureException {
logger.info("Message sent. Type: CtoSMessage: {}", message);
} catch (NodeClosedException e) { // TODO gestire eccezioni
throw new RuntimeException(e);
- } catch (PlayerNotFoundException | RemoteException e) {
+ } catch (RemoteException e) {
throw new RuntimeException(e);
}
}
@@ -114,10 +112,8 @@ public void uploadToServer(CtoSLobbyMessage message) throws UploadFailureExcepti
} catch (RemoteException e) { // TODO come gestisco queste exception??
throw new RuntimeException(e);
- } catch (GameAlreadyStartedException | FullLobbyException | InvalidPlayerNumberException |
- DuplicateNicknameException | GameNotFoundException | GameAlreadyEndedException |
- PlayerNotFoundException | PlayerAlreadyConnectedException | GameNotYetStartedException e) {
-
+ } catch (LobbyMessageException e) {
+ // TODO: Handle exception correctly
// view.failureCtoSLobby
}
}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNodeInt.java b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNodeInt.java
index 8e75a845..b5efec5c 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNodeInt.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ClientNode/RMIClientNodeInt.java
@@ -6,6 +6,5 @@
import java.rmi.RemoteException;
public interface RMIClientNodeInt extends Remote {
-
void uploadStoC(StoCMessage message) throws RemoteException;
}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/NodeInterface.java b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/NodeInterface.java
index 533d30f0..8ef6f7e4 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/NodeInterface.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/NodeInterface.java
@@ -1,13 +1,10 @@
package it.polimi.ingsw.am32.network.ServerNode;
-
import it.polimi.ingsw.am32.message.ServerToClient.StoCMessage;
import it.polimi.ingsw.am32.network.exceptions.UploadFailureException;
public interface NodeInterface {
void uploadToClient(StoCMessage message) throws UploadFailureException;
-
void pingTimeOverdue();
-
void resetTimeCounter();
-}
\ No newline at end of file
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/RMIServerNodeInt.java b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/RMIServerNodeInt.java
index ac9236a0..0d597ccd 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/RMIServerNodeInt.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/RMIServerNodeInt.java
@@ -1,12 +1,11 @@
package it.polimi.ingsw.am32.network.ServerNode;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSMessage;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import it.polimi.ingsw.am32.network.exceptions.NodeClosedException;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIServerNodeInt extends Remote {
- void uploadCtoS(CtoSMessage message) throws RemoteException, PlayerNotFoundException, NodeClosedException;
+ void uploadCtoS(CtoSMessage message) throws RemoteException, NodeClosedException;
}
diff --git a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/SKServerNode.java b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/SKServerNode.java
index 1df4ea4f..55fd3ea7 100644
--- a/src/main/java/it/polimi/ingsw/am32/network/ServerNode/SKServerNode.java
+++ b/src/main/java/it/polimi/ingsw/am32/network/ServerNode/SKServerNode.java
@@ -1,15 +1,14 @@
package it.polimi.ingsw.am32.network.ServerNode;
+import it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageException;
+import it.polimi.ingsw.am32.network.exceptions.ErrorMessageCode;
import it.polimi.ingsw.am32.utilities.Configuration;
import it.polimi.ingsw.am32.controller.GameController;
-import it.polimi.ingsw.am32.controller.exceptions.*;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSLobbyMessage;
import it.polimi.ingsw.am32.message.ClientToServer.CtoSMessage;
import it.polimi.ingsw.am32.message.ClientToServer.PingMessage;
import it.polimi.ingsw.am32.message.ServerToClient.ErrorMessage;
import it.polimi.ingsw.am32.message.ServerToClient.PongMessage;
-import it.polimi.ingsw.am32.model.exceptions.DuplicateNicknameException;
-import it.polimi.ingsw.am32.model.exceptions.PlayerNotFoundException;
import it.polimi.ingsw.am32.network.exceptions.NodeClosedException;
import it.polimi.ingsw.am32.network.exceptions.UninitializedException;
import it.polimi.ingsw.am32.network.exceptions.UploadFailureException;
@@ -169,7 +168,11 @@ private void listenForIncomingMessages() throws IOException, ClassNotFoundExcept
else if (message instanceof CtoSMessage) {
if (gameController == null) { // It should never happen that the gameController hasn't yet been assigned when a CtoSMessage is received
try {
- uploadToClient(new ErrorMessage("Error: StoCMessage was sent before StoCLobbyMessage", "PLAYER"));
+ uploadToClient(new ErrorMessage(
+ "StoCMessage was sent before StoCLobbyMessage",
+ "PLAYER",
+ ErrorMessageCode.STOCMESSAGE_SENT_BEFORE_STOCLOBBYMESSAGE.getCode()
+ ));
logger.info("StoCMessage received before StoCLobbyMessage. Sending ErrorMessage to client");
} catch (UploadFailureException e) {
logger.error("StoCMessage received before StoCLobbyMessage. Failed to send ErrorMessage to client");
@@ -189,7 +192,11 @@ else if (message instanceof CtoSMessage) {
else if (message instanceof CtoSLobbyMessage) {
if (gameController != null) { // It should never happen that the gameController has already been assigned when a CtoSLobbyMessage is received
try {
- uploadToClient(new ErrorMessage("Error: StoCLobbyMessage was sent when the game has already been chosen", "PLAYER"));
+ uploadToClient(new ErrorMessage(
+ "StoCLobbyMessage was sent when the game has already been chosen",
+ "PLAYER",
+ ErrorMessageCode.STOCLOBBYMESSAGE_SENT_BUT_GAMECONTROLLER_ALREADY_PRESENT.getCode()
+ ));
logger.info("StoCLobbyMessage received when gameController already assigned. Sending ErrorMessage to client");
} catch (UploadFailureException e) {
logger.error("StoCLobbyMessage received when gameController already assigned. Failed to send ErrorMessage to client");
@@ -207,70 +214,17 @@ else if (message instanceof CtoSLobbyMessage) {
gameController.getTimer().scheduleAtFixedRate(serverPingTask, 0, Configuration.getInstance().getPingTimeInterval());
logger.info("Elaborated CtoSLobbyMessage received: {}", message.toString());
- } catch (InvalidPlayerNumberException e) {
+ } catch (LobbyMessageException e) {
try {
- uploadToClient(new ErrorMessage("Error: invalid player number", "PLAYER"));
+ uploadToClient(new ErrorMessage(
+ e.getMessage(),
+ "PLAYER",
+ e.getExceptionType().getValue()
+ ));
logger.info("Invalid player number. Sending ErrorMessage to client");
} catch (UploadFailureException ex) {
logger.error("Invalid player number. Failed to send ErrorMessage to client");
}
- } catch (GameAlreadyStartedException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Game already started", "PLAYER"));
- logger.info("Game already started. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Game already started. Failed to send ErrorMessage to client");
- }
- } catch (FullLobbyException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Lobby already is full", "PLAYER"));
- logger.info("Lobby is already full. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Lobby is already full. Failed to send ErrorMessage to client");
- }
- } catch (DuplicateNicknameException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Player nickname already in use", "PLAYER"));
- logger.info("Player nickname already in use. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Player nickname already in use. Failed to send ErrorMessage to client");
- }
- } catch (GameNotFoundException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Game not found", "PLAYER"));
- logger.info("Game not found. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Game not found. Failed to send ErrorMessage to client");
- }
- } catch (GameAlreadyEndedException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Game already ended", "PLAYER"));
- logger.info("Game already ended. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Game already ended. Failed to send ErrorMessage to client");
- }
- } catch (GameNotYetStartedException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Game has not yet started, cannot reconnect now." +
- " Try accessing the game instead", "PLAYER"));
- logger.info("Game not yet started. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Game not yet started. Failed to send ErrorMessage to client");
- }
- } catch (PlayerNotFoundException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Player not found", "PLAYER"));
- logger.info("Player not found. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Player not found. Failed to send ErrorMessage to client");
- }
- } catch (PlayerAlreadyConnectedException e) {
- try {
- uploadToClient(new ErrorMessage("Error: Player already connected", "PLAYER"));
- logger.info("Player already connected. Sending ErrorMessage to client");
- } catch (UploadFailureException ex) {
- logger.error("Player already connected. Failed to send ErrorMessage to client");
- }
} catch (Exception e) {
logger.fatal("Error while elaborating CtoSLobbyMessage: ", e);
throw e;
@@ -278,7 +232,11 @@ else if (message instanceof CtoSLobbyMessage) {
}
else { // Unknown message type received
try {
- uploadToClient(new ErrorMessage("Error: message type not recognized", "PLAYER"));
+ uploadToClient(new ErrorMessage(
+ "Message type not recognized",
+ "PLAYER",
+ ErrorMessageCode.MESSAGE_TYPE_NOT_RECOGNIZED.getCode()
+ ));
logger.info("Message type not recognized. Sending ErrorMessage to client");
} catch (UploadFailureException e) {
logger.error("Message type not recognized. Failed to send ErrorMessage to client");
diff --git a/src/main/java/it/polimi/ingsw/am32/network/exceptions/ConnectionSetupFailedException.java b/src/main/java/it/polimi/ingsw/am32/network/exceptions/ConnectionSetupFailedException.java
new file mode 100644
index 00000000..0d16d0ba
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/network/exceptions/ConnectionSetupFailedException.java
@@ -0,0 +1,3 @@
+package it.polimi.ingsw.am32.network.exceptions;
+
+public class ConnectionSetupFailedException extends Throwable {}
\ No newline at end of file
diff --git a/src/main/java/it/polimi/ingsw/am32/network/exceptions/ErrorMessageCode.java b/src/main/java/it/polimi/ingsw/am32/network/exceptions/ErrorMessageCode.java
new file mode 100644
index 00000000..c8eed5f5
--- /dev/null
+++ b/src/main/java/it/polimi/ingsw/am32/network/exceptions/ErrorMessageCode.java
@@ -0,0 +1,34 @@
+package it.polimi.ingsw.am32.network.exceptions;
+
+/**
+ * Enumerates the error message codes.
+ * The error message codes are used to identify the type of error that occurred.
+ * @see it.polimi.ingsw.am32.controller.exceptions.abstraction.LobbyMessageExceptionEnumeration
+ * @see it.polimi.ingsw.am32.message.ServerToClient.ErrorMessage
+ */
+public enum ErrorMessageCode {
+ STOCMESSAGE_SENT_BEFORE_STOCLOBBYMESSAGE(128),
+ STOCLOBBYMESSAGE_SENT_BUT_GAMECONTROLLER_ALREADY_PRESENT(127),
+ MESSAGE_TYPE_NOT_RECOGNIZED(126);
+
+ /**
+ * The code associated with the error type.
+ */
+ private final int code;
+
+ /**
+ * Constructor for the error type.
+ * @param code The code associated with the error type.
+ */
+ ErrorMessageCode(int code) {
+ this.code = code;
+ }
+
+ /**
+ * Get the code associated with the error type.
+ * @return The code associated with the error type.
+ */
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/src/main/java/it/polimi/ingsw/am32/utilities/IsValid.java b/src/main/java/it/polimi/ingsw/am32/utilities/IsValid.java
index 70a785cb..902bba4b 100644
--- a/src/main/java/it/polimi/ingsw/am32/utilities/IsValid.java
+++ b/src/main/java/it/polimi/ingsw/am32/utilities/IsValid.java
@@ -1,5 +1,9 @@
package it.polimi.ingsw.am32.utilities;
+/**
+ * This class provides methods to check if an IP address and a port number are valid.
+ * Used to validate the IP address and port number provided by the user.
+ */
public class IsValid {
/**
* This method checks if the provided IP address is valid.
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 7aeb17c1..11e8d793 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -14,6 +14,7 @@
exports it.polimi.ingsw.am32.network.ClientAcceptor to java.rmi;
exports it.polimi.ingsw.am32.network to java.rmi;
exports it.polimi.ingsw.am32.model.exceptions to java.rmi;
+ exports it.polimi.ingsw.am32.controller.exceptions.abstraction to java.rmi;
exports it.polimi.ingsw.am32.controller to java.rmi;
exports it.polimi.ingsw.am32.controller.exceptions to java.rmi;
exports it.polimi.ingsw.am32.network.exceptions to java.rmi;
diff --git a/src/main/resources/.configureBeforePackaging.log4j2.xml b/src/main/resources/.configureBeforePackaging.log4j2.xml
new file mode 100644
index 00000000..8a1247e8
--- /dev/null
+++ b/src/main/resources/.configureBeforePackaging.log4j2.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/it/polimi/ingsw/am32/model/match/MatchSimulationTest.java b/src/test/java/it/polimi/ingsw/am32/model/match/MatchSimulationTest.java
index 72613eec..b09e8042 100644
--- a/src/test/java/it/polimi/ingsw/am32/model/match/MatchSimulationTest.java
+++ b/src/test/java/it/polimi/ingsw/am32/model/match/MatchSimulationTest.java
@@ -12,7 +12,6 @@
import static org.junit.jupiter.api.Assertions.*;
-import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.TestTemplate;