Added: Specific Error Display

This commit is contained in:
rubenpirreram
2026-05-26 19:08:11 +02:00
parent 9083fd8df4
commit 55ce0c1d0a
27 changed files with 223 additions and 149 deletions
@@ -78,10 +78,12 @@ public class ClientLauncherTUI {
} }
System.setProperty("java.rmi.server.hostname", myIP); System.setProperty("java.rmi.server.hostname", myIP);
RMIClient client = new RMIClient(controller, IP, 1099, myIP); RMIClient client = new RMIClient(controller, IP, 1099, myIP);
if (client.connect(username, proposedNumPlayers)) { ErrorType serverResponse=client.connect(username, proposedNumPlayers);
if (serverResponse==null) {
System.out.println("Succesfully connected to RMI server\n\n"); System.out.println("Succesfully connected to RMI server\n\n");
} else { } else {
System.out.println("RMI connection refused\n\n"); System.out.println("RMI connection refused\n\n");
controller.view.showError(serverResponse);
return; return;
} }
controller.setClient(client); controller.setClient(client);
@@ -92,10 +94,12 @@ public class ClientLauncherTUI {
} else if (networkType == 1) { } else if (networkType == 1) {
// Connect // Connect
TCPClient client = new TCPClient(controller, IP, 8080,8081); TCPClient client = new TCPClient(controller, IP, 8080,8081);
if (client.connect(username, proposedNumPlayers)) { ErrorType serverResponse=client.connect(username, proposedNumPlayers);
if (serverResponse==null) {
System.out.println("Succesfully connected to TCP server\n\n"); System.out.println("Succesfully connected to TCP server\n\n");
} else { } else {
System.out.println("TCP connection refused\n\n"); System.out.println("TCP connection refused\n\n");
controller.view.showError(serverResponse);
return; return;
} }
controller.setClient(client); controller.setClient(client);
@@ -154,7 +158,7 @@ public class ClientLauncherTUI {
System.out.println("Insert the required position:"); System.out.println("Insert the required position:");
pos = scanner.nextInt(); pos = scanner.nextInt();
} catch (Exception e) { } catch (Exception e) {
view.showError("ERROR: Invalid input(expected number)"); view.showMessage("ERROR: Invalid input(expected number)");
return; return;
} }
} }
@@ -178,7 +182,7 @@ public class ClientLauncherTUI {
} }
else else
{ {
view.showError("ERROR: Invalid input(action not valid)"); view.showMessage("ERROR: Invalid input(action not valid)");
} }
} }
@@ -68,14 +68,6 @@ public class ClientController {
this.myUsername = username; this.myUsername = username;
} }
/**
* Displays an error message in the view.
*
* @param message the error message to display.
*/
public void onError(String message) {
view.showError(message);
}
/** /**
* Requests to draw a tribe card from the upper list. * Requests to draw a tribe card from the upper list.
@@ -1,5 +1,5 @@
package it.polimi.ingsw.gc14; package it.polimi.ingsw.gc14;
public enum ErrorType { public enum ErrorType {
USERNAME_ALREADY_EXISTS,WRONG_PLAYER_NUMBER,WRONG_GAME_ACTION,SERVER_CRASHED USER_NOT_FOUND, USERNAME_ALREADY_USED,USER_ALREADY_CONNECTED,WRONG_PLAYER_NUMBER,WRONG_GAME_ACTION,SERVER_CRASHED,GENERIC_ERROR, GAME_ALREADY_STARTED
} }
@@ -1,5 +1,7 @@
package it.polimi.ingsw.gc14.Network; package it.polimi.ingsw.gc14.Network;
import it.polimi.ingsw.gc14.ErrorType;
/** /**
* Defines the operations that a client can request during the game. * Defines the operations that a client can request during the game.
*/ */
@@ -14,7 +16,7 @@ public interface IClient {
* @return {@code true} if the connection is established successfully, * @return {@code true} if the connection is established successfully,
* {@code false} otherwise. * {@code false} otherwise.
*/ */
boolean connect(String username, int preferredInt); ErrorType connect(String username, int preferredInt);
/** /**
* Requests to draw a tribe card from the upper tribe card list. * Requests to draw a tribe card from the upper tribe card list.
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network; package it.polimi.ingsw.gc14.Network;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Model.OrderLogicCard; import it.polimi.ingsw.gc14.Model.OrderLogicCard;
@@ -21,6 +22,11 @@ import java.util.Map;
*/ */
public abstract class NetworkEvent implements Serializable { public abstract class NetworkEvent implements Serializable {
protected ErrorType errorType;
public ErrorType getErrorType() {
return errorType;
}
/** /**
* Username of the player requesting the event. * Username of the player requesting the event.
*/ */
@@ -120,10 +126,11 @@ public abstract class NetworkEvent implements Serializable {
* @param isError {@code true} if the event represents an error, * @param isError {@code true} if the event represents an error,
* {@code false} otherwise. * {@code false} otherwise.
*/ */
protected NetworkEvent(String username, EventType eventType, boolean isError) { protected NetworkEvent(String username, EventType eventType, boolean isError,ErrorType errorType) {
this.username = username; this.username = username;
this.eventType = eventType; this.eventType = eventType;
this.isError = isError; this.isError = isError;
this.errorType = errorType;
} }
/** /**
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -14,6 +15,10 @@ import java.io.Serializable;
public class AddPlayer extends NetworkEvent implements Serializable { public class AddPlayer extends NetworkEvent implements Serializable {
/** Number of proposed players to add to the match */ /** Number of proposed players to add to the match */
private int proposedNPlayer; private int proposedNPlayer;
public void setErrorType(ErrorType errorType)
{
this.errorType = errorType;
}
/** /**
* @return the number of proposed players to add to the match * @return the number of proposed players to add to the match
@@ -29,7 +34,7 @@ public class AddPlayer extends NetworkEvent implements Serializable {
* @param proposedNPlayer the number of proposed players to add to the match * @param proposedNPlayer the number of proposed players to add to the match
*/ */
public AddPlayer(String username, int proposedNPlayer) { public AddPlayer(String username, int proposedNPlayer) {
super(username, EventType.ADD_PLAYER, false); super(username, EventType.ADD_PLAYER, false, ErrorType.GENERIC_ERROR);
this.proposedNPlayer = proposedNPlayer; this.proposedNPlayer = proposedNPlayer;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard;
import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState;
@@ -38,7 +39,7 @@ public class ApplyNextRound extends NetworkEvent implements Serializable{
* @param players the list of players in the game. * @param players the list of players in the game.
*/ */
public ApplyNextRound(Map<Slot, Player> slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, List<Player> players, ArrayList<TribeCard> upperListTribeCards, ArrayList<TribeCard>lowerListTribeCards, ArrayList<BuildingCard> upperListBuildingCards, ArrayList<BuildingCard>lowerListBuildingCards) { public ApplyNextRound(Map<Slot, Player> slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, List<Player> players, ArrayList<TribeCard> upperListTribeCards, ArrayList<TribeCard>lowerListTribeCards, ArrayList<BuildingCard> upperListBuildingCards, ArrayList<BuildingCard>lowerListBuildingCards) {
super("SERVER",EventType.NEXT_ROUND,false); super("SERVER",EventType.NEXT_ROUND,false, ErrorType.WRONG_GAME_ACTION);
this.upperListBuildingCards = upperListBuildingCards; this.upperListBuildingCards = upperListBuildingCards;
this.lowerListBuildingCards = lowerListBuildingCards; this.lowerListBuildingCards = lowerListBuildingCards;
this.upperListTribeCards = upperListTribeCards; this.upperListTribeCards = upperListTribeCards;
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -18,7 +19,7 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
* @param username the name of the player requesting the event * @param username the name of the player requesting the event
*/ */
public DisconnectedPlayer(String username){ public DisconnectedPlayer(String username){
super(username, EventType.DISCONNECTED_PLAYER, false); super(username, EventType.DISCONNECTED_PLAYER, false, ErrorType.GENERIC_ERROR);
} }
/** /**
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -22,7 +23,7 @@ public class DrawLowerBuildingCard extends NetworkEvent implements Serializable
* @param pos the index of the card to draw * @param pos the index of the card to draw
*/ */
public DrawLowerBuildingCard(String username, int pos){ public DrawLowerBuildingCard(String username, int pos){
super(username, EventType.DRAW_LOWER_BUILD, false); super(username, EventType.DRAW_LOWER_BUILD, false, ErrorType.WRONG_GAME_ACTION);
this.pos = pos; this.pos = pos;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -23,7 +24,7 @@ public class DrawLowerTribeCard extends NetworkEvent implements Serializable{
* @param pos the index of the card to draw * @param pos the index of the card to draw
*/ */
public DrawLowerTribeCard(String username, int pos){ public DrawLowerTribeCard(String username, int pos){
super(username, EventType.DRAW_LOWER_TRIBE, false); super(username, EventType.DRAW_LOWER_TRIBE, false, ErrorType.WRONG_GAME_ACTION);
this.pos = pos; this.pos = pos;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -23,7 +24,7 @@ public class DrawUpperBuildingCard extends NetworkEvent implements Serializable
* @param pos the index of the card to draw * @param pos the index of the card to draw
*/ */
public DrawUpperBuildingCard(String username, int pos){ public DrawUpperBuildingCard(String username, int pos){
super(username, EventType.DRAW_UPPER_BUILD, false); super(username, EventType.DRAW_UPPER_BUILD, false, ErrorType.WRONG_GAME_ACTION);
this.pos = pos; this.pos = pos;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -23,7 +24,7 @@ public class DrawUpperTribeCard extends NetworkEvent implements Serializable{
* @param pos the index of the card to draw * @param pos the index of the card to draw
*/ */
public DrawUpperTribeCard(String username, int pos){ public DrawUpperTribeCard(String username, int pos){
super(username, EventType.DRAW_UPPER_TRIBE, false); super(username, EventType.DRAW_UPPER_TRIBE, false, ErrorType.WRONG_GAME_ACTION);
this.pos = pos; this.pos = pos;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Model.OrderLogicCard; import it.polimi.ingsw.gc14.Model.OrderLogicCard;
@@ -31,7 +32,7 @@ public class EndedGame extends NetworkEvent implements Serializable{
* @param players the list of players at the end of the game. * @param players the list of players at the end of the game.
*/ */
public EndedGame(Map<Slot, Player> slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, ArrayList<Player> players){ public EndedGame(Map<Slot, Player> slotPlayerMap, OrderLogicCard orderLogicCard, CurrentState currentState, ArrayList<Player> players){
super("SERVER",EventType.ENDED_GAME,false); super("SERVER",EventType.ENDED_GAME,false, ErrorType.GENERIC_ERROR);
this.slotPlayerMap = slotPlayerMap; this.slotPlayerMap = slotPlayerMap;
this.orderLogicCard = orderLogicCard; this.orderLogicCard = orderLogicCard;
this.currentState = currentState; this.currentState = currentState;
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -18,7 +19,7 @@ public class ReconnectPlayer extends NetworkEvent implements Serializable {
* @param username the username of the player who reconnected. * @param username the username of the player who reconnected.
*/ */
public ReconnectPlayer(String username) { public ReconnectPlayer(String username) {
super(username, EventType.RECONNECT_PLAYER, false); super(username, EventType.RECONNECT_PLAYER, false, ErrorType.GENERIC_ERROR);
} }
/** /**
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -18,7 +19,7 @@ public class SkipTurn extends NetworkEvent implements Serializable{
* @param username the name of the player requesting the event * @param username the name of the player requesting the event
*/ */
public SkipTurn(String username){ public SkipTurn(String username){
super(username, EventType.SKIP_TURN, false); super(username, EventType.SKIP_TURN, false, ErrorType.WRONG_GAME_ACTION);
} }
/** /**
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -23,7 +24,7 @@ public class SlotChoice extends NetworkEvent implements Serializable {
* @param pos the index of the card to draw * @param pos the index of the card to draw
*/ */
public SlotChoice(String username, int pos) { public SlotChoice(String username, int pos) {
super(username, EventType.SLOT_CHOICE, false); super(username, EventType.SLOT_CHOICE, false, ErrorType.WRONG_GAME_ACTION);
this.pos = pos; this.pos = pos;
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.NetworkEvents; package it.polimi.ingsw.gc14.Network.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
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;
@@ -40,7 +41,7 @@ public class TotemChoice extends NetworkEvent implements Serializable {
* @param totem the name of the selected totem. * @param totem the name of the selected totem.
*/ */
public TotemChoice(String username, String totem) { public TotemChoice(String username, String totem) {
super(username, EventType.TOTEM_CHOICE, false); super(username, EventType.TOTEM_CHOICE, false, ErrorType.WRONG_GAME_ACTION);
this.totem = totem; this.totem = totem;
} }
@@ -55,7 +55,7 @@ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCa
@Override @Override
public void onAction(NetworkEvent event) throws RemoteException { public void onAction(NetworkEvent event) throws RemoteException {
if(event.getIsError()) { if(event.getIsError()) {
clientController.view.showError(event.toString()); clientController.view.showError(event.getErrorType());
} else { } else {
event.apply(clientController.miniModel); event.apply(clientController.miniModel);
clientController.view.render(); clientController.view.render();
@@ -5,6 +5,7 @@ import java.rmi.registry.Registry;
import java.util.concurrent.*; import java.util.concurrent.*;
import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Network.IClient; import it.polimi.ingsw.gc14.Network.IClient;
import it.polimi.ingsw.gc14.Network.NetworkEvents.*; import it.polimi.ingsw.gc14.Network.NetworkEvents.*;
import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer; import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer;
@@ -53,7 +54,7 @@ public class RMIClient implements IClient {
* opening a second socket). * opening a second socket).
*/ */
@Override @Override
public boolean connect(String username, int preferredInt) { public ErrorType connect(String username, int preferredInt) {
try { try {
System.setProperty("java.rmi.server.hostname", this.myIP); System.setProperty("java.rmi.server.hostname", this.myIP);
Registry registry = LocateRegistry.getRegistry(host, port); Registry registry = LocateRegistry.getRegistry(host, port);
@@ -61,16 +62,17 @@ public class RMIClient implements IClient {
this.username = username; this.username = username;
ClientCallbackImpl callback = new ClientCallbackImpl(controller); ClientCallbackImpl callback = new ClientCallbackImpl(controller);
boolean joined = stub.joinGame(username, preferredInt, callback); ErrorType status = stub.joinGame(username, preferredInt, callback);
if (!joined) return false; if(status==null)
{
running = true; running = true;
startHeartbeat(); startHeartbeat();
return true; return null;
}
return status;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return false; return ErrorType.GENERIC_ERROR;
} }
} }
@@ -124,7 +126,7 @@ public class RMIClient implements IClient {
if (!running) return; if (!running) return;
running = false; running = false;
if (pingSender != null) pingSender.shutdownNow(); if (pingSender != null) pingSender.shutdownNow();
controller.view.showError("Connection with server closed"); controller.view.showError(ErrorType.SERVER_CRASHED);
} }
@@ -1,5 +1,7 @@
package it.polimi.ingsw.gc14.Network.RMI.Common; package it.polimi.ingsw.gc14.Network.RMI.Common;
import it.polimi.ingsw.gc14.ErrorType;
import java.rmi.*; import java.rmi.*;
/** /**
@@ -18,7 +20,7 @@ public interface IGameServer extends Remote {
* {@code false} otherwise. * {@code false} otherwise.
* @throws RemoteException if an RMI communication error occurs. * @throws RemoteException if an RMI communication error occurs.
*/ */
boolean joinGame(String username, int preferredInt, IClientCallback callback) throws RemoteException; ErrorType joinGame(String username, int preferredInt, IClientCallback callback) throws RemoteException;
/** /**
* Requests to draw a tribe card from the upper tribe card list. * Requests to draw a tribe card from the upper tribe card list.
@@ -1,8 +1,10 @@
package it.polimi.ingsw.gc14.Network.RMI.Server; package it.polimi.ingsw.gc14.Network.RMI.Server;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.LimitedMap;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
import it.polimi.ingsw.gc14.Network.NetworkEvents.*; import it.polimi.ingsw.gc14.Network.NetworkEvents.*;
@@ -81,9 +83,9 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
* {@code TCPServer.acceptHeartbeat()}. * {@code TCPServer.acceptHeartbeat()}.
*/ */
@Override @Override
public boolean joinGame(String username, int preferredInt, IClientCallback callback) public ErrorType joinGame(String username, int preferredInt, IClientCallback callback)
throws RemoteException { throws RemoteException {
if (preferredInt < 2 || preferredInt > 5) return false; if (preferredInt < 2 || preferredInt > 5) return ErrorType.WRONG_PLAYER_NUMBER;
synchronized (controller) { synchronized (controller) {
@@ -92,32 +94,47 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
playerList.setLimit(preferredInt); playerList.setLimit(preferredInt);
System.out.println("Game Created With :"+preferredInt+" Players"); System.out.println("Game Created With :"+preferredInt+" Players");
} }
if(controller.getModel().getCurrentState().getGameStage()!= GameStages.WAITING ) {
if (!controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))) {
return ErrorType.GAME_ALREADY_STARTED;
}
}
else {
if (controller.addPlayer(username)) { if (controller.addPlayer(username)) {
clients.put(username, callback); clients.put(username, callback);
playerList.put(username, true); playerList.put(username, true);
startWatchdog(username); startWatchdog(username);
System.out.println("Accepted player: " + username); System.out.println("Accepted player: " + username);
return true; return null;
} else {
return ErrorType.USERNAME_ALREADY_USED;
} }
if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) { }
if(!playerList.containsKey(username)){
clients.put(username, callback); clients.put(username, callback);
playerList.put(username, true); playerList.put(username, true);
startWatchdog(username); startWatchdog(username);
System.out.println("(After crash)Reconnected player: " + username); System.out.println("(After crash)Reconnected player: " + username);
return true; return null;
} }
if (playerList.containsKey(username) && !playerList.get(username)) { else {
if(!playerList.get(username))
{
playerList.put(username, true); playerList.put(username, true);
clients.put(username, callback); clients.put(username, callback);
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()));
System.out.println("Model sent: " + username); System.out.println("Model sent: " + username);
actionQueue.add(new ReconnectPlayer(username)); actionQueue.add(new ReconnectPlayer(username));
return true; return null;
}
else
return ErrorType.USER_ALREADY_CONNECTED;
} }
return false;
} }
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.Network.TCP.Client; package it.polimi.ingsw.gc14.Network.TCP.Client;
import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.IClient; import it.polimi.ingsw.gc14.Network.IClient;
@@ -70,7 +71,7 @@ public class TCPClient implements IClient {
* @param proposedNPlayers The desired number of players for the game * @param proposedNPlayers The desired number of players for the game
* @return true if the connection is successful, false otherwise. * @return true if the connection is successful, false otherwise.
*/ */
public boolean connect(String user, int proposedNPlayers) { public ErrorType connect(String user, int proposedNPlayers) {
try { try {
communicationSocket = new Socket(hostname, mainPort); communicationSocket = new Socket(hostname, mainPort);
socketSend = new ObjectOutputStream(communicationSocket.getOutputStream()); socketSend = new ObjectOutputStream(communicationSocket.getOutputStream());
@@ -80,7 +81,16 @@ public class TCPClient implements IClient {
int read= communicationSocket.getInputStream().read(); int read= communicationSocket.getInputStream().read();
if ( read== -1) { if ( read== -1) {
System.out.println("Could not connect to server"); System.out.println("Could not connect to server");
return false;
try {
if( socketReceive.readObject() instanceof AddPlayer x)
{
return x.getErrorType();
}
} catch (ClassNotFoundException e) {
return ErrorType.GENERIC_ERROR;
}
return ErrorType.GENERIC_ERROR;
} }
new Thread(this::receiveMessage, "tcp-reader").start(); new Thread(this::receiveMessage, "tcp-reader").start();
@@ -95,11 +105,11 @@ public class TCPClient implements IClient {
new Thread(this::heartbeatLoop, "heartbeat").start(); new Thread(this::heartbeatLoop, "heartbeat").start();
running = true; running = true;
return true; return null;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return false; return ErrorType.GENERIC_ERROR;
} }
} }
@@ -143,7 +153,7 @@ public class TCPClient implements IClient {
running = false; running = false;
try { communicationSocket.close(); } catch (IOException ignored) {} try { communicationSocket.close(); } catch (IOException ignored) {}
try { heartbeatSocket.close(); } catch (IOException ignored) {} try { heartbeatSocket.close(); } catch (IOException ignored) {}
controller.view.showError("Connection with server lost"); controller.view.showError(ErrorType.SERVER_CRASHED);
} }
@@ -166,7 +176,7 @@ public class TCPClient implements IClient {
if (read instanceof NetworkEvent event) { if (read instanceof NetworkEvent event) {
if (event.getIsError()) { if (event.getIsError()) {
controller.view.showError(event.toString()); controller.view.showError(event.getErrorType());
} else { } else {
event.apply(controller.miniModel); event.apply(controller.miniModel);
controller.view.render(); controller.view.render();
@@ -1,8 +1,10 @@
package it.polimi.ingsw.gc14.Network.TCP.Server; package it.polimi.ingsw.gc14.Network.TCP.Server;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.LimitedMap; import it.polimi.ingsw.gc14.LimitedMap;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import it.polimi.ingsw.gc14.Model.MiniModel; 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;
@@ -168,7 +170,16 @@ public class TCPServer {
playerList.setLimit(eventAddPlayer.getProposedNPlayer()); playerList.setLimit(eventAddPlayer.getProposedNPlayer());
System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players"); System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players");
} }
if(controller.getModel().getCurrentState().getGameStage()!= GameStages.WAITING ) {
if (!controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))) {
clientSocket.getOutputStream().write(-1);
eventAddPlayer.setErrorType(ErrorType.GAME_ALREADY_STARTED);
clientSend.writeObject(eventAddPlayer);
clientSocket.close();
System.out.println("Invalid parameters. Connection terminated.");
}
}
else{
if (controller.addPlayer(username)) { if (controller.addPlayer(username)) {
playerList.put(username, true); playerList.put(username, true);
System.out.println("Accepted player: " + username); System.out.println("Accepted player: " + username);
@@ -194,9 +205,17 @@ public class TCPServer {
continue; continue;
} }
if (controller.getModel().getPlayers().stream() else {
.anyMatch(p -> p.getUserName().equals(username)) clientSocket.getOutputStream().write(-1);
&& !playerList.containsKey(username)) { eventAddPlayer.setErrorType(ErrorType.USERNAME_ALREADY_USED);
clientSend.writeObject(eventAddPlayer);
clientSocket.close();
System.out.println("Invalid parameters. Connection terminated.");
}
}
if (!playerList.containsKey(username)) {
playerList.put(username, true); playerList.put(username, true);
System.out.println("(After crash)Reconnected player: " + username); System.out.println("(After crash)Reconnected player: " + username);
@@ -222,8 +241,8 @@ public class TCPServer {
} }
//reconnect a previously disconnected player //reconnect a previously disconnected player
if (playerList.containsKey(username) else{
&& !playerList.get(username)) { if (!playerList.get(username)) {
playerList.put(username, true); playerList.put(username, true);
System.out.println("Reconnected player: " + username); System.out.println("Reconnected player: " + username);
@@ -248,7 +267,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()
)); ));
Thread thread = new Thread(handler); Thread thread = new Thread(handler);
@@ -260,8 +279,11 @@ public class TCPServer {
} else { } else {
clientSocket.getOutputStream().write(-1); clientSocket.getOutputStream().write(-1);
eventAddPlayer.setErrorType(ErrorType.USER_ALREADY_CONNECTED);
clientSend.writeObject(eventAddPlayer);
clientSocket.close(); clientSocket.close();
System.out.println("Player could not be added. Connection terminated."); System.out.println("Invalid parameters. Connection terminated.");
}
} }
} }
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
@@ -1,25 +1,16 @@
package it.polimi.ingsw.gc14.View.GUI; package it.polimi.ingsw.gc14.View.GUI;
import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.NetworkEvent;
import it.polimi.ingsw.gc14.View.GUI.LoginFXMLController;
import it.polimi.ingsw.gc14.View.GUI.MainFXMLController;
import it.polimi.ingsw.gc14.View.IView; import it.polimi.ingsw.gc14.View.IView;
import javafx.animation.PauseTransition;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D; import javafx.geometry.Rectangle2D;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Screen; import javafx.stage.Screen;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.IOException;
import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.ENDED; import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.ENDED;
import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.TOTEM_CHOICE; import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.TOTEM_CHOICE;
@@ -144,12 +135,11 @@ public class GUI extends Application implements IView {
} }
@Override @Override
public void showError(String message) { public void showError(ErrorType error) {
Platform.runLater(() -> { Platform.runLater(() -> {
synchronized (miniModel) { synchronized (miniModel) {
controllerMain.isError = true; controllerMain.isError = true;
controllerMain.render(); controllerMain.render();
System.out.println("ERRORE PORCODIDODODODOD");
} }
}); });
} }
@@ -1,6 +1,7 @@
package it.polimi.ingsw.gc14.View.GUI; package it.polimi.ingsw.gc14.View.GUI;
import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient; import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
import javafx.animation.*; import javafx.animation.*;
@@ -153,23 +154,28 @@ public class LoginFXMLController {
private void connect(String nome, String ip, int numPlayers, String localInterface) { private void connect(String nome, String ip, int numPlayers, String localInterface) {
if (isRMI) { if (isRMI) {
RMIClient client = new RMIClient(controller, ip, 1099, localInterface); RMIClient client = new RMIClient(controller, ip, 1099, localInterface);
if (client.connect(nome, numPlayers)) { ErrorType serverResponse=client.connect(nome, numPlayers);
if (serverResponse==null) {
controller.setClient(client); controller.setClient(client);
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…")); Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
} else { } else {
Platform.runLater(() -> showError("RMI connection failed.")); Platform.runLater(() -> showError(serverResponse));
} }
} else { } else {
TCPClient client = new TCPClient(controller, ip, 8080, 8081); TCPClient client = new TCPClient(controller, ip, 8080, 8081);
if (client.connect(nome, numPlayers)) { ErrorType serverResponse=client.connect(nome, numPlayers);
if (serverResponse==null) {
controller.setClient(client); controller.setClient(client);
Platform.runLater(() -> showSuccess("Connected! Waiting for other players…")); Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
} else { } else {
Platform.runLater(() -> showError("TCP connection failed.")); Platform.runLater(() -> showError(serverResponse));
} }
} }
} }
private void showError(ErrorType errorType) {
labelErrore.setTextFill(Color.web("#e05050"));
labelErrore.setText(errorType.toString());
}
private void showError(String msg) { private void showError(String msg) {
labelErrore.setTextFill(Color.web("#e05050")); labelErrore.setTextFill(Color.web("#e05050"));
labelErrore.setText(msg); labelErrore.setText(msg);
@@ -1,5 +1,6 @@
package it.polimi.ingsw.gc14.View; package it.polimi.ingsw.gc14.View;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.MiniModel; import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
@@ -7,7 +8,9 @@ import it.polimi.ingsw.gc14.Network.NetworkEvent;
public interface IView { public interface IView {
public void setModel(MiniModel miniModel); public void setModel(MiniModel miniModel);
public void render(); public void render();
public void showMessage(String message);
public void showError(String message); void showMessage(String message);
public void showError(ErrorType error);
} }
@@ -1,4 +1,5 @@
package it.polimi.ingsw.gc14.View.TUI; package it.polimi.ingsw.gc14.View.TUI;
import it.polimi.ingsw.gc14.ErrorType;
import it.polimi.ingsw.gc14.Model.*; import it.polimi.ingsw.gc14.Model.*;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvent;
@@ -231,12 +232,12 @@ public class TUI implements IView {
/** /**
* Prints an error message to standard output. * Prints an error message to standard output.
* *
* @param message the error message to display * @param error the error message to display
*/ */
public void showError(String message) { public void showError(ErrorType error) {
clearTerminal(); clearTerminal();
render(); render();
System.out.println(message); System.out.println(error);
} }
/** /**